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/bundle.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>
76 #include <ardour/session_directory.h>
79 #include <ardour/osc.h>
85 using namespace ARDOUR;
87 using boost::shared_ptr;
90 static const int CPU_CACHE_ALIGN = 64;
92 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
95 sigc::signal<int> Session::AskAboutPendingState;
96 sigc::signal<void> Session::SendFeedback;
98 sigc::signal<void> Session::SMPTEOffsetChanged;
99 sigc::signal<void> Session::StartTimeChanged;
100 sigc::signal<void> Session::EndTimeChanged;
102 Session::Session (AudioEngine &eng,
104 string snapshot_name,
105 string* mix_template)
108 _scratch_buffers(new BufferSet()),
109 _silent_buffers(new BufferSet()),
110 _send_buffers(new BufferSet()),
111 _mmc_port (default_mmc_port),
112 _mtc_port (default_mtc_port),
113 _midi_port (default_midi_port),
114 _session_dir (fullpath),
115 pending_events (2048),
116 //midi_requests (128), // the size of this should match the midi request pool size
117 _send_smpte_update (false),
118 diskstreams (new DiskstreamList),
119 routes (new RouteList),
120 auditioner ((Auditioner*) 0),
124 if (!eng.connected()) {
125 throw failed_constructor();
128 n_physical_outputs = _engine.n_physical_outputs();
129 n_physical_inputs = _engine.n_physical_inputs();
131 first_stage_init (fullpath, snapshot_name);
133 initialize_start_and_end_locations(0, compute_initial_length ());
136 // try and create a new session directory
139 if(!_session_dir.create()) {
140 // an existing session.
141 // throw a_more_meaningful_exception()
143 throw failed_constructor ();
146 catch(sys::filesystem_error& ex)
149 throw failed_constructor ();
152 if(!create_session_file_from_template (*mix_template)) {
154 throw failed_constructor ();
157 cerr << "Creating session " << fullpath
158 <<" using template" << *mix_template
161 // must be an existing session
164 // ensure the necessary session subdirectories exist
165 // in case the directory structure has changed etc.
166 _session_dir.create();
168 catch(sys::filesystem_error& ex)
171 throw failed_constructor ();
174 cerr << "Loading session " << fullpath
175 << " using snapshot " << snapshot_name << " (1)"
179 if (second_stage_init (false)) {
181 throw failed_constructor ();
184 store_recent_sessions(_name, _path);
186 bool was_dirty = dirty();
188 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
190 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
193 DirtyChanged (); /* EMIT SIGNAL */
197 Session::Session (AudioEngine &eng,
199 string snapshot_name,
200 AutoConnectOption input_ac,
201 AutoConnectOption output_ac,
202 uint32_t control_out_channels,
203 uint32_t master_out_channels,
204 uint32_t requested_physical_in,
205 uint32_t requested_physical_out,
206 nframes_t initial_length)
209 _scratch_buffers(new BufferSet()),
210 _silent_buffers(new BufferSet()),
211 _send_buffers(new BufferSet()),
212 _mmc_port (default_mmc_port),
213 _mtc_port (default_mtc_port),
214 _midi_port (default_midi_port),
215 _session_dir (fullpath),
216 pending_events (2048),
217 //midi_requests (16),
218 _send_smpte_update (false),
219 diskstreams (new DiskstreamList),
220 routes (new RouteList),
224 if (!eng.connected()) {
225 throw failed_constructor();
228 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
230 n_physical_outputs = _engine.n_physical_outputs();
231 n_physical_inputs = _engine.n_physical_inputs();
233 if (n_physical_inputs) {
234 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
237 if (n_physical_outputs) {
238 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
241 first_stage_init (fullpath, snapshot_name);
243 initialize_start_and_end_locations(0, initial_length);
245 SessionDirectory _session_dir(fullpath);
247 if (!_session_dir.create () || !create_session_file ()) {
249 throw failed_constructor ();
253 /* set up Master Out and Control Out if necessary */
258 if (control_out_channels) {
259 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
260 r->set_remote_control_id (control_id++);
265 if (master_out_channels) {
266 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
267 r->set_remote_control_id (control_id);
271 /* prohibit auto-connect to master, because there isn't one */
272 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
281 Config->set_input_auto_connect (input_ac);
282 Config->set_output_auto_connect (output_ac);
284 if (second_stage_init (true)) {
286 throw failed_constructor ();
289 store_recent_sessions(_name, _path);
291 bool was_dirty = dirty ();
293 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
295 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
298 DirtyChanged (); /* EMIT SIGNAL */
310 /* if we got to here, leaving pending capture state around
314 remove_pending_capture_state ();
316 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
317 _engine.remove_session ();
319 GoingAway (); /* EMIT SIGNAL */
325 /* clear history so that no references to objects are held any more */
329 /* clear state tree so that no references to objects are held any more */
335 terminate_butler_thread ();
336 //terminate_midi_thread ();
338 if (click_data && click_data != default_click) {
339 delete [] click_data;
342 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
343 delete [] click_emphasis_data;
348 delete _scratch_buffers;
349 delete _silent_buffers;
350 delete _send_buffers;
352 AudioDiskstream::free_working_buffers();
354 #undef TRACK_DESTRUCTION
355 #ifdef TRACK_DESTRUCTION
356 cerr << "delete named selections\n";
357 #endif /* TRACK_DESTRUCTION */
358 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
359 NamedSelectionList::iterator tmp;
368 #ifdef TRACK_DESTRUCTION
369 cerr << "delete playlists\n";
370 #endif /* TRACK_DESTRUCTION */
371 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
372 PlaylistList::iterator tmp;
377 (*i)->drop_references ();
382 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
383 PlaylistList::iterator tmp;
388 (*i)->drop_references ();
394 unused_playlists.clear ();
396 #ifdef TRACK_DESTRUCTION
397 cerr << "delete regions\n";
398 #endif /* TRACK_DESTRUCTION */
400 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
401 RegionList::iterator tmp;
406 i->second->drop_references ();
413 #ifdef TRACK_DESTRUCTION
414 cerr << "delete routes\n";
415 #endif /* TRACK_DESTRUCTION */
417 RCUWriter<RouteList> writer (routes);
418 boost::shared_ptr<RouteList> r = writer.get_copy ();
419 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
420 (*i)->drop_references ();
423 /* writer goes out of scope and updates master */
428 #ifdef TRACK_DESTRUCTION
429 cerr << "delete diskstreams\n";
430 #endif /* TRACK_DESTRUCTION */
432 RCUWriter<DiskstreamList> dwriter (diskstreams);
433 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
434 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
435 (*i)->drop_references ();
439 diskstreams.flush ();
441 #ifdef TRACK_DESTRUCTION
442 cerr << "delete audio sources\n";
443 #endif /* TRACK_DESTRUCTION */
444 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
445 SourceMap::iterator tmp;
450 i->second->drop_references ();
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete mix groups\n";
459 #endif /* TRACK_DESTRUCTION */
460 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
461 list<RouteGroup*>::iterator tmp;
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete edit groups\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
475 list<RouteGroup*>::iterator tmp;
485 #ifdef TRACK_DESTRUCTION
486 cerr << "delete bundles\n";
487 #endif /* TRACK_DESTRUCTION */
488 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ) {
489 BundleList::iterator tmp;
499 if (butler_mixdown_buffer) {
500 delete [] butler_mixdown_buffer;
503 if (butler_gain_buffer) {
504 delete [] butler_gain_buffer;
507 Crossfade::set_buffer_size (0);
515 Session::set_worst_io_latencies ()
517 _worst_output_latency = 0;
518 _worst_input_latency = 0;
520 if (!_engine.connected()) {
524 boost::shared_ptr<RouteList> r = routes.reader ();
526 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
527 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
528 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
533 Session::when_engine_running ()
535 string first_physical_output;
537 /* we don't want to run execute this again */
539 set_block_size (_engine.frames_per_cycle());
540 set_frame_rate (_engine.frame_rate());
542 Config->map_parameters (mem_fun (*this, &Session::config_changed));
544 /* every time we reconnect, recompute worst case output latencies */
546 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
548 if (synced_to_jack()) {
549 _engine.transport_stop ();
552 if (Config->get_jack_time_master()) {
553 _engine.transport_locate (_transport_frame);
561 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
563 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
565 /* existing state for Click */
567 if (_click_io->set_state (*child->children().front()) == 0) {
569 _clicking = Config->get_clicking ();
573 error << _("could not setup Click I/O") << endmsg;
579 /* default state for Click */
581 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
583 if (first_physical_output.length()) {
584 if (_click_io->add_output_port (first_physical_output, this)) {
585 // relax, even though its an error
587 _clicking = Config->get_clicking ();
593 catch (failed_constructor& err) {
594 error << _("cannot setup Click I/O") << endmsg;
597 set_worst_io_latencies ();
600 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
603 /* Create a set of Bundle objects that map
604 to the physical outputs currently available
609 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
611 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
613 Bundle* c = new OutputBundle (buf, true);
614 c->set_nchannels (1);
615 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
620 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
622 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
624 Bundle* c = new InputBundle (buf, true);
625 c->set_nchannels (1);
626 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
633 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
635 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
637 Bundle* c = new OutputBundle (buf, true);
638 c->set_nchannels (2);
639 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
640 c->add_port_to_channel (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
645 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
647 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
649 Bundle* c = new InputBundle (buf, true);
650 c->set_nchannels (2);
651 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
652 c->add_port_to_channel (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
661 /* create master/control ports */
666 /* force the master to ignore any later call to this */
668 if (_master_out->pending_state_node) {
669 _master_out->ports_became_legal();
672 /* no panner resets till we are through */
674 _master_out->defer_pan_reset ();
676 while (_master_out->n_inputs().n_audio()
677 < _master_out->input_maximum().n_audio()) {
678 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
679 error << _("cannot setup master inputs")
685 while (_master_out->n_outputs().n_audio()
686 < _master_out->output_maximum().n_audio()) {
687 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
688 error << _("cannot setup master outputs")
695 _master_out->allow_pan_reset ();
699 Bundle* c = new OutputBundle (_("Master Out"), true);
701 c->set_nchannels (_master_out->n_inputs().n_total());
702 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
703 c->add_port_to_channel ((int) n, _master_out->input(n)->name());
710 /* catch up on send+insert cnts */
714 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
717 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
718 if (id > insert_cnt) {
726 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
729 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
737 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
739 /* hook us up to the engine */
741 _engine.set_session (this);
746 osc->set_session (*this);
749 _state_of_the_state = Clean;
751 DirtyChanged (); /* EMIT SIGNAL */
755 Session::hookup_io ()
757 /* stop graph reordering notifications from
758 causing resorts, etc.
761 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
763 if (auditioner == 0) {
765 /* we delay creating the auditioner till now because
766 it makes its own connections to ports.
767 the engine has to be running for this to work.
771 auditioner.reset (new Auditioner (*this));
774 catch (failed_constructor& err) {
775 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
779 /* Tell all IO objects to create their ports */
785 vector<string> cports;
787 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
788 if (_control_out->add_input_port ("", this)) {
789 error << _("cannot setup control inputs")
795 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
796 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
797 error << _("cannot set up master outputs")
805 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
807 for (n = 0; n < ni; ++n) {
808 cports.push_back (_control_out->input(n)->name());
811 boost::shared_ptr<RouteList> r = routes.reader ();
813 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
814 (*x)->set_control_outs (cports);
818 /* Tell all IO objects to connect themselves together */
820 IO::enable_connecting ();
822 /* Now reset all panners */
824 IO::reset_panners ();
826 /* Anyone who cares about input state, wake up and do something */
828 IOConnectionsComplete (); /* EMIT SIGNAL */
830 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
832 /* now handle the whole enchilada as if it was one
838 /* update mixer solo state */
844 Session::playlist_length_changed ()
846 /* we can't just increase end_location->end() if pl->get_maximum_extent()
847 if larger. if the playlist used to be the longest playlist,
848 and its now shorter, we have to decrease end_location->end(). hence,
849 we have to iterate over all diskstreams and check the
850 playlists currently in use.
856 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
858 boost::shared_ptr<Playlist> playlist;
860 if ((playlist = dstream->playlist()) != 0) {
861 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
864 /* see comment in playlist_length_changed () */
869 Session::record_enabling_legal () const
871 /* this used to be in here, but survey says.... we don't need to restrict it */
872 // if (record_status() == Recording) {
876 if (Config->get_all_safe()) {
883 Session::reset_input_monitor_state ()
885 if (transport_rolling()) {
887 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
889 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
890 if ((*i)->record_enabled ()) {
891 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
892 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
896 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
898 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
899 if ((*i)->record_enabled ()) {
900 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
901 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
908 Session::auto_punch_start_changed (Location* location)
910 replace_event (Event::PunchIn, location->start());
912 if (get_record_enabled() && Config->get_punch_in()) {
913 /* capture start has been changed, so save new pending state */
914 save_state ("", true);
919 Session::auto_punch_end_changed (Location* location)
921 nframes_t when_to_stop = location->end();
922 // when_to_stop += _worst_output_latency + _worst_input_latency;
923 replace_event (Event::PunchOut, when_to_stop);
927 Session::auto_punch_changed (Location* location)
929 nframes_t when_to_stop = location->end();
931 replace_event (Event::PunchIn, location->start());
932 //when_to_stop += _worst_output_latency + _worst_input_latency;
933 replace_event (Event::PunchOut, when_to_stop);
937 Session::auto_loop_changed (Location* location)
939 replace_event (Event::AutoLoop, location->end(), location->start());
941 if (transport_rolling() && play_loop) {
943 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
945 if (_transport_frame > location->end()) {
946 // relocate to beginning of loop
947 clear_events (Event::LocateRoll);
949 request_locate (location->start(), true);
952 else if (Config->get_seamless_loop() && !loop_changing) {
954 // schedule a locate-roll to refill the diskstreams at the
956 loop_changing = true;
958 if (location->end() > last_loopend) {
959 clear_events (Event::LocateRoll);
960 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
967 last_loopend = location->end();
972 Session::set_auto_punch_location (Location* location)
976 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
977 auto_punch_start_changed_connection.disconnect();
978 auto_punch_end_changed_connection.disconnect();
979 auto_punch_changed_connection.disconnect();
980 existing->set_auto_punch (false, this);
981 remove_event (existing->start(), Event::PunchIn);
982 clear_events (Event::PunchOut);
983 auto_punch_location_changed (0);
992 if (location->end() <= location->start()) {
993 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
997 auto_punch_start_changed_connection.disconnect();
998 auto_punch_end_changed_connection.disconnect();
999 auto_punch_changed_connection.disconnect();
1001 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1002 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1003 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1005 location->set_auto_punch (true, this);
1006 auto_punch_location_changed (location);
1010 Session::set_auto_loop_location (Location* location)
1014 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1015 auto_loop_start_changed_connection.disconnect();
1016 auto_loop_end_changed_connection.disconnect();
1017 auto_loop_changed_connection.disconnect();
1018 existing->set_auto_loop (false, this);
1019 remove_event (existing->end(), Event::AutoLoop);
1020 auto_loop_location_changed (0);
1025 if (location == 0) {
1029 if (location->end() <= location->start()) {
1030 error << _("Session: you can't use a mark for auto loop") << endmsg;
1034 last_loopend = location->end();
1036 auto_loop_start_changed_connection.disconnect();
1037 auto_loop_end_changed_connection.disconnect();
1038 auto_loop_changed_connection.disconnect();
1040 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1041 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1042 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1044 location->set_auto_loop (true, this);
1045 auto_loop_location_changed (location);
1049 Session::locations_added (Location* ignored)
1055 Session::locations_changed ()
1057 _locations.apply (*this, &Session::handle_locations_changed);
1061 Session::handle_locations_changed (Locations::LocationList& locations)
1063 Locations::LocationList::iterator i;
1065 bool set_loop = false;
1066 bool set_punch = false;
1068 for (i = locations.begin(); i != locations.end(); ++i) {
1072 if (location->is_auto_punch()) {
1073 set_auto_punch_location (location);
1076 if (location->is_auto_loop()) {
1077 set_auto_loop_location (location);
1084 set_auto_loop_location (0);
1087 set_auto_punch_location (0);
1094 Session::enable_record ()
1096 /* XXX really atomic compare+swap here */
1097 if (g_atomic_int_get (&_record_status) != Recording) {
1098 g_atomic_int_set (&_record_status, Recording);
1099 _last_record_location = _transport_frame;
1100 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1102 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1103 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1104 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1105 if ((*i)->record_enabled ()) {
1106 (*i)->monitor_input (true);
1111 RecordStateChanged ();
1116 Session::disable_record (bool rt_context, bool force)
1120 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1122 if (!Config->get_latched_record_enable () || force) {
1123 g_atomic_int_set (&_record_status, Disabled);
1125 if (rs == Recording) {
1126 g_atomic_int_set (&_record_status, Enabled);
1130 // FIXME: timestamp correct? [DR]
1131 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1132 // does this /need/ to be sent in all cases?
1134 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1136 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1137 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1139 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1140 if ((*i)->record_enabled ()) {
1141 (*i)->monitor_input (false);
1146 RecordStateChanged (); /* emit signal */
1149 remove_pending_capture_state ();
1155 Session::step_back_from_record ()
1157 g_atomic_int_set (&_record_status, Enabled);
1159 if (Config->get_monitoring_model() == HardwareMonitoring) {
1160 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1162 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1163 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1164 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1165 (*i)->monitor_input (false);
1172 Session::maybe_enable_record ()
1174 g_atomic_int_set (&_record_status, Enabled);
1176 /* this function is currently called from somewhere other than an RT thread.
1177 this save_state() call therefore doesn't impact anything.
1180 save_state ("", true);
1182 if (_transport_speed) {
1183 if (!Config->get_punch_in()) {
1187 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1188 RecordStateChanged (); /* EMIT SIGNAL */
1195 Session::audible_frame () const
1201 /* the first of these two possible settings for "offset"
1202 mean that the audible frame is stationary until
1203 audio emerges from the latency compensation
1206 the second means that the audible frame is stationary
1207 until audio would emerge from a physical port
1208 in the absence of any plugin latency compensation
1211 offset = _worst_output_latency;
1213 if (offset > current_block_size) {
1214 offset -= current_block_size;
1216 /* XXX is this correct? if we have no external
1217 physical connections and everything is internal
1218 then surely this is zero? still, how
1219 likely is that anyway?
1221 offset = current_block_size;
1224 if (synced_to_jack()) {
1225 tf = _engine.transport_frame();
1227 tf = _transport_frame;
1230 if (_transport_speed == 0) {
1240 if (!non_realtime_work_pending()) {
1244 /* take latency into account */
1253 Session::set_frame_rate (nframes_t frames_per_second)
1255 /** \fn void Session::set_frame_size(nframes_t)
1256 the AudioEngine object that calls this guarantees
1257 that it will not be called while we are also in
1258 ::process(). Its fine to do things that block
1262 _base_frame_rate = frames_per_second;
1266 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1268 // XXX we need some equivalent to this, somehow
1269 // SndFileSource::setup_standard_crossfades (frames_per_second);
1273 /* XXX need to reset/reinstantiate all LADSPA plugins */
1277 Session::set_block_size (nframes_t nframes)
1279 /* the AudioEngine guarantees
1280 that it will not be called while we are also in
1281 ::process(). It is therefore fine to do things that block
1287 current_block_size = nframes;
1289 ensure_buffers(_scratch_buffers->available());
1291 if (_gain_automation_buffer) {
1292 delete [] _gain_automation_buffer;
1294 _gain_automation_buffer = new gain_t[nframes];
1296 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1298 boost::shared_ptr<RouteList> r = routes.reader ();
1300 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1301 (*i)->set_block_size (nframes);
1304 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1305 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1306 (*i)->set_block_size (nframes);
1309 set_worst_io_latencies ();
1314 Session::set_default_fade (float steepness, float fade_msecs)
1317 nframes_t fade_frames;
1319 /* Don't allow fade of less 1 frame */
1321 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1328 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1332 default_fade_msecs = fade_msecs;
1333 default_fade_steepness = steepness;
1336 // jlc, WTF is this!
1337 Glib::RWLock::ReaderLock lm (route_lock);
1338 AudioRegion::set_default_fade (steepness, fade_frames);
1343 /* XXX have to do this at some point */
1344 /* foreach region using default fade, reset, then
1345 refill_all_diskstream_buffers ();
1350 struct RouteSorter {
1351 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1352 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1354 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1357 if (r1->fed_by.empty()) {
1358 if (r2->fed_by.empty()) {
1359 /* no ardour-based connections inbound to either route. just use signal order */
1360 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1362 /* r2 has connections, r1 does not; run r1 early */
1366 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1373 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1375 shared_ptr<Route> r2;
1377 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1378 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1382 /* make a copy of the existing list of routes that feed r1 */
1384 set<shared_ptr<Route> > existing = r1->fed_by;
1386 /* for each route that feeds r1, recurse, marking it as feeding
1390 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1393 /* r2 is a route that feeds r1 which somehow feeds base. mark
1394 base as being fed by r2
1397 rbase->fed_by.insert (r2);
1401 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1405 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1409 /* now recurse, so that we can mark base as being fed by
1410 all routes that feed r2
1413 trace_terminal (r2, rbase);
1420 Session::resort_routes ()
1422 /* don't do anything here with signals emitted
1423 by Routes while we are being destroyed.
1426 if (_state_of_the_state & Deletion) {
1433 RCUWriter<RouteList> writer (routes);
1434 shared_ptr<RouteList> r = writer.get_copy ();
1435 resort_routes_using (r);
1436 /* writer goes out of scope and forces update */
1441 Session::resort_routes_using (shared_ptr<RouteList> r)
1443 RouteList::iterator i, j;
1445 for (i = r->begin(); i != r->end(); ++i) {
1447 (*i)->fed_by.clear ();
1449 for (j = r->begin(); j != r->end(); ++j) {
1451 /* although routes can feed themselves, it will
1452 cause an endless recursive descent if we
1453 detect it. so don't bother checking for
1461 if ((*j)->feeds (*i)) {
1462 (*i)->fed_by.insert (*j);
1467 for (i = r->begin(); i != r->end(); ++i) {
1468 trace_terminal (*i, *i);
1475 cerr << "finished route resort\n";
1477 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1478 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1485 list<boost::shared_ptr<MidiTrack> >
1486 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1488 char track_name[32];
1489 uint32_t track_id = 0;
1491 uint32_t channels_used = 0;
1493 RouteList new_routes;
1494 list<boost::shared_ptr<MidiTrack> > ret;
1496 /* count existing midi tracks */
1499 shared_ptr<RouteList> r = routes.reader ();
1501 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1502 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1503 if (!(*i)->hidden()) {
1505 channels_used += (*i)->n_inputs().n_midi();
1513 /* check for duplicate route names, since we might have pre-existing
1514 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1515 save, close,restart,add new route - first named route is now
1523 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1525 if (route_by_name (track_name) == 0) {
1529 } while (track_id < (UINT_MAX-1));
1532 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1534 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1535 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1538 channels_used += track->n_inputs ().n_midi();
1540 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1541 track->set_remote_control_id (ntracks());
1543 new_routes.push_back (track);
1544 ret.push_back (track);
1547 catch (failed_constructor &err) {
1548 error << _("Session: could not create new midi track.") << endmsg;
1549 // XXX should we delete the tracks already created?
1557 if (!new_routes.empty()) {
1558 add_routes (new_routes, false);
1559 save_state (_current_snapshot_name);
1565 list<boost::shared_ptr<AudioTrack> >
1566 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1568 char track_name[32];
1569 uint32_t track_id = 0;
1571 uint32_t channels_used = 0;
1573 RouteList new_routes;
1574 list<boost::shared_ptr<AudioTrack> > ret;
1575 uint32_t control_id;
1577 /* count existing audio tracks */
1580 shared_ptr<RouteList> r = routes.reader ();
1582 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1583 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1584 if (!(*i)->hidden()) {
1586 channels_used += (*i)->n_inputs().n_audio();
1592 vector<string> physinputs;
1593 vector<string> physoutputs;
1594 uint32_t nphysical_in;
1595 uint32_t nphysical_out;
1597 _engine.get_physical_outputs (physoutputs);
1598 _engine.get_physical_inputs (physinputs);
1599 control_id = ntracks() + nbusses() + 1;
1603 /* check for duplicate route names, since we might have pre-existing
1604 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1605 save, close,restart,add new route - first named route is now
1613 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1615 if (route_by_name (track_name) == 0) {
1619 } while (track_id < (UINT_MAX-1));
1621 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1622 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1627 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1628 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1633 shared_ptr<AudioTrack> track;
1636 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1638 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1639 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1640 input_channels, output_channels)
1646 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1650 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1651 port = physinputs[(channels_used+x)%nphysical_in];
1654 if (port.length() && track->connect_input (track->input (x), port, this)) {
1660 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1664 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1665 port = physoutputs[(channels_used+x)%nphysical_out];
1666 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1668 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1672 if (port.length() && track->connect_output (track->output (x), port, this)) {
1677 channels_used += track->n_inputs ().n_audio();
1679 track->audio_diskstream()->non_realtime_input_change();
1681 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1682 track->set_remote_control_id (control_id);
1685 new_routes.push_back (track);
1686 ret.push_back (track);
1689 catch (failed_constructor &err) {
1690 error << _("Session: could not create new audio track.") << endmsg;
1693 /* we need to get rid of this, since the track failed to be created */
1694 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1697 RCUWriter<DiskstreamList> writer (diskstreams);
1698 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1699 ds->remove (track->audio_diskstream());
1706 catch (AudioEngine::PortRegistrationFailure& pfe) {
1708 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;
1711 /* we need to get rid of this, since the track failed to be created */
1712 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1715 RCUWriter<DiskstreamList> writer (diskstreams);
1716 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1717 ds->remove (track->audio_diskstream());
1728 if (!new_routes.empty()) {
1729 add_routes (new_routes, false);
1730 save_state (_current_snapshot_name);
1737 Session::set_remote_control_ids ()
1739 RemoteModel m = Config->get_remote_model();
1741 shared_ptr<RouteList> r = routes.reader ();
1743 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1744 if ( MixerOrdered == m) {
1745 long order = (*i)->order_key(N_("signal"));
1746 (*i)->set_remote_control_id( order+1 );
1747 } else if ( EditorOrdered == m) {
1748 long order = (*i)->order_key(N_("editor"));
1749 (*i)->set_remote_control_id( order+1 );
1750 } else if ( UserOrdered == m) {
1751 //do nothing ... only changes to remote id's are initiated by user
1758 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1761 uint32_t bus_id = 1;
1765 uint32_t control_id;
1767 /* count existing audio busses */
1770 shared_ptr<RouteList> r = routes.reader ();
1772 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1773 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1774 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1781 vector<string> physinputs;
1782 vector<string> physoutputs;
1784 _engine.get_physical_outputs (physoutputs);
1785 _engine.get_physical_inputs (physinputs);
1786 control_id = ntracks() + nbusses() + 1;
1791 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1795 if (route_by_name (bus_name) == 0) {
1799 } while (bus_id < (UINT_MAX-1));
1802 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1804 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1805 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1806 input_channels, output_channels)
1811 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1815 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1816 port = physinputs[((n+x)%n_physical_inputs)];
1819 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1824 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1828 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1829 port = physoutputs[((n+x)%n_physical_outputs)];
1830 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1832 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1836 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1841 bus->set_remote_control_id (control_id);
1844 ret.push_back (bus);
1848 catch (failed_constructor &err) {
1849 error << _("Session: could not create new audio route.") << endmsg;
1853 catch (AudioEngine::PortRegistrationFailure& pfe) {
1854 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;
1864 add_routes (ret, false);
1865 save_state (_current_snapshot_name);
1873 Session::add_routes (RouteList& new_routes, bool save)
1876 RCUWriter<RouteList> writer (routes);
1877 shared_ptr<RouteList> r = writer.get_copy ();
1878 r->insert (r->end(), new_routes.begin(), new_routes.end());
1879 resort_routes_using (r);
1882 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1884 boost::weak_ptr<Route> wpr (*x);
1886 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1887 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1888 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1889 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1891 if ((*x)->master()) {
1895 if ((*x)->control()) {
1896 _control_out = (*x);
1900 if (_control_out && IO::connecting_legal) {
1902 vector<string> cports;
1903 uint32_t ni = _control_out->n_inputs().n_audio();
1905 for (uint32_t n = 0; n < ni; ++n) {
1906 cports.push_back (_control_out->input(n)->name());
1909 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1910 (*x)->set_control_outs (cports);
1917 save_state (_current_snapshot_name);
1920 RouteAdded (new_routes); /* EMIT SIGNAL */
1924 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1926 /* need to do this in case we're rolling at the time, to prevent false underruns */
1927 dstream->do_refill_with_alloc ();
1929 dstream->set_block_size (current_block_size);
1932 RCUWriter<DiskstreamList> writer (diskstreams);
1933 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1934 ds->push_back (dstream);
1935 /* writer goes out of scope, copies ds back to main */
1938 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1939 /* this will connect to future changes, and check the current length */
1940 diskstream_playlist_changed (dstream);
1942 dstream->prepare ();
1947 Session::remove_route (shared_ptr<Route> route)
1950 RCUWriter<RouteList> writer (routes);
1951 shared_ptr<RouteList> rs = writer.get_copy ();
1955 /* deleting the master out seems like a dumb
1956 idea, but its more of a UI policy issue
1960 if (route == _master_out) {
1961 _master_out = shared_ptr<Route> ();
1964 if (route == _control_out) {
1965 _control_out = shared_ptr<Route> ();
1967 /* cancel control outs for all routes */
1969 vector<string> empty;
1971 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1972 (*r)->set_control_outs (empty);
1976 update_route_solo_state ();
1978 /* writer goes out of scope, forces route list update */
1982 boost::shared_ptr<Diskstream> ds;
1984 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1985 ds = t->diskstream();
1991 RCUWriter<DiskstreamList> dsl (diskstreams);
1992 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1997 find_current_end ();
1999 update_latency_compensation (false, false);
2002 // We need to disconnect the routes inputs and outputs
2003 route->disconnect_inputs(NULL);
2004 route->disconnect_outputs(NULL);
2006 /* get rid of it from the dead wood collection in the route list manager */
2008 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2012 /* try to cause everyone to drop their references */
2014 route->drop_references ();
2016 /* save the new state of the world */
2018 if (save_state (_current_snapshot_name)) {
2019 save_history (_current_snapshot_name);
2024 Session::route_mute_changed (void* src)
2030 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2032 if (solo_update_disabled) {
2038 boost::shared_ptr<Route> route = wpr.lock ();
2041 /* should not happen */
2042 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2046 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2048 shared_ptr<RouteList> r = routes.reader ();
2050 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2052 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2056 /* don't mess with busses */
2058 if (dynamic_cast<Track*>((*i).get()) == 0) {
2064 /* don't mess with tracks */
2066 if (dynamic_cast<Track*>((*i).get()) != 0) {
2071 if ((*i) != route &&
2072 ((*i)->mix_group () == 0 ||
2073 (*i)->mix_group () != route->mix_group () ||
2074 !route->mix_group ()->is_active())) {
2076 if ((*i)->soloed()) {
2078 /* if its already soloed, and solo latching is enabled,
2079 then leave it as it is.
2082 if (Config->get_solo_latched()) {
2089 solo_update_disabled = true;
2090 (*i)->set_solo (false, src);
2091 solo_update_disabled = false;
2095 bool something_soloed = false;
2096 bool same_thing_soloed = false;
2097 bool signal = false;
2099 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2100 if ((*i)->soloed()) {
2101 something_soloed = true;
2102 if (dynamic_cast<Track*>((*i).get())) {
2104 same_thing_soloed = true;
2109 same_thing_soloed = true;
2117 if (something_soloed != currently_soloing) {
2119 currently_soloing = something_soloed;
2122 modify_solo_mute (is_track, same_thing_soloed);
2125 SoloActive (currently_soloing); /* EMIT SIGNAL */
2128 SoloChanged (); /* EMIT SIGNAL */
2134 Session::update_route_solo_state ()
2137 bool is_track = false;
2138 bool signal = false;
2140 /* caller must hold RouteLock */
2142 /* this is where we actually implement solo by changing
2143 the solo mute setting of each track.
2146 shared_ptr<RouteList> r = routes.reader ();
2148 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2149 if ((*i)->soloed()) {
2151 if (dynamic_cast<Track*>((*i).get())) {
2158 if (mute != currently_soloing) {
2160 currently_soloing = mute;
2163 if (!is_track && !mute) {
2165 /* nothing is soloed */
2167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2168 (*i)->set_solo_mute (false);
2178 modify_solo_mute (is_track, mute);
2181 SoloActive (currently_soloing);
2186 Session::modify_solo_mute (bool is_track, bool mute)
2188 shared_ptr<RouteList> r = routes.reader ();
2190 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2194 /* only alter track solo mute */
2196 if (dynamic_cast<Track*>((*i).get())) {
2197 if ((*i)->soloed()) {
2198 (*i)->set_solo_mute (!mute);
2200 (*i)->set_solo_mute (mute);
2206 /* only alter bus solo mute */
2208 if (!dynamic_cast<Track*>((*i).get())) {
2210 if ((*i)->soloed()) {
2212 (*i)->set_solo_mute (false);
2216 /* don't mute master or control outs
2217 in response to another bus solo
2220 if ((*i) != _master_out &&
2221 (*i) != _control_out) {
2222 (*i)->set_solo_mute (mute);
2233 Session::catch_up_on_solo ()
2235 /* this is called after set_state() to catch the full solo
2236 state, which can't be correctly determined on a per-route
2237 basis, but needs the global overview that only the session
2240 update_route_solo_state();
2244 Session::route_by_name (string name)
2246 shared_ptr<RouteList> r = routes.reader ();
2248 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2249 if ((*i)->name() == name) {
2254 return shared_ptr<Route> ((Route*) 0);
2258 Session::route_by_id (PBD::ID id)
2260 shared_ptr<RouteList> r = routes.reader ();
2262 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2263 if ((*i)->id() == id) {
2268 return shared_ptr<Route> ((Route*) 0);
2272 Session::route_by_remote_id (uint32_t id)
2274 shared_ptr<RouteList> r = routes.reader ();
2276 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2277 if ((*i)->remote_control_id() == id) {
2282 return shared_ptr<Route> ((Route*) 0);
2286 Session::find_current_end ()
2288 if (_state_of_the_state & Loading) {
2292 nframes_t max = get_maximum_extent ();
2294 if (max > end_location->end()) {
2295 end_location->set_end (max);
2297 DurationChanged(); /* EMIT SIGNAL */
2302 Session::get_maximum_extent () const
2307 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2309 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2310 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2311 if ((me = pl->get_maximum_extent()) > max) {
2319 boost::shared_ptr<Diskstream>
2320 Session::diskstream_by_name (string name)
2322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2325 if ((*i)->name() == name) {
2330 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2333 boost::shared_ptr<Diskstream>
2334 Session::diskstream_by_id (const PBD::ID& id)
2336 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2338 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2339 if ((*i)->id() == id) {
2344 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2347 /* Region management */
2350 Session::new_region_name (string old)
2352 string::size_type last_period;
2354 string::size_type len = old.length() + 64;
2357 if ((last_period = old.find_last_of ('.')) == string::npos) {
2359 /* no period present - add one explicitly */
2362 last_period = old.length() - 1;
2367 number = atoi (old.substr (last_period+1).c_str());
2371 while (number < (UINT_MAX-1)) {
2373 RegionList::const_iterator i;
2378 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2381 for (i = regions.begin(); i != regions.end(); ++i) {
2382 if (i->second->name() == sbuf) {
2387 if (i == regions.end()) {
2392 if (number != (UINT_MAX-1)) {
2396 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2401 Session::region_name (string& result, string base, bool newlevel) const
2406 assert(base.find("/") == string::npos);
2410 Glib::Mutex::Lock lm (region_lock);
2412 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2420 /* XXX this is going to be slow. optimize me later */
2425 string::size_type pos;
2427 pos = base.find_last_of ('.');
2429 /* pos may be npos, but then we just use entire base */
2431 subbase = base.substr (0, pos);
2435 bool name_taken = true;
2438 Glib::Mutex::Lock lm (region_lock);
2440 for (int n = 1; n < 5000; ++n) {
2443 snprintf (buf, sizeof (buf), ".%d", n);
2448 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2449 if (i->second->name() == result) {
2462 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2470 Session::add_region (boost::shared_ptr<Region> region)
2472 boost::shared_ptr<Region> other;
2476 Glib::Mutex::Lock lm (region_lock);
2478 RegionList::iterator x;
2480 for (x = regions.begin(); x != regions.end(); ++x) {
2484 if (region->region_list_equivalent (other)) {
2489 if (x == regions.end()) {
2491 pair<RegionList::key_type,RegionList::mapped_type> entry;
2493 entry.first = region->id();
2494 entry.second = region;
2496 pair<RegionList::iterator,bool> x = regions.insert (entry);
2508 /* mark dirty because something has changed even if we didn't
2509 add the region to the region list.
2515 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2516 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2517 RegionAdded (region); /* EMIT SIGNAL */
2522 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2524 boost::shared_ptr<Region> region (weak_region.lock ());
2530 if (what_changed & Region::HiddenChanged) {
2531 /* relay hidden changes */
2532 RegionHiddenChange (region);
2537 Session::remove_region (boost::weak_ptr<Region> weak_region)
2539 RegionList::iterator i;
2540 boost::shared_ptr<Region> region (weak_region.lock ());
2546 bool removed = false;
2549 Glib::Mutex::Lock lm (region_lock);
2551 if ((i = regions.find (region->id())) != regions.end()) {
2557 /* mark dirty because something has changed even if we didn't
2558 remove the region from the region list.
2564 RegionRemoved(region); /* EMIT SIGNAL */
2568 boost::shared_ptr<Region>
2569 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2571 RegionList::iterator i;
2572 boost::shared_ptr<Region> region;
2574 Glib::Mutex::Lock lm (region_lock);
2576 for (i = regions.begin(); i != regions.end(); ++i) {
2580 if (region->whole_file()) {
2582 if (child->source_equivalent (region)) {
2588 return boost::shared_ptr<Region> ();
2592 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2594 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2595 (*i)->get_region_list_equivalent_regions (region, result);
2599 Session::destroy_region (boost::shared_ptr<Region> region)
2601 vector<boost::shared_ptr<Source> > srcs;
2604 boost::shared_ptr<AudioRegion> aregion;
2606 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2610 if (aregion->playlist()) {
2611 aregion->playlist()->destroy_region (region);
2614 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2615 srcs.push_back (aregion->source (n));
2619 region->drop_references ();
2621 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2623 if (!(*i)->used()) {
2624 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2627 (afs)->mark_for_remove ();
2630 (*i)->drop_references ();
2632 cerr << "source was not used by any playlist\n";
2640 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2642 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2643 destroy_region (*i);
2649 Session::remove_last_capture ()
2651 list<boost::shared_ptr<Region> > r;
2653 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2655 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2656 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2659 r.insert (r.end(), l.begin(), l.end());
2664 destroy_regions (r);
2666 save_state (_current_snapshot_name);
2672 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2678 /* Source Management */
2680 Session::add_source (boost::shared_ptr<Source> source)
2682 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2683 pair<SourceMap::iterator,bool> result;
2685 entry.first = source->id();
2686 entry.second = source;
2689 Glib::Mutex::Lock lm (source_lock);
2690 result = sources.insert (entry);
2693 if (result.second) {
2694 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2700 Session::remove_source (boost::weak_ptr<Source> src)
2702 SourceMap::iterator i;
2703 boost::shared_ptr<Source> source = src.lock();
2710 Glib::Mutex::Lock lm (source_lock);
2713 Glib::Mutex::Lock lm (source_lock);
2715 if ((i = sources.find (source->id())) != sources.end()) {
2721 if (!_state_of_the_state & InCleanup) {
2723 /* save state so we don't end up with a session file
2724 referring to non-existent sources.
2727 save_state (_current_snapshot_name);
2731 boost::shared_ptr<Source>
2732 Session::source_by_id (const PBD::ID& id)
2734 Glib::Mutex::Lock lm (source_lock);
2735 SourceMap::iterator i;
2736 boost::shared_ptr<Source> source;
2738 if ((i = sources.find (id)) != sources.end()) {
2742 /* XXX search MIDI or other searches here */
2748 boost::shared_ptr<Source>
2749 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2751 Glib::Mutex::Lock lm (source_lock);
2753 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2754 cerr << "comparing " << path << " with " << i->second->name() << endl;
2755 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2757 if (afs && afs->path() == path && chn == afs->channel()) {
2762 return boost::shared_ptr<Source>();
2766 Session::peak_path_from_audio_path (string audio_path) const
2771 res += PBD::basename_nosuffix (audio_path);
2772 res += peakfile_suffix;
2778 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2781 string old_basename = PBD::basename_nosuffix (oldname);
2782 string new_legalized = legalize_for_path (newname);
2784 /* note: we know (or assume) the old path is already valid */
2788 /* destructive file sources have a name of the form:
2790 /path/to/Tnnnn-NAME(%[LR])?.wav
2792 the task here is to replace NAME with the new name.
2795 /* find last slash */
2799 string::size_type slash;
2800 string::size_type dash;
2802 if ((slash = path.find_last_of ('/')) == string::npos) {
2806 dir = path.substr (0, slash+1);
2808 /* '-' is not a legal character for the NAME part of the path */
2810 if ((dash = path.find_last_of ('-')) == string::npos) {
2814 prefix = path.substr (slash+1, dash-(slash+1));
2819 path += new_legalized;
2820 path += ".wav"; /* XXX gag me with a spoon */
2824 /* non-destructive file sources have a name of the form:
2826 /path/to/NAME-nnnnn(%[LR])?.wav
2828 the task here is to replace NAME with the new name.
2833 string::size_type slash;
2834 string::size_type dash;
2835 string::size_type postfix;
2837 /* find last slash */
2839 if ((slash = path.find_last_of ('/')) == string::npos) {
2843 dir = path.substr (0, slash+1);
2845 /* '-' is not a legal character for the NAME part of the path */
2847 if ((dash = path.find_last_of ('-')) == string::npos) {
2851 suffix = path.substr (dash+1);
2853 // Suffix is now everything after the dash. Now we need to eliminate
2854 // the nnnnn part, which is done by either finding a '%' or a '.'
2856 postfix = suffix.find_last_of ("%");
2857 if (postfix == string::npos) {
2858 postfix = suffix.find_last_of ('.');
2861 if (postfix != string::npos) {
2862 suffix = suffix.substr (postfix);
2864 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2868 const uint32_t limit = 10000;
2869 char buf[PATH_MAX+1];
2871 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2873 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2875 if (access (buf, F_OK) != 0) {
2883 error << "FATAL ERROR! Could not find a " << endl;
2892 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2896 char buf[PATH_MAX+1];
2897 const uint32_t limit = 10000;
2901 legalized = legalize_for_path (name);
2903 /* find a "version" of the file name that doesn't exist in
2904 any of the possible directories.
2907 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2909 vector<space_and_path>::iterator i;
2910 uint32_t existing = 0;
2912 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2916 spath += sound_dir (false);
2920 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2921 } else if (nchan == 2) {
2923 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2925 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2927 } else if (nchan < 26) {
2928 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2930 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2939 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2940 } else if (nchan == 2) {
2942 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2944 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2946 } else if (nchan < 26) {
2947 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2949 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2953 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2959 if (existing == 0) {
2964 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2966 throw failed_constructor();
2970 /* we now have a unique name for the file, but figure out where to
2976 spath = discover_best_sound_dir ();
2979 string::size_type pos = foo.find_last_of ('/');
2981 if (pos == string::npos) {
2984 spath += foo.substr (pos + 1);
2990 boost::shared_ptr<AudioFileSource>
2991 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2993 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2994 return boost::dynamic_pointer_cast<AudioFileSource> (
2995 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2998 // FIXME: _terrible_ code duplication
3000 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3003 string old_basename = PBD::basename_nosuffix (oldname);
3004 string new_legalized = legalize_for_path (newname);
3006 /* note: we know (or assume) the old path is already valid */
3010 /* destructive file sources have a name of the form:
3012 /path/to/Tnnnn-NAME(%[LR])?.wav
3014 the task here is to replace NAME with the new name.
3017 /* find last slash */
3021 string::size_type slash;
3022 string::size_type dash;
3024 if ((slash = path.find_last_of ('/')) == string::npos) {
3028 dir = path.substr (0, slash+1);
3030 /* '-' is not a legal character for the NAME part of the path */
3032 if ((dash = path.find_last_of ('-')) == string::npos) {
3036 prefix = path.substr (slash+1, dash-(slash+1));
3041 path += new_legalized;
3042 path += ".mid"; /* XXX gag me with a spoon */
3046 /* non-destructive file sources have a name of the form:
3048 /path/to/NAME-nnnnn(%[LR])?.wav
3050 the task here is to replace NAME with the new name.
3055 string::size_type slash;
3056 string::size_type dash;
3057 string::size_type postfix;
3059 /* find last slash */
3061 if ((slash = path.find_last_of ('/')) == string::npos) {
3065 dir = path.substr (0, slash+1);
3067 /* '-' is not a legal character for the NAME part of the path */
3069 if ((dash = path.find_last_of ('-')) == string::npos) {
3073 suffix = path.substr (dash+1);
3075 // Suffix is now everything after the dash. Now we need to eliminate
3076 // the nnnnn part, which is done by either finding a '%' or a '.'
3078 postfix = suffix.find_last_of ("%");
3079 if (postfix == string::npos) {
3080 postfix = suffix.find_last_of ('.');
3083 if (postfix != string::npos) {
3084 suffix = suffix.substr (postfix);
3086 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3090 const uint32_t limit = 10000;
3091 char buf[PATH_MAX+1];
3093 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3095 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3097 if (access (buf, F_OK) != 0) {
3105 error << "FATAL ERROR! Could not find a " << endl;
3114 Session::midi_path_from_name (string name)
3118 char buf[PATH_MAX+1];
3119 const uint32_t limit = 10000;
3123 legalized = legalize_for_path (name);
3125 /* find a "version" of the file name that doesn't exist in
3126 any of the possible directories.
3129 for (cnt = 1; cnt <= limit; ++cnt) {
3131 vector<space_and_path>::iterator i;
3132 uint32_t existing = 0;
3134 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3138 // FIXME: different directory from audio?
3139 spath += sound_dir(false) + "/" + legalized;
3141 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3143 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3148 if (existing == 0) {
3153 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3154 throw failed_constructor();
3158 /* we now have a unique name for the file, but figure out where to
3164 // FIXME: different directory than audio?
3165 spath = discover_best_sound_dir ();
3168 string::size_type pos = foo.find_last_of ('/');
3170 if (pos == string::npos) {
3173 spath += foo.substr (pos + 1);
3179 boost::shared_ptr<MidiSource>
3180 Session::create_midi_source_for_session (MidiDiskstream& ds)
3182 string spath = midi_path_from_name (ds.name());
3184 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3188 /* Playlist management */
3190 boost::shared_ptr<Playlist>
3191 Session::playlist_by_name (string name)
3193 Glib::Mutex::Lock lm (playlist_lock);
3194 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3195 if ((*i)->name() == name) {
3199 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3200 if ((*i)->name() == name) {
3205 return boost::shared_ptr<Playlist>();
3209 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3211 if (playlist->hidden()) {
3216 Glib::Mutex::Lock lm (playlist_lock);
3217 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3218 playlists.insert (playlists.begin(), playlist);
3219 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3220 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3226 PlaylistAdded (playlist); /* EMIT SIGNAL */
3230 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3233 Glib::Mutex::Lock lm (playlist_lock);
3234 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3237 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3244 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3246 boost::shared_ptr<Playlist> pl(wpl.lock());
3252 PlaylistList::iterator x;
3255 /* its not supposed to be visible */
3260 Glib::Mutex::Lock lm (playlist_lock);
3264 unused_playlists.insert (pl);
3266 if ((x = playlists.find (pl)) != playlists.end()) {
3267 playlists.erase (x);
3273 playlists.insert (pl);
3275 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3276 unused_playlists.erase (x);
3283 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3285 if (_state_of_the_state & Deletion) {
3289 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3296 Glib::Mutex::Lock lm (playlist_lock);
3298 PlaylistList::iterator i;
3300 i = find (playlists.begin(), playlists.end(), playlist);
3301 if (i != playlists.end()) {
3302 playlists.erase (i);
3305 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3306 if (i != unused_playlists.end()) {
3307 unused_playlists.erase (i);
3314 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3318 Session::set_audition (boost::shared_ptr<Region> r)
3320 pending_audition_region = r;
3321 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3322 schedule_butler_transport_work ();
3326 Session::audition_playlist ()
3328 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3329 ev->region.reset ();
3334 Session::non_realtime_set_audition ()
3336 if (!pending_audition_region) {
3337 auditioner->audition_current_playlist ();
3339 auditioner->audition_region (pending_audition_region);
3340 pending_audition_region.reset ();
3342 AuditionActive (true); /* EMIT SIGNAL */
3346 Session::audition_region (boost::shared_ptr<Region> r)
3348 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3354 Session::cancel_audition ()
3356 if (auditioner->active()) {
3357 auditioner->cancel_audition ();
3358 AuditionActive (false); /* EMIT SIGNAL */
3363 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3365 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3369 Session::remove_empty_sounds ()
3371 PathScanner scanner;
3373 vector<string *>* possible_audiofiles = scanner (_session_dir.sound_path().to_string (),
3374 Config->get_possible_audio_file_regexp (), false, true);
3376 Glib::Mutex::Lock lm (source_lock);
3378 regex_t compiled_tape_track_pattern;
3381 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3385 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3387 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3391 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3393 /* never remove files that appear to be a tape track */
3395 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3400 if (AudioFileSource::is_empty (*this, *(*i))) {
3402 unlink ((*i)->c_str());
3404 string peak_path = peak_path_from_audio_path (**i);
3405 unlink (peak_path.c_str());
3411 delete possible_audiofiles;
3415 Session::is_auditioning () const
3417 /* can be called before we have an auditioner object */
3419 return auditioner->active();
3426 Session::set_all_solo (bool yn)
3428 shared_ptr<RouteList> r = routes.reader ();
3430 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3431 if (!(*i)->hidden()) {
3432 (*i)->set_solo (yn, this);
3440 Session::set_all_mute (bool yn)
3442 shared_ptr<RouteList> r = routes.reader ();
3444 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3445 if (!(*i)->hidden()) {
3446 (*i)->set_mute (yn, this);
3454 Session::n_diskstreams () const
3458 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3460 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3461 if (!(*i)->hidden()) {
3469 Session::graph_reordered ()
3471 /* don't do this stuff if we are setting up connections
3472 from a set_state() call or creating new tracks.
3475 if (_state_of_the_state & InitialConnecting) {
3479 /* every track/bus asked for this to be handled but it was deferred because
3480 we were connecting. do it now.
3483 request_input_change_handling ();
3487 /* force all diskstreams to update their capture offset values to
3488 reflect any changes in latencies within the graph.
3491 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3493 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3494 (*i)->set_capture_offset ();
3499 Session::record_disenable_all ()
3501 record_enable_change_all (false);
3505 Session::record_enable_all ()
3507 record_enable_change_all (true);
3511 Session::record_enable_change_all (bool yn)
3513 shared_ptr<RouteList> r = routes.reader ();
3515 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3518 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3519 at->set_record_enable (yn, this);
3523 /* since we don't keep rec-enable state, don't mark session dirty */
3527 Session::add_redirect (Redirect* redirect)
3531 PortInsert* port_insert;
3532 PluginInsert* plugin_insert;
3534 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3535 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3536 _port_inserts.insert (_port_inserts.begin(), port_insert);
3537 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3538 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3540 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3543 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3544 _sends.insert (_sends.begin(), send);
3546 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3550 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3556 Session::remove_redirect (Redirect* redirect)
3560 PortInsert* port_insert;
3561 PluginInsert* plugin_insert;
3563 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
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);
3573 fatal << string_compose (_("programming error: %1"),
3574 X_("unknown type of Insert deleted!"))
3578 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3579 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3580 if (x != _sends.end()) {
3581 send_bitset[send->bit_slot()] = false;
3585 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3593 Session::available_capture_duration ()
3595 float sample_bytes_on_disk = 4.0; // keep gcc happy
3597 switch (Config->get_native_file_data_format()) {
3599 sample_bytes_on_disk = 4.0;
3603 sample_bytes_on_disk = 3.0;
3607 /* impossible, but keep some gcc versions happy */
3608 fatal << string_compose (_("programming error: %1"),
3609 X_("illegal native file data format"))
3614 double scale = 4096.0 / sample_bytes_on_disk;
3616 if (_total_free_4k_blocks * scale > (double) max_frames) {
3620 return (nframes_t) floor (_total_free_4k_blocks * scale);
3624 Session::add_bundle (ARDOUR::Bundle* bundle)
3627 Glib::Mutex::Lock guard (bundle_lock);
3628 _bundles.push_back (bundle);
3631 BundleAdded (bundle); /* EMIT SIGNAL */
3637 Session::remove_bundle (ARDOUR::Bundle* bundle)
3639 bool removed = false;
3642 Glib::Mutex::Lock guard (bundle_lock);
3643 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3645 if (i != _bundles.end()) {
3652 BundleRemoved (bundle); /* EMIT SIGNAL */
3659 Session::bundle_by_name (string name) const
3661 Glib::Mutex::Lock lm (bundle_lock);
3663 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3664 if ((*i)->name() == name) {
3673 Session::tempo_map_changed (Change ignored)
3679 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3680 * the given count with the current block size.
3683 Session::ensure_buffers (ChanCount howmany)
3685 // FIXME: NASTY assumption (midi block size == audio block size)
3686 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3687 _send_buffers->ensure_buffers(howmany, current_block_size);
3688 _silent_buffers->ensure_buffers(howmany, current_block_size);
3690 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3694 Session::next_insert_id ()
3696 /* this doesn't really loop forever. just think about it */
3699 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3700 if (!insert_bitset[n]) {
3701 insert_bitset[n] = true;
3707 /* none available, so resize and try again */
3709 insert_bitset.resize (insert_bitset.size() + 16, false);
3714 Session::next_send_id ()
3716 /* this doesn't really loop forever. just think about it */
3719 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3720 if (!send_bitset[n]) {
3721 send_bitset[n] = true;
3727 /* none available, so resize and try again */
3729 send_bitset.resize (send_bitset.size() + 16, false);
3734 Session::mark_send_id (uint32_t id)
3736 if (id >= send_bitset.size()) {
3737 send_bitset.resize (id+16, false);
3739 if (send_bitset[id]) {
3740 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3742 send_bitset[id] = true;
3746 Session::mark_insert_id (uint32_t id)
3748 if (id >= insert_bitset.size()) {
3749 insert_bitset.resize (id+16, false);
3751 if (insert_bitset[id]) {
3752 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3754 insert_bitset[id] = true;
3757 /* Named Selection management */
3760 Session::named_selection_by_name (string name)
3762 Glib::Mutex::Lock lm (named_selection_lock);
3763 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3764 if ((*i)->name == name) {
3772 Session::add_named_selection (NamedSelection* named_selection)
3775 Glib::Mutex::Lock lm (named_selection_lock);
3776 named_selections.insert (named_selections.begin(), named_selection);
3779 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3785 NamedSelectionAdded (); /* EMIT SIGNAL */
3789 Session::remove_named_selection (NamedSelection* named_selection)
3791 bool removed = false;
3794 Glib::Mutex::Lock lm (named_selection_lock);
3796 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3798 if (i != named_selections.end()) {
3800 named_selections.erase (i);
3807 NamedSelectionRemoved (); /* EMIT SIGNAL */
3812 Session::reset_native_file_format ()
3814 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3816 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3817 (*i)->reset_write_sources (false);
3822 Session::route_name_unique (string n) const
3824 shared_ptr<RouteList> r = routes.reader ();
3826 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3827 if ((*i)->name() == n) {
3836 Session::n_playlists () const
3838 Glib::Mutex::Lock lm (playlist_lock);
3839 return playlists.size();
3843 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3845 if (!force && howmany <= _npan_buffers) {
3849 if (_pan_automation_buffer) {
3851 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3852 delete [] _pan_automation_buffer[i];
3855 delete [] _pan_automation_buffer;
3858 _pan_automation_buffer = new pan_t*[howmany];
3860 for (uint32_t i = 0; i < howmany; ++i) {
3861 _pan_automation_buffer[i] = new pan_t[nframes];
3864 _npan_buffers = howmany;
3868 Session::freeze (InterThreadInfo& itt)
3870 shared_ptr<RouteList> r = routes.reader ();
3872 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3876 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3877 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3888 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3889 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3892 boost::shared_ptr<Playlist> playlist;
3893 boost::shared_ptr<AudioFileSource> fsource;
3895 char buf[PATH_MAX+1];
3897 ChanCount nchans(track.audio_diskstream()->n_channels());
3899 nframes_t this_chunk;
3903 // any bigger than this seems to cause stack overflows in called functions
3904 const nframes_t chunk_size = (128 * 1024)/4;
3906 g_atomic_int_set (&processing_prohibited, 1);
3908 /* call tree *MUST* hold route_lock */
3910 if ((playlist = track.diskstream()->playlist()) == 0) {
3914 /* external redirects will be a problem */
3916 if (track.has_external_redirects()) {
3920 dir = discover_best_sound_dir ();
3922 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3924 for (x = 0; x < 99999; ++x) {
3925 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3926 if (access (buf, F_OK) != 0) {
3932 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3937 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3938 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3941 catch (failed_constructor& err) {
3942 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3946 srcs.push_back (fsource);
3949 /* XXX need to flush all redirects */
3954 /* create a set of reasonably-sized buffers */
3955 buffers.ensure_buffers(nchans, chunk_size);
3956 buffers.set_count(nchans);
3958 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3959 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3961 afs->prepare_for_peakfile_writes ();
3964 while (to_do && !itt.cancel) {
3966 this_chunk = min (to_do, chunk_size);
3968 if (track.export_stuff (buffers, start, this_chunk)) {
3973 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3974 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3977 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3983 start += this_chunk;
3984 to_do -= this_chunk;
3986 itt.progress = (float) (1.0 - ((double) to_do / len));
3995 xnow = localtime (&now);
3997 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3998 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4001 afs->update_header (position, *xnow, now);
4002 afs->flush_header ();
4006 /* construct a region to represent the bounced material */
4008 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4009 region_name_from_path (srcs.front()->name(), true));
4016 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4017 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4020 afs->mark_for_remove ();
4023 (*src)->drop_references ();
4027 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4028 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4031 afs->done_with_peakfile_writes ();
4035 g_atomic_int_set (&processing_prohibited, 0);
4041 Session::get_silent_buffers (ChanCount count)
4043 assert(_silent_buffers->available() >= count);
4044 _silent_buffers->set_count(count);
4046 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4047 for (size_t i=0; i < count.get(*t); ++i) {
4048 _silent_buffers->get(*t, i).clear();
4052 return *_silent_buffers;
4056 Session::get_scratch_buffers (ChanCount count)
4058 assert(_scratch_buffers->available() >= count);
4059 _scratch_buffers->set_count(count);
4060 return *_scratch_buffers;
4064 Session::get_send_buffers (ChanCount count)
4066 assert(_send_buffers->available() >= count);
4067 _send_buffers->set_count(count);
4068 return *_send_buffers;
4072 Session::ntracks () const
4075 shared_ptr<RouteList> r = routes.reader ();
4077 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4078 if (dynamic_cast<Track*> ((*i).get())) {
4087 Session::nbusses () const
4090 shared_ptr<RouteList> r = routes.reader ();
4092 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4093 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4102 Session::add_automation_list(AutomationList *al)
4104 automation_lists[al->id()] = al;
4108 Session::compute_initial_length ()
4110 return _engine.frame_rate() * 60 * 5;