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/utils.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/midi_diskstream.h>
53 #include <ardour/midi_playlist.h>
54 #include <ardour/midi_region.h>
55 #include <ardour/smf_source.h>
56 #include <ardour/auditioner.h>
57 #include <ardour/recent_sessions.h>
58 #include <ardour/redirect.h>
59 #include <ardour/send.h>
60 #include <ardour/insert.h>
61 #include <ardour/connection.h>
62 #include <ardour/slave.h>
63 #include <ardour/tempo.h>
64 #include <ardour/audio_track.h>
65 #include <ardour/midi_track.h>
66 #include <ardour/cycle_timer.h>
67 #include <ardour/named_selection.h>
68 #include <ardour/crossfade.h>
69 #include <ardour/playlist.h>
70 #include <ardour/click.h>
71 #include <ardour/data_type.h>
72 #include <ardour/buffer_set.h>
73 #include <ardour/source_factory.h>
74 #include <ardour/region_factory.h>
75 #include <ardour/filename_extensions.h>
78 #include <ardour/osc.h>
84 using namespace ARDOUR;
86 using boost::shared_ptr;
89 static const int CPU_CACHE_ALIGN = 64;
91 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
94 const char* Session::old_sound_dir_name = X_("sounds");
95 const char* Session::sound_dir_name = X_("audiofiles");
96 const char* Session::peak_dir_name = X_("peaks");
97 const char* Session::dead_sound_dir_name = X_("dead_sounds");
98 const char* Session::interchange_dir_name = X_("interchange");
99 const char* Session::export_dir_name = X_("export");
101 sigc::signal<int> Session::AskAboutPendingState;
102 sigc::signal<void> Session::SendFeedback;
104 sigc::signal<void> Session::SMPTEOffsetChanged;
105 sigc::signal<void> Session::StartTimeChanged;
106 sigc::signal<void> Session::EndTimeChanged;
108 Session::Session (AudioEngine &eng,
110 string snapshot_name,
111 string* mix_template)
114 _scratch_buffers(new BufferSet()),
115 _silent_buffers(new BufferSet()),
116 _send_buffers(new BufferSet()),
117 _mmc_port (default_mmc_port),
118 _mtc_port (default_mtc_port),
119 _midi_port (default_midi_port),
120 pending_events (2048),
121 //midi_requests (128), // the size of this should match the midi request pool size
122 _send_smpte_update (false),
123 diskstreams (new DiskstreamList),
124 routes (new RouteList),
125 auditioner ((Auditioner*) 0),
129 if (!eng.connected()) {
130 throw failed_constructor();
133 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
135 n_physical_outputs = _engine.n_physical_outputs();
136 n_physical_inputs = _engine.n_physical_inputs();
138 first_stage_init (fullpath, snapshot_name);
140 initialize_start_and_end_locations(0, compute_initial_length ());
142 bool new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
145 // A mix_template must be specified if using this constructor
146 // to create a new session.
147 assert(mix_template);
149 if (!create_session_directory () ||
150 !create_session_file_from_template (*mix_template)) {
152 throw failed_constructor ();
154 // Continue construction like a normal saved session from now on.
158 if (second_stage_init (new_session)) {
160 throw failed_constructor ();
163 store_recent_sessions(_name, _path);
165 bool was_dirty = dirty();
167 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
169 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
172 DirtyChanged (); /* EMIT SIGNAL */
176 Session::Session (AudioEngine &eng,
178 string snapshot_name,
179 AutoConnectOption input_ac,
180 AutoConnectOption output_ac,
181 uint32_t control_out_channels,
182 uint32_t master_out_channels,
183 uint32_t requested_physical_in,
184 uint32_t requested_physical_out,
185 nframes_t initial_length)
188 _scratch_buffers(new BufferSet()),
189 _silent_buffers(new BufferSet()),
190 _send_buffers(new BufferSet()),
191 _mmc_port (default_mmc_port),
192 _mtc_port (default_mtc_port),
193 _midi_port (default_midi_port),
194 pending_events (2048),
195 //midi_requests (16),
196 _send_smpte_update (false),
197 diskstreams (new DiskstreamList),
198 routes (new RouteList),
202 if (!eng.connected()) {
203 throw failed_constructor();
206 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
208 n_physical_outputs = _engine.n_physical_outputs();
209 n_physical_inputs = _engine.n_physical_inputs();
211 if (n_physical_inputs) {
212 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
215 if (n_physical_outputs) {
216 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
219 first_stage_init (fullpath, snapshot_name);
221 initialize_start_and_end_locations(0, initial_length);
223 if (g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ||
224 !create_session_directory () ||
225 !create_session_file ()) {
227 throw failed_constructor ();
231 /* set up Master Out and Control Out if necessary */
236 if (control_out_channels) {
237 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
238 r->set_remote_control_id (control_id++);
243 if (master_out_channels) {
244 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
245 r->set_remote_control_id (control_id);
249 /* prohibit auto-connect to master, because there isn't one */
250 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
259 Config->set_input_auto_connect (input_ac);
260 Config->set_output_auto_connect (output_ac);
262 if (second_stage_init (true)) {
264 throw failed_constructor ();
267 store_recent_sessions(_name, _path);
269 bool was_dirty = dirty ();
271 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
273 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
276 DirtyChanged (); /* EMIT SIGNAL */
288 /* if we got to here, leaving pending capture state around
292 remove_pending_capture_state ();
294 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
295 _engine.remove_session ();
297 GoingAway (); /* EMIT SIGNAL */
303 /* clear history so that no references to objects are held any more */
307 /* clear state tree so that no references to objects are held any more */
313 terminate_butler_thread ();
314 //terminate_midi_thread ();
316 if (click_data && click_data != default_click) {
317 delete [] click_data;
320 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
321 delete [] click_emphasis_data;
326 delete _scratch_buffers;
327 delete _silent_buffers;
328 delete _send_buffers;
330 AudioDiskstream::free_working_buffers();
332 #undef TRACK_DESTRUCTION
333 #ifdef TRACK_DESTRUCTION
334 cerr << "delete named selections\n";
335 #endif /* TRACK_DESTRUCTION */
336 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
337 NamedSelectionList::iterator tmp;
346 #ifdef TRACK_DESTRUCTION
347 cerr << "delete playlists\n";
348 #endif /* TRACK_DESTRUCTION */
349 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
350 PlaylistList::iterator tmp;
355 (*i)->drop_references ();
360 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
361 PlaylistList::iterator tmp;
366 (*i)->drop_references ();
372 unused_playlists.clear ();
374 #ifdef TRACK_DESTRUCTION
375 cerr << "delete regions\n";
376 #endif /* TRACK_DESTRUCTION */
378 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
379 RegionList::iterator tmp;
384 i->second->drop_references ();
391 #ifdef TRACK_DESTRUCTION
392 cerr << "delete routes\n";
393 #endif /* TRACK_DESTRUCTION */
395 RCUWriter<RouteList> writer (routes);
396 boost::shared_ptr<RouteList> r = writer.get_copy ();
397 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
398 (*i)->drop_references ();
401 /* writer goes out of scope and updates master */
406 #ifdef TRACK_DESTRUCTION
407 cerr << "delete diskstreams\n";
408 #endif /* TRACK_DESTRUCTION */
410 RCUWriter<DiskstreamList> dwriter (diskstreams);
411 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
412 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
413 (*i)->drop_references ();
417 diskstreams.flush ();
419 #ifdef TRACK_DESTRUCTION
420 cerr << "delete audio sources\n";
421 #endif /* TRACK_DESTRUCTION */
422 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
423 SourceMap::iterator tmp;
428 i->second->drop_references ();
435 #ifdef TRACK_DESTRUCTION
436 cerr << "delete mix groups\n";
437 #endif /* TRACK_DESTRUCTION */
438 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
439 list<RouteGroup*>::iterator tmp;
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete edit groups\n";
451 #endif /* TRACK_DESTRUCTION */
452 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
453 list<RouteGroup*>::iterator tmp;
463 #ifdef TRACK_DESTRUCTION
464 cerr << "delete connections\n";
465 #endif /* TRACK_DESTRUCTION */
466 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
467 ConnectionList::iterator tmp;
477 if (butler_mixdown_buffer) {
478 delete [] butler_mixdown_buffer;
481 if (butler_gain_buffer) {
482 delete [] butler_gain_buffer;
485 Crossfade::set_buffer_size (0);
493 Session::set_worst_io_latencies ()
495 _worst_output_latency = 0;
496 _worst_input_latency = 0;
498 if (!_engine.connected()) {
502 boost::shared_ptr<RouteList> r = routes.reader ();
504 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
505 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
506 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
511 Session::when_engine_running ()
513 string first_physical_output;
515 /* we don't want to run execute this again */
517 set_block_size (_engine.frames_per_cycle());
518 set_frame_rate (_engine.frame_rate());
520 Config->map_parameters (mem_fun (*this, &Session::config_changed));
522 /* every time we reconnect, recompute worst case output latencies */
524 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
526 if (synced_to_jack()) {
527 _engine.transport_stop ();
530 if (Config->get_jack_time_master()) {
531 _engine.transport_locate (_transport_frame);
539 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
541 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
543 /* existing state for Click */
545 if (_click_io->set_state (*child->children().front()) == 0) {
547 _clicking = Config->get_clicking ();
551 error << _("could not setup Click I/O") << endmsg;
557 /* default state for Click */
559 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
561 if (first_physical_output.length()) {
562 if (_click_io->add_output_port (first_physical_output, this)) {
563 // relax, even though its an error
565 _clicking = Config->get_clicking ();
571 catch (failed_constructor& err) {
572 error << _("cannot setup Click I/O") << endmsg;
575 set_worst_io_latencies ();
578 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
581 /* Create a set of Connection objects that map
582 to the physical outputs currently available
587 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
589 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
591 Connection* c = new OutputConnection (buf, true);
594 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
599 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
601 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
603 Connection* c = new InputConnection (buf, true);
606 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
613 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
615 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
617 Connection* c = new OutputConnection (buf, true);
621 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
622 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
627 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
629 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
631 Connection* c = new InputConnection (buf, true);
635 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
636 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
645 /* create master/control ports */
650 /* force the master to ignore any later call to this */
652 if (_master_out->pending_state_node) {
653 _master_out->ports_became_legal();
656 /* no panner resets till we are through */
658 _master_out->defer_pan_reset ();
660 while (_master_out->n_inputs().n_audio()
661 < _master_out->input_maximum().n_audio()) {
662 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
663 error << _("cannot setup master inputs")
669 while (_master_out->n_outputs().n_audio()
670 < _master_out->output_maximum().n_audio()) {
671 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
672 error << _("cannot setup master outputs")
679 _master_out->allow_pan_reset ();
683 Connection* c = new OutputConnection (_("Master Out"), true);
685 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
687 c->add_connection ((int) n, _master_out->input(n)->name());
694 /* catch up on send+insert cnts */
698 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
701 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
702 if (id > insert_cnt) {
710 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
713 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
721 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
723 /* hook us up to the engine */
725 _engine.set_session (this);
730 osc->set_session (*this);
733 _state_of_the_state = Clean;
735 DirtyChanged (); /* EMIT SIGNAL */
739 Session::hookup_io ()
741 /* stop graph reordering notifications from
742 causing resorts, etc.
745 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
747 if (auditioner == 0) {
749 /* we delay creating the auditioner till now because
750 it makes its own connections to ports.
751 the engine has to be running for this to work.
755 auditioner.reset (new Auditioner (*this));
758 catch (failed_constructor& err) {
759 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
763 /* Tell all IO objects to create their ports */
769 vector<string> cports;
771 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
772 if (_control_out->add_input_port ("", this)) {
773 error << _("cannot setup control inputs")
779 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
780 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
781 error << _("cannot set up master outputs")
789 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
791 for (n = 0; n < ni; ++n) {
792 cports.push_back (_control_out->input(n)->name());
795 boost::shared_ptr<RouteList> r = routes.reader ();
797 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
798 (*x)->set_control_outs (cports);
802 /* Tell all IO objects to connect themselves together */
804 IO::enable_connecting ();
806 /* Now reset all panners */
808 IO::reset_panners ();
810 /* Anyone who cares about input state, wake up and do something */
812 IOConnectionsComplete (); /* EMIT SIGNAL */
814 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
816 /* now handle the whole enchilada as if it was one
822 /* update mixer solo state */
828 Session::playlist_length_changed ()
830 /* we can't just increase end_location->end() if pl->get_maximum_extent()
831 if larger. if the playlist used to be the longest playlist,
832 and its now shorter, we have to decrease end_location->end(). hence,
833 we have to iterate over all diskstreams and check the
834 playlists currently in use.
840 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
842 boost::shared_ptr<Playlist> playlist;
844 if ((playlist = dstream->playlist()) != 0) {
845 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
848 /* see comment in playlist_length_changed () */
853 Session::record_enabling_legal () const
855 /* this used to be in here, but survey says.... we don't need to restrict it */
856 // if (record_status() == Recording) {
860 if (Config->get_all_safe()) {
867 Session::reset_input_monitor_state ()
869 if (transport_rolling()) {
871 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
873 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
874 if ((*i)->record_enabled ()) {
875 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
876 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
880 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
882 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
883 if ((*i)->record_enabled ()) {
884 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
885 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
892 Session::auto_punch_start_changed (Location* location)
894 replace_event (Event::PunchIn, location->start());
896 if (get_record_enabled() && Config->get_punch_in()) {
897 /* capture start has been changed, so save new pending state */
898 save_state ("", true);
903 Session::auto_punch_end_changed (Location* location)
905 nframes_t when_to_stop = location->end();
906 // when_to_stop += _worst_output_latency + _worst_input_latency;
907 replace_event (Event::PunchOut, when_to_stop);
911 Session::auto_punch_changed (Location* location)
913 nframes_t when_to_stop = location->end();
915 replace_event (Event::PunchIn, location->start());
916 //when_to_stop += _worst_output_latency + _worst_input_latency;
917 replace_event (Event::PunchOut, when_to_stop);
921 Session::auto_loop_changed (Location* location)
923 replace_event (Event::AutoLoop, location->end(), location->start());
925 if (transport_rolling() && play_loop) {
927 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
929 if (_transport_frame > location->end()) {
930 // relocate to beginning of loop
931 clear_events (Event::LocateRoll);
933 request_locate (location->start(), true);
936 else if (Config->get_seamless_loop() && !loop_changing) {
938 // schedule a locate-roll to refill the diskstreams at the
940 loop_changing = true;
942 if (location->end() > last_loopend) {
943 clear_events (Event::LocateRoll);
944 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
951 last_loopend = location->end();
956 Session::set_auto_punch_location (Location* location)
960 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
961 auto_punch_start_changed_connection.disconnect();
962 auto_punch_end_changed_connection.disconnect();
963 auto_punch_changed_connection.disconnect();
964 existing->set_auto_punch (false, this);
965 remove_event (existing->start(), Event::PunchIn);
966 clear_events (Event::PunchOut);
967 auto_punch_location_changed (0);
976 if (location->end() <= location->start()) {
977 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
981 auto_punch_start_changed_connection.disconnect();
982 auto_punch_end_changed_connection.disconnect();
983 auto_punch_changed_connection.disconnect();
985 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
986 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
987 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
989 location->set_auto_punch (true, this);
990 auto_punch_location_changed (location);
994 Session::set_auto_loop_location (Location* location)
998 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
999 auto_loop_start_changed_connection.disconnect();
1000 auto_loop_end_changed_connection.disconnect();
1001 auto_loop_changed_connection.disconnect();
1002 existing->set_auto_loop (false, this);
1003 remove_event (existing->end(), Event::AutoLoop);
1004 auto_loop_location_changed (0);
1009 if (location == 0) {
1013 if (location->end() <= location->start()) {
1014 error << _("Session: you can't use a mark for auto loop") << endmsg;
1018 last_loopend = location->end();
1020 auto_loop_start_changed_connection.disconnect();
1021 auto_loop_end_changed_connection.disconnect();
1022 auto_loop_changed_connection.disconnect();
1024 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1025 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1026 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1028 location->set_auto_loop (true, this);
1029 auto_loop_location_changed (location);
1033 Session::locations_added (Location* ignored)
1039 Session::locations_changed ()
1041 _locations.apply (*this, &Session::handle_locations_changed);
1045 Session::handle_locations_changed (Locations::LocationList& locations)
1047 Locations::LocationList::iterator i;
1049 bool set_loop = false;
1050 bool set_punch = false;
1052 for (i = locations.begin(); i != locations.end(); ++i) {
1056 if (location->is_auto_punch()) {
1057 set_auto_punch_location (location);
1060 if (location->is_auto_loop()) {
1061 set_auto_loop_location (location);
1068 set_auto_loop_location (0);
1071 set_auto_punch_location (0);
1078 Session::enable_record ()
1080 /* XXX really atomic compare+swap here */
1081 if (g_atomic_int_get (&_record_status) != Recording) {
1082 g_atomic_int_set (&_record_status, Recording);
1083 _last_record_location = _transport_frame;
1084 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1086 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1087 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1088 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1089 if ((*i)->record_enabled ()) {
1090 (*i)->monitor_input (true);
1095 RecordStateChanged ();
1100 Session::disable_record (bool rt_context, bool force)
1104 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1106 if (!Config->get_latched_record_enable () || force) {
1107 g_atomic_int_set (&_record_status, Disabled);
1109 if (rs == Recording) {
1110 g_atomic_int_set (&_record_status, Enabled);
1114 // FIXME: timestamp correct? [DR]
1115 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1116 // does this /need/ to be sent in all cases?
1118 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1120 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1121 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1123 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1124 if ((*i)->record_enabled ()) {
1125 (*i)->monitor_input (false);
1130 RecordStateChanged (); /* emit signal */
1133 remove_pending_capture_state ();
1139 Session::step_back_from_record ()
1141 g_atomic_int_set (&_record_status, Enabled);
1143 if (Config->get_monitoring_model() == HardwareMonitoring) {
1144 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1146 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1147 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1148 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1149 (*i)->monitor_input (false);
1156 Session::maybe_enable_record ()
1158 g_atomic_int_set (&_record_status, Enabled);
1160 /* this function is currently called from somewhere other than an RT thread.
1161 this save_state() call therefore doesn't impact anything.
1164 save_state ("", true);
1166 if (_transport_speed) {
1167 if (!Config->get_punch_in()) {
1171 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1172 RecordStateChanged (); /* EMIT SIGNAL */
1179 Session::audible_frame () const
1185 /* the first of these two possible settings for "offset"
1186 mean that the audible frame is stationary until
1187 audio emerges from the latency compensation
1190 the second means that the audible frame is stationary
1191 until audio would emerge from a physical port
1192 in the absence of any plugin latency compensation
1195 offset = _worst_output_latency;
1197 if (offset > current_block_size) {
1198 offset -= current_block_size;
1200 /* XXX is this correct? if we have no external
1201 physical connections and everything is internal
1202 then surely this is zero? still, how
1203 likely is that anyway?
1205 offset = current_block_size;
1208 if (synced_to_jack()) {
1209 tf = _engine.transport_frame();
1211 tf = _transport_frame;
1214 if (_transport_speed == 0) {
1224 if (!non_realtime_work_pending()) {
1228 /* take latency into account */
1237 Session::set_frame_rate (nframes_t frames_per_second)
1239 /** \fn void Session::set_frame_size(nframes_t)
1240 the AudioEngine object that calls this guarantees
1241 that it will not be called while we are also in
1242 ::process(). Its fine to do things that block
1246 _base_frame_rate = frames_per_second;
1250 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1252 // XXX we need some equivalent to this, somehow
1253 // SndFileSource::setup_standard_crossfades (frames_per_second);
1257 /* XXX need to reset/reinstantiate all LADSPA plugins */
1261 Session::set_block_size (nframes_t nframes)
1263 /* the AudioEngine guarantees
1264 that it will not be called while we are also in
1265 ::process(). It is therefore fine to do things that block
1271 current_block_size = nframes;
1273 ensure_buffers(_scratch_buffers->available());
1275 if (_gain_automation_buffer) {
1276 delete [] _gain_automation_buffer;
1278 _gain_automation_buffer = new gain_t[nframes];
1280 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1282 boost::shared_ptr<RouteList> r = routes.reader ();
1284 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1285 (*i)->set_block_size (nframes);
1288 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1289 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1290 (*i)->set_block_size (nframes);
1293 set_worst_io_latencies ();
1298 Session::set_default_fade (float steepness, float fade_msecs)
1301 nframes_t fade_frames;
1303 /* Don't allow fade of less 1 frame */
1305 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1312 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1316 default_fade_msecs = fade_msecs;
1317 default_fade_steepness = steepness;
1320 // jlc, WTF is this!
1321 Glib::RWLock::ReaderLock lm (route_lock);
1322 AudioRegion::set_default_fade (steepness, fade_frames);
1327 /* XXX have to do this at some point */
1328 /* foreach region using default fade, reset, then
1329 refill_all_diskstream_buffers ();
1334 struct RouteSorter {
1335 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1336 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1338 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1341 if (r1->fed_by.empty()) {
1342 if (r2->fed_by.empty()) {
1343 /* no ardour-based connections inbound to either route. just use signal order */
1344 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1346 /* r2 has connections, r1 does not; run r1 early */
1350 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1357 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1359 shared_ptr<Route> r2;
1361 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1362 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1366 /* make a copy of the existing list of routes that feed r1 */
1368 set<shared_ptr<Route> > existing = r1->fed_by;
1370 /* for each route that feeds r1, recurse, marking it as feeding
1374 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1377 /* r2 is a route that feeds r1 which somehow feeds base. mark
1378 base as being fed by r2
1381 rbase->fed_by.insert (r2);
1385 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1389 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1393 /* now recurse, so that we can mark base as being fed by
1394 all routes that feed r2
1397 trace_terminal (r2, rbase);
1404 Session::resort_routes ()
1406 /* don't do anything here with signals emitted
1407 by Routes while we are being destroyed.
1410 if (_state_of_the_state & Deletion) {
1417 RCUWriter<RouteList> writer (routes);
1418 shared_ptr<RouteList> r = writer.get_copy ();
1419 resort_routes_using (r);
1420 /* writer goes out of scope and forces update */
1425 Session::resort_routes_using (shared_ptr<RouteList> r)
1427 RouteList::iterator i, j;
1429 for (i = r->begin(); i != r->end(); ++i) {
1431 (*i)->fed_by.clear ();
1433 for (j = r->begin(); j != r->end(); ++j) {
1435 /* although routes can feed themselves, it will
1436 cause an endless recursive descent if we
1437 detect it. so don't bother checking for
1445 if ((*j)->feeds (*i)) {
1446 (*i)->fed_by.insert (*j);
1451 for (i = r->begin(); i != r->end(); ++i) {
1452 trace_terminal (*i, *i);
1459 cerr << "finished route resort\n";
1461 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1462 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1469 list<boost::shared_ptr<MidiTrack> >
1470 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1472 char track_name[32];
1473 uint32_t track_id = 0;
1475 uint32_t channels_used = 0;
1477 RouteList new_routes;
1478 list<boost::shared_ptr<MidiTrack> > ret;
1480 /* count existing midi tracks */
1483 shared_ptr<RouteList> r = routes.reader ();
1485 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1486 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1487 if (!(*i)->hidden()) {
1489 channels_used += (*i)->n_inputs().n_midi();
1497 /* check for duplicate route names, since we might have pre-existing
1498 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1499 save, close,restart,add new route - first named route is now
1507 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1509 if (route_by_name (track_name) == 0) {
1513 } while (track_id < (UINT_MAX-1));
1516 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1518 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1519 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1522 channels_used += track->n_inputs ().n_midi();
1524 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1525 track->set_remote_control_id (ntracks());
1527 new_routes.push_back (track);
1528 ret.push_back (track);
1531 catch (failed_constructor &err) {
1532 error << _("Session: could not create new midi track.") << endmsg;
1533 // XXX should we delete the tracks already created?
1541 if (!new_routes.empty()) {
1542 add_routes (new_routes, false);
1543 save_state (_current_snapshot_name);
1549 list<boost::shared_ptr<AudioTrack> >
1550 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1552 char track_name[32];
1553 uint32_t track_id = 0;
1555 uint32_t channels_used = 0;
1557 RouteList new_routes;
1558 list<boost::shared_ptr<AudioTrack> > ret;
1559 uint32_t control_id;
1561 /* count existing audio tracks */
1564 shared_ptr<RouteList> r = routes.reader ();
1566 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1567 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1568 if (!(*i)->hidden()) {
1570 channels_used += (*i)->n_inputs().n_audio();
1576 vector<string> physinputs;
1577 vector<string> physoutputs;
1578 uint32_t nphysical_in;
1579 uint32_t nphysical_out;
1581 _engine.get_physical_outputs (physoutputs);
1582 _engine.get_physical_inputs (physinputs);
1583 control_id = ntracks() + nbusses() + 1;
1587 /* check for duplicate route names, since we might have pre-existing
1588 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1589 save, close,restart,add new route - first named route is now
1597 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1599 if (route_by_name (track_name) == 0) {
1603 } while (track_id < (UINT_MAX-1));
1605 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1606 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1611 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1612 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1617 shared_ptr<AudioTrack> track;
1620 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1622 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1623 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1624 input_channels, output_channels)
1630 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1634 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1635 port = physinputs[(channels_used+x)%nphysical_in];
1638 if (port.length() && track->connect_input (track->input (x), port, this)) {
1644 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1648 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1649 port = physoutputs[(channels_used+x)%nphysical_out];
1650 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1652 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1656 if (port.length() && track->connect_output (track->output (x), port, this)) {
1661 channels_used += track->n_inputs ().n_audio();
1663 track->audio_diskstream()->non_realtime_input_change();
1665 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1666 track->set_remote_control_id (control_id);
1669 new_routes.push_back (track);
1670 ret.push_back (track);
1673 catch (failed_constructor &err) {
1674 error << _("Session: could not create new audio track.") << endmsg;
1677 /* we need to get rid of this, since the track failed to be created */
1678 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1681 RCUWriter<DiskstreamList> writer (diskstreams);
1682 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1683 ds->remove (track->audio_diskstream());
1690 catch (AudioEngine::PortRegistrationFailure& pfe) {
1692 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;
1695 /* we need to get rid of this, since the track failed to be created */
1696 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1699 RCUWriter<DiskstreamList> writer (diskstreams);
1700 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1701 ds->remove (track->audio_diskstream());
1712 if (!new_routes.empty()) {
1713 add_routes (new_routes, false);
1714 save_state (_current_snapshot_name);
1721 Session::set_remote_control_ids ()
1723 RemoteModel m = Config->get_remote_model();
1725 shared_ptr<RouteList> r = routes.reader ();
1727 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1728 if ( MixerOrdered == m) {
1729 long order = (*i)->order_key(N_("signal"));
1730 (*i)->set_remote_control_id( order+1 );
1731 } else if ( EditorOrdered == m) {
1732 long order = (*i)->order_key(N_("editor"));
1733 (*i)->set_remote_control_id( order+1 );
1734 } else if ( UserOrdered == m) {
1735 //do nothing ... only changes to remote id's are initiated by user
1742 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1745 uint32_t bus_id = 1;
1749 uint32_t control_id;
1751 /* count existing audio busses */
1754 shared_ptr<RouteList> r = routes.reader ();
1756 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1757 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1758 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1765 vector<string> physinputs;
1766 vector<string> physoutputs;
1768 _engine.get_physical_outputs (physoutputs);
1769 _engine.get_physical_inputs (physinputs);
1770 control_id = ntracks() + nbusses() + 1;
1775 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1779 if (route_by_name (bus_name) == 0) {
1783 } while (bus_id < (UINT_MAX-1));
1786 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1788 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1789 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1790 input_channels, output_channels)
1795 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1799 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1800 port = physinputs[((n+x)%n_physical_inputs)];
1803 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1808 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1812 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1813 port = physoutputs[((n+x)%n_physical_outputs)];
1814 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1816 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1820 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1825 bus->set_remote_control_id (control_id);
1828 ret.push_back (bus);
1832 catch (failed_constructor &err) {
1833 error << _("Session: could not create new audio route.") << endmsg;
1837 catch (AudioEngine::PortRegistrationFailure& pfe) {
1838 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;
1848 add_routes (ret, false);
1849 save_state (_current_snapshot_name);
1857 Session::add_routes (RouteList& new_routes, bool save)
1860 RCUWriter<RouteList> writer (routes);
1861 shared_ptr<RouteList> r = writer.get_copy ();
1862 r->insert (r->end(), new_routes.begin(), new_routes.end());
1863 resort_routes_using (r);
1866 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1868 boost::weak_ptr<Route> wpr (*x);
1870 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1871 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1872 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1873 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1875 if ((*x)->master()) {
1879 if ((*x)->control()) {
1880 _control_out = (*x);
1884 if (_control_out && IO::connecting_legal) {
1886 vector<string> cports;
1887 uint32_t ni = _control_out->n_inputs().n_audio();
1889 for (uint32_t n = 0; n < ni; ++n) {
1890 cports.push_back (_control_out->input(n)->name());
1893 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1894 (*x)->set_control_outs (cports);
1901 save_state (_current_snapshot_name);
1904 RouteAdded (new_routes); /* EMIT SIGNAL */
1908 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1910 /* need to do this in case we're rolling at the time, to prevent false underruns */
1911 dstream->do_refill_with_alloc ();
1913 dstream->set_block_size (current_block_size);
1916 RCUWriter<DiskstreamList> writer (diskstreams);
1917 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1918 ds->push_back (dstream);
1919 /* writer goes out of scope, copies ds back to main */
1922 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1923 /* this will connect to future changes, and check the current length */
1924 diskstream_playlist_changed (dstream);
1926 dstream->prepare ();
1931 Session::remove_route (shared_ptr<Route> route)
1934 RCUWriter<RouteList> writer (routes);
1935 shared_ptr<RouteList> rs = writer.get_copy ();
1939 /* deleting the master out seems like a dumb
1940 idea, but its more of a UI policy issue
1944 if (route == _master_out) {
1945 _master_out = shared_ptr<Route> ();
1948 if (route == _control_out) {
1949 _control_out = shared_ptr<Route> ();
1951 /* cancel control outs for all routes */
1953 vector<string> empty;
1955 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1956 (*r)->set_control_outs (empty);
1960 update_route_solo_state ();
1962 /* writer goes out of scope, forces route list update */
1966 boost::shared_ptr<Diskstream> ds;
1968 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1969 ds = t->diskstream();
1975 RCUWriter<DiskstreamList> dsl (diskstreams);
1976 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1981 find_current_end ();
1983 update_latency_compensation (false, false);
1986 // We need to disconnect the routes inputs and outputs
1987 route->disconnect_inputs(NULL);
1988 route->disconnect_outputs(NULL);
1990 /* get rid of it from the dead wood collection in the route list manager */
1992 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1996 /* try to cause everyone to drop their references */
1998 route->drop_references ();
2000 /* save the new state of the world */
2002 if (save_state (_current_snapshot_name)) {
2003 save_history (_current_snapshot_name);
2008 Session::route_mute_changed (void* src)
2014 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2016 if (solo_update_disabled) {
2022 boost::shared_ptr<Route> route = wpr.lock ();
2025 /* should not happen */
2026 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2030 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2032 shared_ptr<RouteList> r = routes.reader ();
2034 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2036 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2040 /* don't mess with busses */
2042 if (dynamic_cast<Track*>((*i).get()) == 0) {
2048 /* don't mess with tracks */
2050 if (dynamic_cast<Track*>((*i).get()) != 0) {
2055 if ((*i) != route &&
2056 ((*i)->mix_group () == 0 ||
2057 (*i)->mix_group () != route->mix_group () ||
2058 !route->mix_group ()->is_active())) {
2060 if ((*i)->soloed()) {
2062 /* if its already soloed, and solo latching is enabled,
2063 then leave it as it is.
2066 if (Config->get_solo_latched()) {
2073 solo_update_disabled = true;
2074 (*i)->set_solo (false, src);
2075 solo_update_disabled = false;
2079 bool something_soloed = false;
2080 bool same_thing_soloed = false;
2081 bool signal = false;
2083 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2084 if ((*i)->soloed()) {
2085 something_soloed = true;
2086 if (dynamic_cast<Track*>((*i).get())) {
2088 same_thing_soloed = true;
2093 same_thing_soloed = true;
2101 if (something_soloed != currently_soloing) {
2103 currently_soloing = something_soloed;
2106 modify_solo_mute (is_track, same_thing_soloed);
2109 SoloActive (currently_soloing); /* EMIT SIGNAL */
2112 SoloChanged (); /* EMIT SIGNAL */
2118 Session::update_route_solo_state ()
2121 bool is_track = false;
2122 bool signal = false;
2124 /* caller must hold RouteLock */
2126 /* this is where we actually implement solo by changing
2127 the solo mute setting of each track.
2130 shared_ptr<RouteList> r = routes.reader ();
2132 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2133 if ((*i)->soloed()) {
2135 if (dynamic_cast<Track*>((*i).get())) {
2142 if (mute != currently_soloing) {
2144 currently_soloing = mute;
2147 if (!is_track && !mute) {
2149 /* nothing is soloed */
2151 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2152 (*i)->set_solo_mute (false);
2162 modify_solo_mute (is_track, mute);
2165 SoloActive (currently_soloing);
2170 Session::modify_solo_mute (bool is_track, bool mute)
2172 shared_ptr<RouteList> r = routes.reader ();
2174 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2178 /* only alter track solo mute */
2180 if (dynamic_cast<Track*>((*i).get())) {
2181 if ((*i)->soloed()) {
2182 (*i)->set_solo_mute (!mute);
2184 (*i)->set_solo_mute (mute);
2190 /* only alter bus solo mute */
2192 if (!dynamic_cast<Track*>((*i).get())) {
2194 if ((*i)->soloed()) {
2196 (*i)->set_solo_mute (false);
2200 /* don't mute master or control outs
2201 in response to another bus solo
2204 if ((*i) != _master_out &&
2205 (*i) != _control_out) {
2206 (*i)->set_solo_mute (mute);
2217 Session::catch_up_on_solo ()
2219 /* this is called after set_state() to catch the full solo
2220 state, which can't be correctly determined on a per-route
2221 basis, but needs the global overview that only the session
2224 update_route_solo_state();
2228 Session::route_by_name (string name)
2230 shared_ptr<RouteList> r = routes.reader ();
2232 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2233 if ((*i)->name() == name) {
2238 return shared_ptr<Route> ((Route*) 0);
2242 Session::route_by_id (PBD::ID id)
2244 shared_ptr<RouteList> r = routes.reader ();
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2247 if ((*i)->id() == id) {
2252 return shared_ptr<Route> ((Route*) 0);
2256 Session::route_by_remote_id (uint32_t id)
2258 shared_ptr<RouteList> r = routes.reader ();
2260 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2261 if ((*i)->remote_control_id() == id) {
2266 return shared_ptr<Route> ((Route*) 0);
2270 Session::find_current_end ()
2272 if (_state_of_the_state & Loading) {
2276 nframes_t max = get_maximum_extent ();
2278 if (max > end_location->end()) {
2279 end_location->set_end (max);
2281 DurationChanged(); /* EMIT SIGNAL */
2286 Session::get_maximum_extent () const
2291 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2293 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2294 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2295 if ((me = pl->get_maximum_extent()) > max) {
2303 boost::shared_ptr<Diskstream>
2304 Session::diskstream_by_name (string name)
2306 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2308 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2309 if ((*i)->name() == name) {
2314 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2317 boost::shared_ptr<Diskstream>
2318 Session::diskstream_by_id (const PBD::ID& id)
2320 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2322 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2323 if ((*i)->id() == id) {
2328 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2331 /* Region management */
2334 Session::new_region_name (string old)
2336 string::size_type last_period;
2338 string::size_type len = old.length() + 64;
2341 if ((last_period = old.find_last_of ('.')) == string::npos) {
2343 /* no period present - add one explicitly */
2346 last_period = old.length() - 1;
2351 number = atoi (old.substr (last_period+1).c_str());
2355 while (number < (UINT_MAX-1)) {
2357 RegionList::const_iterator i;
2362 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2365 for (i = regions.begin(); i != regions.end(); ++i) {
2366 if (i->second->name() == sbuf) {
2371 if (i == regions.end()) {
2376 if (number != (UINT_MAX-1)) {
2380 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2385 Session::region_name (string& result, string base, bool newlevel) const
2390 assert(base.find("/") == string::npos);
2394 Glib::Mutex::Lock lm (region_lock);
2396 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2404 /* XXX this is going to be slow. optimize me later */
2409 string::size_type pos;
2411 pos = base.find_last_of ('.');
2413 /* pos may be npos, but then we just use entire base */
2415 subbase = base.substr (0, pos);
2419 bool name_taken = true;
2422 Glib::Mutex::Lock lm (region_lock);
2424 for (int n = 1; n < 5000; ++n) {
2427 snprintf (buf, sizeof (buf), ".%d", n);
2432 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2433 if (i->second->name() == result) {
2446 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2454 Session::add_region (boost::shared_ptr<Region> region)
2456 boost::shared_ptr<Region> other;
2460 Glib::Mutex::Lock lm (region_lock);
2462 RegionList::iterator x;
2464 for (x = regions.begin(); x != regions.end(); ++x) {
2468 if (region->region_list_equivalent (other)) {
2473 if (x == regions.end()) {
2475 pair<RegionList::key_type,RegionList::mapped_type> entry;
2477 entry.first = region->id();
2478 entry.second = region;
2480 pair<RegionList::iterator,bool> x = regions.insert (entry);
2492 /* mark dirty because something has changed even if we didn't
2493 add the region to the region list.
2499 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2500 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2501 RegionAdded (region); /* EMIT SIGNAL */
2506 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2508 boost::shared_ptr<Region> region (weak_region.lock ());
2514 if (what_changed & Region::HiddenChanged) {
2515 /* relay hidden changes */
2516 RegionHiddenChange (region);
2521 Session::remove_region (boost::weak_ptr<Region> weak_region)
2523 RegionList::iterator i;
2524 boost::shared_ptr<Region> region (weak_region.lock ());
2530 bool removed = false;
2533 Glib::Mutex::Lock lm (region_lock);
2535 if ((i = regions.find (region->id())) != regions.end()) {
2541 /* mark dirty because something has changed even if we didn't
2542 remove the region from the region list.
2548 RegionRemoved(region); /* EMIT SIGNAL */
2552 boost::shared_ptr<Region>
2553 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2555 RegionList::iterator i;
2556 boost::shared_ptr<Region> region;
2558 Glib::Mutex::Lock lm (region_lock);
2560 for (i = regions.begin(); i != regions.end(); ++i) {
2564 if (region->whole_file()) {
2566 if (child->source_equivalent (region)) {
2572 return boost::shared_ptr<Region> ();
2576 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2578 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2579 (*i)->get_region_list_equivalent_regions (region, result);
2583 Session::destroy_region (boost::shared_ptr<Region> region)
2585 vector<boost::shared_ptr<Source> > srcs;
2588 boost::shared_ptr<AudioRegion> aregion;
2590 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2594 if (aregion->playlist()) {
2595 aregion->playlist()->destroy_region (region);
2598 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2599 srcs.push_back (aregion->source (n));
2603 region->drop_references ();
2605 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2607 if (!(*i)->used()) {
2608 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2611 (afs)->mark_for_remove ();
2614 (*i)->drop_references ();
2616 cerr << "source was not used by any playlist\n";
2624 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2626 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2627 destroy_region (*i);
2633 Session::remove_last_capture ()
2635 list<boost::shared_ptr<Region> > r;
2637 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2639 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2640 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2643 r.insert (r.end(), l.begin(), l.end());
2648 destroy_regions (r);
2650 save_state (_current_snapshot_name);
2656 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2662 /* Source Management */
2664 Session::add_source (boost::shared_ptr<Source> source)
2666 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2667 pair<SourceMap::iterator,bool> result;
2669 entry.first = source->id();
2670 entry.second = source;
2673 Glib::Mutex::Lock lm (source_lock);
2674 result = sources.insert (entry);
2677 if (result.second) {
2678 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2684 Session::remove_source (boost::weak_ptr<Source> src)
2686 SourceMap::iterator i;
2687 boost::shared_ptr<Source> source = src.lock();
2694 Glib::Mutex::Lock lm (source_lock);
2697 Glib::Mutex::Lock lm (source_lock);
2699 if ((i = sources.find (source->id())) != sources.end()) {
2705 if (!_state_of_the_state & InCleanup) {
2707 /* save state so we don't end up with a session file
2708 referring to non-existent sources.
2711 save_state (_current_snapshot_name);
2715 boost::shared_ptr<Source>
2716 Session::source_by_id (const PBD::ID& id)
2718 Glib::Mutex::Lock lm (source_lock);
2719 SourceMap::iterator i;
2720 boost::shared_ptr<Source> source;
2722 if ((i = sources.find (id)) != sources.end()) {
2726 /* XXX search MIDI or other searches here */
2732 boost::shared_ptr<Source>
2733 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2735 Glib::Mutex::Lock lm (source_lock);
2737 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2738 cerr << "comparing " << path << " with " << i->second->name() << endl;
2739 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2741 if (afs && afs->path() == path && chn == afs->channel()) {
2746 return boost::shared_ptr<Source>();
2750 Session::peak_path_from_audio_path (string audio_path) const
2755 res += PBD::basename_nosuffix (audio_path);
2762 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2765 string old_basename = PBD::basename_nosuffix (oldname);
2766 string new_legalized = legalize_for_path (newname);
2768 /* note: we know (or assume) the old path is already valid */
2772 /* destructive file sources have a name of the form:
2774 /path/to/Tnnnn-NAME(%[LR])?.wav
2776 the task here is to replace NAME with the new name.
2779 /* find last slash */
2783 string::size_type slash;
2784 string::size_type dash;
2786 if ((slash = path.find_last_of ('/')) == string::npos) {
2790 dir = path.substr (0, slash+1);
2792 /* '-' is not a legal character for the NAME part of the path */
2794 if ((dash = path.find_last_of ('-')) == string::npos) {
2798 prefix = path.substr (slash+1, dash-(slash+1));
2803 path += new_legalized;
2804 path += ".wav"; /* XXX gag me with a spoon */
2808 /* non-destructive file sources have a name of the form:
2810 /path/to/NAME-nnnnn(%[LR])?.wav
2812 the task here is to replace NAME with the new name.
2817 string::size_type slash;
2818 string::size_type dash;
2819 string::size_type postfix;
2821 /* find last slash */
2823 if ((slash = path.find_last_of ('/')) == string::npos) {
2827 dir = path.substr (0, slash+1);
2829 /* '-' is not a legal character for the NAME part of the path */
2831 if ((dash = path.find_last_of ('-')) == string::npos) {
2835 suffix = path.substr (dash+1);
2837 // Suffix is now everything after the dash. Now we need to eliminate
2838 // the nnnnn part, which is done by either finding a '%' or a '.'
2840 postfix = suffix.find_last_of ("%");
2841 if (postfix == string::npos) {
2842 postfix = suffix.find_last_of ('.');
2845 if (postfix != string::npos) {
2846 suffix = suffix.substr (postfix);
2848 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2852 const uint32_t limit = 10000;
2853 char buf[PATH_MAX+1];
2855 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2857 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2859 if (access (buf, F_OK) != 0) {
2867 error << "FATAL ERROR! Could not find a " << endl;
2876 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2880 char buf[PATH_MAX+1];
2881 const uint32_t limit = 10000;
2885 legalized = legalize_for_path (name);
2887 /* find a "version" of the file name that doesn't exist in
2888 any of the possible directories.
2891 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2893 vector<space_and_path>::iterator i;
2894 uint32_t existing = 0;
2896 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2900 spath += sound_dir (false);
2904 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2905 } else if (nchan == 2) {
2907 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2909 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2911 } else if (nchan < 26) {
2912 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2914 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2923 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2924 } else if (nchan == 2) {
2926 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2928 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2930 } else if (nchan < 26) {
2931 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2933 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2937 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2943 if (existing == 0) {
2948 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2950 throw failed_constructor();
2954 /* we now have a unique name for the file, but figure out where to
2960 spath = discover_best_sound_dir ();
2963 string::size_type pos = foo.find_last_of ('/');
2965 if (pos == string::npos) {
2968 spath += foo.substr (pos + 1);
2974 boost::shared_ptr<AudioFileSource>
2975 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2977 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2978 return boost::dynamic_pointer_cast<AudioFileSource> (
2979 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2982 // FIXME: _terrible_ code duplication
2984 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
2987 string old_basename = PBD::basename_nosuffix (oldname);
2988 string new_legalized = legalize_for_path (newname);
2990 /* note: we know (or assume) the old path is already valid */
2994 /* destructive file sources have a name of the form:
2996 /path/to/Tnnnn-NAME(%[LR])?.wav
2998 the task here is to replace NAME with the new name.
3001 /* find last slash */
3005 string::size_type slash;
3006 string::size_type dash;
3008 if ((slash = path.find_last_of ('/')) == string::npos) {
3012 dir = path.substr (0, slash+1);
3014 /* '-' is not a legal character for the NAME part of the path */
3016 if ((dash = path.find_last_of ('-')) == string::npos) {
3020 prefix = path.substr (slash+1, dash-(slash+1));
3025 path += new_legalized;
3026 path += ".mid"; /* XXX gag me with a spoon */
3030 /* non-destructive file sources have a name of the form:
3032 /path/to/NAME-nnnnn(%[LR])?.wav
3034 the task here is to replace NAME with the new name.
3039 string::size_type slash;
3040 string::size_type dash;
3041 string::size_type postfix;
3043 /* find last slash */
3045 if ((slash = path.find_last_of ('/')) == string::npos) {
3049 dir = path.substr (0, slash+1);
3051 /* '-' is not a legal character for the NAME part of the path */
3053 if ((dash = path.find_last_of ('-')) == string::npos) {
3057 suffix = path.substr (dash+1);
3059 // Suffix is now everything after the dash. Now we need to eliminate
3060 // the nnnnn part, which is done by either finding a '%' or a '.'
3062 postfix = suffix.find_last_of ("%");
3063 if (postfix == string::npos) {
3064 postfix = suffix.find_last_of ('.');
3067 if (postfix != string::npos) {
3068 suffix = suffix.substr (postfix);
3070 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3074 const uint32_t limit = 10000;
3075 char buf[PATH_MAX+1];
3077 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3079 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3081 if (access (buf, F_OK) != 0) {
3089 error << "FATAL ERROR! Could not find a " << endl;
3098 Session::midi_path_from_name (string name)
3102 char buf[PATH_MAX+1];
3103 const uint32_t limit = 10000;
3107 legalized = legalize_for_path (name);
3109 /* find a "version" of the file name that doesn't exist in
3110 any of the possible directories.
3113 for (cnt = 1; cnt <= limit; ++cnt) {
3115 vector<space_and_path>::iterator i;
3116 uint32_t existing = 0;
3118 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3122 // FIXME: different directory from audio?
3123 spath += sound_dir(false) + "/" + legalized;
3125 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3127 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3132 if (existing == 0) {
3137 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3138 throw failed_constructor();
3142 /* we now have a unique name for the file, but figure out where to
3148 // FIXME: different directory than audio?
3149 spath = discover_best_sound_dir ();
3152 string::size_type pos = foo.find_last_of ('/');
3154 if (pos == string::npos) {
3157 spath += foo.substr (pos + 1);
3163 boost::shared_ptr<MidiSource>
3164 Session::create_midi_source_for_session (MidiDiskstream& ds)
3166 string spath = midi_path_from_name (ds.name());
3168 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3172 /* Playlist management */
3174 boost::shared_ptr<Playlist>
3175 Session::playlist_by_name (string name)
3177 Glib::Mutex::Lock lm (playlist_lock);
3178 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3179 if ((*i)->name() == name) {
3183 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3184 if ((*i)->name() == name) {
3189 return boost::shared_ptr<Playlist>();
3193 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3195 if (playlist->hidden()) {
3200 Glib::Mutex::Lock lm (playlist_lock);
3201 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3202 playlists.insert (playlists.begin(), playlist);
3203 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3204 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3210 PlaylistAdded (playlist); /* EMIT SIGNAL */
3214 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3217 Glib::Mutex::Lock lm (playlist_lock);
3218 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3221 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3228 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3230 boost::shared_ptr<Playlist> pl(wpl.lock());
3236 PlaylistList::iterator x;
3239 /* its not supposed to be visible */
3244 Glib::Mutex::Lock lm (playlist_lock);
3248 unused_playlists.insert (pl);
3250 if ((x = playlists.find (pl)) != playlists.end()) {
3251 playlists.erase (x);
3257 playlists.insert (pl);
3259 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3260 unused_playlists.erase (x);
3267 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3269 if (_state_of_the_state & Deletion) {
3273 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3280 Glib::Mutex::Lock lm (playlist_lock);
3282 PlaylistList::iterator i;
3284 i = find (playlists.begin(), playlists.end(), playlist);
3285 if (i != playlists.end()) {
3286 playlists.erase (i);
3289 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3290 if (i != unused_playlists.end()) {
3291 unused_playlists.erase (i);
3298 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3302 Session::set_audition (boost::shared_ptr<Region> r)
3304 pending_audition_region = r;
3305 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3306 schedule_butler_transport_work ();
3310 Session::audition_playlist ()
3312 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3313 ev->region.reset ();
3318 Session::non_realtime_set_audition ()
3320 if (!pending_audition_region) {
3321 auditioner->audition_current_playlist ();
3323 auditioner->audition_region (pending_audition_region);
3324 pending_audition_region.reset ();
3326 AuditionActive (true); /* EMIT SIGNAL */
3330 Session::audition_region (boost::shared_ptr<Region> r)
3332 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3338 Session::cancel_audition ()
3340 if (auditioner->active()) {
3341 auditioner->cancel_audition ();
3342 AuditionActive (false); /* EMIT SIGNAL */
3347 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3349 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3353 Session::remove_empty_sounds ()
3355 PathScanner scanner;
3357 vector<string *>* possible_audiofiles = scanner (sound_dir(), Config->get_possible_audio_file_regexp (), false, true);
3359 Glib::Mutex::Lock lm (source_lock);
3361 regex_t compiled_tape_track_pattern;
3364 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3368 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3370 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3374 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3376 /* never remove files that appear to be a tape track */
3378 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3383 if (AudioFileSource::is_empty (*this, *(*i))) {
3385 unlink ((*i)->c_str());
3387 string peak_path = peak_path_from_audio_path (**i);
3388 unlink (peak_path.c_str());
3394 delete possible_audiofiles;
3398 Session::is_auditioning () const
3400 /* can be called before we have an auditioner object */
3402 return auditioner->active();
3409 Session::set_all_solo (bool yn)
3411 shared_ptr<RouteList> r = routes.reader ();
3413 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3414 if (!(*i)->hidden()) {
3415 (*i)->set_solo (yn, this);
3423 Session::set_all_mute (bool yn)
3425 shared_ptr<RouteList> r = routes.reader ();
3427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3428 if (!(*i)->hidden()) {
3429 (*i)->set_mute (yn, this);
3437 Session::n_diskstreams () const
3441 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3443 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3444 if (!(*i)->hidden()) {
3452 Session::graph_reordered ()
3454 /* don't do this stuff if we are setting up connections
3455 from a set_state() call or creating new tracks.
3458 if (_state_of_the_state & InitialConnecting) {
3462 /* every track/bus asked for this to be handled but it was deferred because
3463 we were connecting. do it now.
3466 request_input_change_handling ();
3470 /* force all diskstreams to update their capture offset values to
3471 reflect any changes in latencies within the graph.
3474 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3476 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3477 (*i)->set_capture_offset ();
3482 Session::record_disenable_all ()
3484 record_enable_change_all (false);
3488 Session::record_enable_all ()
3490 record_enable_change_all (true);
3494 Session::record_enable_change_all (bool yn)
3496 shared_ptr<RouteList> r = routes.reader ();
3498 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3501 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3502 at->set_record_enable (yn, this);
3506 /* since we don't keep rec-enable state, don't mark session dirty */
3510 Session::add_redirect (Redirect* redirect)
3514 PortInsert* port_insert;
3515 PluginInsert* plugin_insert;
3517 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3518 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3519 _port_inserts.insert (_port_inserts.begin(), port_insert);
3520 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3521 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3523 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3526 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3527 _sends.insert (_sends.begin(), send);
3529 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3533 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3539 Session::remove_redirect (Redirect* redirect)
3543 PortInsert* port_insert;
3544 PluginInsert* plugin_insert;
3546 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3547 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3548 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3549 if (x != _port_inserts.end()) {
3550 insert_bitset[port_insert->bit_slot()] = false;
3551 _port_inserts.erase (x);
3553 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3554 _plugin_inserts.remove (plugin_insert);
3556 fatal << string_compose (_("programming error: %1"),
3557 X_("unknown type of Insert deleted!"))
3561 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3562 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3563 if (x != _sends.end()) {
3564 send_bitset[send->bit_slot()] = false;
3568 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3576 Session::available_capture_duration ()
3578 float sample_bytes_on_disk = 4.0; // keep gcc happy
3580 switch (Config->get_native_file_data_format()) {
3582 sample_bytes_on_disk = 4.0;
3586 sample_bytes_on_disk = 3.0;
3590 /* impossible, but keep some gcc versions happy */
3591 fatal << string_compose (_("programming error: %1"),
3592 X_("illegal native file data format"))
3597 double scale = 4096.0 / sample_bytes_on_disk;
3599 if (_total_free_4k_blocks * scale > (double) max_frames) {
3603 return (nframes_t) floor (_total_free_4k_blocks * scale);
3607 Session::add_connection (ARDOUR::Connection* connection)
3610 Glib::Mutex::Lock guard (connection_lock);
3611 _connections.push_back (connection);
3614 ConnectionAdded (connection); /* EMIT SIGNAL */
3620 Session::remove_connection (ARDOUR::Connection* connection)
3622 bool removed = false;
3625 Glib::Mutex::Lock guard (connection_lock);
3626 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3628 if (i != _connections.end()) {
3629 _connections.erase (i);
3635 ConnectionRemoved (connection); /* EMIT SIGNAL */
3641 ARDOUR::Connection *
3642 Session::connection_by_name (string name) const
3644 Glib::Mutex::Lock lm (connection_lock);
3646 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3647 if ((*i)->name() == name) {
3656 Session::tempo_map_changed (Change ignored)
3662 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3663 * the given count with the current block size.
3666 Session::ensure_buffers (ChanCount howmany)
3668 // FIXME: NASTY assumption (midi block size == audio block size)
3669 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3670 _send_buffers->ensure_buffers(howmany, current_block_size);
3671 _silent_buffers->ensure_buffers(howmany, current_block_size);
3673 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3677 Session::next_insert_id ()
3679 /* this doesn't really loop forever. just think about it */
3682 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3683 if (!insert_bitset[n]) {
3684 insert_bitset[n] = true;
3690 /* none available, so resize and try again */
3692 insert_bitset.resize (insert_bitset.size() + 16, false);
3697 Session::next_send_id ()
3699 /* this doesn't really loop forever. just think about it */
3702 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3703 if (!send_bitset[n]) {
3704 send_bitset[n] = true;
3710 /* none available, so resize and try again */
3712 send_bitset.resize (send_bitset.size() + 16, false);
3717 Session::mark_send_id (uint32_t id)
3719 if (id >= send_bitset.size()) {
3720 send_bitset.resize (id+16, false);
3722 if (send_bitset[id]) {
3723 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3725 send_bitset[id] = true;
3729 Session::mark_insert_id (uint32_t id)
3731 if (id >= insert_bitset.size()) {
3732 insert_bitset.resize (id+16, false);
3734 if (insert_bitset[id]) {
3735 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3737 insert_bitset[id] = true;
3740 /* Named Selection management */
3743 Session::named_selection_by_name (string name)
3745 Glib::Mutex::Lock lm (named_selection_lock);
3746 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3747 if ((*i)->name == name) {
3755 Session::add_named_selection (NamedSelection* named_selection)
3758 Glib::Mutex::Lock lm (named_selection_lock);
3759 named_selections.insert (named_selections.begin(), named_selection);
3762 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3768 NamedSelectionAdded (); /* EMIT SIGNAL */
3772 Session::remove_named_selection (NamedSelection* named_selection)
3774 bool removed = false;
3777 Glib::Mutex::Lock lm (named_selection_lock);
3779 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3781 if (i != named_selections.end()) {
3783 named_selections.erase (i);
3790 NamedSelectionRemoved (); /* EMIT SIGNAL */
3795 Session::reset_native_file_format ()
3797 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3799 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3800 (*i)->reset_write_sources (false);
3805 Session::route_name_unique (string n) const
3807 shared_ptr<RouteList> r = routes.reader ();
3809 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3810 if ((*i)->name() == n) {
3819 Session::n_playlists () const
3821 Glib::Mutex::Lock lm (playlist_lock);
3822 return playlists.size();
3826 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3828 if (!force && howmany <= _npan_buffers) {
3832 if (_pan_automation_buffer) {
3834 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3835 delete [] _pan_automation_buffer[i];
3838 delete [] _pan_automation_buffer;
3841 _pan_automation_buffer = new pan_t*[howmany];
3843 for (uint32_t i = 0; i < howmany; ++i) {
3844 _pan_automation_buffer[i] = new pan_t[nframes];
3847 _npan_buffers = howmany;
3851 Session::freeze (InterThreadInfo& itt)
3853 shared_ptr<RouteList> r = routes.reader ();
3855 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3859 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3860 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3871 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3872 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3875 boost::shared_ptr<Playlist> playlist;
3876 boost::shared_ptr<AudioFileSource> fsource;
3878 char buf[PATH_MAX+1];
3880 ChanCount nchans(track.audio_diskstream()->n_channels());
3882 nframes_t this_chunk;
3886 // any bigger than this seems to cause stack overflows in called functions
3887 const nframes_t chunk_size = (128 * 1024)/4;
3889 g_atomic_int_set (&processing_prohibited, 1);
3891 /* call tree *MUST* hold route_lock */
3893 if ((playlist = track.diskstream()->playlist()) == 0) {
3897 /* external redirects will be a problem */
3899 if (track.has_external_redirects()) {
3903 dir = discover_best_sound_dir ();
3905 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3907 for (x = 0; x < 99999; ++x) {
3908 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3909 if (access (buf, F_OK) != 0) {
3915 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3920 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3921 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3924 catch (failed_constructor& err) {
3925 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3929 srcs.push_back (fsource);
3932 /* XXX need to flush all redirects */
3937 /* create a set of reasonably-sized buffers */
3938 buffers.ensure_buffers(nchans, chunk_size);
3939 buffers.set_count(nchans);
3941 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3942 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3944 afs->prepare_for_peakfile_writes ();
3947 while (to_do && !itt.cancel) {
3949 this_chunk = min (to_do, chunk_size);
3951 if (track.export_stuff (buffers, start, this_chunk)) {
3956 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3957 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3960 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3966 start += this_chunk;
3967 to_do -= this_chunk;
3969 itt.progress = (float) (1.0 - ((double) to_do / len));
3978 xnow = localtime (&now);
3980 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3981 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3984 afs->update_header (position, *xnow, now);
3985 afs->flush_header ();
3989 /* construct a region to represent the bounced material */
3991 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3992 region_name_from_path (srcs.front()->name(), true));
3999 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4000 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4003 afs->mark_for_remove ();
4006 (*src)->drop_references ();
4010 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4011 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4014 afs->done_with_peakfile_writes ();
4018 g_atomic_int_set (&processing_prohibited, 0);
4024 Session::get_silent_buffers (ChanCount count)
4026 assert(_silent_buffers->available() >= count);
4027 _silent_buffers->set_count(count);
4029 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4030 for (size_t i=0; i < count.get(*t); ++i) {
4031 _silent_buffers->get(*t, i).clear();
4035 return *_silent_buffers;
4039 Session::get_scratch_buffers (ChanCount count)
4041 assert(_scratch_buffers->available() >= count);
4042 _scratch_buffers->set_count(count);
4043 return *_scratch_buffers;
4047 Session::get_send_buffers (ChanCount count)
4049 assert(_send_buffers->available() >= count);
4050 _send_buffers->set_count(count);
4051 return *_send_buffers;
4055 Session::ntracks () const
4058 shared_ptr<RouteList> r = routes.reader ();
4060 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4061 if (dynamic_cast<Track*> ((*i).get())) {
4070 Session::nbusses () const
4073 shared_ptr<RouteList> r = routes.reader ();
4075 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4076 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4085 Session::add_automation_list(AutomationList *al)
4087 automation_lists[al->id()] = al;
4091 Session::compute_initial_length ()
4093 return _engine.frame_rate() * 60 * 5;