2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/session_directory.h>
48 #include <ardour/utils.h>
49 #include <ardour/audio_diskstream.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/midi_diskstream.h>
54 #include <ardour/midi_playlist.h>
55 #include <ardour/midi_region.h>
56 #include <ardour/smf_source.h>
57 #include <ardour/auditioner.h>
58 #include <ardour/recent_sessions.h>
59 #include <ardour/redirect.h>
60 #include <ardour/send.h>
61 #include <ardour/insert.h>
62 #include <ardour/plugin_insert.h>
63 #include <ardour/port_insert.h>
64 #include <ardour/bundle.h>
65 #include <ardour/slave.h>
66 #include <ardour/tempo.h>
67 #include <ardour/audio_track.h>
68 #include <ardour/midi_track.h>
69 #include <ardour/cycle_timer.h>
70 #include <ardour/named_selection.h>
71 #include <ardour/crossfade.h>
72 #include <ardour/playlist.h>
73 #include <ardour/click.h>
74 #include <ardour/data_type.h>
75 #include <ardour/buffer_set.h>
76 #include <ardour/source_factory.h>
77 #include <ardour/region_factory.h>
78 #include <ardour/filename_extensions.h>
79 #include <ardour/session_directory.h>
82 #include <ardour/osc.h>
88 using namespace ARDOUR;
90 using boost::shared_ptr;
93 static const int CPU_CACHE_ALIGN = 64;
95 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
98 sigc::signal<int> Session::AskAboutPendingState;
99 sigc::signal<void> Session::SendFeedback;
101 sigc::signal<void> Session::SMPTEOffsetChanged;
102 sigc::signal<void> Session::StartTimeChanged;
103 sigc::signal<void> Session::EndTimeChanged;
105 Session::Session (AudioEngine &eng,
107 string snapshot_name,
108 string* mix_template)
111 _scratch_buffers(new BufferSet()),
112 _silent_buffers(new BufferSet()),
113 _send_buffers(new BufferSet()),
114 _mmc_port (default_mmc_port),
115 _mtc_port (default_mtc_port),
116 _midi_port (default_midi_port),
117 _session_dir (new SessionDirectory(fullpath)),
118 pending_events (2048),
119 //midi_requests (128), // the size of this should match the midi request pool size
120 _send_smpte_update (false),
121 diskstreams (new DiskstreamList),
122 routes (new RouteList),
123 auditioner ((Auditioner*) 0),
127 if (!eng.connected()) {
128 throw failed_constructor();
131 n_physical_outputs = _engine.n_physical_outputs();
132 n_physical_inputs = _engine.n_physical_inputs();
134 first_stage_init (fullpath, snapshot_name);
136 initialize_start_and_end_locations(0, compute_initial_length ());
139 // try and create a new session directory
142 if(!_session_dir->create()) {
143 // an existing session.
144 // throw a_more_meaningful_exception()
146 throw failed_constructor ();
149 catch(sys::filesystem_error& ex)
152 throw failed_constructor ();
155 if(!create_session_file_from_template (*mix_template)) {
157 throw failed_constructor ();
160 cerr << "Creating session " << fullpath
161 <<" using template" << *mix_template
164 // must be an existing session
167 // ensure the necessary session subdirectories exist
168 // in case the directory structure has changed etc.
169 _session_dir->create();
171 catch(sys::filesystem_error& ex)
174 throw failed_constructor ();
177 cerr << "Loading session " << fullpath
178 << " using snapshot " << snapshot_name << " (1)"
182 if (second_stage_init (false)) {
184 throw failed_constructor ();
187 store_recent_sessions(_name, _path);
189 bool was_dirty = dirty();
191 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
193 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
196 DirtyChanged (); /* EMIT SIGNAL */
200 Session::Session (AudioEngine &eng,
202 string snapshot_name,
203 AutoConnectOption input_ac,
204 AutoConnectOption output_ac,
205 uint32_t control_out_channels,
206 uint32_t master_out_channels,
207 uint32_t requested_physical_in,
208 uint32_t requested_physical_out,
209 nframes_t initial_length)
212 _scratch_buffers(new BufferSet()),
213 _silent_buffers(new BufferSet()),
214 _send_buffers(new BufferSet()),
215 _mmc_port (default_mmc_port),
216 _mtc_port (default_mtc_port),
217 _midi_port (default_midi_port),
218 _session_dir ( new SessionDirectory(fullpath)),
219 pending_events (2048),
220 //midi_requests (16),
221 _send_smpte_update (false),
222 diskstreams (new DiskstreamList),
223 routes (new RouteList),
227 if (!eng.connected()) {
228 throw failed_constructor();
231 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
233 n_physical_outputs = _engine.n_physical_outputs();
234 n_physical_inputs = _engine.n_physical_inputs();
236 if (n_physical_inputs) {
237 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
240 if (n_physical_outputs) {
241 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
244 first_stage_init (fullpath, snapshot_name);
246 initialize_start_and_end_locations(0, initial_length);
248 if (!_session_dir->create () || !create_session_file ()) {
250 throw failed_constructor ();
254 /* set up Master Out and Control Out if necessary */
259 if (control_out_channels) {
260 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
261 r->set_remote_control_id (control_id++);
266 if (master_out_channels) {
267 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
268 r->set_remote_control_id (control_id);
272 /* prohibit auto-connect to master, because there isn't one */
273 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
282 Config->set_input_auto_connect (input_ac);
283 Config->set_output_auto_connect (output_ac);
285 if (second_stage_init (true)) {
287 throw failed_constructor ();
290 store_recent_sessions(_name, _path);
292 bool was_dirty = dirty ();
294 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
296 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
299 DirtyChanged (); /* EMIT SIGNAL */
311 /* if we got to here, leaving pending capture state around
315 remove_pending_capture_state ();
317 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
318 _engine.remove_session ();
320 GoingAway (); /* EMIT SIGNAL */
326 /* clear history so that no references to objects are held any more */
330 /* clear state tree so that no references to objects are held any more */
336 terminate_butler_thread ();
337 //terminate_midi_thread ();
339 if (click_data && click_data != default_click) {
340 delete [] click_data;
343 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
344 delete [] click_emphasis_data;
349 delete _scratch_buffers;
350 delete _silent_buffers;
351 delete _send_buffers;
353 AudioDiskstream::free_working_buffers();
355 #undef TRACK_DESTRUCTION
356 #ifdef TRACK_DESTRUCTION
357 cerr << "delete named selections\n";
358 #endif /* TRACK_DESTRUCTION */
359 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
360 NamedSelectionList::iterator tmp;
369 #ifdef TRACK_DESTRUCTION
370 cerr << "delete playlists\n";
371 #endif /* TRACK_DESTRUCTION */
372 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
373 PlaylistList::iterator tmp;
378 (*i)->drop_references ();
383 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
384 PlaylistList::iterator tmp;
389 (*i)->drop_references ();
395 unused_playlists.clear ();
397 #ifdef TRACK_DESTRUCTION
398 cerr << "delete regions\n";
399 #endif /* TRACK_DESTRUCTION */
401 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
402 RegionList::iterator tmp;
407 i->second->drop_references ();
414 #ifdef TRACK_DESTRUCTION
415 cerr << "delete routes\n";
416 #endif /* TRACK_DESTRUCTION */
418 RCUWriter<RouteList> writer (routes);
419 boost::shared_ptr<RouteList> r = writer.get_copy ();
420 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
421 (*i)->drop_references ();
424 /* writer goes out of scope and updates master */
429 #ifdef TRACK_DESTRUCTION
430 cerr << "delete diskstreams\n";
431 #endif /* TRACK_DESTRUCTION */
433 RCUWriter<DiskstreamList> dwriter (diskstreams);
434 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
435 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
436 (*i)->drop_references ();
440 diskstreams.flush ();
442 #ifdef TRACK_DESTRUCTION
443 cerr << "delete audio sources\n";
444 #endif /* TRACK_DESTRUCTION */
445 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
446 SourceMap::iterator tmp;
451 i->second->drop_references ();
458 #ifdef TRACK_DESTRUCTION
459 cerr << "delete mix groups\n";
460 #endif /* TRACK_DESTRUCTION */
461 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
462 list<RouteGroup*>::iterator tmp;
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete edit groups\n";
474 #endif /* TRACK_DESTRUCTION */
475 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
476 list<RouteGroup*>::iterator tmp;
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete bundles\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ) {
490 BundleList::iterator tmp;
500 if (butler_mixdown_buffer) {
501 delete [] butler_mixdown_buffer;
504 if (butler_gain_buffer) {
505 delete [] butler_gain_buffer;
508 Crossfade::set_buffer_size (0);
516 Session::set_worst_io_latencies ()
518 _worst_output_latency = 0;
519 _worst_input_latency = 0;
521 if (!_engine.connected()) {
525 boost::shared_ptr<RouteList> r = routes.reader ();
527 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
528 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
529 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
534 Session::when_engine_running ()
536 string first_physical_output;
538 /* we don't want to run execute this again */
540 set_block_size (_engine.frames_per_cycle());
541 set_frame_rate (_engine.frame_rate());
543 Config->map_parameters (mem_fun (*this, &Session::config_changed));
545 /* every time we reconnect, recompute worst case output latencies */
547 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
549 if (synced_to_jack()) {
550 _engine.transport_stop ();
553 if (Config->get_jack_time_master()) {
554 _engine.transport_locate (_transport_frame);
562 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
564 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
566 /* existing state for Click */
568 if (_click_io->set_state (*child->children().front()) == 0) {
570 _clicking = Config->get_clicking ();
574 error << _("could not setup Click I/O") << endmsg;
580 /* default state for Click */
582 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
584 if (first_physical_output.length()) {
585 if (_click_io->add_output_port (first_physical_output, this)) {
586 // relax, even though its an error
588 _clicking = Config->get_clicking ();
594 catch (failed_constructor& err) {
595 error << _("cannot setup Click I/O") << endmsg;
598 set_worst_io_latencies ();
601 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
604 /* Create a set of Bundle objects that map
605 to the physical outputs currently available
610 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
612 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
614 Bundle* c = new OutputBundle (buf, true);
615 c->set_nchannels (1);
616 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
621 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
623 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
625 Bundle* c = new InputBundle (buf, true);
626 c->set_nchannels (1);
627 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
634 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
636 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
638 Bundle* c = new OutputBundle (buf, true);
639 c->set_nchannels (2);
640 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
641 c->add_port_to_channel (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
646 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
648 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
650 Bundle* c = new InputBundle (buf, true);
651 c->set_nchannels (2);
652 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
653 c->add_port_to_channel (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
662 /* create master/control ports */
667 /* force the master to ignore any later call to this */
669 if (_master_out->pending_state_node) {
670 _master_out->ports_became_legal();
673 /* no panner resets till we are through */
675 _master_out->defer_pan_reset ();
677 while (_master_out->n_inputs().n_audio()
678 < _master_out->input_maximum().n_audio()) {
679 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
680 error << _("cannot setup master inputs")
686 while (_master_out->n_outputs().n_audio()
687 < _master_out->output_maximum().n_audio()) {
688 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
689 error << _("cannot setup master outputs")
696 _master_out->allow_pan_reset ();
700 Bundle* c = new OutputBundle (_("Master Out"), true);
702 c->set_nchannels (_master_out->n_inputs().n_total());
703 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
704 c->add_port_to_channel ((int) n, _master_out->input(n)->name());
711 /* catch up on send+insert cnts */
715 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
718 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
719 if (id > insert_cnt) {
727 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
730 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
738 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
740 /* hook us up to the engine */
742 _engine.set_session (this);
747 osc->set_session (*this);
750 _state_of_the_state = Clean;
752 DirtyChanged (); /* EMIT SIGNAL */
756 Session::hookup_io ()
758 /* stop graph reordering notifications from
759 causing resorts, etc.
762 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
764 if (auditioner == 0) {
766 /* we delay creating the auditioner till now because
767 it makes its own connections to ports.
768 the engine has to be running for this to work.
772 auditioner.reset (new Auditioner (*this));
775 catch (failed_constructor& err) {
776 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
780 /* Tell all IO objects to create their ports */
786 vector<string> cports;
788 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
789 if (_control_out->add_input_port ("", this)) {
790 error << _("cannot setup control inputs")
796 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
797 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
798 error << _("cannot set up master outputs")
806 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
808 for (n = 0; n < ni; ++n) {
809 cports.push_back (_control_out->input(n)->name());
812 boost::shared_ptr<RouteList> r = routes.reader ();
814 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
815 (*x)->set_control_outs (cports);
819 /* Tell all IO objects to connect themselves together */
821 IO::enable_connecting ();
823 /* Now reset all panners */
825 IO::reset_panners ();
827 /* Anyone who cares about input state, wake up and do something */
829 IOConnectionsComplete (); /* EMIT SIGNAL */
831 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
833 /* now handle the whole enchilada as if it was one
839 /* update mixer solo state */
845 Session::playlist_length_changed ()
847 /* we can't just increase end_location->end() if pl->get_maximum_extent()
848 if larger. if the playlist used to be the longest playlist,
849 and its now shorter, we have to decrease end_location->end(). hence,
850 we have to iterate over all diskstreams and check the
851 playlists currently in use.
857 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
859 boost::shared_ptr<Playlist> playlist;
861 if ((playlist = dstream->playlist()) != 0) {
862 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
865 /* see comment in playlist_length_changed () */
870 Session::record_enabling_legal () const
872 /* this used to be in here, but survey says.... we don't need to restrict it */
873 // if (record_status() == Recording) {
877 if (Config->get_all_safe()) {
884 Session::reset_input_monitor_state ()
886 if (transport_rolling()) {
888 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
890 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
891 if ((*i)->record_enabled ()) {
892 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
893 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
897 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
899 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
900 if ((*i)->record_enabled ()) {
901 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
902 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
909 Session::auto_punch_start_changed (Location* location)
911 replace_event (Event::PunchIn, location->start());
913 if (get_record_enabled() && Config->get_punch_in()) {
914 /* capture start has been changed, so save new pending state */
915 save_state ("", true);
920 Session::auto_punch_end_changed (Location* location)
922 nframes_t when_to_stop = location->end();
923 // when_to_stop += _worst_output_latency + _worst_input_latency;
924 replace_event (Event::PunchOut, when_to_stop);
928 Session::auto_punch_changed (Location* location)
930 nframes_t when_to_stop = location->end();
932 replace_event (Event::PunchIn, location->start());
933 //when_to_stop += _worst_output_latency + _worst_input_latency;
934 replace_event (Event::PunchOut, when_to_stop);
938 Session::auto_loop_changed (Location* location)
940 replace_event (Event::AutoLoop, location->end(), location->start());
942 if (transport_rolling() && play_loop) {
944 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
946 if (_transport_frame > location->end()) {
947 // relocate to beginning of loop
948 clear_events (Event::LocateRoll);
950 request_locate (location->start(), true);
953 else if (Config->get_seamless_loop() && !loop_changing) {
955 // schedule a locate-roll to refill the diskstreams at the
957 loop_changing = true;
959 if (location->end() > last_loopend) {
960 clear_events (Event::LocateRoll);
961 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
968 last_loopend = location->end();
973 Session::set_auto_punch_location (Location* location)
977 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
978 auto_punch_start_changed_connection.disconnect();
979 auto_punch_end_changed_connection.disconnect();
980 auto_punch_changed_connection.disconnect();
981 existing->set_auto_punch (false, this);
982 remove_event (existing->start(), Event::PunchIn);
983 clear_events (Event::PunchOut);
984 auto_punch_location_changed (0);
993 if (location->end() <= location->start()) {
994 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
998 auto_punch_start_changed_connection.disconnect();
999 auto_punch_end_changed_connection.disconnect();
1000 auto_punch_changed_connection.disconnect();
1002 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1003 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1004 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1006 location->set_auto_punch (true, this);
1007 auto_punch_location_changed (location);
1011 Session::set_auto_loop_location (Location* location)
1015 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1016 auto_loop_start_changed_connection.disconnect();
1017 auto_loop_end_changed_connection.disconnect();
1018 auto_loop_changed_connection.disconnect();
1019 existing->set_auto_loop (false, this);
1020 remove_event (existing->end(), Event::AutoLoop);
1021 auto_loop_location_changed (0);
1026 if (location == 0) {
1030 if (location->end() <= location->start()) {
1031 error << _("Session: you can't use a mark for auto loop") << endmsg;
1035 last_loopend = location->end();
1037 auto_loop_start_changed_connection.disconnect();
1038 auto_loop_end_changed_connection.disconnect();
1039 auto_loop_changed_connection.disconnect();
1041 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1042 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1043 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1045 location->set_auto_loop (true, this);
1046 auto_loop_location_changed (location);
1050 Session::locations_added (Location* ignored)
1056 Session::locations_changed ()
1058 _locations.apply (*this, &Session::handle_locations_changed);
1062 Session::handle_locations_changed (Locations::LocationList& locations)
1064 Locations::LocationList::iterator i;
1066 bool set_loop = false;
1067 bool set_punch = false;
1069 for (i = locations.begin(); i != locations.end(); ++i) {
1073 if (location->is_auto_punch()) {
1074 set_auto_punch_location (location);
1077 if (location->is_auto_loop()) {
1078 set_auto_loop_location (location);
1085 set_auto_loop_location (0);
1088 set_auto_punch_location (0);
1095 Session::enable_record ()
1097 /* XXX really atomic compare+swap here */
1098 if (g_atomic_int_get (&_record_status) != Recording) {
1099 g_atomic_int_set (&_record_status, Recording);
1100 _last_record_location = _transport_frame;
1101 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1103 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1104 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1105 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1106 if ((*i)->record_enabled ()) {
1107 (*i)->monitor_input (true);
1112 RecordStateChanged ();
1117 Session::disable_record (bool rt_context, bool force)
1121 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1123 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1124 g_atomic_int_set (&_record_status, Disabled);
1126 if (rs == Recording) {
1127 g_atomic_int_set (&_record_status, Enabled);
1131 // FIXME: timestamp correct? [DR]
1132 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1133 // does this /need/ to be sent in all cases?
1135 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1137 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1138 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1140 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1141 if ((*i)->record_enabled ()) {
1142 (*i)->monitor_input (false);
1147 RecordStateChanged (); /* emit signal */
1150 remove_pending_capture_state ();
1156 Session::step_back_from_record ()
1158 /* XXX really atomic compare+swap here */
1159 if (g_atomic_int_get (&_record_status) == Recording) {
1160 g_atomic_int_set (&_record_status, Enabled);
1162 if (Config->get_monitoring_model() == HardwareMonitoring) {
1163 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1165 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1166 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1167 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1168 (*i)->monitor_input (false);
1176 Session::maybe_enable_record ()
1178 g_atomic_int_set (&_record_status, Enabled);
1180 /* this function is currently called from somewhere other than an RT thread.
1181 this save_state() call therefore doesn't impact anything.
1184 save_state ("", true);
1186 if (_transport_speed) {
1187 if (!Config->get_punch_in()) {
1191 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1192 RecordStateChanged (); /* EMIT SIGNAL */
1199 Session::audible_frame () const
1205 /* the first of these two possible settings for "offset"
1206 mean that the audible frame is stationary until
1207 audio emerges from the latency compensation
1210 the second means that the audible frame is stationary
1211 until audio would emerge from a physical port
1212 in the absence of any plugin latency compensation
1215 offset = _worst_output_latency;
1217 if (offset > current_block_size) {
1218 offset -= current_block_size;
1220 /* XXX is this correct? if we have no external
1221 physical connections and everything is internal
1222 then surely this is zero? still, how
1223 likely is that anyway?
1225 offset = current_block_size;
1228 if (synced_to_jack()) {
1229 tf = _engine.transport_frame();
1231 tf = _transport_frame;
1234 if (_transport_speed == 0) {
1244 if (!non_realtime_work_pending()) {
1248 /* take latency into account */
1257 Session::set_frame_rate (nframes_t frames_per_second)
1259 /** \fn void Session::set_frame_size(nframes_t)
1260 the AudioEngine object that calls this guarantees
1261 that it will not be called while we are also in
1262 ::process(). Its fine to do things that block
1266 _base_frame_rate = frames_per_second;
1270 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1272 // XXX we need some equivalent to this, somehow
1273 // SndFileSource::setup_standard_crossfades (frames_per_second);
1277 /* XXX need to reset/reinstantiate all LADSPA plugins */
1281 Session::set_block_size (nframes_t nframes)
1283 /* the AudioEngine guarantees
1284 that it will not be called while we are also in
1285 ::process(). It is therefore fine to do things that block
1291 current_block_size = nframes;
1293 ensure_buffers(_scratch_buffers->available());
1295 if (_gain_automation_buffer) {
1296 delete [] _gain_automation_buffer;
1298 _gain_automation_buffer = new gain_t[nframes];
1300 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1302 boost::shared_ptr<RouteList> r = routes.reader ();
1304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1305 (*i)->set_block_size (nframes);
1308 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1309 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1310 (*i)->set_block_size (nframes);
1313 set_worst_io_latencies ();
1318 Session::set_default_fade (float steepness, float fade_msecs)
1321 nframes_t fade_frames;
1323 /* Don't allow fade of less 1 frame */
1325 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1332 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1336 default_fade_msecs = fade_msecs;
1337 default_fade_steepness = steepness;
1340 // jlc, WTF is this!
1341 Glib::RWLock::ReaderLock lm (route_lock);
1342 AudioRegion::set_default_fade (steepness, fade_frames);
1347 /* XXX have to do this at some point */
1348 /* foreach region using default fade, reset, then
1349 refill_all_diskstream_buffers ();
1354 struct RouteSorter {
1355 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1356 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1358 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1361 if (r1->fed_by.empty()) {
1362 if (r2->fed_by.empty()) {
1363 /* no ardour-based connections inbound to either route. just use signal order */
1364 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1366 /* r2 has connections, r1 does not; run r1 early */
1370 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1377 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1379 shared_ptr<Route> r2;
1381 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1382 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1386 /* make a copy of the existing list of routes that feed r1 */
1388 set<shared_ptr<Route> > existing = r1->fed_by;
1390 /* for each route that feeds r1, recurse, marking it as feeding
1394 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1397 /* r2 is a route that feeds r1 which somehow feeds base. mark
1398 base as being fed by r2
1401 rbase->fed_by.insert (r2);
1405 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1409 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1413 /* now recurse, so that we can mark base as being fed by
1414 all routes that feed r2
1417 trace_terminal (r2, rbase);
1424 Session::resort_routes ()
1426 /* don't do anything here with signals emitted
1427 by Routes while we are being destroyed.
1430 if (_state_of_the_state & Deletion) {
1437 RCUWriter<RouteList> writer (routes);
1438 shared_ptr<RouteList> r = writer.get_copy ();
1439 resort_routes_using (r);
1440 /* writer goes out of scope and forces update */
1445 Session::resort_routes_using (shared_ptr<RouteList> r)
1447 RouteList::iterator i, j;
1449 for (i = r->begin(); i != r->end(); ++i) {
1451 (*i)->fed_by.clear ();
1453 for (j = r->begin(); j != r->end(); ++j) {
1455 /* although routes can feed themselves, it will
1456 cause an endless recursive descent if we
1457 detect it. so don't bother checking for
1465 if ((*j)->feeds (*i)) {
1466 (*i)->fed_by.insert (*j);
1471 for (i = r->begin(); i != r->end(); ++i) {
1472 trace_terminal (*i, *i);
1479 cerr << "finished route resort\n";
1481 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1482 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1489 list<boost::shared_ptr<MidiTrack> >
1490 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1492 char track_name[32];
1493 uint32_t track_id = 0;
1495 uint32_t channels_used = 0;
1497 RouteList new_routes;
1498 list<boost::shared_ptr<MidiTrack> > ret;
1500 /* count existing midi tracks */
1503 shared_ptr<RouteList> r = routes.reader ();
1505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1506 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1507 if (!(*i)->hidden()) {
1509 channels_used += (*i)->n_inputs().n_midi();
1517 /* check for duplicate route names, since we might have pre-existing
1518 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1519 save, close,restart,add new route - first named route is now
1527 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1529 if (route_by_name (track_name) == 0) {
1533 } while (track_id < (UINT_MAX-1));
1536 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1538 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1539 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1542 channels_used += track->n_inputs ().n_midi();
1544 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1545 track->set_remote_control_id (ntracks());
1547 new_routes.push_back (track);
1548 ret.push_back (track);
1551 catch (failed_constructor &err) {
1552 error << _("Session: could not create new midi track.") << endmsg;
1553 // XXX should we delete the tracks already created?
1561 if (!new_routes.empty()) {
1562 add_routes (new_routes, false);
1563 save_state (_current_snapshot_name);
1569 list<boost::shared_ptr<AudioTrack> >
1570 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1572 char track_name[32];
1573 uint32_t track_id = 0;
1575 uint32_t channels_used = 0;
1577 RouteList new_routes;
1578 list<boost::shared_ptr<AudioTrack> > ret;
1579 uint32_t control_id;
1581 /* count existing audio tracks */
1584 shared_ptr<RouteList> r = routes.reader ();
1586 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1587 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1588 if (!(*i)->hidden()) {
1590 channels_used += (*i)->n_inputs().n_audio();
1596 vector<string> physinputs;
1597 vector<string> physoutputs;
1598 uint32_t nphysical_in;
1599 uint32_t nphysical_out;
1601 _engine.get_physical_outputs (physoutputs);
1602 _engine.get_physical_inputs (physinputs);
1603 control_id = ntracks() + nbusses() + 1;
1607 /* check for duplicate route names, since we might have pre-existing
1608 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1609 save, close,restart,add new route - first named route is now
1617 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1619 if (route_by_name (track_name) == 0) {
1623 } while (track_id < (UINT_MAX-1));
1625 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1626 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1631 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1632 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1637 shared_ptr<AudioTrack> track;
1640 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1642 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1643 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1644 input_channels, output_channels)
1650 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1654 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1655 port = physinputs[(channels_used+x)%nphysical_in];
1658 if (port.length() && track->connect_input (track->input (x), port, this)) {
1664 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1668 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1669 port = physoutputs[(channels_used+x)%nphysical_out];
1670 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1672 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1676 if (port.length() && track->connect_output (track->output (x), port, this)) {
1681 channels_used += track->n_inputs ().n_audio();
1683 track->audio_diskstream()->non_realtime_input_change();
1685 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1686 track->set_remote_control_id (control_id);
1689 new_routes.push_back (track);
1690 ret.push_back (track);
1693 catch (failed_constructor &err) {
1694 error << _("Session: could not create new audio track.") << endmsg;
1697 /* we need to get rid of this, since the track failed to be created */
1698 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1701 RCUWriter<DiskstreamList> writer (diskstreams);
1702 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1703 ds->remove (track->audio_diskstream());
1710 catch (AudioEngine::PortRegistrationFailure& pfe) {
1712 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1715 /* we need to get rid of this, since the track failed to be created */
1716 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1719 RCUWriter<DiskstreamList> writer (diskstreams);
1720 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1721 ds->remove (track->audio_diskstream());
1732 if (!new_routes.empty()) {
1733 add_routes (new_routes, false);
1734 save_state (_current_snapshot_name);
1741 Session::set_remote_control_ids ()
1743 RemoteModel m = Config->get_remote_model();
1745 shared_ptr<RouteList> r = routes.reader ();
1747 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1748 if ( MixerOrdered == m) {
1749 long order = (*i)->order_key(N_("signal"));
1750 (*i)->set_remote_control_id( order+1 );
1751 } else if ( EditorOrdered == m) {
1752 long order = (*i)->order_key(N_("editor"));
1753 (*i)->set_remote_control_id( order+1 );
1754 } else if ( UserOrdered == m) {
1755 //do nothing ... only changes to remote id's are initiated by user
1762 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1765 uint32_t bus_id = 1;
1769 uint32_t control_id;
1771 /* count existing audio busses */
1774 shared_ptr<RouteList> r = routes.reader ();
1776 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1777 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1778 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1785 vector<string> physinputs;
1786 vector<string> physoutputs;
1788 _engine.get_physical_outputs (physoutputs);
1789 _engine.get_physical_inputs (physinputs);
1790 control_id = ntracks() + nbusses() + 1;
1795 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1799 if (route_by_name (bus_name) == 0) {
1803 } while (bus_id < (UINT_MAX-1));
1806 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1808 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1809 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1810 input_channels, output_channels)
1815 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1819 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1820 port = physinputs[((n+x)%n_physical_inputs)];
1823 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1828 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1832 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1833 port = physoutputs[((n+x)%n_physical_outputs)];
1834 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1836 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1840 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1845 bus->set_remote_control_id (control_id);
1848 ret.push_back (bus);
1852 catch (failed_constructor &err) {
1853 error << _("Session: could not create new audio route.") << endmsg;
1857 catch (AudioEngine::PortRegistrationFailure& pfe) {
1858 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1868 add_routes (ret, false);
1869 save_state (_current_snapshot_name);
1877 Session::add_routes (RouteList& new_routes, bool save)
1880 RCUWriter<RouteList> writer (routes);
1881 shared_ptr<RouteList> r = writer.get_copy ();
1882 r->insert (r->end(), new_routes.begin(), new_routes.end());
1883 resort_routes_using (r);
1886 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1888 boost::weak_ptr<Route> wpr (*x);
1890 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1891 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1892 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1893 (*x)->inserts_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1895 if ((*x)->master()) {
1899 if ((*x)->control()) {
1900 _control_out = (*x);
1904 if (_control_out && IO::connecting_legal) {
1906 vector<string> cports;
1907 uint32_t ni = _control_out->n_inputs().n_audio();
1909 for (uint32_t n = 0; n < ni; ++n) {
1910 cports.push_back (_control_out->input(n)->name());
1913 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1914 (*x)->set_control_outs (cports);
1921 save_state (_current_snapshot_name);
1924 RouteAdded (new_routes); /* EMIT SIGNAL */
1928 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1930 /* need to do this in case we're rolling at the time, to prevent false underruns */
1931 dstream->do_refill_with_alloc ();
1933 dstream->set_block_size (current_block_size);
1936 RCUWriter<DiskstreamList> writer (diskstreams);
1937 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1938 ds->push_back (dstream);
1939 /* writer goes out of scope, copies ds back to main */
1942 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1943 /* this will connect to future changes, and check the current length */
1944 diskstream_playlist_changed (dstream);
1946 dstream->prepare ();
1951 Session::remove_route (shared_ptr<Route> route)
1954 RCUWriter<RouteList> writer (routes);
1955 shared_ptr<RouteList> rs = writer.get_copy ();
1959 /* deleting the master out seems like a dumb
1960 idea, but its more of a UI policy issue
1964 if (route == _master_out) {
1965 _master_out = shared_ptr<Route> ();
1968 if (route == _control_out) {
1969 _control_out = shared_ptr<Route> ();
1971 /* cancel control outs for all routes */
1973 vector<string> empty;
1975 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1976 (*r)->set_control_outs (empty);
1980 update_route_solo_state ();
1982 /* writer goes out of scope, forces route list update */
1986 boost::shared_ptr<Diskstream> ds;
1988 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1989 ds = t->diskstream();
1995 RCUWriter<DiskstreamList> dsl (diskstreams);
1996 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2001 find_current_end ();
2003 update_latency_compensation (false, false);
2006 // We need to disconnect the routes inputs and outputs
2007 route->disconnect_inputs(NULL);
2008 route->disconnect_outputs(NULL);
2010 /* get rid of it from the dead wood collection in the route list manager */
2012 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2016 /* try to cause everyone to drop their references */
2018 route->drop_references ();
2020 /* save the new state of the world */
2022 if (save_state (_current_snapshot_name)) {
2023 save_history (_current_snapshot_name);
2028 Session::route_mute_changed (void* src)
2034 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2036 if (solo_update_disabled) {
2042 boost::shared_ptr<Route> route = wpr.lock ();
2045 /* should not happen */
2046 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2050 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2052 shared_ptr<RouteList> r = routes.reader ();
2054 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2056 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2060 /* don't mess with busses */
2062 if (dynamic_cast<Track*>((*i).get()) == 0) {
2068 /* don't mess with tracks */
2070 if (dynamic_cast<Track*>((*i).get()) != 0) {
2075 if ((*i) != route &&
2076 ((*i)->mix_group () == 0 ||
2077 (*i)->mix_group () != route->mix_group () ||
2078 !route->mix_group ()->is_active())) {
2080 if ((*i)->soloed()) {
2082 /* if its already soloed, and solo latching is enabled,
2083 then leave it as it is.
2086 if (Config->get_solo_latched()) {
2093 solo_update_disabled = true;
2094 (*i)->set_solo (false, src);
2095 solo_update_disabled = false;
2099 bool something_soloed = false;
2100 bool same_thing_soloed = false;
2101 bool signal = false;
2103 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2104 if ((*i)->soloed()) {
2105 something_soloed = true;
2106 if (dynamic_cast<Track*>((*i).get())) {
2108 same_thing_soloed = true;
2113 same_thing_soloed = true;
2121 if (something_soloed != currently_soloing) {
2123 currently_soloing = something_soloed;
2126 modify_solo_mute (is_track, same_thing_soloed);
2129 SoloActive (currently_soloing); /* EMIT SIGNAL */
2132 SoloChanged (); /* EMIT SIGNAL */
2138 Session::update_route_solo_state ()
2141 bool is_track = false;
2142 bool signal = false;
2144 /* caller must hold RouteLock */
2146 /* this is where we actually implement solo by changing
2147 the solo mute setting of each track.
2150 shared_ptr<RouteList> r = routes.reader ();
2152 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2153 if ((*i)->soloed()) {
2155 if (dynamic_cast<Track*>((*i).get())) {
2162 if (mute != currently_soloing) {
2164 currently_soloing = mute;
2167 if (!is_track && !mute) {
2169 /* nothing is soloed */
2171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2172 (*i)->set_solo_mute (false);
2182 modify_solo_mute (is_track, mute);
2185 SoloActive (currently_soloing);
2190 Session::modify_solo_mute (bool is_track, bool mute)
2192 shared_ptr<RouteList> r = routes.reader ();
2194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 /* only alter track solo mute */
2200 if (dynamic_cast<Track*>((*i).get())) {
2201 if ((*i)->soloed()) {
2202 (*i)->set_solo_mute (!mute);
2204 (*i)->set_solo_mute (mute);
2210 /* only alter bus solo mute */
2212 if (!dynamic_cast<Track*>((*i).get())) {
2214 if ((*i)->soloed()) {
2216 (*i)->set_solo_mute (false);
2220 /* don't mute master or control outs
2221 in response to another bus solo
2224 if ((*i) != _master_out &&
2225 (*i) != _control_out) {
2226 (*i)->set_solo_mute (mute);
2237 Session::catch_up_on_solo ()
2239 /* this is called after set_state() to catch the full solo
2240 state, which can't be correctly determined on a per-route
2241 basis, but needs the global overview that only the session
2244 update_route_solo_state();
2248 Session::route_by_name (string name)
2250 shared_ptr<RouteList> r = routes.reader ();
2252 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2253 if ((*i)->name() == name) {
2258 return shared_ptr<Route> ((Route*) 0);
2262 Session::route_by_id (PBD::ID id)
2264 shared_ptr<RouteList> r = routes.reader ();
2266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267 if ((*i)->id() == id) {
2272 return shared_ptr<Route> ((Route*) 0);
2276 Session::route_by_remote_id (uint32_t id)
2278 shared_ptr<RouteList> r = routes.reader ();
2280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 if ((*i)->remote_control_id() == id) {
2286 return shared_ptr<Route> ((Route*) 0);
2290 Session::find_current_end ()
2292 if (_state_of_the_state & Loading) {
2296 nframes_t max = get_maximum_extent ();
2298 if (max > end_location->end()) {
2299 end_location->set_end (max);
2301 DurationChanged(); /* EMIT SIGNAL */
2306 Session::get_maximum_extent () const
2311 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2313 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2314 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2315 if ((me = pl->get_maximum_extent()) > max) {
2323 boost::shared_ptr<Diskstream>
2324 Session::diskstream_by_name (string name)
2326 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2328 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2329 if ((*i)->name() == name) {
2334 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2337 boost::shared_ptr<Diskstream>
2338 Session::diskstream_by_id (const PBD::ID& id)
2340 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2342 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2343 if ((*i)->id() == id) {
2348 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2351 /* Region management */
2354 Session::new_region_name (string old)
2356 string::size_type last_period;
2358 string::size_type len = old.length() + 64;
2361 if ((last_period = old.find_last_of ('.')) == string::npos) {
2363 /* no period present - add one explicitly */
2366 last_period = old.length() - 1;
2371 number = atoi (old.substr (last_period+1).c_str());
2375 while (number < (UINT_MAX-1)) {
2377 RegionList::const_iterator i;
2382 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2385 for (i = regions.begin(); i != regions.end(); ++i) {
2386 if (i->second->name() == sbuf) {
2391 if (i == regions.end()) {
2396 if (number != (UINT_MAX-1)) {
2400 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2405 Session::region_name (string& result, string base, bool newlevel) const
2410 assert(base.find("/") == string::npos);
2414 Glib::Mutex::Lock lm (region_lock);
2416 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2424 /* XXX this is going to be slow. optimize me later */
2429 string::size_type pos;
2431 pos = base.find_last_of ('.');
2433 /* pos may be npos, but then we just use entire base */
2435 subbase = base.substr (0, pos);
2439 bool name_taken = true;
2442 Glib::Mutex::Lock lm (region_lock);
2444 for (int n = 1; n < 5000; ++n) {
2447 snprintf (buf, sizeof (buf), ".%d", n);
2452 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2453 if (i->second->name() == result) {
2466 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2474 Session::add_region (boost::shared_ptr<Region> region)
2476 boost::shared_ptr<Region> other;
2480 Glib::Mutex::Lock lm (region_lock);
2482 RegionList::iterator x;
2484 for (x = regions.begin(); x != regions.end(); ++x) {
2488 if (region->region_list_equivalent (other)) {
2493 if (x == regions.end()) {
2495 pair<RegionList::key_type,RegionList::mapped_type> entry;
2497 entry.first = region->id();
2498 entry.second = region;
2500 pair<RegionList::iterator,bool> x = regions.insert (entry);
2512 /* mark dirty because something has changed even if we didn't
2513 add the region to the region list.
2519 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2520 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2521 RegionAdded (region); /* EMIT SIGNAL */
2526 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2528 boost::shared_ptr<Region> region (weak_region.lock ());
2534 if (what_changed & Region::HiddenChanged) {
2535 /* relay hidden changes */
2536 RegionHiddenChange (region);
2541 Session::remove_region (boost::weak_ptr<Region> weak_region)
2543 RegionList::iterator i;
2544 boost::shared_ptr<Region> region (weak_region.lock ());
2550 bool removed = false;
2553 Glib::Mutex::Lock lm (region_lock);
2555 if ((i = regions.find (region->id())) != regions.end()) {
2561 /* mark dirty because something has changed even if we didn't
2562 remove the region from the region list.
2568 RegionRemoved(region); /* EMIT SIGNAL */
2572 boost::shared_ptr<Region>
2573 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2575 RegionList::iterator i;
2576 boost::shared_ptr<Region> region;
2578 Glib::Mutex::Lock lm (region_lock);
2580 for (i = regions.begin(); i != regions.end(); ++i) {
2584 if (region->whole_file()) {
2586 if (child->source_equivalent (region)) {
2592 return boost::shared_ptr<Region> ();
2596 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2598 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2599 (*i)->get_region_list_equivalent_regions (region, result);
2603 Session::destroy_region (boost::shared_ptr<Region> region)
2605 vector<boost::shared_ptr<Source> > srcs;
2608 boost::shared_ptr<AudioRegion> aregion;
2610 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2614 if (aregion->playlist()) {
2615 aregion->playlist()->destroy_region (region);
2618 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2619 srcs.push_back (aregion->source (n));
2623 region->drop_references ();
2625 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2627 if (!(*i)->used()) {
2628 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2631 (afs)->mark_for_remove ();
2634 (*i)->drop_references ();
2636 cerr << "source was not used by any playlist\n";
2644 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2646 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2647 destroy_region (*i);
2653 Session::remove_last_capture ()
2655 list<boost::shared_ptr<Region> > r;
2657 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2659 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2660 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2663 r.insert (r.end(), l.begin(), l.end());
2668 destroy_regions (r);
2670 save_state (_current_snapshot_name);
2676 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2682 /* Source Management */
2684 Session::add_source (boost::shared_ptr<Source> source)
2686 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2687 pair<SourceMap::iterator,bool> result;
2689 entry.first = source->id();
2690 entry.second = source;
2693 Glib::Mutex::Lock lm (source_lock);
2694 result = sources.insert (entry);
2697 if (result.second) {
2698 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2704 Session::remove_source (boost::weak_ptr<Source> src)
2706 SourceMap::iterator i;
2707 boost::shared_ptr<Source> source = src.lock();
2714 Glib::Mutex::Lock lm (source_lock);
2717 Glib::Mutex::Lock lm (source_lock);
2719 if ((i = sources.find (source->id())) != sources.end()) {
2725 if (!_state_of_the_state & InCleanup) {
2727 /* save state so we don't end up with a session file
2728 referring to non-existent sources.
2731 save_state (_current_snapshot_name);
2735 boost::shared_ptr<Source>
2736 Session::source_by_id (const PBD::ID& id)
2738 Glib::Mutex::Lock lm (source_lock);
2739 SourceMap::iterator i;
2740 boost::shared_ptr<Source> source;
2742 if ((i = sources.find (id)) != sources.end()) {
2746 /* XXX search MIDI or other searches here */
2752 boost::shared_ptr<Source>
2753 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2755 Glib::Mutex::Lock lm (source_lock);
2757 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2758 cerr << "comparing " << path << " with " << i->second->name() << endl;
2759 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2761 if (afs && afs->path() == path && chn == afs->channel()) {
2766 return boost::shared_ptr<Source>();
2770 Session::peak_path_from_audio_path (string audio_path) const
2772 sys::path peakfile_path(_session_dir->peak_path());
2774 peakfile_path /= basename_nosuffix (audio_path) + peakfile_suffix;
2776 return peakfile_path.to_string();
2780 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2783 string old_basename = PBD::basename_nosuffix (oldname);
2784 string new_legalized = legalize_for_path (newname);
2786 /* note: we know (or assume) the old path is already valid */
2790 /* destructive file sources have a name of the form:
2792 /path/to/Tnnnn-NAME(%[LR])?.wav
2794 the task here is to replace NAME with the new name.
2797 /* find last slash */
2801 string::size_type slash;
2802 string::size_type dash;
2804 if ((slash = path.find_last_of ('/')) == string::npos) {
2808 dir = path.substr (0, slash+1);
2810 /* '-' is not a legal character for the NAME part of the path */
2812 if ((dash = path.find_last_of ('-')) == string::npos) {
2816 prefix = path.substr (slash+1, dash-(slash+1));
2821 path += new_legalized;
2822 path += ".wav"; /* XXX gag me with a spoon */
2826 /* non-destructive file sources have a name of the form:
2828 /path/to/NAME-nnnnn(%[LR])?.wav
2830 the task here is to replace NAME with the new name.
2835 string::size_type slash;
2836 string::size_type dash;
2837 string::size_type postfix;
2839 /* find last slash */
2841 if ((slash = path.find_last_of ('/')) == string::npos) {
2845 dir = path.substr (0, slash+1);
2847 /* '-' is not a legal character for the NAME part of the path */
2849 if ((dash = path.find_last_of ('-')) == string::npos) {
2853 suffix = path.substr (dash+1);
2855 // Suffix is now everything after the dash. Now we need to eliminate
2856 // the nnnnn part, which is done by either finding a '%' or a '.'
2858 postfix = suffix.find_last_of ("%");
2859 if (postfix == string::npos) {
2860 postfix = suffix.find_last_of ('.');
2863 if (postfix != string::npos) {
2864 suffix = suffix.substr (postfix);
2866 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2870 const uint32_t limit = 10000;
2871 char buf[PATH_MAX+1];
2873 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2875 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2877 if (access (buf, F_OK) != 0) {
2885 error << "FATAL ERROR! Could not find a " << endl;
2894 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2898 char buf[PATH_MAX+1];
2899 const uint32_t limit = 10000;
2903 legalized = legalize_for_path (name);
2905 /* find a "version" of the file name that doesn't exist in
2906 any of the possible directories.
2909 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2911 vector<space_and_path>::iterator i;
2912 uint32_t existing = 0;
2914 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2916 SessionDirectory sdir((*i).path);
2918 spath = sdir.sound_path().to_string();
2922 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2923 } else if (nchan == 2) {
2925 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2927 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2929 } else if (nchan < 26) {
2930 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2932 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2941 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2942 } else if (nchan == 2) {
2944 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2946 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2948 } else if (nchan < 26) {
2949 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2951 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2955 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2961 if (existing == 0) {
2966 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2968 throw failed_constructor();
2972 /* we now have a unique name for the file, but figure out where to
2978 SessionDirectory sdir(get_best_session_directory_for_new_source ());
2980 spath = sdir.sound_path().to_string();
2983 string::size_type pos = foo.find_last_of ('/');
2985 if (pos == string::npos) {
2988 spath += foo.substr (pos + 1);
2994 boost::shared_ptr<AudioFileSource>
2995 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2997 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2998 return boost::dynamic_pointer_cast<AudioFileSource> (
2999 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3002 // FIXME: _terrible_ code duplication
3004 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3007 string old_basename = PBD::basename_nosuffix (oldname);
3008 string new_legalized = legalize_for_path (newname);
3010 /* note: we know (or assume) the old path is already valid */
3014 /* destructive file sources have a name of the form:
3016 /path/to/Tnnnn-NAME(%[LR])?.wav
3018 the task here is to replace NAME with the new name.
3021 /* find last slash */
3025 string::size_type slash;
3026 string::size_type dash;
3028 if ((slash = path.find_last_of ('/')) == string::npos) {
3032 dir = path.substr (0, slash+1);
3034 /* '-' is not a legal character for the NAME part of the path */
3036 if ((dash = path.find_last_of ('-')) == string::npos) {
3040 prefix = path.substr (slash+1, dash-(slash+1));
3045 path += new_legalized;
3046 path += ".mid"; /* XXX gag me with a spoon */
3050 /* non-destructive file sources have a name of the form:
3052 /path/to/NAME-nnnnn(%[LR])?.wav
3054 the task here is to replace NAME with the new name.
3059 string::size_type slash;
3060 string::size_type dash;
3061 string::size_type postfix;
3063 /* find last slash */
3065 if ((slash = path.find_last_of ('/')) == string::npos) {
3069 dir = path.substr (0, slash+1);
3071 /* '-' is not a legal character for the NAME part of the path */
3073 if ((dash = path.find_last_of ('-')) == string::npos) {
3077 suffix = path.substr (dash+1);
3079 // Suffix is now everything after the dash. Now we need to eliminate
3080 // the nnnnn part, which is done by either finding a '%' or a '.'
3082 postfix = suffix.find_last_of ("%");
3083 if (postfix == string::npos) {
3084 postfix = suffix.find_last_of ('.');
3087 if (postfix != string::npos) {
3088 suffix = suffix.substr (postfix);
3090 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3094 const uint32_t limit = 10000;
3095 char buf[PATH_MAX+1];
3097 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3099 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3101 if (access (buf, F_OK) != 0) {
3109 error << "FATAL ERROR! Could not find a " << endl;
3118 Session::midi_path_from_name (string name)
3122 char buf[PATH_MAX+1];
3123 const uint32_t limit = 10000;
3127 legalized = legalize_for_path (name);
3129 /* find a "version" of the file name that doesn't exist in
3130 any of the possible directories.
3133 for (cnt = 1; cnt <= limit; ++cnt) {
3135 vector<space_and_path>::iterator i;
3136 uint32_t existing = 0;
3138 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3140 SessionDirectory sdir((*i).path);
3142 sys::path p = sdir.midi_path();
3146 spath = p.to_string();
3148 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3150 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3155 if (existing == 0) {
3160 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3161 throw failed_constructor();
3165 /* we now have a unique name for the file, but figure out where to
3171 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3173 spath = sdir.midi_path().to_string();
3176 string::size_type pos = foo.find_last_of ('/');
3178 if (pos == string::npos) {
3181 spath += foo.substr (pos + 1);
3187 boost::shared_ptr<MidiSource>
3188 Session::create_midi_source_for_session (MidiDiskstream& ds)
3190 string mpath = midi_path_from_name (ds.name());
3192 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3196 /* Playlist management */
3198 boost::shared_ptr<Playlist>
3199 Session::playlist_by_name (string name)
3201 Glib::Mutex::Lock lm (playlist_lock);
3202 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3203 if ((*i)->name() == name) {
3207 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3208 if ((*i)->name() == name) {
3213 return boost::shared_ptr<Playlist>();
3217 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3219 if (playlist->hidden()) {
3224 Glib::Mutex::Lock lm (playlist_lock);
3225 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3226 playlists.insert (playlists.begin(), playlist);
3227 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3228 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3234 PlaylistAdded (playlist); /* EMIT SIGNAL */
3238 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3241 Glib::Mutex::Lock lm (playlist_lock);
3242 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3245 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3252 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3254 boost::shared_ptr<Playlist> pl(wpl.lock());
3260 PlaylistList::iterator x;
3263 /* its not supposed to be visible */
3268 Glib::Mutex::Lock lm (playlist_lock);
3272 unused_playlists.insert (pl);
3274 if ((x = playlists.find (pl)) != playlists.end()) {
3275 playlists.erase (x);
3281 playlists.insert (pl);
3283 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3284 unused_playlists.erase (x);
3291 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3293 if (_state_of_the_state & Deletion) {
3297 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3304 Glib::Mutex::Lock lm (playlist_lock);
3306 PlaylistList::iterator i;
3308 i = find (playlists.begin(), playlists.end(), playlist);
3309 if (i != playlists.end()) {
3310 playlists.erase (i);
3313 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3314 if (i != unused_playlists.end()) {
3315 unused_playlists.erase (i);
3322 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3326 Session::set_audition (boost::shared_ptr<Region> r)
3328 pending_audition_region = r;
3329 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3330 schedule_butler_transport_work ();
3334 Session::audition_playlist ()
3336 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3337 ev->region.reset ();
3342 Session::non_realtime_set_audition ()
3344 if (!pending_audition_region) {
3345 auditioner->audition_current_playlist ();
3347 auditioner->audition_region (pending_audition_region);
3348 pending_audition_region.reset ();
3350 AuditionActive (true); /* EMIT SIGNAL */
3354 Session::audition_region (boost::shared_ptr<Region> r)
3356 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3362 Session::cancel_audition ()
3364 if (auditioner->active()) {
3365 auditioner->cancel_audition ();
3366 AuditionActive (false); /* EMIT SIGNAL */
3371 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3373 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3377 Session::remove_empty_sounds ()
3379 PathScanner scanner;
3381 vector<string *>* possible_audiofiles = scanner (_session_dir->sound_path().to_string (),
3382 Config->get_possible_audio_file_regexp (), false, true);
3384 Glib::Mutex::Lock lm (source_lock);
3386 regex_t compiled_tape_track_pattern;
3389 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3393 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3395 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3399 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3401 /* never remove files that appear to be a tape track */
3403 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3408 if (AudioFileSource::is_empty (*this, *(*i))) {
3410 unlink ((*i)->c_str());
3412 string peak_path = peak_path_from_audio_path (**i);
3413 unlink (peak_path.c_str());
3419 delete possible_audiofiles;
3423 Session::is_auditioning () const
3425 /* can be called before we have an auditioner object */
3427 return auditioner->active();
3434 Session::set_all_solo (bool yn)
3436 shared_ptr<RouteList> r = routes.reader ();
3438 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3439 if (!(*i)->hidden()) {
3440 (*i)->set_solo (yn, this);
3448 Session::set_all_mute (bool yn)
3450 shared_ptr<RouteList> r = routes.reader ();
3452 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3453 if (!(*i)->hidden()) {
3454 (*i)->set_mute (yn, this);
3462 Session::n_diskstreams () const
3466 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3468 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3469 if (!(*i)->hidden()) {
3477 Session::graph_reordered ()
3479 /* don't do this stuff if we are setting up connections
3480 from a set_state() call or creating new tracks.
3483 if (_state_of_the_state & InitialConnecting) {
3487 /* every track/bus asked for this to be handled but it was deferred because
3488 we were connecting. do it now.
3491 request_input_change_handling ();
3495 /* force all diskstreams to update their capture offset values to
3496 reflect any changes in latencies within the graph.
3499 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3501 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3502 (*i)->set_capture_offset ();
3507 Session::record_disenable_all ()
3509 record_enable_change_all (false);
3513 Session::record_enable_all ()
3515 record_enable_change_all (true);
3519 Session::record_enable_change_all (bool yn)
3521 shared_ptr<RouteList> r = routes.reader ();
3523 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3526 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3527 at->set_record_enable (yn, this);
3531 /* since we don't keep rec-enable state, don't mark session dirty */
3535 Session::add_insert (Insert* insert)
3538 PortInsert* port_insert;
3539 PluginInsert* plugin_insert;
3541 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3542 _port_inserts.insert (_port_inserts.begin(), port_insert);
3543 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3544 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3545 } else if ((send = dynamic_cast<Send *> (insert)) != 0) {
3546 _sends.insert (_sends.begin(), send);
3548 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3552 insert->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_insert), insert));
3558 Session::remove_insert (Insert* insert)
3561 PortInsert* port_insert;
3562 PluginInsert* plugin_insert;
3564 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3565 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3566 if (x != _port_inserts.end()) {
3567 insert_bitset[port_insert->bit_slot()] = false;
3568 _port_inserts.erase (x);
3570 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3571 _plugin_inserts.remove (plugin_insert);
3572 } else if ((send = dynamic_cast<Send *> (insert)) != 0) {
3573 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3574 if (x != _sends.end()) {
3575 send_bitset[send->bit_slot()] = false;
3579 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3587 Session::available_capture_duration ()
3589 float sample_bytes_on_disk = 4.0; // keep gcc happy
3591 switch (Config->get_native_file_data_format()) {
3593 sample_bytes_on_disk = 4.0;
3597 sample_bytes_on_disk = 3.0;
3601 /* impossible, but keep some gcc versions happy */
3602 fatal << string_compose (_("programming error: %1"),
3603 X_("illegal native file data format"))
3608 double scale = 4096.0 / sample_bytes_on_disk;
3610 if (_total_free_4k_blocks * scale > (double) max_frames) {
3614 return (nframes_t) floor (_total_free_4k_blocks * scale);
3618 Session::add_bundle (ARDOUR::Bundle* bundle)
3621 Glib::Mutex::Lock guard (bundle_lock);
3622 _bundles.push_back (bundle);
3625 BundleAdded (bundle); /* EMIT SIGNAL */
3631 Session::remove_bundle (ARDOUR::Bundle* bundle)
3633 bool removed = false;
3636 Glib::Mutex::Lock guard (bundle_lock);
3637 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3639 if (i != _bundles.end()) {
3646 BundleRemoved (bundle); /* EMIT SIGNAL */
3653 Session::bundle_by_name (string name) const
3655 Glib::Mutex::Lock lm (bundle_lock);
3657 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3658 if ((*i)->name() == name) {
3667 Session::tempo_map_changed (Change ignored)
3673 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3674 * the given count with the current block size.
3677 Session::ensure_buffers (ChanCount howmany)
3679 // FIXME: NASTY assumption (midi block size == audio block size)
3680 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3681 _send_buffers->ensure_buffers(howmany, current_block_size);
3682 _silent_buffers->ensure_buffers(howmany, current_block_size);
3684 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3688 Session::next_insert_id ()
3690 /* this doesn't really loop forever. just think about it */
3693 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3694 if (!insert_bitset[n]) {
3695 insert_bitset[n] = true;
3701 /* none available, so resize and try again */
3703 insert_bitset.resize (insert_bitset.size() + 16, false);
3708 Session::next_send_id ()
3710 /* this doesn't really loop forever. just think about it */
3713 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3714 if (!send_bitset[n]) {
3715 send_bitset[n] = true;
3721 /* none available, so resize and try again */
3723 send_bitset.resize (send_bitset.size() + 16, false);
3728 Session::mark_send_id (uint32_t id)
3730 if (id >= send_bitset.size()) {
3731 send_bitset.resize (id+16, false);
3733 if (send_bitset[id]) {
3734 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3736 send_bitset[id] = true;
3740 Session::mark_insert_id (uint32_t id)
3742 if (id >= insert_bitset.size()) {
3743 insert_bitset.resize (id+16, false);
3745 if (insert_bitset[id]) {
3746 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3748 insert_bitset[id] = true;
3751 /* Named Selection management */
3754 Session::named_selection_by_name (string name)
3756 Glib::Mutex::Lock lm (named_selection_lock);
3757 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3758 if ((*i)->name == name) {
3766 Session::add_named_selection (NamedSelection* named_selection)
3769 Glib::Mutex::Lock lm (named_selection_lock);
3770 named_selections.insert (named_selections.begin(), named_selection);
3773 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3779 NamedSelectionAdded (); /* EMIT SIGNAL */
3783 Session::remove_named_selection (NamedSelection* named_selection)
3785 bool removed = false;
3788 Glib::Mutex::Lock lm (named_selection_lock);
3790 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3792 if (i != named_selections.end()) {
3794 named_selections.erase (i);
3801 NamedSelectionRemoved (); /* EMIT SIGNAL */
3806 Session::reset_native_file_format ()
3808 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3810 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3811 (*i)->reset_write_sources (false);
3816 Session::route_name_unique (string n) const
3818 shared_ptr<RouteList> r = routes.reader ();
3820 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3821 if ((*i)->name() == n) {
3830 Session::n_playlists () const
3832 Glib::Mutex::Lock lm (playlist_lock);
3833 return playlists.size();
3837 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3839 if (!force && howmany <= _npan_buffers) {
3843 if (_pan_automation_buffer) {
3845 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3846 delete [] _pan_automation_buffer[i];
3849 delete [] _pan_automation_buffer;
3852 _pan_automation_buffer = new pan_t*[howmany];
3854 for (uint32_t i = 0; i < howmany; ++i) {
3855 _pan_automation_buffer[i] = new pan_t[nframes];
3858 _npan_buffers = howmany;
3862 Session::freeze (InterThreadInfo& itt)
3864 shared_ptr<RouteList> r = routes.reader ();
3866 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3870 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3871 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3882 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3883 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3886 boost::shared_ptr<Playlist> playlist;
3887 boost::shared_ptr<AudioFileSource> fsource;
3889 char buf[PATH_MAX+1];
3890 ChanCount nchans(track.audio_diskstream()->n_channels());
3892 nframes_t this_chunk;
3895 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3896 const string sound_dir = sdir.sound_path().to_string();
3898 // any bigger than this seems to cause stack overflows in called functions
3899 const nframes_t chunk_size = (128 * 1024)/4;
3901 g_atomic_int_set (&processing_prohibited, 1);
3903 /* call tree *MUST* hold route_lock */
3905 if ((playlist = track.diskstream()->playlist()) == 0) {
3909 /* external redirects will be a problem */
3911 if (track.has_external_redirects()) {
3915 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3917 for (x = 0; x < 99999; ++x) {
3918 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3919 if (access (buf, F_OK) != 0) {
3925 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3930 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3931 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3934 catch (failed_constructor& err) {
3935 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3939 srcs.push_back (fsource);
3942 /* XXX need to flush all redirects */
3947 /* create a set of reasonably-sized buffers */
3948 buffers.ensure_buffers(nchans, chunk_size);
3949 buffers.set_count(nchans);
3951 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3952 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3954 afs->prepare_for_peakfile_writes ();
3957 while (to_do && !itt.cancel) {
3959 this_chunk = min (to_do, chunk_size);
3961 if (track.export_stuff (buffers, start, this_chunk)) {
3966 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3967 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3970 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3976 start += this_chunk;
3977 to_do -= this_chunk;
3979 itt.progress = (float) (1.0 - ((double) to_do / len));
3988 xnow = localtime (&now);
3990 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3991 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3994 afs->update_header (position, *xnow, now);
3995 afs->flush_header ();
3999 /* construct a region to represent the bounced material */
4001 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4002 region_name_from_path (srcs.front()->name(), true));
4009 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4010 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4013 afs->mark_for_remove ();
4016 (*src)->drop_references ();
4020 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4021 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4024 afs->done_with_peakfile_writes ();
4028 g_atomic_int_set (&processing_prohibited, 0);
4034 Session::get_silent_buffers (ChanCount count)
4036 assert(_silent_buffers->available() >= count);
4037 _silent_buffers->set_count(count);
4039 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4040 for (size_t i=0; i < count.get(*t); ++i) {
4041 _silent_buffers->get(*t, i).clear();
4045 return *_silent_buffers;
4049 Session::get_scratch_buffers (ChanCount count)
4051 assert(_scratch_buffers->available() >= count);
4052 _scratch_buffers->set_count(count);
4053 return *_scratch_buffers;
4057 Session::get_send_buffers (ChanCount count)
4059 assert(_send_buffers->available() >= count);
4060 _send_buffers->set_count(count);
4061 return *_send_buffers;
4065 Session::ntracks () const
4068 shared_ptr<RouteList> r = routes.reader ();
4070 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4071 if (dynamic_cast<Track*> ((*i).get())) {
4080 Session::nbusses () const
4083 shared_ptr<RouteList> r = routes.reader ();
4085 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4086 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4095 Session::add_automation_list(AutomationList *al)
4097 automation_lists[al->id()] = al;
4101 Session::compute_initial_length ()
4103 return _engine.frame_rate() * 60 * 5;