2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/session_directory.h>
48 #include <ardour/utils.h>
49 #include <ardour/audio_diskstream.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/midi_diskstream.h>
54 #include <ardour/midi_playlist.h>
55 #include <ardour/midi_region.h>
56 #include <ardour/smf_source.h>
57 #include <ardour/auditioner.h>
58 #include <ardour/recent_sessions.h>
59 #include <ardour/redirect.h>
60 #include <ardour/send.h>
61 #include <ardour/insert.h>
62 #include <ardour/plugin_insert.h>
63 #include <ardour/port_insert.h>
64 #include <ardour/bundle.h>
65 #include <ardour/slave.h>
66 #include <ardour/tempo.h>
67 #include <ardour/audio_track.h>
68 #include <ardour/midi_track.h>
69 #include <ardour/cycle_timer.h>
70 #include <ardour/named_selection.h>
71 #include <ardour/crossfade.h>
72 #include <ardour/playlist.h>
73 #include <ardour/click.h>
74 #include <ardour/data_type.h>
75 #include <ardour/buffer_set.h>
76 #include <ardour/source_factory.h>
77 #include <ardour/region_factory.h>
78 #include <ardour/filename_extensions.h>
79 #include <ardour/session_directory.h>
82 #include <ardour/osc.h>
88 using namespace ARDOUR;
90 using boost::shared_ptr;
93 static const int CPU_CACHE_ALIGN = 64;
95 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
98 sigc::signal<int> Session::AskAboutPendingState;
99 sigc::signal<void> Session::SendFeedback;
101 sigc::signal<void> Session::SMPTEOffsetChanged;
102 sigc::signal<void> Session::StartTimeChanged;
103 sigc::signal<void> Session::EndTimeChanged;
105 Session::Session (AudioEngine &eng,
107 string snapshot_name,
108 string* mix_template)
111 _scratch_buffers(new BufferSet()),
112 _silent_buffers(new BufferSet()),
113 _send_buffers(new BufferSet()),
114 _mmc_port (default_mmc_port),
115 _mtc_port (default_mtc_port),
116 _midi_port (default_midi_port),
117 _session_dir (new SessionDirectory(fullpath)),
118 pending_events (2048),
119 //midi_requests (128), // the size of this should match the midi request pool size
120 _send_smpte_update (false),
121 diskstreams (new DiskstreamList),
122 routes (new RouteList),
123 auditioner ((Auditioner*) 0),
127 if (!eng.connected()) {
128 throw failed_constructor();
131 n_physical_outputs = _engine.n_physical_outputs();
132 n_physical_inputs = _engine.n_physical_inputs();
134 first_stage_init (fullpath, snapshot_name);
136 initialize_start_and_end_locations(0, compute_initial_length ());
139 // try and create a new session directory
142 if(!_session_dir->create()) {
143 // an existing session.
144 // throw a_more_meaningful_exception()
146 throw failed_constructor ();
149 catch(sys::filesystem_error& ex)
152 throw failed_constructor ();
155 if(!create_session_file_from_template (*mix_template)) {
157 throw failed_constructor ();
160 cerr << "Creating session " << fullpath
161 <<" using template" << *mix_template
164 // must be an existing session
167 // ensure the necessary session subdirectories exist
168 // in case the directory structure has changed etc.
169 _session_dir->create();
171 catch(sys::filesystem_error& ex)
174 throw failed_constructor ();
177 cerr << "Loading session " << fullpath
178 << " using snapshot " << snapshot_name << " (1)"
182 if (second_stage_init (false)) {
184 throw failed_constructor ();
187 store_recent_sessions(_name, _path);
189 bool was_dirty = dirty();
191 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
193 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
196 DirtyChanged (); /* EMIT SIGNAL */
200 Session::Session (AudioEngine &eng,
202 string snapshot_name,
203 AutoConnectOption input_ac,
204 AutoConnectOption output_ac,
205 uint32_t control_out_channels,
206 uint32_t master_out_channels,
207 uint32_t requested_physical_in,
208 uint32_t requested_physical_out,
209 nframes_t initial_length)
212 _scratch_buffers(new BufferSet()),
213 _silent_buffers(new BufferSet()),
214 _send_buffers(new BufferSet()),
215 _mmc_port (default_mmc_port),
216 _mtc_port (default_mtc_port),
217 _midi_port (default_midi_port),
218 _session_dir ( new SessionDirectory(fullpath)),
219 pending_events (2048),
220 //midi_requests (16),
221 _send_smpte_update (false),
222 diskstreams (new DiskstreamList),
223 routes (new RouteList),
227 if (!eng.connected()) {
228 throw failed_constructor();
231 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
233 n_physical_outputs = _engine.n_physical_outputs();
234 n_physical_inputs = _engine.n_physical_inputs();
236 if (n_physical_inputs) {
237 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
240 if (n_physical_outputs) {
241 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
244 first_stage_init (fullpath, snapshot_name);
246 initialize_start_and_end_locations(0, initial_length);
248 if (!_session_dir->create () || !create_session_file ()) {
250 throw failed_constructor ();
254 /* set up Master Out and Control Out if necessary */
259 if (control_out_channels) {
260 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
261 r->set_remote_control_id (control_id++);
266 if (master_out_channels) {
267 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
268 r->set_remote_control_id (control_id);
272 /* prohibit auto-connect to master, because there isn't one */
273 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
282 Config->set_input_auto_connect (input_ac);
283 Config->set_output_auto_connect (output_ac);
285 if (second_stage_init (true)) {
287 throw failed_constructor ();
290 store_recent_sessions(_name, _path);
292 bool was_dirty = dirty ();
294 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
296 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
299 DirtyChanged (); /* EMIT SIGNAL */
311 /* if we got to here, leaving pending capture state around
315 remove_pending_capture_state ();
317 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
318 _engine.remove_session ();
320 GoingAway (); /* EMIT SIGNAL */
326 /* clear history so that no references to objects are held any more */
330 /* clear state tree so that no references to objects are held any more */
336 terminate_butler_thread ();
337 //terminate_midi_thread ();
339 if (click_data && click_data != default_click) {
340 delete [] click_data;
343 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
344 delete [] click_emphasis_data;
349 delete _scratch_buffers;
350 delete _silent_buffers;
351 delete _send_buffers;
353 AudioDiskstream::free_working_buffers();
355 #undef TRACK_DESTRUCTION
356 #ifdef TRACK_DESTRUCTION
357 cerr << "delete named selections\n";
358 #endif /* TRACK_DESTRUCTION */
359 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
360 NamedSelectionList::iterator tmp;
369 #ifdef TRACK_DESTRUCTION
370 cerr << "delete playlists\n";
371 #endif /* TRACK_DESTRUCTION */
372 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
373 PlaylistList::iterator tmp;
378 (*i)->drop_references ();
383 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
384 PlaylistList::iterator tmp;
389 (*i)->drop_references ();
395 unused_playlists.clear ();
397 #ifdef TRACK_DESTRUCTION
398 cerr << "delete regions\n";
399 #endif /* TRACK_DESTRUCTION */
401 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
402 RegionList::iterator tmp;
407 i->second->drop_references ();
414 #ifdef TRACK_DESTRUCTION
415 cerr << "delete routes\n";
416 #endif /* TRACK_DESTRUCTION */
418 RCUWriter<RouteList> writer (routes);
419 boost::shared_ptr<RouteList> r = writer.get_copy ();
420 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
421 (*i)->drop_references ();
424 /* writer goes out of scope and updates master */
429 #ifdef TRACK_DESTRUCTION
430 cerr << "delete diskstreams\n";
431 #endif /* TRACK_DESTRUCTION */
433 RCUWriter<DiskstreamList> dwriter (diskstreams);
434 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
435 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
436 (*i)->drop_references ();
440 diskstreams.flush ();
442 #ifdef TRACK_DESTRUCTION
443 cerr << "delete audio sources\n";
444 #endif /* TRACK_DESTRUCTION */
445 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
446 SourceMap::iterator tmp;
451 i->second->drop_references ();
458 #ifdef TRACK_DESTRUCTION
459 cerr << "delete mix groups\n";
460 #endif /* TRACK_DESTRUCTION */
461 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
462 list<RouteGroup*>::iterator tmp;
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete edit groups\n";
474 #endif /* TRACK_DESTRUCTION */
475 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
476 list<RouteGroup*>::iterator tmp;
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete bundles\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ) {
490 BundleList::iterator tmp;
500 if (butler_mixdown_buffer) {
501 delete [] butler_mixdown_buffer;
504 if (butler_gain_buffer) {
505 delete [] butler_gain_buffer;
508 Crossfade::set_buffer_size (0);
516 Session::set_worst_io_latencies ()
518 _worst_output_latency = 0;
519 _worst_input_latency = 0;
521 if (!_engine.connected()) {
525 boost::shared_ptr<RouteList> r = routes.reader ();
527 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
528 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
529 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
534 Session::when_engine_running ()
536 string first_physical_output;
538 /* we don't want to run execute this again */
540 set_block_size (_engine.frames_per_cycle());
541 set_frame_rate (_engine.frame_rate());
543 Config->map_parameters (mem_fun (*this, &Session::config_changed));
545 /* every time we reconnect, recompute worst case output latencies */
547 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
549 if (synced_to_jack()) {
550 _engine.transport_stop ();
553 if (Config->get_jack_time_master()) {
554 _engine.transport_locate (_transport_frame);
562 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
564 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
566 /* existing state for Click */
568 if (_click_io->set_state (*child->children().front()) == 0) {
570 _clicking = Config->get_clicking ();
574 error << _("could not setup Click I/O") << endmsg;
580 /* default state for Click */
582 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
584 if (first_physical_output.length()) {
585 if (_click_io->add_output_port (first_physical_output, this)) {
586 // relax, even though its an error
588 _clicking = Config->get_clicking ();
594 catch (failed_constructor& err) {
595 error << _("cannot setup Click I/O") << endmsg;
598 set_worst_io_latencies ();
601 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
604 /* Create a set of Bundle objects that map
605 to the physical outputs currently available
610 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
612 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
614 Bundle* c = new OutputBundle (buf, true);
615 c->set_nchannels (1);
616 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
621 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
623 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
625 Bundle* c = new InputBundle (buf, true);
626 c->set_nchannels (1);
627 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
634 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
636 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
638 Bundle* c = new OutputBundle (buf, true);
639 c->set_nchannels (2);
640 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
641 c->add_port_to_channel (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
646 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
648 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
650 Bundle* c = new InputBundle (buf, true);
651 c->set_nchannels (2);
652 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
653 c->add_port_to_channel (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
662 /* create master/control ports */
667 /* force the master to ignore any later call to this */
669 if (_master_out->pending_state_node) {
670 _master_out->ports_became_legal();
673 /* no panner resets till we are through */
675 _master_out->defer_pan_reset ();
677 while (_master_out->n_inputs().n_audio()
678 < _master_out->input_maximum().n_audio()) {
679 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
680 error << _("cannot setup master inputs")
686 while (_master_out->n_outputs().n_audio()
687 < _master_out->output_maximum().n_audio()) {
688 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
689 error << _("cannot setup master outputs")
696 _master_out->allow_pan_reset ();
700 Bundle* c = new OutputBundle (_("Master Out"), true);
702 c->set_nchannels (_master_out->n_inputs().n_total());
703 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
704 c->add_port_to_channel ((int) n, _master_out->input(n)->name());
711 /* catch up on send+insert cnts */
715 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
718 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
719 if (id > insert_cnt) {
727 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
730 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
738 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
740 /* hook us up to the engine */
742 _engine.set_session (this);
747 osc->set_session (*this);
750 _state_of_the_state = Clean;
752 DirtyChanged (); /* EMIT SIGNAL */
756 Session::hookup_io ()
758 /* stop graph reordering notifications from
759 causing resorts, etc.
762 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
764 if (auditioner == 0) {
766 /* we delay creating the auditioner till now because
767 it makes its own connections to ports.
768 the engine has to be running for this to work.
772 auditioner.reset (new Auditioner (*this));
775 catch (failed_constructor& err) {
776 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
780 /* Tell all IO objects to create their ports */
786 vector<string> cports;
788 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
789 if (_control_out->add_input_port ("", this)) {
790 error << _("cannot setup control inputs")
796 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
797 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
798 error << _("cannot set up master outputs")
806 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
808 for (n = 0; n < ni; ++n) {
809 cports.push_back (_control_out->input(n)->name());
812 boost::shared_ptr<RouteList> r = routes.reader ();
814 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
815 (*x)->set_control_outs (cports);
819 /* Tell all IO objects to connect themselves together */
821 IO::enable_connecting ();
823 /* Now reset all panners */
825 IO::reset_panners ();
827 /* Anyone who cares about input state, wake up and do something */
829 IOConnectionsComplete (); /* EMIT SIGNAL */
831 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
833 /* now handle the whole enchilada as if it was one
839 /* update mixer solo state */
845 Session::playlist_length_changed ()
847 /* we can't just increase end_location->end() if pl->get_maximum_extent()
848 if larger. if the playlist used to be the longest playlist,
849 and its now shorter, we have to decrease end_location->end(). hence,
850 we have to iterate over all diskstreams and check the
851 playlists currently in use.
857 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
859 boost::shared_ptr<Playlist> playlist;
861 if ((playlist = dstream->playlist()) != 0) {
862 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
865 /* see comment in playlist_length_changed () */
870 Session::record_enabling_legal () const
872 /* this used to be in here, but survey says.... we don't need to restrict it */
873 // if (record_status() == Recording) {
877 if (Config->get_all_safe()) {
884 Session::reset_input_monitor_state ()
886 if (transport_rolling()) {
888 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
890 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
891 if ((*i)->record_enabled ()) {
892 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
893 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
897 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
899 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
900 if ((*i)->record_enabled ()) {
901 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
902 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
909 Session::auto_punch_start_changed (Location* location)
911 replace_event (Event::PunchIn, location->start());
913 if (get_record_enabled() && Config->get_punch_in()) {
914 /* capture start has been changed, so save new pending state */
915 save_state ("", true);
920 Session::auto_punch_end_changed (Location* location)
922 nframes_t when_to_stop = location->end();
923 // when_to_stop += _worst_output_latency + _worst_input_latency;
924 replace_event (Event::PunchOut, when_to_stop);
928 Session::auto_punch_changed (Location* location)
930 nframes_t when_to_stop = location->end();
932 replace_event (Event::PunchIn, location->start());
933 //when_to_stop += _worst_output_latency + _worst_input_latency;
934 replace_event (Event::PunchOut, when_to_stop);
938 Session::auto_loop_changed (Location* location)
940 replace_event (Event::AutoLoop, location->end(), location->start());
942 if (transport_rolling() && play_loop) {
944 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
946 if (_transport_frame > location->end()) {
947 // relocate to beginning of loop
948 clear_events (Event::LocateRoll);
950 request_locate (location->start(), true);
953 else if (Config->get_seamless_loop() && !loop_changing) {
955 // schedule a locate-roll to refill the diskstreams at the
957 loop_changing = true;
959 if (location->end() > last_loopend) {
960 clear_events (Event::LocateRoll);
961 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
968 last_loopend = location->end();
973 Session::set_auto_punch_location (Location* location)
977 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
978 auto_punch_start_changed_connection.disconnect();
979 auto_punch_end_changed_connection.disconnect();
980 auto_punch_changed_connection.disconnect();
981 existing->set_auto_punch (false, this);
982 remove_event (existing->start(), Event::PunchIn);
983 clear_events (Event::PunchOut);
984 auto_punch_location_changed (0);
993 if (location->end() <= location->start()) {
994 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
998 auto_punch_start_changed_connection.disconnect();
999 auto_punch_end_changed_connection.disconnect();
1000 auto_punch_changed_connection.disconnect();
1002 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1003 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1004 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1006 location->set_auto_punch (true, this);
1007 auto_punch_location_changed (location);
1011 Session::set_auto_loop_location (Location* location)
1015 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1016 auto_loop_start_changed_connection.disconnect();
1017 auto_loop_end_changed_connection.disconnect();
1018 auto_loop_changed_connection.disconnect();
1019 existing->set_auto_loop (false, this);
1020 remove_event (existing->end(), Event::AutoLoop);
1021 auto_loop_location_changed (0);
1026 if (location == 0) {
1030 if (location->end() <= location->start()) {
1031 error << _("Session: you can't use a mark for auto loop") << endmsg;
1035 last_loopend = location->end();
1037 auto_loop_start_changed_connection.disconnect();
1038 auto_loop_end_changed_connection.disconnect();
1039 auto_loop_changed_connection.disconnect();
1041 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1042 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1043 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1045 location->set_auto_loop (true, this);
1046 auto_loop_location_changed (location);
1050 Session::locations_added (Location* ignored)
1056 Session::locations_changed ()
1058 _locations.apply (*this, &Session::handle_locations_changed);
1062 Session::handle_locations_changed (Locations::LocationList& locations)
1064 Locations::LocationList::iterator i;
1066 bool set_loop = false;
1067 bool set_punch = false;
1069 for (i = locations.begin(); i != locations.end(); ++i) {
1073 if (location->is_auto_punch()) {
1074 set_auto_punch_location (location);
1077 if (location->is_auto_loop()) {
1078 set_auto_loop_location (location);
1085 set_auto_loop_location (0);
1088 set_auto_punch_location (0);
1095 Session::enable_record ()
1097 /* XXX really atomic compare+swap here */
1098 if (g_atomic_int_get (&_record_status) != Recording) {
1099 g_atomic_int_set (&_record_status, Recording);
1100 _last_record_location = _transport_frame;
1101 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1103 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1104 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1105 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1106 if ((*i)->record_enabled ()) {
1107 (*i)->monitor_input (true);
1112 RecordStateChanged ();
1117 Session::disable_record (bool rt_context, bool force)
1121 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1123 if (!Config->get_latched_record_enable () || force) {
1124 g_atomic_int_set (&_record_status, Disabled);
1126 if (rs == Recording) {
1127 g_atomic_int_set (&_record_status, Enabled);
1131 // FIXME: timestamp correct? [DR]
1132 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1133 // does this /need/ to be sent in all cases?
1135 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1137 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1138 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1140 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1141 if ((*i)->record_enabled ()) {
1142 (*i)->monitor_input (false);
1147 RecordStateChanged (); /* emit signal */
1150 remove_pending_capture_state ();
1156 Session::step_back_from_record ()
1158 g_atomic_int_set (&_record_status, Enabled);
1160 if (Config->get_monitoring_model() == HardwareMonitoring) {
1161 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1163 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1164 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1165 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1166 (*i)->monitor_input (false);
1173 Session::maybe_enable_record ()
1175 g_atomic_int_set (&_record_status, Enabled);
1177 /* this function is currently called from somewhere other than an RT thread.
1178 this save_state() call therefore doesn't impact anything.
1181 save_state ("", true);
1183 if (_transport_speed) {
1184 if (!Config->get_punch_in()) {
1188 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1189 RecordStateChanged (); /* EMIT SIGNAL */
1196 Session::audible_frame () const
1202 /* the first of these two possible settings for "offset"
1203 mean that the audible frame is stationary until
1204 audio emerges from the latency compensation
1207 the second means that the audible frame is stationary
1208 until audio would emerge from a physical port
1209 in the absence of any plugin latency compensation
1212 offset = _worst_output_latency;
1214 if (offset > current_block_size) {
1215 offset -= current_block_size;
1217 /* XXX is this correct? if we have no external
1218 physical connections and everything is internal
1219 then surely this is zero? still, how
1220 likely is that anyway?
1222 offset = current_block_size;
1225 if (synced_to_jack()) {
1226 tf = _engine.transport_frame();
1228 tf = _transport_frame;
1231 if (_transport_speed == 0) {
1241 if (!non_realtime_work_pending()) {
1245 /* take latency into account */
1254 Session::set_frame_rate (nframes_t frames_per_second)
1256 /** \fn void Session::set_frame_size(nframes_t)
1257 the AudioEngine object that calls this guarantees
1258 that it will not be called while we are also in
1259 ::process(). Its fine to do things that block
1263 _base_frame_rate = frames_per_second;
1267 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1269 // XXX we need some equivalent to this, somehow
1270 // SndFileSource::setup_standard_crossfades (frames_per_second);
1274 /* XXX need to reset/reinstantiate all LADSPA plugins */
1278 Session::set_block_size (nframes_t nframes)
1280 /* the AudioEngine guarantees
1281 that it will not be called while we are also in
1282 ::process(). It is therefore fine to do things that block
1288 current_block_size = nframes;
1290 ensure_buffers(_scratch_buffers->available());
1292 if (_gain_automation_buffer) {
1293 delete [] _gain_automation_buffer;
1295 _gain_automation_buffer = new gain_t[nframes];
1297 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1299 boost::shared_ptr<RouteList> r = routes.reader ();
1301 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1302 (*i)->set_block_size (nframes);
1305 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1306 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1307 (*i)->set_block_size (nframes);
1310 set_worst_io_latencies ();
1315 Session::set_default_fade (float steepness, float fade_msecs)
1318 nframes_t fade_frames;
1320 /* Don't allow fade of less 1 frame */
1322 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1329 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1333 default_fade_msecs = fade_msecs;
1334 default_fade_steepness = steepness;
1337 // jlc, WTF is this!
1338 Glib::RWLock::ReaderLock lm (route_lock);
1339 AudioRegion::set_default_fade (steepness, fade_frames);
1344 /* XXX have to do this at some point */
1345 /* foreach region using default fade, reset, then
1346 refill_all_diskstream_buffers ();
1351 struct RouteSorter {
1352 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1353 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1355 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1358 if (r1->fed_by.empty()) {
1359 if (r2->fed_by.empty()) {
1360 /* no ardour-based connections inbound to either route. just use signal order */
1361 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1363 /* r2 has connections, r1 does not; run r1 early */
1367 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1374 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1376 shared_ptr<Route> r2;
1378 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1379 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1383 /* make a copy of the existing list of routes that feed r1 */
1385 set<shared_ptr<Route> > existing = r1->fed_by;
1387 /* for each route that feeds r1, recurse, marking it as feeding
1391 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1394 /* r2 is a route that feeds r1 which somehow feeds base. mark
1395 base as being fed by r2
1398 rbase->fed_by.insert (r2);
1402 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1406 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1410 /* now recurse, so that we can mark base as being fed by
1411 all routes that feed r2
1414 trace_terminal (r2, rbase);
1421 Session::resort_routes ()
1423 /* don't do anything here with signals emitted
1424 by Routes while we are being destroyed.
1427 if (_state_of_the_state & Deletion) {
1434 RCUWriter<RouteList> writer (routes);
1435 shared_ptr<RouteList> r = writer.get_copy ();
1436 resort_routes_using (r);
1437 /* writer goes out of scope and forces update */
1442 Session::resort_routes_using (shared_ptr<RouteList> r)
1444 RouteList::iterator i, j;
1446 for (i = r->begin(); i != r->end(); ++i) {
1448 (*i)->fed_by.clear ();
1450 for (j = r->begin(); j != r->end(); ++j) {
1452 /* although routes can feed themselves, it will
1453 cause an endless recursive descent if we
1454 detect it. so don't bother checking for
1462 if ((*j)->feeds (*i)) {
1463 (*i)->fed_by.insert (*j);
1468 for (i = r->begin(); i != r->end(); ++i) {
1469 trace_terminal (*i, *i);
1476 cerr << "finished route resort\n";
1478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1479 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1486 list<boost::shared_ptr<MidiTrack> >
1487 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1489 char track_name[32];
1490 uint32_t track_id = 0;
1492 uint32_t channels_used = 0;
1494 RouteList new_routes;
1495 list<boost::shared_ptr<MidiTrack> > ret;
1497 /* count existing midi tracks */
1500 shared_ptr<RouteList> r = routes.reader ();
1502 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1503 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1504 if (!(*i)->hidden()) {
1506 channels_used += (*i)->n_inputs().n_midi();
1514 /* check for duplicate route names, since we might have pre-existing
1515 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1516 save, close,restart,add new route - first named route is now
1524 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1526 if (route_by_name (track_name) == 0) {
1530 } while (track_id < (UINT_MAX-1));
1533 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1535 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1536 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1539 channels_used += track->n_inputs ().n_midi();
1541 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1542 track->set_remote_control_id (ntracks());
1544 new_routes.push_back (track);
1545 ret.push_back (track);
1548 catch (failed_constructor &err) {
1549 error << _("Session: could not create new midi track.") << endmsg;
1550 // XXX should we delete the tracks already created?
1558 if (!new_routes.empty()) {
1559 add_routes (new_routes, false);
1560 save_state (_current_snapshot_name);
1566 list<boost::shared_ptr<AudioTrack> >
1567 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1569 char track_name[32];
1570 uint32_t track_id = 0;
1572 uint32_t channels_used = 0;
1574 RouteList new_routes;
1575 list<boost::shared_ptr<AudioTrack> > ret;
1576 uint32_t control_id;
1578 /* count existing audio tracks */
1581 shared_ptr<RouteList> r = routes.reader ();
1583 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1584 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1585 if (!(*i)->hidden()) {
1587 channels_used += (*i)->n_inputs().n_audio();
1593 vector<string> physinputs;
1594 vector<string> physoutputs;
1595 uint32_t nphysical_in;
1596 uint32_t nphysical_out;
1598 _engine.get_physical_outputs (physoutputs);
1599 _engine.get_physical_inputs (physinputs);
1600 control_id = ntracks() + nbusses() + 1;
1604 /* check for duplicate route names, since we might have pre-existing
1605 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1606 save, close,restart,add new route - first named route is now
1614 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1616 if (route_by_name (track_name) == 0) {
1620 } while (track_id < (UINT_MAX-1));
1622 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1623 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1628 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1629 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1634 shared_ptr<AudioTrack> track;
1637 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1639 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1640 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1641 input_channels, output_channels)
1647 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1651 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1652 port = physinputs[(channels_used+x)%nphysical_in];
1655 if (port.length() && track->connect_input (track->input (x), port, this)) {
1661 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1665 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1666 port = physoutputs[(channels_used+x)%nphysical_out];
1667 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1669 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1673 if (port.length() && track->connect_output (track->output (x), port, this)) {
1678 channels_used += track->n_inputs ().n_audio();
1680 track->audio_diskstream()->non_realtime_input_change();
1682 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1683 track->set_remote_control_id (control_id);
1686 new_routes.push_back (track);
1687 ret.push_back (track);
1690 catch (failed_constructor &err) {
1691 error << _("Session: could not create new audio track.") << endmsg;
1694 /* we need to get rid of this, since the track failed to be created */
1695 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1698 RCUWriter<DiskstreamList> writer (diskstreams);
1699 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1700 ds->remove (track->audio_diskstream());
1707 catch (AudioEngine::PortRegistrationFailure& pfe) {
1709 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;
1712 /* we need to get rid of this, since the track failed to be created */
1713 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1716 RCUWriter<DiskstreamList> writer (diskstreams);
1717 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1718 ds->remove (track->audio_diskstream());
1729 if (!new_routes.empty()) {
1730 add_routes (new_routes, false);
1731 save_state (_current_snapshot_name);
1738 Session::set_remote_control_ids ()
1740 RemoteModel m = Config->get_remote_model();
1742 shared_ptr<RouteList> r = routes.reader ();
1744 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1745 if ( MixerOrdered == m) {
1746 long order = (*i)->order_key(N_("signal"));
1747 (*i)->set_remote_control_id( order+1 );
1748 } else if ( EditorOrdered == m) {
1749 long order = (*i)->order_key(N_("editor"));
1750 (*i)->set_remote_control_id( order+1 );
1751 } else if ( UserOrdered == m) {
1752 //do nothing ... only changes to remote id's are initiated by user
1759 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1762 uint32_t bus_id = 1;
1766 uint32_t control_id;
1768 /* count existing audio busses */
1771 shared_ptr<RouteList> r = routes.reader ();
1773 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1774 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1775 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1782 vector<string> physinputs;
1783 vector<string> physoutputs;
1785 _engine.get_physical_outputs (physoutputs);
1786 _engine.get_physical_inputs (physinputs);
1787 control_id = ntracks() + nbusses() + 1;
1792 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1796 if (route_by_name (bus_name) == 0) {
1800 } while (bus_id < (UINT_MAX-1));
1803 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1805 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1806 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1807 input_channels, output_channels)
1812 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1816 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1817 port = physinputs[((n+x)%n_physical_inputs)];
1820 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1825 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1829 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1830 port = physoutputs[((n+x)%n_physical_outputs)];
1831 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1833 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1837 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1842 bus->set_remote_control_id (control_id);
1845 ret.push_back (bus);
1849 catch (failed_constructor &err) {
1850 error << _("Session: could not create new audio route.") << endmsg;
1854 catch (AudioEngine::PortRegistrationFailure& pfe) {
1855 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;
1865 add_routes (ret, false);
1866 save_state (_current_snapshot_name);
1874 Session::add_routes (RouteList& new_routes, bool save)
1877 RCUWriter<RouteList> writer (routes);
1878 shared_ptr<RouteList> r = writer.get_copy ();
1879 r->insert (r->end(), new_routes.begin(), new_routes.end());
1880 resort_routes_using (r);
1883 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1885 boost::weak_ptr<Route> wpr (*x);
1887 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1888 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1889 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1890 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1892 if ((*x)->master()) {
1896 if ((*x)->control()) {
1897 _control_out = (*x);
1901 if (_control_out && IO::connecting_legal) {
1903 vector<string> cports;
1904 uint32_t ni = _control_out->n_inputs().n_audio();
1906 for (uint32_t n = 0; n < ni; ++n) {
1907 cports.push_back (_control_out->input(n)->name());
1910 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1911 (*x)->set_control_outs (cports);
1918 save_state (_current_snapshot_name);
1921 RouteAdded (new_routes); /* EMIT SIGNAL */
1925 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1927 /* need to do this in case we're rolling at the time, to prevent false underruns */
1928 dstream->do_refill_with_alloc ();
1930 dstream->set_block_size (current_block_size);
1933 RCUWriter<DiskstreamList> writer (diskstreams);
1934 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1935 ds->push_back (dstream);
1936 /* writer goes out of scope, copies ds back to main */
1939 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1940 /* this will connect to future changes, and check the current length */
1941 diskstream_playlist_changed (dstream);
1943 dstream->prepare ();
1948 Session::remove_route (shared_ptr<Route> route)
1951 RCUWriter<RouteList> writer (routes);
1952 shared_ptr<RouteList> rs = writer.get_copy ();
1956 /* deleting the master out seems like a dumb
1957 idea, but its more of a UI policy issue
1961 if (route == _master_out) {
1962 _master_out = shared_ptr<Route> ();
1965 if (route == _control_out) {
1966 _control_out = shared_ptr<Route> ();
1968 /* cancel control outs for all routes */
1970 vector<string> empty;
1972 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1973 (*r)->set_control_outs (empty);
1977 update_route_solo_state ();
1979 /* writer goes out of scope, forces route list update */
1983 boost::shared_ptr<Diskstream> ds;
1985 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1986 ds = t->diskstream();
1992 RCUWriter<DiskstreamList> dsl (diskstreams);
1993 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1998 find_current_end ();
2000 update_latency_compensation (false, false);
2003 // We need to disconnect the routes inputs and outputs
2004 route->disconnect_inputs(NULL);
2005 route->disconnect_outputs(NULL);
2007 /* get rid of it from the dead wood collection in the route list manager */
2009 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2013 /* try to cause everyone to drop their references */
2015 route->drop_references ();
2017 /* save the new state of the world */
2019 if (save_state (_current_snapshot_name)) {
2020 save_history (_current_snapshot_name);
2025 Session::route_mute_changed (void* src)
2031 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2033 if (solo_update_disabled) {
2039 boost::shared_ptr<Route> route = wpr.lock ();
2042 /* should not happen */
2043 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2047 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2049 shared_ptr<RouteList> r = routes.reader ();
2051 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2053 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2057 /* don't mess with busses */
2059 if (dynamic_cast<Track*>((*i).get()) == 0) {
2065 /* don't mess with tracks */
2067 if (dynamic_cast<Track*>((*i).get()) != 0) {
2072 if ((*i) != route &&
2073 ((*i)->mix_group () == 0 ||
2074 (*i)->mix_group () != route->mix_group () ||
2075 !route->mix_group ()->is_active())) {
2077 if ((*i)->soloed()) {
2079 /* if its already soloed, and solo latching is enabled,
2080 then leave it as it is.
2083 if (Config->get_solo_latched()) {
2090 solo_update_disabled = true;
2091 (*i)->set_solo (false, src);
2092 solo_update_disabled = false;
2096 bool something_soloed = false;
2097 bool same_thing_soloed = false;
2098 bool signal = false;
2100 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2101 if ((*i)->soloed()) {
2102 something_soloed = true;
2103 if (dynamic_cast<Track*>((*i).get())) {
2105 same_thing_soloed = true;
2110 same_thing_soloed = true;
2118 if (something_soloed != currently_soloing) {
2120 currently_soloing = something_soloed;
2123 modify_solo_mute (is_track, same_thing_soloed);
2126 SoloActive (currently_soloing); /* EMIT SIGNAL */
2129 SoloChanged (); /* EMIT SIGNAL */
2135 Session::update_route_solo_state ()
2138 bool is_track = false;
2139 bool signal = false;
2141 /* caller must hold RouteLock */
2143 /* this is where we actually implement solo by changing
2144 the solo mute setting of each track.
2147 shared_ptr<RouteList> r = routes.reader ();
2149 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2150 if ((*i)->soloed()) {
2152 if (dynamic_cast<Track*>((*i).get())) {
2159 if (mute != currently_soloing) {
2161 currently_soloing = mute;
2164 if (!is_track && !mute) {
2166 /* nothing is soloed */
2168 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2169 (*i)->set_solo_mute (false);
2179 modify_solo_mute (is_track, mute);
2182 SoloActive (currently_soloing);
2187 Session::modify_solo_mute (bool is_track, bool mute)
2189 shared_ptr<RouteList> r = routes.reader ();
2191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2195 /* only alter track solo mute */
2197 if (dynamic_cast<Track*>((*i).get())) {
2198 if ((*i)->soloed()) {
2199 (*i)->set_solo_mute (!mute);
2201 (*i)->set_solo_mute (mute);
2207 /* only alter bus solo mute */
2209 if (!dynamic_cast<Track*>((*i).get())) {
2211 if ((*i)->soloed()) {
2213 (*i)->set_solo_mute (false);
2217 /* don't mute master or control outs
2218 in response to another bus solo
2221 if ((*i) != _master_out &&
2222 (*i) != _control_out) {
2223 (*i)->set_solo_mute (mute);
2234 Session::catch_up_on_solo ()
2236 /* this is called after set_state() to catch the full solo
2237 state, which can't be correctly determined on a per-route
2238 basis, but needs the global overview that only the session
2241 update_route_solo_state();
2245 Session::route_by_name (string name)
2247 shared_ptr<RouteList> r = routes.reader ();
2249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2250 if ((*i)->name() == name) {
2255 return shared_ptr<Route> ((Route*) 0);
2259 Session::route_by_id (PBD::ID id)
2261 shared_ptr<RouteList> r = routes.reader ();
2263 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2264 if ((*i)->id() == id) {
2269 return shared_ptr<Route> ((Route*) 0);
2273 Session::route_by_remote_id (uint32_t id)
2275 shared_ptr<RouteList> r = routes.reader ();
2277 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2278 if ((*i)->remote_control_id() == id) {
2283 return shared_ptr<Route> ((Route*) 0);
2287 Session::find_current_end ()
2289 if (_state_of_the_state & Loading) {
2293 nframes_t max = get_maximum_extent ();
2295 if (max > end_location->end()) {
2296 end_location->set_end (max);
2298 DurationChanged(); /* EMIT SIGNAL */
2303 Session::get_maximum_extent () const
2308 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2310 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2311 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2312 if ((me = pl->get_maximum_extent()) > max) {
2320 boost::shared_ptr<Diskstream>
2321 Session::diskstream_by_name (string name)
2323 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2325 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2326 if ((*i)->name() == name) {
2331 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2334 boost::shared_ptr<Diskstream>
2335 Session::diskstream_by_id (const PBD::ID& id)
2337 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2339 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2340 if ((*i)->id() == id) {
2345 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2348 /* Region management */
2351 Session::new_region_name (string old)
2353 string::size_type last_period;
2355 string::size_type len = old.length() + 64;
2358 if ((last_period = old.find_last_of ('.')) == string::npos) {
2360 /* no period present - add one explicitly */
2363 last_period = old.length() - 1;
2368 number = atoi (old.substr (last_period+1).c_str());
2372 while (number < (UINT_MAX-1)) {
2374 RegionList::const_iterator i;
2379 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2382 for (i = regions.begin(); i != regions.end(); ++i) {
2383 if (i->second->name() == sbuf) {
2388 if (i == regions.end()) {
2393 if (number != (UINT_MAX-1)) {
2397 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2402 Session::region_name (string& result, string base, bool newlevel) const
2407 assert(base.find("/") == string::npos);
2411 Glib::Mutex::Lock lm (region_lock);
2413 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2421 /* XXX this is going to be slow. optimize me later */
2426 string::size_type pos;
2428 pos = base.find_last_of ('.');
2430 /* pos may be npos, but then we just use entire base */
2432 subbase = base.substr (0, pos);
2436 bool name_taken = true;
2439 Glib::Mutex::Lock lm (region_lock);
2441 for (int n = 1; n < 5000; ++n) {
2444 snprintf (buf, sizeof (buf), ".%d", n);
2449 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2450 if (i->second->name() == result) {
2463 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2471 Session::add_region (boost::shared_ptr<Region> region)
2473 boost::shared_ptr<Region> other;
2477 Glib::Mutex::Lock lm (region_lock);
2479 RegionList::iterator x;
2481 for (x = regions.begin(); x != regions.end(); ++x) {
2485 if (region->region_list_equivalent (other)) {
2490 if (x == regions.end()) {
2492 pair<RegionList::key_type,RegionList::mapped_type> entry;
2494 entry.first = region->id();
2495 entry.second = region;
2497 pair<RegionList::iterator,bool> x = regions.insert (entry);
2509 /* mark dirty because something has changed even if we didn't
2510 add the region to the region list.
2516 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2517 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2518 RegionAdded (region); /* EMIT SIGNAL */
2523 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2525 boost::shared_ptr<Region> region (weak_region.lock ());
2531 if (what_changed & Region::HiddenChanged) {
2532 /* relay hidden changes */
2533 RegionHiddenChange (region);
2538 Session::remove_region (boost::weak_ptr<Region> weak_region)
2540 RegionList::iterator i;
2541 boost::shared_ptr<Region> region (weak_region.lock ());
2547 bool removed = false;
2550 Glib::Mutex::Lock lm (region_lock);
2552 if ((i = regions.find (region->id())) != regions.end()) {
2558 /* mark dirty because something has changed even if we didn't
2559 remove the region from the region list.
2565 RegionRemoved(region); /* EMIT SIGNAL */
2569 boost::shared_ptr<Region>
2570 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2572 RegionList::iterator i;
2573 boost::shared_ptr<Region> region;
2575 Glib::Mutex::Lock lm (region_lock);
2577 for (i = regions.begin(); i != regions.end(); ++i) {
2581 if (region->whole_file()) {
2583 if (child->source_equivalent (region)) {
2589 return boost::shared_ptr<Region> ();
2593 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2595 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2596 (*i)->get_region_list_equivalent_regions (region, result);
2600 Session::destroy_region (boost::shared_ptr<Region> region)
2602 vector<boost::shared_ptr<Source> > srcs;
2605 boost::shared_ptr<AudioRegion> aregion;
2607 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2611 if (aregion->playlist()) {
2612 aregion->playlist()->destroy_region (region);
2615 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2616 srcs.push_back (aregion->source (n));
2620 region->drop_references ();
2622 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2624 if (!(*i)->used()) {
2625 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2628 (afs)->mark_for_remove ();
2631 (*i)->drop_references ();
2633 cerr << "source was not used by any playlist\n";
2641 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2643 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2644 destroy_region (*i);
2650 Session::remove_last_capture ()
2652 list<boost::shared_ptr<Region> > r;
2654 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2656 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2657 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2660 r.insert (r.end(), l.begin(), l.end());
2665 destroy_regions (r);
2667 save_state (_current_snapshot_name);
2673 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2679 /* Source Management */
2681 Session::add_source (boost::shared_ptr<Source> source)
2683 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2684 pair<SourceMap::iterator,bool> result;
2686 entry.first = source->id();
2687 entry.second = source;
2690 Glib::Mutex::Lock lm (source_lock);
2691 result = sources.insert (entry);
2694 if (result.second) {
2695 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2701 Session::remove_source (boost::weak_ptr<Source> src)
2703 SourceMap::iterator i;
2704 boost::shared_ptr<Source> source = src.lock();
2711 Glib::Mutex::Lock lm (source_lock);
2714 Glib::Mutex::Lock lm (source_lock);
2716 if ((i = sources.find (source->id())) != sources.end()) {
2722 if (!_state_of_the_state & InCleanup) {
2724 /* save state so we don't end up with a session file
2725 referring to non-existent sources.
2728 save_state (_current_snapshot_name);
2732 boost::shared_ptr<Source>
2733 Session::source_by_id (const PBD::ID& id)
2735 Glib::Mutex::Lock lm (source_lock);
2736 SourceMap::iterator i;
2737 boost::shared_ptr<Source> source;
2739 if ((i = sources.find (id)) != sources.end()) {
2743 /* XXX search MIDI or other searches here */
2749 boost::shared_ptr<Source>
2750 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2752 Glib::Mutex::Lock lm (source_lock);
2754 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2755 cerr << "comparing " << path << " with " << i->second->name() << endl;
2756 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2758 if (afs && afs->path() == path && chn == afs->channel()) {
2763 return boost::shared_ptr<Source>();
2767 Session::peak_path_from_audio_path (string audio_path) const
2769 sys::path peakfile_path(_session_dir->peak_path());
2771 peakfile_path /= basename_nosuffix (audio_path) + peakfile_suffix;
2773 return peakfile_path.to_string();
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 SessionDirectory sdir(get_best_session_directory_for_new_source ());
2977 spath = sdir.sound_path().to_string();
2980 string::size_type pos = foo.find_last_of ('/');
2982 if (pos == string::npos) {
2985 spath += foo.substr (pos + 1);
2991 boost::shared_ptr<AudioFileSource>
2992 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2994 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2995 return boost::dynamic_pointer_cast<AudioFileSource> (
2996 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2999 // FIXME: _terrible_ code duplication
3001 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3004 string old_basename = PBD::basename_nosuffix (oldname);
3005 string new_legalized = legalize_for_path (newname);
3007 /* note: we know (or assume) the old path is already valid */
3011 /* destructive file sources have a name of the form:
3013 /path/to/Tnnnn-NAME(%[LR])?.wav
3015 the task here is to replace NAME with the new name.
3018 /* find last slash */
3022 string::size_type slash;
3023 string::size_type dash;
3025 if ((slash = path.find_last_of ('/')) == string::npos) {
3029 dir = path.substr (0, slash+1);
3031 /* '-' is not a legal character for the NAME part of the path */
3033 if ((dash = path.find_last_of ('-')) == string::npos) {
3037 prefix = path.substr (slash+1, dash-(slash+1));
3042 path += new_legalized;
3043 path += ".mid"; /* XXX gag me with a spoon */
3047 /* non-destructive file sources have a name of the form:
3049 /path/to/NAME-nnnnn(%[LR])?.wav
3051 the task here is to replace NAME with the new name.
3056 string::size_type slash;
3057 string::size_type dash;
3058 string::size_type postfix;
3060 /* find last slash */
3062 if ((slash = path.find_last_of ('/')) == string::npos) {
3066 dir = path.substr (0, slash+1);
3068 /* '-' is not a legal character for the NAME part of the path */
3070 if ((dash = path.find_last_of ('-')) == string::npos) {
3074 suffix = path.substr (dash+1);
3076 // Suffix is now everything after the dash. Now we need to eliminate
3077 // the nnnnn part, which is done by either finding a '%' or a '.'
3079 postfix = suffix.find_last_of ("%");
3080 if (postfix == string::npos) {
3081 postfix = suffix.find_last_of ('.');
3084 if (postfix != string::npos) {
3085 suffix = suffix.substr (postfix);
3087 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3091 const uint32_t limit = 10000;
3092 char buf[PATH_MAX+1];
3094 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3096 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3098 if (access (buf, F_OK) != 0) {
3106 error << "FATAL ERROR! Could not find a " << endl;
3115 Session::midi_path_from_name (string name)
3119 char buf[PATH_MAX+1];
3120 const uint32_t limit = 10000;
3124 legalized = legalize_for_path (name);
3126 /* find a "version" of the file name that doesn't exist in
3127 any of the possible directories.
3130 for (cnt = 1; cnt <= limit; ++cnt) {
3132 vector<space_and_path>::iterator i;
3133 uint32_t existing = 0;
3135 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3137 SessionDirectory sdir((*i).path);
3139 sys::path p = sdir.midi_path();
3143 spath = p.to_string();
3145 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3147 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3152 if (existing == 0) {
3157 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3158 throw failed_constructor();
3162 /* we now have a unique name for the file, but figure out where to
3168 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3170 spath = sdir.midi_path().to_string();
3173 string::size_type pos = foo.find_last_of ('/');
3175 if (pos == string::npos) {
3178 spath += foo.substr (pos + 1);
3184 boost::shared_ptr<MidiSource>
3185 Session::create_midi_source_for_session (MidiDiskstream& ds)
3187 string mpath = midi_path_from_name (ds.name());
3189 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3193 /* Playlist management */
3195 boost::shared_ptr<Playlist>
3196 Session::playlist_by_name (string name)
3198 Glib::Mutex::Lock lm (playlist_lock);
3199 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3200 if ((*i)->name() == name) {
3204 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3205 if ((*i)->name() == name) {
3210 return boost::shared_ptr<Playlist>();
3214 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3216 if (playlist->hidden()) {
3221 Glib::Mutex::Lock lm (playlist_lock);
3222 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3223 playlists.insert (playlists.begin(), playlist);
3224 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3225 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3231 PlaylistAdded (playlist); /* EMIT SIGNAL */
3235 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3238 Glib::Mutex::Lock lm (playlist_lock);
3239 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3242 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3249 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3251 boost::shared_ptr<Playlist> pl(wpl.lock());
3257 PlaylistList::iterator x;
3260 /* its not supposed to be visible */
3265 Glib::Mutex::Lock lm (playlist_lock);
3269 unused_playlists.insert (pl);
3271 if ((x = playlists.find (pl)) != playlists.end()) {
3272 playlists.erase (x);
3278 playlists.insert (pl);
3280 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3281 unused_playlists.erase (x);
3288 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3290 if (_state_of_the_state & Deletion) {
3294 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3301 Glib::Mutex::Lock lm (playlist_lock);
3303 PlaylistList::iterator i;
3305 i = find (playlists.begin(), playlists.end(), playlist);
3306 if (i != playlists.end()) {
3307 playlists.erase (i);
3310 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3311 if (i != unused_playlists.end()) {
3312 unused_playlists.erase (i);
3319 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3323 Session::set_audition (boost::shared_ptr<Region> r)
3325 pending_audition_region = r;
3326 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3327 schedule_butler_transport_work ();
3331 Session::audition_playlist ()
3333 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3334 ev->region.reset ();
3339 Session::non_realtime_set_audition ()
3341 if (!pending_audition_region) {
3342 auditioner->audition_current_playlist ();
3344 auditioner->audition_region (pending_audition_region);
3345 pending_audition_region.reset ();
3347 AuditionActive (true); /* EMIT SIGNAL */
3351 Session::audition_region (boost::shared_ptr<Region> r)
3353 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3359 Session::cancel_audition ()
3361 if (auditioner->active()) {
3362 auditioner->cancel_audition ();
3363 AuditionActive (false); /* EMIT SIGNAL */
3368 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3370 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3374 Session::remove_empty_sounds ()
3376 PathScanner scanner;
3378 vector<string *>* possible_audiofiles = scanner (_session_dir->sound_path().to_string (),
3379 Config->get_possible_audio_file_regexp (), false, true);
3381 Glib::Mutex::Lock lm (source_lock);
3383 regex_t compiled_tape_track_pattern;
3386 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3390 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3392 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3396 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3398 /* never remove files that appear to be a tape track */
3400 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3405 if (AudioFileSource::is_empty (*this, *(*i))) {
3407 unlink ((*i)->c_str());
3409 string peak_path = peak_path_from_audio_path (**i);
3410 unlink (peak_path.c_str());
3416 delete possible_audiofiles;
3420 Session::is_auditioning () const
3422 /* can be called before we have an auditioner object */
3424 return auditioner->active();
3431 Session::set_all_solo (bool yn)
3433 shared_ptr<RouteList> r = routes.reader ();
3435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3436 if (!(*i)->hidden()) {
3437 (*i)->set_solo (yn, this);
3445 Session::set_all_mute (bool yn)
3447 shared_ptr<RouteList> r = routes.reader ();
3449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3450 if (!(*i)->hidden()) {
3451 (*i)->set_mute (yn, this);
3459 Session::n_diskstreams () const
3463 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3465 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3466 if (!(*i)->hidden()) {
3474 Session::graph_reordered ()
3476 /* don't do this stuff if we are setting up connections
3477 from a set_state() call or creating new tracks.
3480 if (_state_of_the_state & InitialConnecting) {
3484 /* every track/bus asked for this to be handled but it was deferred because
3485 we were connecting. do it now.
3488 request_input_change_handling ();
3492 /* force all diskstreams to update their capture offset values to
3493 reflect any changes in latencies within the graph.
3496 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3498 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3499 (*i)->set_capture_offset ();
3504 Session::record_disenable_all ()
3506 record_enable_change_all (false);
3510 Session::record_enable_all ()
3512 record_enable_change_all (true);
3516 Session::record_enable_change_all (bool yn)
3518 shared_ptr<RouteList> r = routes.reader ();
3520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3523 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3524 at->set_record_enable (yn, this);
3528 /* since we don't keep rec-enable state, don't mark session dirty */
3532 Session::add_redirect (Redirect* redirect)
3536 PortInsert* port_insert;
3537 PluginInsert* plugin_insert;
3539 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3540 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3541 _port_inserts.insert (_port_inserts.begin(), port_insert);
3542 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3543 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3545 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3548 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3549 _sends.insert (_sends.begin(), send);
3551 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3555 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3561 Session::remove_redirect (Redirect* redirect)
3565 PortInsert* port_insert;
3566 PluginInsert* plugin_insert;
3568 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3569 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3570 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3571 if (x != _port_inserts.end()) {
3572 insert_bitset[port_insert->bit_slot()] = false;
3573 _port_inserts.erase (x);
3575 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3576 _plugin_inserts.remove (plugin_insert);
3578 fatal << string_compose (_("programming error: %1"),
3579 X_("unknown type of Insert deleted!"))
3583 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3584 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3585 if (x != _sends.end()) {
3586 send_bitset[send->bit_slot()] = false;
3590 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3598 Session::available_capture_duration ()
3600 float sample_bytes_on_disk = 4.0; // keep gcc happy
3602 switch (Config->get_native_file_data_format()) {
3604 sample_bytes_on_disk = 4.0;
3608 sample_bytes_on_disk = 3.0;
3612 /* impossible, but keep some gcc versions happy */
3613 fatal << string_compose (_("programming error: %1"),
3614 X_("illegal native file data format"))
3619 double scale = 4096.0 / sample_bytes_on_disk;
3621 if (_total_free_4k_blocks * scale > (double) max_frames) {
3625 return (nframes_t) floor (_total_free_4k_blocks * scale);
3629 Session::add_bundle (ARDOUR::Bundle* bundle)
3632 Glib::Mutex::Lock guard (bundle_lock);
3633 _bundles.push_back (bundle);
3636 BundleAdded (bundle); /* EMIT SIGNAL */
3642 Session::remove_bundle (ARDOUR::Bundle* bundle)
3644 bool removed = false;
3647 Glib::Mutex::Lock guard (bundle_lock);
3648 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3650 if (i != _bundles.end()) {
3657 BundleRemoved (bundle); /* EMIT SIGNAL */
3664 Session::bundle_by_name (string name) const
3666 Glib::Mutex::Lock lm (bundle_lock);
3668 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3669 if ((*i)->name() == name) {
3678 Session::tempo_map_changed (Change ignored)
3684 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3685 * the given count with the current block size.
3688 Session::ensure_buffers (ChanCount howmany)
3690 // FIXME: NASTY assumption (midi block size == audio block size)
3691 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3692 _send_buffers->ensure_buffers(howmany, current_block_size);
3693 _silent_buffers->ensure_buffers(howmany, current_block_size);
3695 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3699 Session::next_insert_id ()
3701 /* this doesn't really loop forever. just think about it */
3704 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3705 if (!insert_bitset[n]) {
3706 insert_bitset[n] = true;
3712 /* none available, so resize and try again */
3714 insert_bitset.resize (insert_bitset.size() + 16, false);
3719 Session::next_send_id ()
3721 /* this doesn't really loop forever. just think about it */
3724 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3725 if (!send_bitset[n]) {
3726 send_bitset[n] = true;
3732 /* none available, so resize and try again */
3734 send_bitset.resize (send_bitset.size() + 16, false);
3739 Session::mark_send_id (uint32_t id)
3741 if (id >= send_bitset.size()) {
3742 send_bitset.resize (id+16, false);
3744 if (send_bitset[id]) {
3745 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3747 send_bitset[id] = true;
3751 Session::mark_insert_id (uint32_t id)
3753 if (id >= insert_bitset.size()) {
3754 insert_bitset.resize (id+16, false);
3756 if (insert_bitset[id]) {
3757 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3759 insert_bitset[id] = true;
3762 /* Named Selection management */
3765 Session::named_selection_by_name (string name)
3767 Glib::Mutex::Lock lm (named_selection_lock);
3768 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3769 if ((*i)->name == name) {
3777 Session::add_named_selection (NamedSelection* named_selection)
3780 Glib::Mutex::Lock lm (named_selection_lock);
3781 named_selections.insert (named_selections.begin(), named_selection);
3784 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3790 NamedSelectionAdded (); /* EMIT SIGNAL */
3794 Session::remove_named_selection (NamedSelection* named_selection)
3796 bool removed = false;
3799 Glib::Mutex::Lock lm (named_selection_lock);
3801 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3803 if (i != named_selections.end()) {
3805 named_selections.erase (i);
3812 NamedSelectionRemoved (); /* EMIT SIGNAL */
3817 Session::reset_native_file_format ()
3819 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3821 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3822 (*i)->reset_write_sources (false);
3827 Session::route_name_unique (string n) const
3829 shared_ptr<RouteList> r = routes.reader ();
3831 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3832 if ((*i)->name() == n) {
3841 Session::n_playlists () const
3843 Glib::Mutex::Lock lm (playlist_lock);
3844 return playlists.size();
3848 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3850 if (!force && howmany <= _npan_buffers) {
3854 if (_pan_automation_buffer) {
3856 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3857 delete [] _pan_automation_buffer[i];
3860 delete [] _pan_automation_buffer;
3863 _pan_automation_buffer = new pan_t*[howmany];
3865 for (uint32_t i = 0; i < howmany; ++i) {
3866 _pan_automation_buffer[i] = new pan_t[nframes];
3869 _npan_buffers = howmany;
3873 Session::freeze (InterThreadInfo& itt)
3875 shared_ptr<RouteList> r = routes.reader ();
3877 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3881 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3882 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3893 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3894 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3897 boost::shared_ptr<Playlist> playlist;
3898 boost::shared_ptr<AudioFileSource> fsource;
3900 char buf[PATH_MAX+1];
3901 ChanCount nchans(track.audio_diskstream()->n_channels());
3903 nframes_t this_chunk;
3906 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3907 const string sound_dir = sdir.sound_path().to_string();
3909 // any bigger than this seems to cause stack overflows in called functions
3910 const nframes_t chunk_size = (128 * 1024)/4;
3912 g_atomic_int_set (&processing_prohibited, 1);
3914 /* call tree *MUST* hold route_lock */
3916 if ((playlist = track.diskstream()->playlist()) == 0) {
3920 /* external redirects will be a problem */
3922 if (track.has_external_redirects()) {
3926 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3928 for (x = 0; x < 99999; ++x) {
3929 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3930 if (access (buf, F_OK) != 0) {
3936 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3941 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3942 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3945 catch (failed_constructor& err) {
3946 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3950 srcs.push_back (fsource);
3953 /* XXX need to flush all redirects */
3958 /* create a set of reasonably-sized buffers */
3959 buffers.ensure_buffers(nchans, chunk_size);
3960 buffers.set_count(nchans);
3962 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3963 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3965 afs->prepare_for_peakfile_writes ();
3968 while (to_do && !itt.cancel) {
3970 this_chunk = min (to_do, chunk_size);
3972 if (track.export_stuff (buffers, start, this_chunk)) {
3977 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3978 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3981 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3987 start += this_chunk;
3988 to_do -= this_chunk;
3990 itt.progress = (float) (1.0 - ((double) to_do / len));
3999 xnow = localtime (&now);
4001 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4002 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4005 afs->update_header (position, *xnow, now);
4006 afs->flush_header ();
4010 /* construct a region to represent the bounced material */
4012 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4013 region_name_from_path (srcs.front()->name(), true));
4020 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4021 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4024 afs->mark_for_remove ();
4027 (*src)->drop_references ();
4031 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4032 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4035 afs->done_with_peakfile_writes ();
4039 g_atomic_int_set (&processing_prohibited, 0);
4045 Session::get_silent_buffers (ChanCount count)
4047 assert(_silent_buffers->available() >= count);
4048 _silent_buffers->set_count(count);
4050 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4051 for (size_t i=0; i < count.get(*t); ++i) {
4052 _silent_buffers->get(*t, i).clear();
4056 return *_silent_buffers;
4060 Session::get_scratch_buffers (ChanCount count)
4062 assert(_scratch_buffers->available() >= count);
4063 _scratch_buffers->set_count(count);
4064 return *_scratch_buffers;
4068 Session::get_send_buffers (ChanCount count)
4070 assert(_send_buffers->available() >= count);
4071 _send_buffers->set_count(count);
4072 return *_send_buffers;
4076 Session::ntracks () const
4079 shared_ptr<RouteList> r = routes.reader ();
4081 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4082 if (dynamic_cast<Track*> ((*i).get())) {
4091 Session::nbusses () const
4094 shared_ptr<RouteList> r = routes.reader ();
4096 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4097 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4106 Session::add_automation_list(AutomationList *al)
4108 automation_lists[al->id()] = al;
4112 Session::compute_initial_length ()
4114 return _engine.frame_rate() * 60 * 5;