2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/session_directory.h>
48 #include <ardour/utils.h>
49 #include <ardour/audio_diskstream.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/midi_diskstream.h>
54 #include <ardour/midi_playlist.h>
55 #include <ardour/midi_region.h>
56 #include <ardour/smf_source.h>
57 #include <ardour/auditioner.h>
58 #include <ardour/recent_sessions.h>
59 #include <ardour/redirect.h>
60 #include <ardour/send.h>
61 #include <ardour/insert.h>
62 #include <ardour/bundle.h>
63 #include <ardour/slave.h>
64 #include <ardour/tempo.h>
65 #include <ardour/audio_track.h>
66 #include <ardour/midi_track.h>
67 #include <ardour/cycle_timer.h>
68 #include <ardour/named_selection.h>
69 #include <ardour/crossfade.h>
70 #include <ardour/playlist.h>
71 #include <ardour/click.h>
72 #include <ardour/data_type.h>
73 #include <ardour/buffer_set.h>
74 #include <ardour/source_factory.h>
75 #include <ardour/region_factory.h>
76 #include <ardour/filename_extensions.h>
77 #include <ardour/session_directory.h>
80 #include <ardour/osc.h>
86 using namespace ARDOUR;
88 using boost::shared_ptr;
91 static const int CPU_CACHE_ALIGN = 64;
93 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
96 sigc::signal<int> Session::AskAboutPendingState;
97 sigc::signal<void> Session::SendFeedback;
99 sigc::signal<void> Session::SMPTEOffsetChanged;
100 sigc::signal<void> Session::StartTimeChanged;
101 sigc::signal<void> Session::EndTimeChanged;
103 Session::Session (AudioEngine &eng,
105 string snapshot_name,
106 string* mix_template)
109 _scratch_buffers(new BufferSet()),
110 _silent_buffers(new BufferSet()),
111 _send_buffers(new BufferSet()),
112 _mmc_port (default_mmc_port),
113 _mtc_port (default_mtc_port),
114 _midi_port (default_midi_port),
115 _session_dir (new SessionDirectory(fullpath)),
116 pending_events (2048),
117 //midi_requests (128), // the size of this should match the midi request pool size
118 _send_smpte_update (false),
119 diskstreams (new DiskstreamList),
120 routes (new RouteList),
121 auditioner ((Auditioner*) 0),
125 if (!eng.connected()) {
126 throw failed_constructor();
129 n_physical_outputs = _engine.n_physical_outputs();
130 n_physical_inputs = _engine.n_physical_inputs();
132 first_stage_init (fullpath, snapshot_name);
134 initialize_start_and_end_locations(0, compute_initial_length ());
137 // try and create a new session directory
140 if(!_session_dir->create()) {
141 // an existing session.
142 // throw a_more_meaningful_exception()
144 throw failed_constructor ();
147 catch(sys::filesystem_error& ex)
150 throw failed_constructor ();
153 if(!create_session_file_from_template (*mix_template)) {
155 throw failed_constructor ();
158 cerr << "Creating session " << fullpath
159 <<" using template" << *mix_template
162 // must be an existing session
165 // ensure the necessary session subdirectories exist
166 // in case the directory structure has changed etc.
167 _session_dir->create();
169 catch(sys::filesystem_error& ex)
172 throw failed_constructor ();
175 cerr << "Loading session " << fullpath
176 << " using snapshot " << snapshot_name << " (1)"
180 if (second_stage_init (false)) {
182 throw failed_constructor ();
185 store_recent_sessions(_name, _path);
187 bool was_dirty = dirty();
189 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
191 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
194 DirtyChanged (); /* EMIT SIGNAL */
198 Session::Session (AudioEngine &eng,
200 string snapshot_name,
201 AutoConnectOption input_ac,
202 AutoConnectOption output_ac,
203 uint32_t control_out_channels,
204 uint32_t master_out_channels,
205 uint32_t requested_physical_in,
206 uint32_t requested_physical_out,
207 nframes_t initial_length)
210 _scratch_buffers(new BufferSet()),
211 _silent_buffers(new BufferSet()),
212 _send_buffers(new BufferSet()),
213 _mmc_port (default_mmc_port),
214 _mtc_port (default_mtc_port),
215 _midi_port (default_midi_port),
216 _session_dir ( new SessionDirectory(fullpath)),
217 pending_events (2048),
218 //midi_requests (16),
219 _send_smpte_update (false),
220 diskstreams (new DiskstreamList),
221 routes (new RouteList),
225 if (!eng.connected()) {
226 throw failed_constructor();
229 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
231 n_physical_outputs = _engine.n_physical_outputs();
232 n_physical_inputs = _engine.n_physical_inputs();
234 if (n_physical_inputs) {
235 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
238 if (n_physical_outputs) {
239 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
242 first_stage_init (fullpath, snapshot_name);
244 initialize_start_and_end_locations(0, initial_length);
246 if (!_session_dir->create () || !create_session_file ()) {
248 throw failed_constructor ();
252 /* set up Master Out and Control Out if necessary */
257 if (control_out_channels) {
258 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
259 r->set_remote_control_id (control_id++);
264 if (master_out_channels) {
265 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
266 r->set_remote_control_id (control_id);
270 /* prohibit auto-connect to master, because there isn't one */
271 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
280 Config->set_input_auto_connect (input_ac);
281 Config->set_output_auto_connect (output_ac);
283 if (second_stage_init (true)) {
285 throw failed_constructor ();
288 store_recent_sessions(_name, _path);
290 bool was_dirty = dirty ();
292 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
294 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
297 DirtyChanged (); /* EMIT SIGNAL */
309 /* if we got to here, leaving pending capture state around
313 remove_pending_capture_state ();
315 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
316 _engine.remove_session ();
318 GoingAway (); /* EMIT SIGNAL */
324 /* clear history so that no references to objects are held any more */
328 /* clear state tree so that no references to objects are held any more */
334 terminate_butler_thread ();
335 //terminate_midi_thread ();
337 if (click_data && click_data != default_click) {
338 delete [] click_data;
341 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
342 delete [] click_emphasis_data;
347 delete _scratch_buffers;
348 delete _silent_buffers;
349 delete _send_buffers;
351 AudioDiskstream::free_working_buffers();
353 #undef TRACK_DESTRUCTION
354 #ifdef TRACK_DESTRUCTION
355 cerr << "delete named selections\n";
356 #endif /* TRACK_DESTRUCTION */
357 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
358 NamedSelectionList::iterator tmp;
367 #ifdef TRACK_DESTRUCTION
368 cerr << "delete playlists\n";
369 #endif /* TRACK_DESTRUCTION */
370 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
371 PlaylistList::iterator tmp;
376 (*i)->drop_references ();
381 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
382 PlaylistList::iterator tmp;
387 (*i)->drop_references ();
393 unused_playlists.clear ();
395 #ifdef TRACK_DESTRUCTION
396 cerr << "delete regions\n";
397 #endif /* TRACK_DESTRUCTION */
399 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
400 RegionList::iterator tmp;
405 i->second->drop_references ();
412 #ifdef TRACK_DESTRUCTION
413 cerr << "delete routes\n";
414 #endif /* TRACK_DESTRUCTION */
416 RCUWriter<RouteList> writer (routes);
417 boost::shared_ptr<RouteList> r = writer.get_copy ();
418 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
419 (*i)->drop_references ();
422 /* writer goes out of scope and updates master */
427 #ifdef TRACK_DESTRUCTION
428 cerr << "delete diskstreams\n";
429 #endif /* TRACK_DESTRUCTION */
431 RCUWriter<DiskstreamList> dwriter (diskstreams);
432 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
433 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
434 (*i)->drop_references ();
438 diskstreams.flush ();
440 #ifdef TRACK_DESTRUCTION
441 cerr << "delete audio sources\n";
442 #endif /* TRACK_DESTRUCTION */
443 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
444 SourceMap::iterator tmp;
449 i->second->drop_references ();
456 #ifdef TRACK_DESTRUCTION
457 cerr << "delete mix groups\n";
458 #endif /* TRACK_DESTRUCTION */
459 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
460 list<RouteGroup*>::iterator tmp;
470 #ifdef TRACK_DESTRUCTION
471 cerr << "delete edit groups\n";
472 #endif /* TRACK_DESTRUCTION */
473 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
474 list<RouteGroup*>::iterator tmp;
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete bundles\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ) {
488 BundleList::iterator tmp;
498 if (butler_mixdown_buffer) {
499 delete [] butler_mixdown_buffer;
502 if (butler_gain_buffer) {
503 delete [] butler_gain_buffer;
506 Crossfade::set_buffer_size (0);
514 Session::set_worst_io_latencies ()
516 _worst_output_latency = 0;
517 _worst_input_latency = 0;
519 if (!_engine.connected()) {
523 boost::shared_ptr<RouteList> r = routes.reader ();
525 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
526 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
527 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
532 Session::when_engine_running ()
534 string first_physical_output;
536 /* we don't want to run execute this again */
538 set_block_size (_engine.frames_per_cycle());
539 set_frame_rate (_engine.frame_rate());
541 Config->map_parameters (mem_fun (*this, &Session::config_changed));
543 /* every time we reconnect, recompute worst case output latencies */
545 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
547 if (synced_to_jack()) {
548 _engine.transport_stop ();
551 if (Config->get_jack_time_master()) {
552 _engine.transport_locate (_transport_frame);
560 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
562 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
564 /* existing state for Click */
566 if (_click_io->set_state (*child->children().front()) == 0) {
568 _clicking = Config->get_clicking ();
572 error << _("could not setup Click I/O") << endmsg;
578 /* default state for Click */
580 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
582 if (first_physical_output.length()) {
583 if (_click_io->add_output_port (first_physical_output, this)) {
584 // relax, even though its an error
586 _clicking = Config->get_clicking ();
592 catch (failed_constructor& err) {
593 error << _("cannot setup Click I/O") << endmsg;
596 set_worst_io_latencies ();
599 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
602 /* Create a set of Bundle objects that map
603 to the physical outputs currently available
608 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
610 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
612 Bundle* c = new OutputBundle (buf, true);
613 c->set_nchannels (1);
614 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
619 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
621 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
623 Bundle* c = new InputBundle (buf, true);
624 c->set_nchannels (1);
625 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
632 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
634 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
636 Bundle* c = new OutputBundle (buf, true);
637 c->set_nchannels (2);
638 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
639 c->add_port_to_channel (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
644 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
646 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
648 Bundle* c = new InputBundle (buf, true);
649 c->set_nchannels (2);
650 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
651 c->add_port_to_channel (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
660 /* create master/control ports */
665 /* force the master to ignore any later call to this */
667 if (_master_out->pending_state_node) {
668 _master_out->ports_became_legal();
671 /* no panner resets till we are through */
673 _master_out->defer_pan_reset ();
675 while (_master_out->n_inputs().n_audio()
676 < _master_out->input_maximum().n_audio()) {
677 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
678 error << _("cannot setup master inputs")
684 while (_master_out->n_outputs().n_audio()
685 < _master_out->output_maximum().n_audio()) {
686 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
687 error << _("cannot setup master outputs")
694 _master_out->allow_pan_reset ();
698 Bundle* c = new OutputBundle (_("Master Out"), true);
700 c->set_nchannels (_master_out->n_inputs().n_total());
701 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
702 c->add_port_to_channel ((int) n, _master_out->input(n)->name());
709 /* catch up on send+insert cnts */
713 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
716 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
717 if (id > insert_cnt) {
725 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
728 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
736 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
738 /* hook us up to the engine */
740 _engine.set_session (this);
745 osc->set_session (*this);
748 _state_of_the_state = Clean;
750 DirtyChanged (); /* EMIT SIGNAL */
754 Session::hookup_io ()
756 /* stop graph reordering notifications from
757 causing resorts, etc.
760 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
762 if (auditioner == 0) {
764 /* we delay creating the auditioner till now because
765 it makes its own connections to ports.
766 the engine has to be running for this to work.
770 auditioner.reset (new Auditioner (*this));
773 catch (failed_constructor& err) {
774 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
778 /* Tell all IO objects to create their ports */
784 vector<string> cports;
786 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
787 if (_control_out->add_input_port ("", this)) {
788 error << _("cannot setup control inputs")
794 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
795 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
796 error << _("cannot set up master outputs")
804 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
806 for (n = 0; n < ni; ++n) {
807 cports.push_back (_control_out->input(n)->name());
810 boost::shared_ptr<RouteList> r = routes.reader ();
812 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
813 (*x)->set_control_outs (cports);
817 /* Tell all IO objects to connect themselves together */
819 IO::enable_connecting ();
821 /* Now reset all panners */
823 IO::reset_panners ();
825 /* Anyone who cares about input state, wake up and do something */
827 IOConnectionsComplete (); /* EMIT SIGNAL */
829 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
831 /* now handle the whole enchilada as if it was one
837 /* update mixer solo state */
843 Session::playlist_length_changed ()
845 /* we can't just increase end_location->end() if pl->get_maximum_extent()
846 if larger. if the playlist used to be the longest playlist,
847 and its now shorter, we have to decrease end_location->end(). hence,
848 we have to iterate over all diskstreams and check the
849 playlists currently in use.
855 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
857 boost::shared_ptr<Playlist> playlist;
859 if ((playlist = dstream->playlist()) != 0) {
860 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
863 /* see comment in playlist_length_changed () */
868 Session::record_enabling_legal () const
870 /* this used to be in here, but survey says.... we don't need to restrict it */
871 // if (record_status() == Recording) {
875 if (Config->get_all_safe()) {
882 Session::reset_input_monitor_state ()
884 if (transport_rolling()) {
886 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
888 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
889 if ((*i)->record_enabled ()) {
890 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
891 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
895 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
897 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
898 if ((*i)->record_enabled ()) {
899 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
900 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
907 Session::auto_punch_start_changed (Location* location)
909 replace_event (Event::PunchIn, location->start());
911 if (get_record_enabled() && Config->get_punch_in()) {
912 /* capture start has been changed, so save new pending state */
913 save_state ("", true);
918 Session::auto_punch_end_changed (Location* location)
920 nframes_t when_to_stop = location->end();
921 // when_to_stop += _worst_output_latency + _worst_input_latency;
922 replace_event (Event::PunchOut, when_to_stop);
926 Session::auto_punch_changed (Location* location)
928 nframes_t when_to_stop = location->end();
930 replace_event (Event::PunchIn, location->start());
931 //when_to_stop += _worst_output_latency + _worst_input_latency;
932 replace_event (Event::PunchOut, when_to_stop);
936 Session::auto_loop_changed (Location* location)
938 replace_event (Event::AutoLoop, location->end(), location->start());
940 if (transport_rolling() && play_loop) {
942 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
944 if (_transport_frame > location->end()) {
945 // relocate to beginning of loop
946 clear_events (Event::LocateRoll);
948 request_locate (location->start(), true);
951 else if (Config->get_seamless_loop() && !loop_changing) {
953 // schedule a locate-roll to refill the diskstreams at the
955 loop_changing = true;
957 if (location->end() > last_loopend) {
958 clear_events (Event::LocateRoll);
959 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
966 last_loopend = location->end();
971 Session::set_auto_punch_location (Location* location)
975 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
976 auto_punch_start_changed_connection.disconnect();
977 auto_punch_end_changed_connection.disconnect();
978 auto_punch_changed_connection.disconnect();
979 existing->set_auto_punch (false, this);
980 remove_event (existing->start(), Event::PunchIn);
981 clear_events (Event::PunchOut);
982 auto_punch_location_changed (0);
991 if (location->end() <= location->start()) {
992 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
996 auto_punch_start_changed_connection.disconnect();
997 auto_punch_end_changed_connection.disconnect();
998 auto_punch_changed_connection.disconnect();
1000 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1001 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1002 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1004 location->set_auto_punch (true, this);
1005 auto_punch_location_changed (location);
1009 Session::set_auto_loop_location (Location* location)
1013 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1014 auto_loop_start_changed_connection.disconnect();
1015 auto_loop_end_changed_connection.disconnect();
1016 auto_loop_changed_connection.disconnect();
1017 existing->set_auto_loop (false, this);
1018 remove_event (existing->end(), Event::AutoLoop);
1019 auto_loop_location_changed (0);
1024 if (location == 0) {
1028 if (location->end() <= location->start()) {
1029 error << _("Session: you can't use a mark for auto loop") << endmsg;
1033 last_loopend = location->end();
1035 auto_loop_start_changed_connection.disconnect();
1036 auto_loop_end_changed_connection.disconnect();
1037 auto_loop_changed_connection.disconnect();
1039 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1040 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1041 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1043 location->set_auto_loop (true, this);
1044 auto_loop_location_changed (location);
1048 Session::locations_added (Location* ignored)
1054 Session::locations_changed ()
1056 _locations.apply (*this, &Session::handle_locations_changed);
1060 Session::handle_locations_changed (Locations::LocationList& locations)
1062 Locations::LocationList::iterator i;
1064 bool set_loop = false;
1065 bool set_punch = false;
1067 for (i = locations.begin(); i != locations.end(); ++i) {
1071 if (location->is_auto_punch()) {
1072 set_auto_punch_location (location);
1075 if (location->is_auto_loop()) {
1076 set_auto_loop_location (location);
1083 set_auto_loop_location (0);
1086 set_auto_punch_location (0);
1093 Session::enable_record ()
1095 /* XXX really atomic compare+swap here */
1096 if (g_atomic_int_get (&_record_status) != Recording) {
1097 g_atomic_int_set (&_record_status, Recording);
1098 _last_record_location = _transport_frame;
1099 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1101 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1102 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1103 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1104 if ((*i)->record_enabled ()) {
1105 (*i)->monitor_input (true);
1110 RecordStateChanged ();
1115 Session::disable_record (bool rt_context, bool force)
1119 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1121 if (!Config->get_latched_record_enable () || force) {
1122 g_atomic_int_set (&_record_status, Disabled);
1124 if (rs == Recording) {
1125 g_atomic_int_set (&_record_status, Enabled);
1129 // FIXME: timestamp correct? [DR]
1130 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1131 // does this /need/ to be sent in all cases?
1133 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1135 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1136 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1138 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1139 if ((*i)->record_enabled ()) {
1140 (*i)->monitor_input (false);
1145 RecordStateChanged (); /* emit signal */
1148 remove_pending_capture_state ();
1154 Session::step_back_from_record ()
1156 g_atomic_int_set (&_record_status, Enabled);
1158 if (Config->get_monitoring_model() == HardwareMonitoring) {
1159 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1161 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1162 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1163 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1164 (*i)->monitor_input (false);
1171 Session::maybe_enable_record ()
1173 g_atomic_int_set (&_record_status, Enabled);
1175 /* this function is currently called from somewhere other than an RT thread.
1176 this save_state() call therefore doesn't impact anything.
1179 save_state ("", true);
1181 if (_transport_speed) {
1182 if (!Config->get_punch_in()) {
1186 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1187 RecordStateChanged (); /* EMIT SIGNAL */
1194 Session::audible_frame () const
1200 /* the first of these two possible settings for "offset"
1201 mean that the audible frame is stationary until
1202 audio emerges from the latency compensation
1205 the second means that the audible frame is stationary
1206 until audio would emerge from a physical port
1207 in the absence of any plugin latency compensation
1210 offset = _worst_output_latency;
1212 if (offset > current_block_size) {
1213 offset -= current_block_size;
1215 /* XXX is this correct? if we have no external
1216 physical connections and everything is internal
1217 then surely this is zero? still, how
1218 likely is that anyway?
1220 offset = current_block_size;
1223 if (synced_to_jack()) {
1224 tf = _engine.transport_frame();
1226 tf = _transport_frame;
1229 if (_transport_speed == 0) {
1239 if (!non_realtime_work_pending()) {
1243 /* take latency into account */
1252 Session::set_frame_rate (nframes_t frames_per_second)
1254 /** \fn void Session::set_frame_size(nframes_t)
1255 the AudioEngine object that calls this guarantees
1256 that it will not be called while we are also in
1257 ::process(). Its fine to do things that block
1261 _base_frame_rate = frames_per_second;
1265 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1267 // XXX we need some equivalent to this, somehow
1268 // SndFileSource::setup_standard_crossfades (frames_per_second);
1272 /* XXX need to reset/reinstantiate all LADSPA plugins */
1276 Session::set_block_size (nframes_t nframes)
1278 /* the AudioEngine guarantees
1279 that it will not be called while we are also in
1280 ::process(). It is therefore fine to do things that block
1286 current_block_size = nframes;
1288 ensure_buffers(_scratch_buffers->available());
1290 if (_gain_automation_buffer) {
1291 delete [] _gain_automation_buffer;
1293 _gain_automation_buffer = new gain_t[nframes];
1295 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1297 boost::shared_ptr<RouteList> r = routes.reader ();
1299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1300 (*i)->set_block_size (nframes);
1303 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1304 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1305 (*i)->set_block_size (nframes);
1308 set_worst_io_latencies ();
1313 Session::set_default_fade (float steepness, float fade_msecs)
1316 nframes_t fade_frames;
1318 /* Don't allow fade of less 1 frame */
1320 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1327 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1331 default_fade_msecs = fade_msecs;
1332 default_fade_steepness = steepness;
1335 // jlc, WTF is this!
1336 Glib::RWLock::ReaderLock lm (route_lock);
1337 AudioRegion::set_default_fade (steepness, fade_frames);
1342 /* XXX have to do this at some point */
1343 /* foreach region using default fade, reset, then
1344 refill_all_diskstream_buffers ();
1349 struct RouteSorter {
1350 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1351 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1353 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1356 if (r1->fed_by.empty()) {
1357 if (r2->fed_by.empty()) {
1358 /* no ardour-based connections inbound to either route. just use signal order */
1359 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1361 /* r2 has connections, r1 does not; run r1 early */
1365 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1372 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1374 shared_ptr<Route> r2;
1376 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1377 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1381 /* make a copy of the existing list of routes that feed r1 */
1383 set<shared_ptr<Route> > existing = r1->fed_by;
1385 /* for each route that feeds r1, recurse, marking it as feeding
1389 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1392 /* r2 is a route that feeds r1 which somehow feeds base. mark
1393 base as being fed by r2
1396 rbase->fed_by.insert (r2);
1400 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1404 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1408 /* now recurse, so that we can mark base as being fed by
1409 all routes that feed r2
1412 trace_terminal (r2, rbase);
1419 Session::resort_routes ()
1421 /* don't do anything here with signals emitted
1422 by Routes while we are being destroyed.
1425 if (_state_of_the_state & Deletion) {
1432 RCUWriter<RouteList> writer (routes);
1433 shared_ptr<RouteList> r = writer.get_copy ();
1434 resort_routes_using (r);
1435 /* writer goes out of scope and forces update */
1440 Session::resort_routes_using (shared_ptr<RouteList> r)
1442 RouteList::iterator i, j;
1444 for (i = r->begin(); i != r->end(); ++i) {
1446 (*i)->fed_by.clear ();
1448 for (j = r->begin(); j != r->end(); ++j) {
1450 /* although routes can feed themselves, it will
1451 cause an endless recursive descent if we
1452 detect it. so don't bother checking for
1460 if ((*j)->feeds (*i)) {
1461 (*i)->fed_by.insert (*j);
1466 for (i = r->begin(); i != r->end(); ++i) {
1467 trace_terminal (*i, *i);
1474 cerr << "finished route resort\n";
1476 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1477 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1484 list<boost::shared_ptr<MidiTrack> >
1485 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1487 char track_name[32];
1488 uint32_t track_id = 0;
1490 uint32_t channels_used = 0;
1492 RouteList new_routes;
1493 list<boost::shared_ptr<MidiTrack> > ret;
1495 /* count existing midi tracks */
1498 shared_ptr<RouteList> r = routes.reader ();
1500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1502 if (!(*i)->hidden()) {
1504 channels_used += (*i)->n_inputs().n_midi();
1512 /* check for duplicate route names, since we might have pre-existing
1513 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1514 save, close,restart,add new route - first named route is now
1522 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1524 if (route_by_name (track_name) == 0) {
1528 } while (track_id < (UINT_MAX-1));
1531 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1533 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1534 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1537 channels_used += track->n_inputs ().n_midi();
1539 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1540 track->set_remote_control_id (ntracks());
1542 new_routes.push_back (track);
1543 ret.push_back (track);
1546 catch (failed_constructor &err) {
1547 error << _("Session: could not create new midi track.") << endmsg;
1548 // XXX should we delete the tracks already created?
1556 if (!new_routes.empty()) {
1557 add_routes (new_routes, false);
1558 save_state (_current_snapshot_name);
1564 list<boost::shared_ptr<AudioTrack> >
1565 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1567 char track_name[32];
1568 uint32_t track_id = 0;
1570 uint32_t channels_used = 0;
1572 RouteList new_routes;
1573 list<boost::shared_ptr<AudioTrack> > ret;
1574 uint32_t control_id;
1576 /* count existing audio tracks */
1579 shared_ptr<RouteList> r = routes.reader ();
1581 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1582 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1583 if (!(*i)->hidden()) {
1585 channels_used += (*i)->n_inputs().n_audio();
1591 vector<string> physinputs;
1592 vector<string> physoutputs;
1593 uint32_t nphysical_in;
1594 uint32_t nphysical_out;
1596 _engine.get_physical_outputs (physoutputs);
1597 _engine.get_physical_inputs (physinputs);
1598 control_id = ntracks() + nbusses() + 1;
1602 /* check for duplicate route names, since we might have pre-existing
1603 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1604 save, close,restart,add new route - first named route is now
1612 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1614 if (route_by_name (track_name) == 0) {
1618 } while (track_id < (UINT_MAX-1));
1620 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1621 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1626 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1627 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1632 shared_ptr<AudioTrack> track;
1635 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1637 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1638 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1639 input_channels, output_channels)
1645 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1649 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1650 port = physinputs[(channels_used+x)%nphysical_in];
1653 if (port.length() && track->connect_input (track->input (x), port, this)) {
1659 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1663 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1664 port = physoutputs[(channels_used+x)%nphysical_out];
1665 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1667 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1671 if (port.length() && track->connect_output (track->output (x), port, this)) {
1676 channels_used += track->n_inputs ().n_audio();
1678 track->audio_diskstream()->non_realtime_input_change();
1680 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1681 track->set_remote_control_id (control_id);
1684 new_routes.push_back (track);
1685 ret.push_back (track);
1688 catch (failed_constructor &err) {
1689 error << _("Session: could not create new audio track.") << endmsg;
1692 /* we need to get rid of this, since the track failed to be created */
1693 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1696 RCUWriter<DiskstreamList> writer (diskstreams);
1697 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1698 ds->remove (track->audio_diskstream());
1705 catch (AudioEngine::PortRegistrationFailure& pfe) {
1707 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;
1710 /* we need to get rid of this, since the track failed to be created */
1711 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1714 RCUWriter<DiskstreamList> writer (diskstreams);
1715 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1716 ds->remove (track->audio_diskstream());
1727 if (!new_routes.empty()) {
1728 add_routes (new_routes, false);
1729 save_state (_current_snapshot_name);
1736 Session::set_remote_control_ids ()
1738 RemoteModel m = Config->get_remote_model();
1740 shared_ptr<RouteList> r = routes.reader ();
1742 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1743 if ( MixerOrdered == m) {
1744 long order = (*i)->order_key(N_("signal"));
1745 (*i)->set_remote_control_id( order+1 );
1746 } else if ( EditorOrdered == m) {
1747 long order = (*i)->order_key(N_("editor"));
1748 (*i)->set_remote_control_id( order+1 );
1749 } else if ( UserOrdered == m) {
1750 //do nothing ... only changes to remote id's are initiated by user
1757 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1760 uint32_t bus_id = 1;
1764 uint32_t control_id;
1766 /* count existing audio busses */
1769 shared_ptr<RouteList> r = routes.reader ();
1771 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1772 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1773 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1780 vector<string> physinputs;
1781 vector<string> physoutputs;
1783 _engine.get_physical_outputs (physoutputs);
1784 _engine.get_physical_inputs (physinputs);
1785 control_id = ntracks() + nbusses() + 1;
1790 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1794 if (route_by_name (bus_name) == 0) {
1798 } while (bus_id < (UINT_MAX-1));
1801 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1803 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1804 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1805 input_channels, output_channels)
1810 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1814 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1815 port = physinputs[((n+x)%n_physical_inputs)];
1818 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1823 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1827 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1828 port = physoutputs[((n+x)%n_physical_outputs)];
1829 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1831 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1835 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1840 bus->set_remote_control_id (control_id);
1843 ret.push_back (bus);
1847 catch (failed_constructor &err) {
1848 error << _("Session: could not create new audio route.") << endmsg;
1852 catch (AudioEngine::PortRegistrationFailure& pfe) {
1853 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;
1863 add_routes (ret, false);
1864 save_state (_current_snapshot_name);
1872 Session::add_routes (RouteList& new_routes, bool save)
1875 RCUWriter<RouteList> writer (routes);
1876 shared_ptr<RouteList> r = writer.get_copy ();
1877 r->insert (r->end(), new_routes.begin(), new_routes.end());
1878 resort_routes_using (r);
1881 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1883 boost::weak_ptr<Route> wpr (*x);
1885 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1886 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1887 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1888 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1890 if ((*x)->master()) {
1894 if ((*x)->control()) {
1895 _control_out = (*x);
1899 if (_control_out && IO::connecting_legal) {
1901 vector<string> cports;
1902 uint32_t ni = _control_out->n_inputs().n_audio();
1904 for (uint32_t n = 0; n < ni; ++n) {
1905 cports.push_back (_control_out->input(n)->name());
1908 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1909 (*x)->set_control_outs (cports);
1916 save_state (_current_snapshot_name);
1919 RouteAdded (new_routes); /* EMIT SIGNAL */
1923 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1925 /* need to do this in case we're rolling at the time, to prevent false underruns */
1926 dstream->do_refill_with_alloc ();
1928 dstream->set_block_size (current_block_size);
1931 RCUWriter<DiskstreamList> writer (diskstreams);
1932 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1933 ds->push_back (dstream);
1934 /* writer goes out of scope, copies ds back to main */
1937 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1938 /* this will connect to future changes, and check the current length */
1939 diskstream_playlist_changed (dstream);
1941 dstream->prepare ();
1946 Session::remove_route (shared_ptr<Route> route)
1949 RCUWriter<RouteList> writer (routes);
1950 shared_ptr<RouteList> rs = writer.get_copy ();
1954 /* deleting the master out seems like a dumb
1955 idea, but its more of a UI policy issue
1959 if (route == _master_out) {
1960 _master_out = shared_ptr<Route> ();
1963 if (route == _control_out) {
1964 _control_out = shared_ptr<Route> ();
1966 /* cancel control outs for all routes */
1968 vector<string> empty;
1970 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1971 (*r)->set_control_outs (empty);
1975 update_route_solo_state ();
1977 /* writer goes out of scope, forces route list update */
1981 boost::shared_ptr<Diskstream> ds;
1983 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1984 ds = t->diskstream();
1990 RCUWriter<DiskstreamList> dsl (diskstreams);
1991 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1996 find_current_end ();
1998 update_latency_compensation (false, false);
2001 // We need to disconnect the routes inputs and outputs
2002 route->disconnect_inputs(NULL);
2003 route->disconnect_outputs(NULL);
2005 /* get rid of it from the dead wood collection in the route list manager */
2007 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2011 /* try to cause everyone to drop their references */
2013 route->drop_references ();
2015 /* save the new state of the world */
2017 if (save_state (_current_snapshot_name)) {
2018 save_history (_current_snapshot_name);
2023 Session::route_mute_changed (void* src)
2029 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2031 if (solo_update_disabled) {
2037 boost::shared_ptr<Route> route = wpr.lock ();
2040 /* should not happen */
2041 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2045 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2047 shared_ptr<RouteList> r = routes.reader ();
2049 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2051 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2055 /* don't mess with busses */
2057 if (dynamic_cast<Track*>((*i).get()) == 0) {
2063 /* don't mess with tracks */
2065 if (dynamic_cast<Track*>((*i).get()) != 0) {
2070 if ((*i) != route &&
2071 ((*i)->mix_group () == 0 ||
2072 (*i)->mix_group () != route->mix_group () ||
2073 !route->mix_group ()->is_active())) {
2075 if ((*i)->soloed()) {
2077 /* if its already soloed, and solo latching is enabled,
2078 then leave it as it is.
2081 if (Config->get_solo_latched()) {
2088 solo_update_disabled = true;
2089 (*i)->set_solo (false, src);
2090 solo_update_disabled = false;
2094 bool something_soloed = false;
2095 bool same_thing_soloed = false;
2096 bool signal = false;
2098 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2099 if ((*i)->soloed()) {
2100 something_soloed = true;
2101 if (dynamic_cast<Track*>((*i).get())) {
2103 same_thing_soloed = true;
2108 same_thing_soloed = true;
2116 if (something_soloed != currently_soloing) {
2118 currently_soloing = something_soloed;
2121 modify_solo_mute (is_track, same_thing_soloed);
2124 SoloActive (currently_soloing); /* EMIT SIGNAL */
2127 SoloChanged (); /* EMIT SIGNAL */
2133 Session::update_route_solo_state ()
2136 bool is_track = false;
2137 bool signal = false;
2139 /* caller must hold RouteLock */
2141 /* this is where we actually implement solo by changing
2142 the solo mute setting of each track.
2145 shared_ptr<RouteList> r = routes.reader ();
2147 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2148 if ((*i)->soloed()) {
2150 if (dynamic_cast<Track*>((*i).get())) {
2157 if (mute != currently_soloing) {
2159 currently_soloing = mute;
2162 if (!is_track && !mute) {
2164 /* nothing is soloed */
2166 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2167 (*i)->set_solo_mute (false);
2177 modify_solo_mute (is_track, mute);
2180 SoloActive (currently_soloing);
2185 Session::modify_solo_mute (bool is_track, bool mute)
2187 shared_ptr<RouteList> r = routes.reader ();
2189 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2193 /* only alter track solo mute */
2195 if (dynamic_cast<Track*>((*i).get())) {
2196 if ((*i)->soloed()) {
2197 (*i)->set_solo_mute (!mute);
2199 (*i)->set_solo_mute (mute);
2205 /* only alter bus solo mute */
2207 if (!dynamic_cast<Track*>((*i).get())) {
2209 if ((*i)->soloed()) {
2211 (*i)->set_solo_mute (false);
2215 /* don't mute master or control outs
2216 in response to another bus solo
2219 if ((*i) != _master_out &&
2220 (*i) != _control_out) {
2221 (*i)->set_solo_mute (mute);
2232 Session::catch_up_on_solo ()
2234 /* this is called after set_state() to catch the full solo
2235 state, which can't be correctly determined on a per-route
2236 basis, but needs the global overview that only the session
2239 update_route_solo_state();
2243 Session::route_by_name (string name)
2245 shared_ptr<RouteList> r = routes.reader ();
2247 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2248 if ((*i)->name() == name) {
2253 return shared_ptr<Route> ((Route*) 0);
2257 Session::route_by_id (PBD::ID id)
2259 shared_ptr<RouteList> r = routes.reader ();
2261 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2262 if ((*i)->id() == id) {
2267 return shared_ptr<Route> ((Route*) 0);
2271 Session::route_by_remote_id (uint32_t id)
2273 shared_ptr<RouteList> r = routes.reader ();
2275 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2276 if ((*i)->remote_control_id() == id) {
2281 return shared_ptr<Route> ((Route*) 0);
2285 Session::find_current_end ()
2287 if (_state_of_the_state & Loading) {
2291 nframes_t max = get_maximum_extent ();
2293 if (max > end_location->end()) {
2294 end_location->set_end (max);
2296 DurationChanged(); /* EMIT SIGNAL */
2301 Session::get_maximum_extent () const
2306 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2308 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2309 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2310 if ((me = pl->get_maximum_extent()) > max) {
2318 boost::shared_ptr<Diskstream>
2319 Session::diskstream_by_name (string name)
2321 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2323 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2324 if ((*i)->name() == name) {
2329 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2332 boost::shared_ptr<Diskstream>
2333 Session::diskstream_by_id (const PBD::ID& id)
2335 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2337 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2338 if ((*i)->id() == id) {
2343 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2346 /* Region management */
2349 Session::new_region_name (string old)
2351 string::size_type last_period;
2353 string::size_type len = old.length() + 64;
2356 if ((last_period = old.find_last_of ('.')) == string::npos) {
2358 /* no period present - add one explicitly */
2361 last_period = old.length() - 1;
2366 number = atoi (old.substr (last_period+1).c_str());
2370 while (number < (UINT_MAX-1)) {
2372 RegionList::const_iterator i;
2377 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2380 for (i = regions.begin(); i != regions.end(); ++i) {
2381 if (i->second->name() == sbuf) {
2386 if (i == regions.end()) {
2391 if (number != (UINT_MAX-1)) {
2395 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2400 Session::region_name (string& result, string base, bool newlevel) const
2405 assert(base.find("/") == string::npos);
2409 Glib::Mutex::Lock lm (region_lock);
2411 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2419 /* XXX this is going to be slow. optimize me later */
2424 string::size_type pos;
2426 pos = base.find_last_of ('.');
2428 /* pos may be npos, but then we just use entire base */
2430 subbase = base.substr (0, pos);
2434 bool name_taken = true;
2437 Glib::Mutex::Lock lm (region_lock);
2439 for (int n = 1; n < 5000; ++n) {
2442 snprintf (buf, sizeof (buf), ".%d", n);
2447 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2448 if (i->second->name() == result) {
2461 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2469 Session::add_region (boost::shared_ptr<Region> region)
2471 boost::shared_ptr<Region> other;
2475 Glib::Mutex::Lock lm (region_lock);
2477 RegionList::iterator x;
2479 for (x = regions.begin(); x != regions.end(); ++x) {
2483 if (region->region_list_equivalent (other)) {
2488 if (x == regions.end()) {
2490 pair<RegionList::key_type,RegionList::mapped_type> entry;
2492 entry.first = region->id();
2493 entry.second = region;
2495 pair<RegionList::iterator,bool> x = regions.insert (entry);
2507 /* mark dirty because something has changed even if we didn't
2508 add the region to the region list.
2514 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2515 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2516 RegionAdded (region); /* EMIT SIGNAL */
2521 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2523 boost::shared_ptr<Region> region (weak_region.lock ());
2529 if (what_changed & Region::HiddenChanged) {
2530 /* relay hidden changes */
2531 RegionHiddenChange (region);
2536 Session::remove_region (boost::weak_ptr<Region> weak_region)
2538 RegionList::iterator i;
2539 boost::shared_ptr<Region> region (weak_region.lock ());
2545 bool removed = false;
2548 Glib::Mutex::Lock lm (region_lock);
2550 if ((i = regions.find (region->id())) != regions.end()) {
2556 /* mark dirty because something has changed even if we didn't
2557 remove the region from the region list.
2563 RegionRemoved(region); /* EMIT SIGNAL */
2567 boost::shared_ptr<Region>
2568 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2570 RegionList::iterator i;
2571 boost::shared_ptr<Region> region;
2573 Glib::Mutex::Lock lm (region_lock);
2575 for (i = regions.begin(); i != regions.end(); ++i) {
2579 if (region->whole_file()) {
2581 if (child->source_equivalent (region)) {
2587 return boost::shared_ptr<Region> ();
2591 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2593 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2594 (*i)->get_region_list_equivalent_regions (region, result);
2598 Session::destroy_region (boost::shared_ptr<Region> region)
2600 vector<boost::shared_ptr<Source> > srcs;
2603 boost::shared_ptr<AudioRegion> aregion;
2605 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2609 if (aregion->playlist()) {
2610 aregion->playlist()->destroy_region (region);
2613 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2614 srcs.push_back (aregion->source (n));
2618 region->drop_references ();
2620 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2622 if (!(*i)->used()) {
2623 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2626 (afs)->mark_for_remove ();
2629 (*i)->drop_references ();
2631 cerr << "source was not used by any playlist\n";
2639 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2641 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2642 destroy_region (*i);
2648 Session::remove_last_capture ()
2650 list<boost::shared_ptr<Region> > r;
2652 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2654 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2655 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2658 r.insert (r.end(), l.begin(), l.end());
2663 destroy_regions (r);
2665 save_state (_current_snapshot_name);
2671 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2677 /* Source Management */
2679 Session::add_source (boost::shared_ptr<Source> source)
2681 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2682 pair<SourceMap::iterator,bool> result;
2684 entry.first = source->id();
2685 entry.second = source;
2688 Glib::Mutex::Lock lm (source_lock);
2689 result = sources.insert (entry);
2692 if (result.second) {
2693 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2699 Session::remove_source (boost::weak_ptr<Source> src)
2701 SourceMap::iterator i;
2702 boost::shared_ptr<Source> source = src.lock();
2709 Glib::Mutex::Lock lm (source_lock);
2712 Glib::Mutex::Lock lm (source_lock);
2714 if ((i = sources.find (source->id())) != sources.end()) {
2720 if (!_state_of_the_state & InCleanup) {
2722 /* save state so we don't end up with a session file
2723 referring to non-existent sources.
2726 save_state (_current_snapshot_name);
2730 boost::shared_ptr<Source>
2731 Session::source_by_id (const PBD::ID& id)
2733 Glib::Mutex::Lock lm (source_lock);
2734 SourceMap::iterator i;
2735 boost::shared_ptr<Source> source;
2737 if ((i = sources.find (id)) != sources.end()) {
2741 /* XXX search MIDI or other searches here */
2747 boost::shared_ptr<Source>
2748 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2750 Glib::Mutex::Lock lm (source_lock);
2752 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2753 cerr << "comparing " << path << " with " << i->second->name() << endl;
2754 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2756 if (afs && afs->path() == path && chn == afs->channel()) {
2761 return boost::shared_ptr<Source>();
2765 Session::peak_path_from_audio_path (string audio_path) const
2770 res += PBD::basename_nosuffix (audio_path);
2771 res += peakfile_suffix;
2777 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2780 string old_basename = PBD::basename_nosuffix (oldname);
2781 string new_legalized = legalize_for_path (newname);
2783 /* note: we know (or assume) the old path is already valid */
2787 /* destructive file sources have a name of the form:
2789 /path/to/Tnnnn-NAME(%[LR])?.wav
2791 the task here is to replace NAME with the new name.
2794 /* find last slash */
2798 string::size_type slash;
2799 string::size_type dash;
2801 if ((slash = path.find_last_of ('/')) == string::npos) {
2805 dir = path.substr (0, slash+1);
2807 /* '-' is not a legal character for the NAME part of the path */
2809 if ((dash = path.find_last_of ('-')) == string::npos) {
2813 prefix = path.substr (slash+1, dash-(slash+1));
2818 path += new_legalized;
2819 path += ".wav"; /* XXX gag me with a spoon */
2823 /* non-destructive file sources have a name of the form:
2825 /path/to/NAME-nnnnn(%[LR])?.wav
2827 the task here is to replace NAME with the new name.
2832 string::size_type slash;
2833 string::size_type dash;
2834 string::size_type postfix;
2836 /* find last slash */
2838 if ((slash = path.find_last_of ('/')) == string::npos) {
2842 dir = path.substr (0, slash+1);
2844 /* '-' is not a legal character for the NAME part of the path */
2846 if ((dash = path.find_last_of ('-')) == string::npos) {
2850 suffix = path.substr (dash+1);
2852 // Suffix is now everything after the dash. Now we need to eliminate
2853 // the nnnnn part, which is done by either finding a '%' or a '.'
2855 postfix = suffix.find_last_of ("%");
2856 if (postfix == string::npos) {
2857 postfix = suffix.find_last_of ('.');
2860 if (postfix != string::npos) {
2861 suffix = suffix.substr (postfix);
2863 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2867 const uint32_t limit = 10000;
2868 char buf[PATH_MAX+1];
2870 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2872 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2874 if (access (buf, F_OK) != 0) {
2882 error << "FATAL ERROR! Could not find a " << endl;
2891 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2895 char buf[PATH_MAX+1];
2896 const uint32_t limit = 10000;
2900 legalized = legalize_for_path (name);
2902 /* find a "version" of the file name that doesn't exist in
2903 any of the possible directories.
2906 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2908 vector<space_and_path>::iterator i;
2909 uint32_t existing = 0;
2911 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2913 SessionDirectory sdir((*i).path);
2915 spath = sdir.sound_path().to_string();
2919 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2920 } else if (nchan == 2) {
2922 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2924 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2926 } else if (nchan < 26) {
2927 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2929 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2938 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2939 } else if (nchan == 2) {
2941 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2943 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2945 } else if (nchan < 26) {
2946 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2948 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2952 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2958 if (existing == 0) {
2963 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2965 throw failed_constructor();
2969 /* we now have a unique name for the file, but figure out where to
2975 spath = discover_best_sound_dir ();
2978 string::size_type pos = foo.find_last_of ('/');
2980 if (pos == string::npos) {
2983 spath += foo.substr (pos + 1);
2989 boost::shared_ptr<AudioFileSource>
2990 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2992 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2993 return boost::dynamic_pointer_cast<AudioFileSource> (
2994 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2997 // FIXME: _terrible_ code duplication
2999 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3002 string old_basename = PBD::basename_nosuffix (oldname);
3003 string new_legalized = legalize_for_path (newname);
3005 /* note: we know (or assume) the old path is already valid */
3009 /* destructive file sources have a name of the form:
3011 /path/to/Tnnnn-NAME(%[LR])?.wav
3013 the task here is to replace NAME with the new name.
3016 /* find last slash */
3020 string::size_type slash;
3021 string::size_type dash;
3023 if ((slash = path.find_last_of ('/')) == string::npos) {
3027 dir = path.substr (0, slash+1);
3029 /* '-' is not a legal character for the NAME part of the path */
3031 if ((dash = path.find_last_of ('-')) == string::npos) {
3035 prefix = path.substr (slash+1, dash-(slash+1));
3040 path += new_legalized;
3041 path += ".mid"; /* XXX gag me with a spoon */
3045 /* non-destructive file sources have a name of the form:
3047 /path/to/NAME-nnnnn(%[LR])?.wav
3049 the task here is to replace NAME with the new name.
3054 string::size_type slash;
3055 string::size_type dash;
3056 string::size_type postfix;
3058 /* find last slash */
3060 if ((slash = path.find_last_of ('/')) == string::npos) {
3064 dir = path.substr (0, slash+1);
3066 /* '-' is not a legal character for the NAME part of the path */
3068 if ((dash = path.find_last_of ('-')) == string::npos) {
3072 suffix = path.substr (dash+1);
3074 // Suffix is now everything after the dash. Now we need to eliminate
3075 // the nnnnn part, which is done by either finding a '%' or a '.'
3077 postfix = suffix.find_last_of ("%");
3078 if (postfix == string::npos) {
3079 postfix = suffix.find_last_of ('.');
3082 if (postfix != string::npos) {
3083 suffix = suffix.substr (postfix);
3085 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3089 const uint32_t limit = 10000;
3090 char buf[PATH_MAX+1];
3092 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3094 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3096 if (access (buf, F_OK) != 0) {
3104 error << "FATAL ERROR! Could not find a " << endl;
3113 Session::midi_path_from_name (string name)
3117 char buf[PATH_MAX+1];
3118 const uint32_t limit = 10000;
3122 legalized = legalize_for_path (name);
3124 /* find a "version" of the file name that doesn't exist in
3125 any of the possible directories.
3128 for (cnt = 1; cnt <= limit; ++cnt) {
3130 vector<space_and_path>::iterator i;
3131 uint32_t existing = 0;
3133 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3137 spath += midi_dir(false) + "/" + legalized;
3139 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3141 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3146 if (existing == 0) {
3151 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3152 throw failed_constructor();
3156 /* we now have a unique name for the file, but figure out where to
3162 spath = discover_best_midi_dir ();
3165 string::size_type pos = foo.find_last_of ('/');
3167 if (pos == string::npos) {
3170 spath += foo.substr (pos + 1);
3176 boost::shared_ptr<MidiSource>
3177 Session::create_midi_source_for_session (MidiDiskstream& ds)
3179 string mpath = midi_path_from_name (ds.name());
3181 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3185 /* Playlist management */
3187 boost::shared_ptr<Playlist>
3188 Session::playlist_by_name (string name)
3190 Glib::Mutex::Lock lm (playlist_lock);
3191 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3192 if ((*i)->name() == name) {
3196 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3197 if ((*i)->name() == name) {
3202 return boost::shared_ptr<Playlist>();
3206 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3208 if (playlist->hidden()) {
3213 Glib::Mutex::Lock lm (playlist_lock);
3214 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3215 playlists.insert (playlists.begin(), playlist);
3216 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3217 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3223 PlaylistAdded (playlist); /* EMIT SIGNAL */
3227 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3230 Glib::Mutex::Lock lm (playlist_lock);
3231 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3234 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3241 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3243 boost::shared_ptr<Playlist> pl(wpl.lock());
3249 PlaylistList::iterator x;
3252 /* its not supposed to be visible */
3257 Glib::Mutex::Lock lm (playlist_lock);
3261 unused_playlists.insert (pl);
3263 if ((x = playlists.find (pl)) != playlists.end()) {
3264 playlists.erase (x);
3270 playlists.insert (pl);
3272 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3273 unused_playlists.erase (x);
3280 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3282 if (_state_of_the_state & Deletion) {
3286 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3293 Glib::Mutex::Lock lm (playlist_lock);
3295 PlaylistList::iterator i;
3297 i = find (playlists.begin(), playlists.end(), playlist);
3298 if (i != playlists.end()) {
3299 playlists.erase (i);
3302 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3303 if (i != unused_playlists.end()) {
3304 unused_playlists.erase (i);
3311 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3315 Session::set_audition (boost::shared_ptr<Region> r)
3317 pending_audition_region = r;
3318 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3319 schedule_butler_transport_work ();
3323 Session::audition_playlist ()
3325 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3326 ev->region.reset ();
3331 Session::non_realtime_set_audition ()
3333 if (!pending_audition_region) {
3334 auditioner->audition_current_playlist ();
3336 auditioner->audition_region (pending_audition_region);
3337 pending_audition_region.reset ();
3339 AuditionActive (true); /* EMIT SIGNAL */
3343 Session::audition_region (boost::shared_ptr<Region> r)
3345 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3351 Session::cancel_audition ()
3353 if (auditioner->active()) {
3354 auditioner->cancel_audition ();
3355 AuditionActive (false); /* EMIT SIGNAL */
3360 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3362 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3366 Session::remove_empty_sounds ()
3368 PathScanner scanner;
3370 vector<string *>* possible_audiofiles = scanner (_session_dir->sound_path().to_string (),
3371 Config->get_possible_audio_file_regexp (), false, true);
3373 Glib::Mutex::Lock lm (source_lock);
3375 regex_t compiled_tape_track_pattern;
3378 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3382 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3384 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3388 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3390 /* never remove files that appear to be a tape track */
3392 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3397 if (AudioFileSource::is_empty (*this, *(*i))) {
3399 unlink ((*i)->c_str());
3401 string peak_path = peak_path_from_audio_path (**i);
3402 unlink (peak_path.c_str());
3408 delete possible_audiofiles;
3412 Session::is_auditioning () const
3414 /* can be called before we have an auditioner object */
3416 return auditioner->active();
3423 Session::set_all_solo (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_solo (yn, this);
3437 Session::set_all_mute (bool yn)
3439 shared_ptr<RouteList> r = routes.reader ();
3441 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3442 if (!(*i)->hidden()) {
3443 (*i)->set_mute (yn, this);
3451 Session::n_diskstreams () const
3455 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3457 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3458 if (!(*i)->hidden()) {
3466 Session::graph_reordered ()
3468 /* don't do this stuff if we are setting up connections
3469 from a set_state() call or creating new tracks.
3472 if (_state_of_the_state & InitialConnecting) {
3476 /* every track/bus asked for this to be handled but it was deferred because
3477 we were connecting. do it now.
3480 request_input_change_handling ();
3484 /* force all diskstreams to update their capture offset values to
3485 reflect any changes in latencies within the graph.
3488 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3490 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3491 (*i)->set_capture_offset ();
3496 Session::record_disenable_all ()
3498 record_enable_change_all (false);
3502 Session::record_enable_all ()
3504 record_enable_change_all (true);
3508 Session::record_enable_change_all (bool yn)
3510 shared_ptr<RouteList> r = routes.reader ();
3512 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3515 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3516 at->set_record_enable (yn, this);
3520 /* since we don't keep rec-enable state, don't mark session dirty */
3524 Session::add_redirect (Redirect* redirect)
3528 PortInsert* port_insert;
3529 PluginInsert* plugin_insert;
3531 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3532 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3533 _port_inserts.insert (_port_inserts.begin(), port_insert);
3534 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3535 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3537 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3540 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3541 _sends.insert (_sends.begin(), send);
3543 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3547 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3553 Session::remove_redirect (Redirect* redirect)
3557 PortInsert* port_insert;
3558 PluginInsert* plugin_insert;
3560 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3561 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3562 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3563 if (x != _port_inserts.end()) {
3564 insert_bitset[port_insert->bit_slot()] = false;
3565 _port_inserts.erase (x);
3567 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3568 _plugin_inserts.remove (plugin_insert);
3570 fatal << string_compose (_("programming error: %1"),
3571 X_("unknown type of Insert deleted!"))
3575 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3576 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3577 if (x != _sends.end()) {
3578 send_bitset[send->bit_slot()] = false;
3582 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3590 Session::available_capture_duration ()
3592 float sample_bytes_on_disk = 4.0; // keep gcc happy
3594 switch (Config->get_native_file_data_format()) {
3596 sample_bytes_on_disk = 4.0;
3600 sample_bytes_on_disk = 3.0;
3604 /* impossible, but keep some gcc versions happy */
3605 fatal << string_compose (_("programming error: %1"),
3606 X_("illegal native file data format"))
3611 double scale = 4096.0 / sample_bytes_on_disk;
3613 if (_total_free_4k_blocks * scale > (double) max_frames) {
3617 return (nframes_t) floor (_total_free_4k_blocks * scale);
3621 Session::add_bundle (ARDOUR::Bundle* bundle)
3624 Glib::Mutex::Lock guard (bundle_lock);
3625 _bundles.push_back (bundle);
3628 BundleAdded (bundle); /* EMIT SIGNAL */
3634 Session::remove_bundle (ARDOUR::Bundle* bundle)
3636 bool removed = false;
3639 Glib::Mutex::Lock guard (bundle_lock);
3640 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3642 if (i != _bundles.end()) {
3649 BundleRemoved (bundle); /* EMIT SIGNAL */
3656 Session::bundle_by_name (string name) const
3658 Glib::Mutex::Lock lm (bundle_lock);
3660 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3661 if ((*i)->name() == name) {
3670 Session::tempo_map_changed (Change ignored)
3676 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3677 * the given count with the current block size.
3680 Session::ensure_buffers (ChanCount howmany)
3682 // FIXME: NASTY assumption (midi block size == audio block size)
3683 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3684 _send_buffers->ensure_buffers(howmany, current_block_size);
3685 _silent_buffers->ensure_buffers(howmany, current_block_size);
3687 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3691 Session::next_insert_id ()
3693 /* this doesn't really loop forever. just think about it */
3696 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3697 if (!insert_bitset[n]) {
3698 insert_bitset[n] = true;
3704 /* none available, so resize and try again */
3706 insert_bitset.resize (insert_bitset.size() + 16, false);
3711 Session::next_send_id ()
3713 /* this doesn't really loop forever. just think about it */
3716 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3717 if (!send_bitset[n]) {
3718 send_bitset[n] = true;
3724 /* none available, so resize and try again */
3726 send_bitset.resize (send_bitset.size() + 16, false);
3731 Session::mark_send_id (uint32_t id)
3733 if (id >= send_bitset.size()) {
3734 send_bitset.resize (id+16, false);
3736 if (send_bitset[id]) {
3737 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3739 send_bitset[id] = true;
3743 Session::mark_insert_id (uint32_t id)
3745 if (id >= insert_bitset.size()) {
3746 insert_bitset.resize (id+16, false);
3748 if (insert_bitset[id]) {
3749 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3751 insert_bitset[id] = true;
3754 /* Named Selection management */
3757 Session::named_selection_by_name (string name)
3759 Glib::Mutex::Lock lm (named_selection_lock);
3760 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3761 if ((*i)->name == name) {
3769 Session::add_named_selection (NamedSelection* named_selection)
3772 Glib::Mutex::Lock lm (named_selection_lock);
3773 named_selections.insert (named_selections.begin(), named_selection);
3776 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3782 NamedSelectionAdded (); /* EMIT SIGNAL */
3786 Session::remove_named_selection (NamedSelection* named_selection)
3788 bool removed = false;
3791 Glib::Mutex::Lock lm (named_selection_lock);
3793 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3795 if (i != named_selections.end()) {
3797 named_selections.erase (i);
3804 NamedSelectionRemoved (); /* EMIT SIGNAL */
3809 Session::reset_native_file_format ()
3811 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3813 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3814 (*i)->reset_write_sources (false);
3819 Session::route_name_unique (string n) const
3821 shared_ptr<RouteList> r = routes.reader ();
3823 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3824 if ((*i)->name() == n) {
3833 Session::n_playlists () const
3835 Glib::Mutex::Lock lm (playlist_lock);
3836 return playlists.size();
3840 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3842 if (!force && howmany <= _npan_buffers) {
3846 if (_pan_automation_buffer) {
3848 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3849 delete [] _pan_automation_buffer[i];
3852 delete [] _pan_automation_buffer;
3855 _pan_automation_buffer = new pan_t*[howmany];
3857 for (uint32_t i = 0; i < howmany; ++i) {
3858 _pan_automation_buffer[i] = new pan_t[nframes];
3861 _npan_buffers = howmany;
3865 Session::freeze (InterThreadInfo& itt)
3867 shared_ptr<RouteList> r = routes.reader ();
3869 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3873 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3874 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3885 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3886 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3889 boost::shared_ptr<Playlist> playlist;
3890 boost::shared_ptr<AudioFileSource> fsource;
3892 char buf[PATH_MAX+1];
3894 ChanCount nchans(track.audio_diskstream()->n_channels());
3896 nframes_t this_chunk;
3900 // any bigger than this seems to cause stack overflows in called functions
3901 const nframes_t chunk_size = (128 * 1024)/4;
3903 g_atomic_int_set (&processing_prohibited, 1);
3905 /* call tree *MUST* hold route_lock */
3907 if ((playlist = track.diskstream()->playlist()) == 0) {
3911 /* external redirects will be a problem */
3913 if (track.has_external_redirects()) {
3917 dir = discover_best_sound_dir ();
3919 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3921 for (x = 0; x < 99999; ++x) {
3922 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3923 if (access (buf, F_OK) != 0) {
3929 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3934 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3935 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3938 catch (failed_constructor& err) {
3939 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3943 srcs.push_back (fsource);
3946 /* XXX need to flush all redirects */
3951 /* create a set of reasonably-sized buffers */
3952 buffers.ensure_buffers(nchans, chunk_size);
3953 buffers.set_count(nchans);
3955 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3956 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3958 afs->prepare_for_peakfile_writes ();
3961 while (to_do && !itt.cancel) {
3963 this_chunk = min (to_do, chunk_size);
3965 if (track.export_stuff (buffers, start, this_chunk)) {
3970 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3971 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3974 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3980 start += this_chunk;
3981 to_do -= this_chunk;
3983 itt.progress = (float) (1.0 - ((double) to_do / len));
3992 xnow = localtime (&now);
3994 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3995 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3998 afs->update_header (position, *xnow, now);
3999 afs->flush_header ();
4003 /* construct a region to represent the bounced material */
4005 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4006 region_name_from_path (srcs.front()->name(), true));
4013 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4014 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4017 afs->mark_for_remove ();
4020 (*src)->drop_references ();
4024 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4025 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4028 afs->done_with_peakfile_writes ();
4032 g_atomic_int_set (&processing_prohibited, 0);
4038 Session::get_silent_buffers (ChanCount count)
4040 assert(_silent_buffers->available() >= count);
4041 _silent_buffers->set_count(count);
4043 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4044 for (size_t i=0; i < count.get(*t); ++i) {
4045 _silent_buffers->get(*t, i).clear();
4049 return *_silent_buffers;
4053 Session::get_scratch_buffers (ChanCount count)
4055 assert(_scratch_buffers->available() >= count);
4056 _scratch_buffers->set_count(count);
4057 return *_scratch_buffers;
4061 Session::get_send_buffers (ChanCount count)
4063 assert(_send_buffers->available() >= count);
4064 _send_buffers->set_count(count);
4065 return *_send_buffers;
4069 Session::ntracks () const
4072 shared_ptr<RouteList> r = routes.reader ();
4074 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4075 if (dynamic_cast<Track*> ((*i).get())) {
4084 Session::nbusses () const
4087 shared_ptr<RouteList> r = routes.reader ();
4089 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4090 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4099 Session::add_automation_list(AutomationList *al)
4101 automation_lists[al->id()] = al;
4105 Session::compute_initial_length ()
4107 return _engine.frame_rate() * 60 * 5;