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>
43 #include <pbd/file_utils.h>
45 #include <ardour/audioengine.h>
46 #include <ardour/configuration.h>
47 #include <ardour/session.h>
48 #include <ardour/session_directory.h>
49 #include <ardour/utils.h>
50 #include <ardour/audio_diskstream.h>
51 #include <ardour/audioplaylist.h>
52 #include <ardour/audioregion.h>
53 #include <ardour/audiofilesource.h>
54 #include <ardour/midi_diskstream.h>
55 #include <ardour/midi_playlist.h>
56 #include <ardour/midi_region.h>
57 #include <ardour/smf_source.h>
58 #include <ardour/auditioner.h>
59 #include <ardour/recent_sessions.h>
60 #include <ardour/io_processor.h>
61 #include <ardour/send.h>
62 #include <ardour/processor.h>
63 #include <ardour/plugin_insert.h>
64 #include <ardour/port_insert.h>
65 #include <ardour/bundle.h>
66 #include <ardour/slave.h>
67 #include <ardour/tempo.h>
68 #include <ardour/audio_track.h>
69 #include <ardour/midi_track.h>
70 #include <ardour/cycle_timer.h>
71 #include <ardour/named_selection.h>
72 #include <ardour/crossfade.h>
73 #include <ardour/playlist.h>
74 #include <ardour/click.h>
75 #include <ardour/data_type.h>
76 #include <ardour/buffer_set.h>
77 #include <ardour/source_factory.h>
78 #include <ardour/region_factory.h>
79 #include <ardour/filename_extensions.h>
80 #include <ardour/session_directory.h>
81 #include <ardour/tape_file_matcher.h>
84 #include <ardour/osc.h>
90 using namespace ARDOUR;
92 using boost::shared_ptr;
95 static const int CPU_CACHE_ALIGN = 64;
97 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
100 sigc::signal<int> Session::AskAboutPendingState;
101 sigc::signal<void> Session::SendFeedback;
103 sigc::signal<void> Session::SMPTEOffsetChanged;
104 sigc::signal<void> Session::StartTimeChanged;
105 sigc::signal<void> Session::EndTimeChanged;
107 Session::Session (AudioEngine &eng,
109 string snapshot_name,
110 string* mix_template)
113 _scratch_buffers(new BufferSet()),
114 _silent_buffers(new BufferSet()),
115 _mix_buffers(new BufferSet()),
116 _mmc_port (default_mmc_port),
117 _mtc_port (default_mtc_port),
118 _midi_port (default_midi_port),
119 _session_dir (new SessionDirectory(fullpath)),
120 pending_events (2048),
121 //midi_requests (128), // the size of this should match the midi request pool size
122 _send_smpte_update (false),
123 diskstreams (new DiskstreamList),
124 routes (new RouteList),
125 auditioner ((Auditioner*) 0),
129 if (!eng.connected()) {
130 throw failed_constructor();
133 n_physical_outputs = _engine.n_physical_outputs();
134 n_physical_inputs = _engine.n_physical_inputs();
136 first_stage_init (fullpath, snapshot_name);
138 initialize_start_and_end_locations(0, compute_initial_length ());
141 // try and create a new session directory
144 if(!_session_dir->create()) {
145 // an existing session.
146 // throw a_more_meaningful_exception()
148 throw failed_constructor ();
151 catch(sys::filesystem_error& ex)
154 throw failed_constructor ();
157 if(!create_session_file_from_template (*mix_template)) {
159 throw failed_constructor ();
162 cerr << "Creating session " << fullpath
163 <<" using template" << *mix_template
166 // must be an existing session
169 // ensure the necessary session subdirectories exist
170 // in case the directory structure has changed etc.
171 _session_dir->create();
173 catch(sys::filesystem_error& ex)
176 throw failed_constructor ();
179 cerr << "Loading session " << fullpath
180 << " using snapshot " << snapshot_name << " (1)"
184 if (second_stage_init (false)) {
186 throw failed_constructor ();
189 store_recent_sessions(_name, _path);
191 bool was_dirty = dirty();
193 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
195 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
198 DirtyChanged (); /* EMIT SIGNAL */
202 Session::Session (AudioEngine &eng,
204 string snapshot_name,
205 AutoConnectOption input_ac,
206 AutoConnectOption output_ac,
207 uint32_t control_out_channels,
208 uint32_t master_out_channels,
209 uint32_t requested_physical_in,
210 uint32_t requested_physical_out,
211 nframes_t initial_length)
214 _scratch_buffers(new BufferSet()),
215 _silent_buffers(new BufferSet()),
216 _mix_buffers(new BufferSet()),
217 _mmc_port (default_mmc_port),
218 _mtc_port (default_mtc_port),
219 _midi_port (default_midi_port),
220 _session_dir ( new SessionDirectory(fullpath)),
221 pending_events (2048),
222 //midi_requests (16),
223 _send_smpte_update (false),
224 diskstreams (new DiskstreamList),
225 routes (new RouteList),
229 if (!eng.connected()) {
230 throw failed_constructor();
233 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
235 n_physical_outputs = _engine.n_physical_outputs();
236 n_physical_inputs = _engine.n_physical_inputs();
238 if (n_physical_inputs) {
239 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
242 if (n_physical_outputs) {
243 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
246 first_stage_init (fullpath, snapshot_name);
248 initialize_start_and_end_locations(0, initial_length);
250 if (!_session_dir->create () || !create_session_file ()) {
252 throw failed_constructor ();
256 /* set up Master Out and Control Out if necessary */
261 if (control_out_channels) {
262 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
263 r->set_remote_control_id (control_id++);
268 if (master_out_channels) {
269 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
270 r->set_remote_control_id (control_id);
274 /* prohibit auto-connect to master, because there isn't one */
275 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
284 Config->set_input_auto_connect (input_ac);
285 Config->set_output_auto_connect (output_ac);
287 if (second_stage_init (true)) {
289 throw failed_constructor ();
292 store_recent_sessions(_name, _path);
294 bool was_dirty = dirty ();
296 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
298 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
301 DirtyChanged (); /* EMIT SIGNAL */
313 /* if we got to here, leaving pending capture state around
317 remove_pending_capture_state ();
319 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
320 _engine.remove_session ();
322 GoingAway (); /* EMIT SIGNAL */
328 /* clear history so that no references to objects are held any more */
332 /* clear state tree so that no references to objects are held any more */
338 terminate_butler_thread ();
339 //terminate_midi_thread ();
341 if (click_data && click_data != default_click) {
342 delete [] click_data;
345 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
346 delete [] click_emphasis_data;
351 delete _scratch_buffers;
352 delete _silent_buffers;
355 AudioDiskstream::free_working_buffers();
357 #undef TRACK_DESTRUCTION
358 #ifdef TRACK_DESTRUCTION
359 cerr << "delete named selections\n";
360 #endif /* TRACK_DESTRUCTION */
361 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
362 NamedSelectionList::iterator tmp;
371 #ifdef TRACK_DESTRUCTION
372 cerr << "delete playlists\n";
373 #endif /* TRACK_DESTRUCTION */
374 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
375 PlaylistList::iterator tmp;
380 (*i)->drop_references ();
385 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
386 PlaylistList::iterator tmp;
391 (*i)->drop_references ();
397 unused_playlists.clear ();
399 #ifdef TRACK_DESTRUCTION
400 cerr << "delete regions\n";
401 #endif /* TRACK_DESTRUCTION */
403 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
404 RegionList::iterator tmp;
409 i->second->drop_references ();
416 #ifdef TRACK_DESTRUCTION
417 cerr << "delete routes\n";
418 #endif /* TRACK_DESTRUCTION */
420 RCUWriter<RouteList> writer (routes);
421 boost::shared_ptr<RouteList> r = writer.get_copy ();
422 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
423 (*i)->drop_references ();
426 /* writer goes out of scope and updates master */
431 #ifdef TRACK_DESTRUCTION
432 cerr << "delete diskstreams\n";
433 #endif /* TRACK_DESTRUCTION */
435 RCUWriter<DiskstreamList> dwriter (diskstreams);
436 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
437 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
438 (*i)->drop_references ();
442 diskstreams.flush ();
444 #ifdef TRACK_DESTRUCTION
445 cerr << "delete audio sources\n";
446 #endif /* TRACK_DESTRUCTION */
447 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
448 SourceMap::iterator tmp;
453 i->second->drop_references ();
460 #ifdef TRACK_DESTRUCTION
461 cerr << "delete mix groups\n";
462 #endif /* TRACK_DESTRUCTION */
463 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
464 list<RouteGroup*>::iterator tmp;
474 #ifdef TRACK_DESTRUCTION
475 cerr << "delete edit groups\n";
476 #endif /* TRACK_DESTRUCTION */
477 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
478 list<RouteGroup*>::iterator tmp;
488 if (butler_mixdown_buffer) {
489 delete [] butler_mixdown_buffer;
492 if (butler_gain_buffer) {
493 delete [] butler_gain_buffer;
496 Crossfade::set_buffer_size (0);
504 Session::set_worst_io_latencies ()
506 _worst_output_latency = 0;
507 _worst_input_latency = 0;
509 if (!_engine.connected()) {
513 boost::shared_ptr<RouteList> r = routes.reader ();
515 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
516 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
517 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
522 Session::when_engine_running ()
524 string first_physical_output;
526 /* we don't want to run execute this again */
528 set_block_size (_engine.frames_per_cycle());
529 set_frame_rate (_engine.frame_rate());
531 Config->map_parameters (mem_fun (*this, &Session::config_changed));
533 /* every time we reconnect, recompute worst case output latencies */
535 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
537 if (synced_to_jack()) {
538 _engine.transport_stop ();
541 if (Config->get_jack_time_master()) {
542 _engine.transport_locate (_transport_frame);
550 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
552 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
554 /* existing state for Click */
556 if (_click_io->set_state (*child->children().front()) == 0) {
558 _clicking = Config->get_clicking ();
562 error << _("could not setup Click I/O") << endmsg;
568 /* default state for Click */
570 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
572 if (first_physical_output.length()) {
573 if (_click_io->add_output_port (first_physical_output, this)) {
574 // relax, even though its an error
576 _clicking = Config->get_clicking ();
582 catch (failed_constructor& err) {
583 error << _("cannot setup Click I/O") << endmsg;
586 set_worst_io_latencies ();
589 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
592 /* Create a set of Bundle objects that map
593 to the physical outputs currently available
598 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
600 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
602 shared_ptr<Bundle> c (new InputBundle (buf, true));
603 c->set_nchannels (1);
604 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
609 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
611 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
613 shared_ptr<Bundle> c (new OutputBundle (buf, true));
614 c->set_nchannels (1);
615 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
622 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
624 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
626 shared_ptr<Bundle> c (new InputBundle (buf, true));
627 c->set_nchannels (2);
628 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
629 c->add_port_to_channel (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
634 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
636 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
638 shared_ptr<Bundle> c (new OutputBundle (buf, true));
639 c->set_nchannels (2);
640 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
641 c->add_port_to_channel (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
650 /* create master/control ports */
655 /* force the master to ignore any later call to this */
657 if (_master_out->pending_state_node) {
658 _master_out->ports_became_legal();
661 /* no panner resets till we are through */
663 _master_out->defer_pan_reset ();
665 while (_master_out->n_inputs().n_audio()
666 < _master_out->input_maximum().n_audio()) {
667 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
668 error << _("cannot setup master inputs")
674 while (_master_out->n_outputs().n_audio()
675 < _master_out->output_maximum().n_audio()) {
676 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
677 error << _("cannot setup master outputs")
684 _master_out->allow_pan_reset ();
688 shared_ptr<Bundle> c (new OutputBundle (_("Master Out"), true));
690 c->set_nchannels (_master_out->n_inputs().n_total());
691 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
692 c->add_port_to_channel ((int) n, _master_out->input(n)->name());
699 /* catch up on send+insert cnts */
703 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
706 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
707 if (id > insert_cnt) {
715 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
718 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
726 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
728 /* hook us up to the engine */
730 _engine.set_session (this);
735 osc->set_session (*this);
738 _state_of_the_state = Clean;
740 DirtyChanged (); /* EMIT SIGNAL */
744 Session::hookup_io ()
746 /* stop graph reordering notifications from
747 causing resorts, etc.
750 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
752 if (auditioner == 0) {
754 /* we delay creating the auditioner till now because
755 it makes its own connections to ports.
756 the engine has to be running for this to work.
760 auditioner.reset (new Auditioner (*this));
763 catch (failed_constructor& err) {
764 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
768 /* Tell all IO objects to create their ports */
774 vector<string> cports;
776 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
777 if (_control_out->add_input_port ("", this)) {
778 error << _("cannot setup control inputs")
784 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
785 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
786 error << _("cannot set up master outputs")
794 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
796 for (n = 0; n < ni; ++n) {
797 cports.push_back (_control_out->input(n)->name());
800 boost::shared_ptr<RouteList> r = routes.reader ();
802 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
803 (*x)->set_control_outs (cports);
807 /* Tell all IO objects to connect themselves together */
809 IO::enable_connecting ();
811 /* Now reset all panners */
813 IO::reset_panners ();
815 /* Anyone who cares about input state, wake up and do something */
817 IOConnectionsComplete (); /* EMIT SIGNAL */
819 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
821 /* now handle the whole enchilada as if it was one
827 /* update mixer solo state */
833 Session::playlist_length_changed ()
835 /* we can't just increase end_location->end() if pl->get_maximum_extent()
836 if larger. if the playlist used to be the longest playlist,
837 and its now shorter, we have to decrease end_location->end(). hence,
838 we have to iterate over all diskstreams and check the
839 playlists currently in use.
845 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
847 boost::shared_ptr<Playlist> playlist;
849 if ((playlist = dstream->playlist()) != 0) {
850 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
853 /* see comment in playlist_length_changed () */
858 Session::record_enabling_legal () const
860 /* this used to be in here, but survey says.... we don't need to restrict it */
861 // if (record_status() == Recording) {
865 if (Config->get_all_safe()) {
872 Session::reset_input_monitor_state ()
874 if (transport_rolling()) {
876 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
878 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
879 if ((*i)->record_enabled ()) {
880 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
881 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
885 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
887 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
888 if ((*i)->record_enabled ()) {
889 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
890 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
897 Session::auto_punch_start_changed (Location* location)
899 replace_event (Event::PunchIn, location->start());
901 if (get_record_enabled() && Config->get_punch_in()) {
902 /* capture start has been changed, so save new pending state */
903 save_state ("", true);
908 Session::auto_punch_end_changed (Location* location)
910 nframes_t when_to_stop = location->end();
911 // when_to_stop += _worst_output_latency + _worst_input_latency;
912 replace_event (Event::PunchOut, when_to_stop);
916 Session::auto_punch_changed (Location* location)
918 nframes_t when_to_stop = location->end();
920 replace_event (Event::PunchIn, location->start());
921 //when_to_stop += _worst_output_latency + _worst_input_latency;
922 replace_event (Event::PunchOut, when_to_stop);
926 Session::auto_loop_changed (Location* location)
928 replace_event (Event::AutoLoop, location->end(), location->start());
930 if (transport_rolling() && play_loop) {
932 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
934 if (_transport_frame > location->end()) {
935 // relocate to beginning of loop
936 clear_events (Event::LocateRoll);
938 request_locate (location->start(), true);
941 else if (Config->get_seamless_loop() && !loop_changing) {
943 // schedule a locate-roll to refill the diskstreams at the
945 loop_changing = true;
947 if (location->end() > last_loopend) {
948 clear_events (Event::LocateRoll);
949 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
956 last_loopend = location->end();
961 Session::set_auto_punch_location (Location* location)
965 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
966 auto_punch_start_changed_connection.disconnect();
967 auto_punch_end_changed_connection.disconnect();
968 auto_punch_changed_connection.disconnect();
969 existing->set_auto_punch (false, this);
970 remove_event (existing->start(), Event::PunchIn);
971 clear_events (Event::PunchOut);
972 auto_punch_location_changed (0);
981 if (location->end() <= location->start()) {
982 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
986 auto_punch_start_changed_connection.disconnect();
987 auto_punch_end_changed_connection.disconnect();
988 auto_punch_changed_connection.disconnect();
990 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
991 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
992 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
994 location->set_auto_punch (true, this);
995 auto_punch_location_changed (location);
999 Session::set_auto_loop_location (Location* location)
1003 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1004 auto_loop_start_changed_connection.disconnect();
1005 auto_loop_end_changed_connection.disconnect();
1006 auto_loop_changed_connection.disconnect();
1007 existing->set_auto_loop (false, this);
1008 remove_event (existing->end(), Event::AutoLoop);
1009 auto_loop_location_changed (0);
1014 if (location == 0) {
1018 if (location->end() <= location->start()) {
1019 error << _("Session: you can't use a mark for auto loop") << endmsg;
1023 last_loopend = location->end();
1025 auto_loop_start_changed_connection.disconnect();
1026 auto_loop_end_changed_connection.disconnect();
1027 auto_loop_changed_connection.disconnect();
1029 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1030 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1031 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1033 location->set_auto_loop (true, this);
1034 auto_loop_location_changed (location);
1038 Session::locations_added (Location* ignored)
1044 Session::locations_changed ()
1046 _locations.apply (*this, &Session::handle_locations_changed);
1050 Session::handle_locations_changed (Locations::LocationList& locations)
1052 Locations::LocationList::iterator i;
1054 bool set_loop = false;
1055 bool set_punch = false;
1057 for (i = locations.begin(); i != locations.end(); ++i) {
1061 if (location->is_auto_punch()) {
1062 set_auto_punch_location (location);
1065 if (location->is_auto_loop()) {
1066 set_auto_loop_location (location);
1073 set_auto_loop_location (0);
1076 set_auto_punch_location (0);
1083 Session::enable_record ()
1085 /* XXX really atomic compare+swap here */
1086 if (g_atomic_int_get (&_record_status) != Recording) {
1087 g_atomic_int_set (&_record_status, Recording);
1088 _last_record_location = _transport_frame;
1089 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1091 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1092 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1093 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1094 if ((*i)->record_enabled ()) {
1095 (*i)->monitor_input (true);
1100 RecordStateChanged ();
1105 Session::disable_record (bool rt_context, bool force)
1109 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1111 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1112 g_atomic_int_set (&_record_status, Disabled);
1114 if (rs == Recording) {
1115 g_atomic_int_set (&_record_status, Enabled);
1119 // FIXME: timestamp correct? [DR]
1120 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1121 // does this /need/ to be sent in all cases?
1123 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1125 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1126 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1128 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1129 if ((*i)->record_enabled ()) {
1130 (*i)->monitor_input (false);
1135 RecordStateChanged (); /* emit signal */
1138 remove_pending_capture_state ();
1144 Session::step_back_from_record ()
1146 /* XXX really atomic compare+swap here */
1147 if (g_atomic_int_get (&_record_status) == Recording) {
1148 g_atomic_int_set (&_record_status, Enabled);
1150 if (Config->get_monitoring_model() == HardwareMonitoring) {
1151 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1153 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1154 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1155 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1156 (*i)->monitor_input (false);
1164 Session::maybe_enable_record ()
1166 g_atomic_int_set (&_record_status, Enabled);
1168 /* this function is currently called from somewhere other than an RT thread.
1169 this save_state() call therefore doesn't impact anything.
1172 save_state ("", true);
1174 if (_transport_speed) {
1175 if (!Config->get_punch_in()) {
1179 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1180 RecordStateChanged (); /* EMIT SIGNAL */
1187 Session::audible_frame () const
1193 /* the first of these two possible settings for "offset"
1194 mean that the audible frame is stationary until
1195 audio emerges from the latency compensation
1198 the second means that the audible frame is stationary
1199 until audio would emerge from a physical port
1200 in the absence of any plugin latency compensation
1203 offset = _worst_output_latency;
1205 if (offset > current_block_size) {
1206 offset -= current_block_size;
1208 /* XXX is this correct? if we have no external
1209 physical connections and everything is internal
1210 then surely this is zero? still, how
1211 likely is that anyway?
1213 offset = current_block_size;
1216 if (synced_to_jack()) {
1217 tf = _engine.transport_frame();
1219 tf = _transport_frame;
1222 if (_transport_speed == 0) {
1232 if (!non_realtime_work_pending()) {
1236 /* take latency into account */
1245 Session::set_frame_rate (nframes_t frames_per_second)
1247 /** \fn void Session::set_frame_size(nframes_t)
1248 the AudioEngine object that calls this guarantees
1249 that it will not be called while we are also in
1250 ::process(). Its fine to do things that block
1254 _base_frame_rate = frames_per_second;
1258 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1262 // XXX we need some equivalent to this, somehow
1263 // SndFileSource::setup_standard_crossfades (frames_per_second);
1267 /* XXX need to reset/reinstantiate all LADSPA plugins */
1271 Session::set_block_size (nframes_t nframes)
1273 /* the AudioEngine guarantees
1274 that it will not be called while we are also in
1275 ::process(). It is therefore fine to do things that block
1281 current_block_size = nframes;
1283 ensure_buffers(_scratch_buffers->available());
1285 if (_gain_automation_buffer) {
1286 delete [] _gain_automation_buffer;
1288 _gain_automation_buffer = new gain_t[nframes];
1290 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1292 boost::shared_ptr<RouteList> r = routes.reader ();
1294 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1295 (*i)->set_block_size (nframes);
1298 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1300 (*i)->set_block_size (nframes);
1303 set_worst_io_latencies ();
1308 Session::set_default_fade (float steepness, float fade_msecs)
1311 nframes_t fade_frames;
1313 /* Don't allow fade of less 1 frame */
1315 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1322 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1326 default_fade_msecs = fade_msecs;
1327 default_fade_steepness = steepness;
1330 // jlc, WTF is this!
1331 Glib::RWLock::ReaderLock lm (route_lock);
1332 AudioRegion::set_default_fade (steepness, fade_frames);
1337 /* XXX have to do this at some point */
1338 /* foreach region using default fade, reset, then
1339 refill_all_diskstream_buffers ();
1344 struct RouteSorter {
1345 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1346 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1348 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1351 if (r1->fed_by.empty()) {
1352 if (r2->fed_by.empty()) {
1353 /* no ardour-based connections inbound to either route. just use signal order */
1354 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1356 /* r2 has connections, r1 does not; run r1 early */
1360 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1367 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1369 shared_ptr<Route> r2;
1371 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1372 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1376 /* make a copy of the existing list of routes that feed r1 */
1378 set<shared_ptr<Route> > existing = r1->fed_by;
1380 /* for each route that feeds r1, recurse, marking it as feeding
1384 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1387 /* r2 is a route that feeds r1 which somehow feeds base. mark
1388 base as being fed by r2
1391 rbase->fed_by.insert (r2);
1395 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1399 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1403 /* now recurse, so that we can mark base as being fed by
1404 all routes that feed r2
1407 trace_terminal (r2, rbase);
1414 Session::resort_routes ()
1416 /* don't do anything here with signals emitted
1417 by Routes while we are being destroyed.
1420 if (_state_of_the_state & Deletion) {
1427 RCUWriter<RouteList> writer (routes);
1428 shared_ptr<RouteList> r = writer.get_copy ();
1429 resort_routes_using (r);
1430 /* writer goes out of scope and forces update */
1435 Session::resort_routes_using (shared_ptr<RouteList> r)
1437 RouteList::iterator i, j;
1439 for (i = r->begin(); i != r->end(); ++i) {
1441 (*i)->fed_by.clear ();
1443 for (j = r->begin(); j != r->end(); ++j) {
1445 /* although routes can feed themselves, it will
1446 cause an endless recursive descent if we
1447 detect it. so don't bother checking for
1455 if ((*j)->feeds (*i)) {
1456 (*i)->fed_by.insert (*j);
1461 for (i = r->begin(); i != r->end(); ++i) {
1462 trace_terminal (*i, *i);
1469 cerr << "finished route resort\n";
1471 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1472 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1479 list<boost::shared_ptr<MidiTrack> >
1480 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1482 char track_name[32];
1483 uint32_t track_id = 0;
1485 uint32_t channels_used = 0;
1487 RouteList new_routes;
1488 list<boost::shared_ptr<MidiTrack> > ret;
1490 /* count existing midi tracks */
1493 shared_ptr<RouteList> r = routes.reader ();
1495 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1496 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1497 if (!(*i)->is_hidden()) {
1499 channels_used += (*i)->n_inputs().n_midi();
1507 /* check for duplicate route names, since we might have pre-existing
1508 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1509 save, close,restart,add new route - first named route is now
1517 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1519 if (route_by_name (track_name) == 0) {
1523 } while (track_id < (UINT_MAX-1));
1526 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1528 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1529 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1532 channels_used += track->n_inputs ().n_midi();
1534 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1535 track->set_remote_control_id (ntracks());
1537 new_routes.push_back (track);
1538 ret.push_back (track);
1541 catch (failed_constructor &err) {
1542 error << _("Session: could not create new midi track.") << endmsg;
1543 // XXX should we delete the tracks already created?
1551 if (!new_routes.empty()) {
1552 add_routes (new_routes, false);
1553 save_state (_current_snapshot_name);
1559 list<boost::shared_ptr<AudioTrack> >
1560 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1562 char track_name[32];
1563 uint32_t track_id = 0;
1565 uint32_t channels_used = 0;
1567 RouteList new_routes;
1568 list<boost::shared_ptr<AudioTrack> > ret;
1569 uint32_t control_id;
1571 /* count existing audio tracks */
1574 shared_ptr<RouteList> r = routes.reader ();
1576 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1577 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1578 if (!(*i)->is_hidden()) {
1580 channels_used += (*i)->n_inputs().n_audio();
1586 vector<string> physinputs;
1587 vector<string> physoutputs;
1588 uint32_t nphysical_in;
1589 uint32_t nphysical_out;
1591 _engine.get_physical_outputs (physoutputs);
1592 _engine.get_physical_inputs (physinputs);
1593 control_id = ntracks() + nbusses() + 1;
1597 /* check for duplicate route names, since we might have pre-existing
1598 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1599 save, close,restart,add new route - first named route is now
1607 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1609 if (route_by_name (track_name) == 0) {
1613 } while (track_id < (UINT_MAX-1));
1615 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1616 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1621 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1622 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1627 shared_ptr<AudioTrack> track;
1630 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1632 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1633 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1634 input_channels, output_channels)
1640 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1644 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1645 port = physinputs[(channels_used+x)%nphysical_in];
1648 if (port.length() && track->connect_input (track->input (x), port, this)) {
1654 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1658 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1659 port = physoutputs[(channels_used+x)%nphysical_out];
1660 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1662 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1666 if (port.length() && track->connect_output (track->output (x), port, this)) {
1671 channels_used += track->n_inputs ().n_audio();
1673 track->audio_diskstream()->non_realtime_input_change();
1675 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1676 track->set_remote_control_id (control_id);
1679 new_routes.push_back (track);
1680 ret.push_back (track);
1683 catch (failed_constructor &err) {
1684 error << _("Session: could not create new audio track.") << endmsg;
1687 /* we need to get rid of this, since the track failed to be created */
1688 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1691 RCUWriter<DiskstreamList> writer (diskstreams);
1692 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1693 ds->remove (track->audio_diskstream());
1700 catch (AudioEngine::PortRegistrationFailure& pfe) {
1702 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;
1705 /* we need to get rid of this, since the track failed to be created */
1706 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1709 RCUWriter<DiskstreamList> writer (diskstreams);
1710 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1711 ds->remove (track->audio_diskstream());
1722 if (!new_routes.empty()) {
1723 add_routes (new_routes, false);
1724 save_state (_current_snapshot_name);
1731 Session::set_remote_control_ids ()
1733 RemoteModel m = Config->get_remote_model();
1735 shared_ptr<RouteList> r = routes.reader ();
1737 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1738 if ( MixerOrdered == m) {
1739 long order = (*i)->order_key(N_("signal"));
1740 (*i)->set_remote_control_id( order+1 );
1741 } else if ( EditorOrdered == m) {
1742 long order = (*i)->order_key(N_("editor"));
1743 (*i)->set_remote_control_id( order+1 );
1744 } else if ( UserOrdered == m) {
1745 //do nothing ... only changes to remote id's are initiated by user
1752 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1755 uint32_t bus_id = 1;
1759 uint32_t control_id;
1761 /* count existing audio busses */
1764 shared_ptr<RouteList> r = routes.reader ();
1766 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1767 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1768 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1775 vector<string> physinputs;
1776 vector<string> physoutputs;
1778 _engine.get_physical_outputs (physoutputs);
1779 _engine.get_physical_inputs (physinputs);
1780 control_id = ntracks() + nbusses() + 1;
1785 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1789 if (route_by_name (bus_name) == 0) {
1793 } while (bus_id < (UINT_MAX-1));
1796 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1798 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1799 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1800 input_channels, output_channels)
1805 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1809 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1810 port = physinputs[((n+x)%n_physical_inputs)];
1813 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1818 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1822 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1823 port = physoutputs[((n+x)%n_physical_outputs)];
1824 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1826 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1830 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1835 bus->set_remote_control_id (control_id);
1838 ret.push_back (bus);
1842 catch (failed_constructor &err) {
1843 error << _("Session: could not create new audio route.") << endmsg;
1847 catch (AudioEngine::PortRegistrationFailure& pfe) {
1848 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;
1858 add_routes (ret, false);
1859 save_state (_current_snapshot_name);
1867 Session::add_routes (RouteList& new_routes, bool save)
1870 RCUWriter<RouteList> writer (routes);
1871 shared_ptr<RouteList> r = writer.get_copy ();
1872 r->insert (r->end(), new_routes.begin(), new_routes.end());
1873 resort_routes_using (r);
1876 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1878 boost::weak_ptr<Route> wpr (*x);
1880 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1881 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1882 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1883 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1885 if ((*x)->is_master()) {
1889 if ((*x)->is_control()) {
1890 _control_out = (*x);
1893 add_bundle ((*x)->bundle_for_inputs());
1894 add_bundle ((*x)->bundle_for_outputs());
1897 if (_control_out && IO::connecting_legal) {
1899 vector<string> cports;
1900 uint32_t ni = _control_out->n_inputs().n_audio();
1902 for (uint32_t n = 0; n < ni; ++n) {
1903 cports.push_back (_control_out->input(n)->name());
1906 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1907 (*x)->set_control_outs (cports);
1914 save_state (_current_snapshot_name);
1917 RouteAdded (new_routes); /* EMIT SIGNAL */
1921 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1923 /* need to do this in case we're rolling at the time, to prevent false underruns */
1924 dstream->do_refill_with_alloc ();
1926 dstream->set_block_size (current_block_size);
1929 RCUWriter<DiskstreamList> writer (diskstreams);
1930 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1931 ds->push_back (dstream);
1932 /* writer goes out of scope, copies ds back to main */
1935 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1936 /* this will connect to future changes, and check the current length */
1937 diskstream_playlist_changed (dstream);
1939 dstream->prepare ();
1944 Session::remove_route (shared_ptr<Route> route)
1947 RCUWriter<RouteList> writer (routes);
1948 shared_ptr<RouteList> rs = writer.get_copy ();
1952 /* deleting the master out seems like a dumb
1953 idea, but its more of a UI policy issue
1957 if (route == _master_out) {
1958 _master_out = shared_ptr<Route> ();
1961 if (route == _control_out) {
1962 _control_out = shared_ptr<Route> ();
1964 /* cancel control outs for all routes */
1966 vector<string> empty;
1968 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1969 (*r)->set_control_outs (empty);
1973 update_route_solo_state ();
1975 /* writer goes out of scope, forces route list update */
1979 boost::shared_ptr<Diskstream> ds;
1981 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1982 ds = t->diskstream();
1988 RCUWriter<DiskstreamList> dsl (diskstreams);
1989 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1994 find_current_end ();
1996 update_latency_compensation (false, false);
1999 // We need to disconnect the routes inputs and outputs
2000 route->disconnect_inputs(NULL);
2001 route->disconnect_outputs(NULL);
2003 /* get rid of it from the dead wood collection in the route list manager */
2005 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2009 /* try to cause everyone to drop their references */
2011 route->drop_references ();
2013 /* save the new state of the world */
2015 if (save_state (_current_snapshot_name)) {
2016 save_history (_current_snapshot_name);
2021 Session::route_mute_changed (void* src)
2027 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2029 if (solo_update_disabled) {
2035 boost::shared_ptr<Route> route = wpr.lock ();
2038 /* should not happen */
2039 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2043 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2045 shared_ptr<RouteList> r = routes.reader ();
2047 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2049 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2053 /* don't mess with busses */
2055 if (dynamic_cast<Track*>((*i).get()) == 0) {
2061 /* don't mess with tracks */
2063 if (dynamic_cast<Track*>((*i).get()) != 0) {
2068 if ((*i) != route &&
2069 ((*i)->mix_group () == 0 ||
2070 (*i)->mix_group () != route->mix_group () ||
2071 !route->mix_group ()->is_active())) {
2073 if ((*i)->soloed()) {
2075 /* if its already soloed, and solo latching is enabled,
2076 then leave it as it is.
2079 if (Config->get_solo_latched()) {
2086 solo_update_disabled = true;
2087 (*i)->set_solo (false, src);
2088 solo_update_disabled = false;
2092 bool something_soloed = false;
2093 bool same_thing_soloed = false;
2094 bool signal = false;
2096 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2097 if ((*i)->soloed()) {
2098 something_soloed = true;
2099 if (dynamic_cast<Track*>((*i).get())) {
2101 same_thing_soloed = true;
2106 same_thing_soloed = true;
2114 if (something_soloed != currently_soloing) {
2116 currently_soloing = something_soloed;
2119 modify_solo_mute (is_track, same_thing_soloed);
2122 SoloActive (currently_soloing); /* EMIT SIGNAL */
2125 SoloChanged (); /* EMIT SIGNAL */
2131 Session::update_route_solo_state ()
2134 bool is_track = false;
2135 bool signal = false;
2137 /* caller must hold RouteLock */
2139 /* this is where we actually implement solo by changing
2140 the solo mute setting of each track.
2143 shared_ptr<RouteList> r = routes.reader ();
2145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2146 if ((*i)->soloed()) {
2148 if (dynamic_cast<Track*>((*i).get())) {
2155 if (mute != currently_soloing) {
2157 currently_soloing = mute;
2160 if (!is_track && !mute) {
2162 /* nothing is soloed */
2164 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2165 (*i)->set_solo_mute (false);
2175 modify_solo_mute (is_track, mute);
2178 SoloActive (currently_soloing);
2183 Session::modify_solo_mute (bool is_track, bool mute)
2185 shared_ptr<RouteList> r = routes.reader ();
2187 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2191 /* only alter track solo mute */
2193 if (dynamic_cast<Track*>((*i).get())) {
2194 if ((*i)->soloed()) {
2195 (*i)->set_solo_mute (!mute);
2197 (*i)->set_solo_mute (mute);
2203 /* only alter bus solo mute */
2205 if (!dynamic_cast<Track*>((*i).get())) {
2207 if ((*i)->soloed()) {
2209 (*i)->set_solo_mute (false);
2213 /* don't mute master or control outs
2214 in response to another bus solo
2217 if ((*i) != _master_out &&
2218 (*i) != _control_out) {
2219 (*i)->set_solo_mute (mute);
2230 Session::catch_up_on_solo ()
2232 /* this is called after set_state() to catch the full solo
2233 state, which can't be correctly determined on a per-route
2234 basis, but needs the global overview that only the session
2237 update_route_solo_state();
2241 Session::route_by_name (string name)
2243 shared_ptr<RouteList> r = routes.reader ();
2245 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2246 if ((*i)->name() == name) {
2251 return shared_ptr<Route> ((Route*) 0);
2255 Session::route_by_id (PBD::ID id)
2257 shared_ptr<RouteList> r = routes.reader ();
2259 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2260 if ((*i)->id() == id) {
2265 return shared_ptr<Route> ((Route*) 0);
2269 Session::route_by_remote_id (uint32_t id)
2271 shared_ptr<RouteList> r = routes.reader ();
2273 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2274 if ((*i)->remote_control_id() == id) {
2279 return shared_ptr<Route> ((Route*) 0);
2283 Session::find_current_end ()
2285 if (_state_of_the_state & Loading) {
2289 nframes_t max = get_maximum_extent ();
2291 if (max > end_location->end()) {
2292 end_location->set_end (max);
2294 DurationChanged(); /* EMIT SIGNAL */
2299 Session::get_maximum_extent () const
2304 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2306 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2307 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2308 if ((me = pl->get_maximum_extent()) > max) {
2316 boost::shared_ptr<Diskstream>
2317 Session::diskstream_by_name (string name)
2319 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2321 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2322 if ((*i)->name() == name) {
2327 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2330 boost::shared_ptr<Diskstream>
2331 Session::diskstream_by_id (const PBD::ID& id)
2333 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2335 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2336 if ((*i)->id() == id) {
2341 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2344 /* Region management */
2347 Session::new_region_name (string old)
2349 string::size_type last_period;
2351 string::size_type len = old.length() + 64;
2354 if ((last_period = old.find_last_of ('.')) == string::npos) {
2356 /* no period present - add one explicitly */
2359 last_period = old.length() - 1;
2364 number = atoi (old.substr (last_period+1).c_str());
2368 while (number < (UINT_MAX-1)) {
2370 RegionList::const_iterator i;
2375 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2378 for (i = regions.begin(); i != regions.end(); ++i) {
2379 if (i->second->name() == sbuf) {
2384 if (i == regions.end()) {
2389 if (number != (UINT_MAX-1)) {
2393 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2398 Session::region_name (string& result, string base, bool newlevel) const
2403 assert(base.find("/") == string::npos);
2407 Glib::Mutex::Lock lm (region_lock);
2409 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2417 /* XXX this is going to be slow. optimize me later */
2422 string::size_type pos;
2424 pos = base.find_last_of ('.');
2426 /* pos may be npos, but then we just use entire base */
2428 subbase = base.substr (0, pos);
2432 bool name_taken = true;
2435 Glib::Mutex::Lock lm (region_lock);
2437 for (int n = 1; n < 5000; ++n) {
2440 snprintf (buf, sizeof (buf), ".%d", n);
2445 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2446 if (i->second->name() == result) {
2459 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2467 Session::add_region (boost::shared_ptr<Region> region)
2469 boost::shared_ptr<Region> other;
2473 Glib::Mutex::Lock lm (region_lock);
2475 RegionList::iterator x;
2477 for (x = regions.begin(); x != regions.end(); ++x) {
2481 if (region->region_list_equivalent (other)) {
2486 if (x == regions.end()) {
2488 pair<RegionList::key_type,RegionList::mapped_type> entry;
2490 entry.first = region->id();
2491 entry.second = region;
2493 pair<RegionList::iterator,bool> x = regions.insert (entry);
2505 /* mark dirty because something has changed even if we didn't
2506 add the region to the region list.
2512 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2513 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2514 RegionAdded (region); /* EMIT SIGNAL */
2519 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2521 boost::shared_ptr<Region> region (weak_region.lock ());
2527 if (what_changed & Region::HiddenChanged) {
2528 /* relay hidden changes */
2529 RegionHiddenChange (region);
2534 Session::remove_region (boost::weak_ptr<Region> weak_region)
2536 RegionList::iterator i;
2537 boost::shared_ptr<Region> region (weak_region.lock ());
2543 bool removed = false;
2546 Glib::Mutex::Lock lm (region_lock);
2548 if ((i = regions.find (region->id())) != regions.end()) {
2554 /* mark dirty because something has changed even if we didn't
2555 remove the region from the region list.
2561 RegionRemoved(region); /* EMIT SIGNAL */
2565 boost::shared_ptr<Region>
2566 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2568 RegionList::iterator i;
2569 boost::shared_ptr<Region> region;
2571 Glib::Mutex::Lock lm (region_lock);
2573 for (i = regions.begin(); i != regions.end(); ++i) {
2577 if (region->whole_file()) {
2579 if (child->source_equivalent (region)) {
2585 return boost::shared_ptr<Region> ();
2589 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2591 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2592 (*i)->get_region_list_equivalent_regions (region, result);
2596 Session::destroy_region (boost::shared_ptr<Region> region)
2598 vector<boost::shared_ptr<Source> > srcs;
2601 boost::shared_ptr<AudioRegion> aregion;
2603 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2607 if (aregion->playlist()) {
2608 aregion->playlist()->destroy_region (region);
2611 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2612 srcs.push_back (aregion->source (n));
2616 region->drop_references ();
2618 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2620 if (!(*i)->used()) {
2621 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2624 (afs)->mark_for_remove ();
2627 (*i)->drop_references ();
2629 cerr << "source was not used by any playlist\n";
2637 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2639 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2640 destroy_region (*i);
2646 Session::remove_last_capture ()
2648 list<boost::shared_ptr<Region> > r;
2650 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2652 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2653 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2656 r.insert (r.end(), l.begin(), l.end());
2661 destroy_regions (r);
2663 save_state (_current_snapshot_name);
2669 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2675 /* Source Management */
2677 Session::add_source (boost::shared_ptr<Source> source)
2679 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2680 pair<SourceMap::iterator,bool> result;
2682 entry.first = source->id();
2683 entry.second = source;
2686 Glib::Mutex::Lock lm (source_lock);
2687 result = sources.insert (entry);
2690 if (result.second) {
2691 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2697 Session::remove_source (boost::weak_ptr<Source> src)
2699 SourceMap::iterator i;
2700 boost::shared_ptr<Source> source = src.lock();
2707 Glib::Mutex::Lock lm (source_lock);
2709 if ((i = sources.find (source->id())) != sources.end()) {
2714 if (!_state_of_the_state & InCleanup) {
2716 /* save state so we don't end up with a session file
2717 referring to non-existent sources.
2720 save_state (_current_snapshot_name);
2724 boost::shared_ptr<Source>
2725 Session::source_by_id (const PBD::ID& id)
2727 Glib::Mutex::Lock lm (source_lock);
2728 SourceMap::iterator i;
2729 boost::shared_ptr<Source> source;
2731 if ((i = sources.find (id)) != sources.end()) {
2735 /* XXX search MIDI or other searches here */
2741 boost::shared_ptr<Source>
2742 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2744 Glib::Mutex::Lock lm (source_lock);
2746 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2747 cerr << "comparing " << path << " with " << i->second->name() << endl;
2748 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2750 if (afs && afs->path() == path && chn == afs->channel()) {
2755 return boost::shared_ptr<Source>();
2759 Session::peak_path (Glib::ustring base) const
2761 sys::path peakfile_path(_session_dir->peak_path());
2762 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2763 return peakfile_path.to_string();
2767 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2770 string old_basename = PBD::basename_nosuffix (oldname);
2771 string new_legalized = legalize_for_path (newname);
2773 /* note: we know (or assume) the old path is already valid */
2777 /* destructive file sources have a name of the form:
2779 /path/to/Tnnnn-NAME(%[LR])?.wav
2781 the task here is to replace NAME with the new name.
2784 /* find last slash */
2788 string::size_type slash;
2789 string::size_type dash;
2791 if ((slash = path.find_last_of ('/')) == string::npos) {
2795 dir = path.substr (0, slash+1);
2797 /* '-' is not a legal character for the NAME part of the path */
2799 if ((dash = path.find_last_of ('-')) == string::npos) {
2803 prefix = path.substr (slash+1, dash-(slash+1));
2808 path += new_legalized;
2809 path += ".wav"; /* XXX gag me with a spoon */
2813 /* non-destructive file sources have a name of the form:
2815 /path/to/NAME-nnnnn(%[LR])?.wav
2817 the task here is to replace NAME with the new name.
2822 string::size_type slash;
2823 string::size_type dash;
2824 string::size_type postfix;
2826 /* find last slash */
2828 if ((slash = path.find_last_of ('/')) == string::npos) {
2832 dir = path.substr (0, slash+1);
2834 /* '-' is not a legal character for the NAME part of the path */
2836 if ((dash = path.find_last_of ('-')) == string::npos) {
2840 suffix = path.substr (dash+1);
2842 // Suffix is now everything after the dash. Now we need to eliminate
2843 // the nnnnn part, which is done by either finding a '%' or a '.'
2845 postfix = suffix.find_last_of ("%");
2846 if (postfix == string::npos) {
2847 postfix = suffix.find_last_of ('.');
2850 if (postfix != string::npos) {
2851 suffix = suffix.substr (postfix);
2853 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2857 const uint32_t limit = 10000;
2858 char buf[PATH_MAX+1];
2860 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2862 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2864 if (access (buf, F_OK) != 0) {
2872 error << "FATAL ERROR! Could not find a " << endl;
2881 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2885 char buf[PATH_MAX+1];
2886 const uint32_t limit = 10000;
2890 legalized = legalize_for_path (name);
2892 /* find a "version" of the file name that doesn't exist in
2893 any of the possible directories.
2896 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2898 vector<space_and_path>::iterator i;
2899 uint32_t existing = 0;
2901 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2903 SessionDirectory sdir((*i).path);
2905 spath = sdir.sound_path().to_string();
2909 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2910 } else if (nchan == 2) {
2912 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2914 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2916 } else if (nchan < 26) {
2917 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2919 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2928 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2929 } else if (nchan == 2) {
2931 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2933 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2935 } else if (nchan < 26) {
2936 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2938 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2942 if (sys::exists(buf)) {
2948 if (existing == 0) {
2953 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2955 throw failed_constructor();
2959 /* we now have a unique name for the file, but figure out where to
2965 SessionDirectory sdir(get_best_session_directory_for_new_source ());
2967 spath = sdir.sound_path().to_string();
2970 string::size_type pos = foo.find_last_of ('/');
2972 if (pos == string::npos) {
2975 spath += foo.substr (pos + 1);
2981 boost::shared_ptr<AudioFileSource>
2982 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2984 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2985 return boost::dynamic_pointer_cast<AudioFileSource> (
2986 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2989 // FIXME: _terrible_ code duplication
2991 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
2994 string old_basename = PBD::basename_nosuffix (oldname);
2995 string new_legalized = legalize_for_path (newname);
2997 /* note: we know (or assume) the old path is already valid */
3001 /* destructive file sources have a name of the form:
3003 /path/to/Tnnnn-NAME(%[LR])?.wav
3005 the task here is to replace NAME with the new name.
3008 /* find last slash */
3012 string::size_type slash;
3013 string::size_type dash;
3015 if ((slash = path.find_last_of ('/')) == string::npos) {
3019 dir = path.substr (0, slash+1);
3021 /* '-' is not a legal character for the NAME part of the path */
3023 if ((dash = path.find_last_of ('-')) == string::npos) {
3027 prefix = path.substr (slash+1, dash-(slash+1));
3032 path += new_legalized;
3033 path += ".mid"; /* XXX gag me with a spoon */
3037 /* non-destructive file sources have a name of the form:
3039 /path/to/NAME-nnnnn(%[LR])?.wav
3041 the task here is to replace NAME with the new name.
3046 string::size_type slash;
3047 string::size_type dash;
3048 string::size_type postfix;
3050 /* find last slash */
3052 if ((slash = path.find_last_of ('/')) == string::npos) {
3056 dir = path.substr (0, slash+1);
3058 /* '-' is not a legal character for the NAME part of the path */
3060 if ((dash = path.find_last_of ('-')) == string::npos) {
3064 suffix = path.substr (dash+1);
3066 // Suffix is now everything after the dash. Now we need to eliminate
3067 // the nnnnn part, which is done by either finding a '%' or a '.'
3069 postfix = suffix.find_last_of ("%");
3070 if (postfix == string::npos) {
3071 postfix = suffix.find_last_of ('.');
3074 if (postfix != string::npos) {
3075 suffix = suffix.substr (postfix);
3077 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3081 const uint32_t limit = 10000;
3082 char buf[PATH_MAX+1];
3084 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3086 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3088 if (access (buf, F_OK) != 0) {
3096 error << "FATAL ERROR! Could not find a " << endl;
3105 Session::midi_path_from_name (string name)
3109 char buf[PATH_MAX+1];
3110 const uint32_t limit = 10000;
3114 legalized = legalize_for_path (name);
3116 /* find a "version" of the file name that doesn't exist in
3117 any of the possible directories.
3120 for (cnt = 1; cnt <= limit; ++cnt) {
3122 vector<space_and_path>::iterator i;
3123 uint32_t existing = 0;
3125 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3127 SessionDirectory sdir((*i).path);
3129 sys::path p = sdir.midi_path();
3133 spath = p.to_string();
3135 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3137 if (sys::exists (buf)) {
3142 if (existing == 0) {
3147 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3148 throw failed_constructor();
3152 /* we now have a unique name for the file, but figure out where to
3158 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3160 spath = sdir.midi_path().to_string();
3163 string::size_type pos = foo.find_last_of ('/');
3165 if (pos == string::npos) {
3168 spath += foo.substr (pos + 1);
3174 boost::shared_ptr<MidiSource>
3175 Session::create_midi_source_for_session (MidiDiskstream& ds)
3177 string mpath = midi_path_from_name (ds.name());
3179 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3183 /* Playlist management */
3185 boost::shared_ptr<Playlist>
3186 Session::playlist_by_name (string name)
3188 Glib::Mutex::Lock lm (playlist_lock);
3189 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3190 if ((*i)->name() == name) {
3194 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3195 if ((*i)->name() == name) {
3200 return boost::shared_ptr<Playlist>();
3204 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3206 if (playlist->hidden()) {
3211 Glib::Mutex::Lock lm (playlist_lock);
3212 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3213 playlists.insert (playlists.begin(), playlist);
3214 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3215 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3221 PlaylistAdded (playlist); /* EMIT SIGNAL */
3225 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3228 Glib::Mutex::Lock lm (playlist_lock);
3229 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3232 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3239 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3241 boost::shared_ptr<Playlist> pl(wpl.lock());
3247 PlaylistList::iterator x;
3250 /* its not supposed to be visible */
3255 Glib::Mutex::Lock lm (playlist_lock);
3259 unused_playlists.insert (pl);
3261 if ((x = playlists.find (pl)) != playlists.end()) {
3262 playlists.erase (x);
3268 playlists.insert (pl);
3270 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3271 unused_playlists.erase (x);
3278 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3280 if (_state_of_the_state & Deletion) {
3284 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3291 Glib::Mutex::Lock lm (playlist_lock);
3293 PlaylistList::iterator i;
3295 i = find (playlists.begin(), playlists.end(), playlist);
3296 if (i != playlists.end()) {
3297 playlists.erase (i);
3300 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3301 if (i != unused_playlists.end()) {
3302 unused_playlists.erase (i);
3309 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3313 Session::set_audition (boost::shared_ptr<Region> r)
3315 pending_audition_region = r;
3316 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3317 schedule_butler_transport_work ();
3321 Session::audition_playlist ()
3323 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3324 ev->region.reset ();
3329 Session::non_realtime_set_audition ()
3331 if (!pending_audition_region) {
3332 auditioner->audition_current_playlist ();
3334 auditioner->audition_region (pending_audition_region);
3335 pending_audition_region.reset ();
3337 AuditionActive (true); /* EMIT SIGNAL */
3341 Session::audition_region (boost::shared_ptr<Region> r)
3343 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3349 Session::cancel_audition ()
3351 if (auditioner->active()) {
3352 auditioner->cancel_audition ();
3353 AuditionActive (false); /* EMIT SIGNAL */
3358 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3360 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3364 Session::remove_empty_sounds ()
3366 vector<string> audio_filenames;
3368 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3370 Glib::Mutex::Lock lm (source_lock);
3372 TapeFileMatcher tape_file_matcher;
3374 remove_if (audio_filenames.begin(), audio_filenames.end(),
3375 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3377 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3379 sys::path audio_file_path (_session_dir->sound_path());
3381 audio_file_path /= *i;
3383 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3387 sys::remove (audio_file_path);
3388 const string peakfile = peak_path (audio_file_path.to_string());
3389 sys::remove (peakfile);
3391 catch (const sys::filesystem_error& err)
3393 error << err.what() << endmsg;
3400 Session::is_auditioning () const
3402 /* can be called before we have an auditioner object */
3404 return auditioner->active();
3411 Session::set_all_solo (bool yn)
3413 shared_ptr<RouteList> r = routes.reader ();
3415 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3416 if (!(*i)->is_hidden()) {
3417 (*i)->set_solo (yn, this);
3425 Session::set_all_mute (bool yn)
3427 shared_ptr<RouteList> r = routes.reader ();
3429 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3430 if (!(*i)->is_hidden()) {
3431 (*i)->set_mute (yn, this);
3439 Session::n_diskstreams () const
3443 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3445 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3446 if (!(*i)->hidden()) {
3454 Session::graph_reordered ()
3456 /* don't do this stuff if we are setting up connections
3457 from a set_state() call or creating new tracks.
3460 if (_state_of_the_state & InitialConnecting) {
3464 /* every track/bus asked for this to be handled but it was deferred because
3465 we were connecting. do it now.
3468 request_input_change_handling ();
3472 /* force all diskstreams to update their capture offset values to
3473 reflect any changes in latencies within the graph.
3476 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3478 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3479 (*i)->set_capture_offset ();
3484 Session::record_disenable_all ()
3486 record_enable_change_all (false);
3490 Session::record_enable_all ()
3492 record_enable_change_all (true);
3496 Session::record_enable_change_all (bool yn)
3498 shared_ptr<RouteList> r = routes.reader ();
3500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3503 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3504 at->set_record_enable (yn, this);
3508 /* since we don't keep rec-enable state, don't mark session dirty */
3512 Session::add_processor (Processor* processor)
3515 PortInsert* port_insert;
3516 PluginInsert* plugin_insert;
3518 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3519 _port_inserts.insert (_port_inserts.begin(), port_insert);
3520 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3521 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3522 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3523 _sends.insert (_sends.begin(), send);
3525 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3529 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3535 Session::remove_processor (Processor* processor)
3538 PortInsert* port_insert;
3539 PluginInsert* plugin_insert;
3541 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3542 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3543 if (x != _port_inserts.end()) {
3544 insert_bitset[port_insert->bit_slot()] = false;
3545 _port_inserts.erase (x);
3547 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3548 _plugin_inserts.remove (plugin_insert);
3549 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3550 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3551 if (x != _sends.end()) {
3552 send_bitset[send->bit_slot()] = false;
3556 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3564 Session::available_capture_duration ()
3566 float sample_bytes_on_disk = 4.0; // keep gcc happy
3568 switch (Config->get_native_file_data_format()) {
3570 sample_bytes_on_disk = 4.0;
3574 sample_bytes_on_disk = 3.0;
3578 sample_bytes_on_disk = 2.0;
3582 /* impossible, but keep some gcc versions happy */
3583 fatal << string_compose (_("programming error: %1"),
3584 X_("illegal native file data format"))
3589 double scale = 4096.0 / sample_bytes_on_disk;
3591 if (_total_free_4k_blocks * scale > (double) max_frames) {
3595 return (nframes_t) floor (_total_free_4k_blocks * scale);
3599 Session::add_bundle (shared_ptr<Bundle> bundle)
3602 Glib::Mutex::Lock guard (bundle_lock);
3603 _bundles.push_back (bundle);
3606 BundleAdded (bundle); /* EMIT SIGNAL */
3612 Session::remove_bundle (shared_ptr<Bundle> bundle)
3614 bool removed = false;
3617 Glib::Mutex::Lock guard (bundle_lock);
3618 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3620 if (i != _bundles.end()) {
3627 BundleRemoved (bundle); /* EMIT SIGNAL */
3634 Session::bundle_by_name (string name) const
3636 Glib::Mutex::Lock lm (bundle_lock);
3638 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3639 if ((*i)->name() == name) {
3644 return boost::shared_ptr<Bundle> ();
3647 boost::shared_ptr<Bundle>
3648 Session::bundle_by_ports (std::vector<std::string> const & wanted_ports) const
3650 Glib::Mutex::Lock lm (bundle_lock);
3652 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3653 if ((*i)->nchannels() != wanted_ports.size()) {
3658 for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
3659 Bundle::PortList const p = (*i)->channel_ports (j);
3660 if (p.empty() || p[0] != wanted_ports[j]) {
3661 /* not this bundle */
3668 /* matched bundle */
3673 return boost::shared_ptr<Bundle> ();
3677 Session::tempo_map_changed (Change ignored)
3683 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3684 * the given count with the current block size.
3687 Session::ensure_buffers (ChanCount howmany)
3689 if (current_block_size == 0)
3690 return; // too early? (is this ok?)
3692 // We need at least 2 MIDI scratch buffers to mix/merge
3693 if (howmany.n_midi() < 2)
3694 howmany.set_midi(2);
3696 // FIXME: JACK needs to tell us maximum MIDI buffer size
3697 // Using nasty assumption (max # events == nframes) for now
3698 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3699 _mix_buffers->ensure_buffers(howmany, current_block_size);
3700 _silent_buffers->ensure_buffers(howmany, current_block_size);
3702 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3706 Session::next_insert_id ()
3708 /* this doesn't really loop forever. just think about it */
3711 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3712 if (!insert_bitset[n]) {
3713 insert_bitset[n] = true;
3719 /* none available, so resize and try again */
3721 insert_bitset.resize (insert_bitset.size() + 16, false);
3726 Session::next_send_id ()
3728 /* this doesn't really loop forever. just think about it */
3731 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3732 if (!send_bitset[n]) {
3733 send_bitset[n] = true;
3739 /* none available, so resize and try again */
3741 send_bitset.resize (send_bitset.size() + 16, false);
3746 Session::mark_send_id (uint32_t id)
3748 if (id >= send_bitset.size()) {
3749 send_bitset.resize (id+16, false);
3751 if (send_bitset[id]) {
3752 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3754 send_bitset[id] = true;
3758 Session::mark_insert_id (uint32_t id)
3760 if (id >= insert_bitset.size()) {
3761 insert_bitset.resize (id+16, false);
3763 if (insert_bitset[id]) {
3764 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3766 insert_bitset[id] = true;
3769 /* Named Selection management */
3772 Session::named_selection_by_name (string name)
3774 Glib::Mutex::Lock lm (named_selection_lock);
3775 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3776 if ((*i)->name == name) {
3784 Session::add_named_selection (NamedSelection* named_selection)
3787 Glib::Mutex::Lock lm (named_selection_lock);
3788 named_selections.insert (named_selections.begin(), named_selection);
3791 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3797 NamedSelectionAdded (); /* EMIT SIGNAL */
3801 Session::remove_named_selection (NamedSelection* named_selection)
3803 bool removed = false;
3806 Glib::Mutex::Lock lm (named_selection_lock);
3808 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3810 if (i != named_selections.end()) {
3812 named_selections.erase (i);
3819 NamedSelectionRemoved (); /* EMIT SIGNAL */
3824 Session::reset_native_file_format ()
3826 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3828 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3829 (*i)->reset_write_sources (false);
3834 Session::route_name_unique (string n) const
3836 shared_ptr<RouteList> r = routes.reader ();
3838 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3839 if ((*i)->name() == n) {
3848 Session::n_playlists () const
3850 Glib::Mutex::Lock lm (playlist_lock);
3851 return playlists.size();
3855 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3857 if (!force && howmany <= _npan_buffers) {
3861 if (_pan_automation_buffer) {
3863 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3864 delete [] _pan_automation_buffer[i];
3867 delete [] _pan_automation_buffer;
3870 _pan_automation_buffer = new pan_t*[howmany];
3872 for (uint32_t i = 0; i < howmany; ++i) {
3873 _pan_automation_buffer[i] = new pan_t[nframes];
3876 _npan_buffers = howmany;
3880 Session::freeze (InterThreadInfo& itt)
3882 shared_ptr<RouteList> r = routes.reader ();
3884 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3888 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3889 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3900 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3901 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3904 boost::shared_ptr<Playlist> playlist;
3905 boost::shared_ptr<AudioFileSource> fsource;
3907 char buf[PATH_MAX+1];
3908 ChanCount nchans(track.audio_diskstream()->n_channels());
3910 nframes_t this_chunk;
3913 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3914 const string sound_dir = sdir.sound_path().to_string();
3916 // any bigger than this seems to cause stack overflows in called functions
3917 const nframes_t chunk_size = (128 * 1024)/4;
3919 g_atomic_int_set (&processing_prohibited, 1);
3921 /* call tree *MUST* hold route_lock */
3923 if ((playlist = track.diskstream()->playlist()) == 0) {
3927 /* external redirects will be a problem */
3929 if (track.has_external_redirects()) {
3933 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3935 for (x = 0; x < 99999; ++x) {
3936 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3937 if (access (buf, F_OK) != 0) {
3943 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3948 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3949 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3952 catch (failed_constructor& err) {
3953 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3957 srcs.push_back (fsource);
3960 /* XXX need to flush all redirects */
3965 /* create a set of reasonably-sized buffers */
3966 buffers.ensure_buffers(nchans, chunk_size);
3967 buffers.set_count(nchans);
3969 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3970 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3972 afs->prepare_for_peakfile_writes ();
3975 while (to_do && !itt.cancel) {
3977 this_chunk = min (to_do, chunk_size);
3979 if (track.export_stuff (buffers, start, this_chunk)) {
3984 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3985 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3988 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3994 start += this_chunk;
3995 to_do -= this_chunk;
3997 itt.progress = (float) (1.0 - ((double) to_do / len));
4006 xnow = localtime (&now);
4008 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4009 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4012 afs->update_header (position, *xnow, now);
4013 afs->flush_header ();
4017 /* construct a region to represent the bounced material */
4019 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4020 region_name_from_path (srcs.front()->name(), true));
4027 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4028 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4031 afs->mark_for_remove ();
4034 (*src)->drop_references ();
4038 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4039 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4042 afs->done_with_peakfile_writes ();
4046 g_atomic_int_set (&processing_prohibited, 0);
4052 Session::get_silent_buffers (ChanCount count)
4054 assert(_silent_buffers->available() >= count);
4055 _silent_buffers->set_count(count);
4057 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4058 for (size_t i=0; i < count.get(*t); ++i) {
4059 _silent_buffers->get(*t, i).clear();
4063 return *_silent_buffers;
4067 Session::get_scratch_buffers (ChanCount count)
4069 assert(_scratch_buffers->available() >= count);
4070 _scratch_buffers->set_count(count);
4071 return *_scratch_buffers;
4075 Session::get_mix_buffers (ChanCount count)
4077 assert(_mix_buffers->available() >= count);
4078 _mix_buffers->set_count(count);
4079 return *_mix_buffers;
4083 Session::ntracks () const
4086 shared_ptr<RouteList> r = routes.reader ();
4088 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4089 if (dynamic_cast<Track*> ((*i).get())) {
4098 Session::nbusses () const
4101 shared_ptr<RouteList> r = routes.reader ();
4103 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4104 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4113 Session::add_automation_list(AutomationList *al)
4115 automation_lists[al->id()] = al;
4119 Session::compute_initial_length ()
4121 return _engine.frame_rate() * 60 * 5;
4125 Session::sync_order_keys ()
4127 if (!Config->get_sync_all_route_ordering()) {
4128 /* leave order keys as they are */
4132 boost::shared_ptr<RouteList> r = routes.reader ();
4134 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4135 (*i)->sync_order_keys ();
4138 Route::SyncOrderKeys (); // EMIT SIGNAL
4142 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4144 Glib::Mutex::Lock lm (bundle_lock);
4145 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {