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/io_processor.h>
60 #include <ardour/send.h>
61 #include <ardour/processor.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),
126 _automation_interval (0)
128 if (!eng.connected()) {
129 throw failed_constructor();
132 n_physical_outputs = _engine.n_physical_outputs();
133 n_physical_inputs = _engine.n_physical_inputs();
135 first_stage_init (fullpath, snapshot_name);
137 initialize_start_and_end_locations(0, compute_initial_length ());
140 // try and create a new session directory
143 if(!_session_dir->create()) {
144 // an existing session.
145 // throw a_more_meaningful_exception()
147 throw failed_constructor ();
150 catch(sys::filesystem_error& ex)
153 throw failed_constructor ();
156 if(!create_session_file_from_template (*mix_template)) {
158 throw failed_constructor ();
161 cerr << "Creating session " << fullpath
162 <<" using template" << *mix_template
165 // must be an existing session
168 // ensure the necessary session subdirectories exist
169 // in case the directory structure has changed etc.
170 _session_dir->create();
172 catch(sys::filesystem_error& ex)
175 throw failed_constructor ();
178 cerr << "Loading session " << fullpath
179 << " using snapshot " << snapshot_name << " (1)"
183 if (second_stage_init (false)) {
185 throw failed_constructor ();
188 store_recent_sessions(_name, _path);
190 bool was_dirty = dirty();
192 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
194 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
197 DirtyChanged (); /* EMIT SIGNAL */
201 Session::Session (AudioEngine &eng,
203 string snapshot_name,
204 AutoConnectOption input_ac,
205 AutoConnectOption output_ac,
206 uint32_t control_out_channels,
207 uint32_t master_out_channels,
208 uint32_t requested_physical_in,
209 uint32_t requested_physical_out,
210 nframes_t initial_length)
213 _scratch_buffers(new BufferSet()),
214 _silent_buffers(new BufferSet()),
215 _send_buffers(new BufferSet()),
216 _mmc_port (default_mmc_port),
217 _mtc_port (default_mtc_port),
218 _midi_port (default_midi_port),
219 _session_dir ( new SessionDirectory(fullpath)),
220 pending_events (2048),
221 //midi_requests (16),
222 _send_smpte_update (false),
223 diskstreams (new DiskstreamList),
224 routes (new RouteList),
226 _automation_interval (0)
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;
353 delete _send_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 #ifdef TRACK_DESTRUCTION
489 cerr << "delete bundles\n";
490 #endif /* TRACK_DESTRUCTION */
491 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ) {
492 BundleList::iterator tmp;
502 if (butler_mixdown_buffer) {
503 delete [] butler_mixdown_buffer;
506 if (butler_gain_buffer) {
507 delete [] butler_gain_buffer;
510 Crossfade::set_buffer_size (0);
518 Session::set_worst_io_latencies ()
520 _worst_output_latency = 0;
521 _worst_input_latency = 0;
523 if (!_engine.connected()) {
527 boost::shared_ptr<RouteList> r = routes.reader ();
529 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
530 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
531 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
536 Session::when_engine_running ()
538 string first_physical_output;
540 /* we don't want to run execute this again */
542 set_block_size (_engine.frames_per_cycle());
543 set_frame_rate (_engine.frame_rate());
545 Config->map_parameters (mem_fun (*this, &Session::config_changed));
547 /* every time we reconnect, recompute worst case output latencies */
549 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
551 if (synced_to_jack()) {
552 _engine.transport_stop ();
555 if (Config->get_jack_time_master()) {
556 _engine.transport_locate (_transport_frame);
564 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
566 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
568 /* existing state for Click */
570 if (_click_io->set_state (*child->children().front()) == 0) {
572 _clicking = Config->get_clicking ();
576 error << _("could not setup Click I/O") << endmsg;
582 /* default state for Click */
584 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
586 if (first_physical_output.length()) {
587 if (_click_io->add_output_port (first_physical_output, this)) {
588 // relax, even though its an error
590 _clicking = Config->get_clicking ();
596 catch (failed_constructor& err) {
597 error << _("cannot setup Click I/O") << endmsg;
600 set_worst_io_latencies ();
603 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
606 /* Create a set of Bundle objects that map
607 to the physical outputs currently available
612 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
614 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
616 Bundle* c = new OutputBundle (buf, true);
617 c->set_nchannels (1);
618 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
623 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
625 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
627 Bundle* c = new InputBundle (buf, true);
628 c->set_nchannels (1);
629 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
636 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
638 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
640 Bundle* c = new OutputBundle (buf, true);
641 c->set_nchannels (2);
642 c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
643 c->add_port_to_channel (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
648 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
650 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
652 Bundle* c = new InputBundle (buf, true);
653 c->set_nchannels (2);
654 c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
655 c->add_port_to_channel (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
664 /* create master/control ports */
669 /* force the master to ignore any later call to this */
671 if (_master_out->pending_state_node) {
672 _master_out->ports_became_legal();
675 /* no panner resets till we are through */
677 _master_out->defer_pan_reset ();
679 while (_master_out->n_inputs().n_audio()
680 < _master_out->input_maximum().n_audio()) {
681 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
682 error << _("cannot setup master inputs")
688 while (_master_out->n_outputs().n_audio()
689 < _master_out->output_maximum().n_audio()) {
690 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
691 error << _("cannot setup master outputs")
698 _master_out->allow_pan_reset ();
702 Bundle* c = new OutputBundle (_("Master Out"), true);
704 c->set_nchannels (_master_out->n_inputs().n_total());
705 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
706 c->add_port_to_channel ((int) n, _master_out->input(n)->name());
713 /* catch up on send+insert cnts */
717 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
720 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
721 if (id > insert_cnt) {
729 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
732 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
740 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
742 /* hook us up to the engine */
744 _engine.set_session (this);
749 osc->set_session (*this);
752 _state_of_the_state = Clean;
754 DirtyChanged (); /* EMIT SIGNAL */
758 Session::hookup_io ()
760 /* stop graph reordering notifications from
761 causing resorts, etc.
764 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
766 if (auditioner == 0) {
768 /* we delay creating the auditioner till now because
769 it makes its own connections to ports.
770 the engine has to be running for this to work.
774 auditioner.reset (new Auditioner (*this));
777 catch (failed_constructor& err) {
778 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
782 /* Tell all IO objects to create their ports */
788 vector<string> cports;
790 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
791 if (_control_out->add_input_port ("", this)) {
792 error << _("cannot setup control inputs")
798 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
799 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
800 error << _("cannot set up master outputs")
808 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
810 for (n = 0; n < ni; ++n) {
811 cports.push_back (_control_out->input(n)->name());
814 boost::shared_ptr<RouteList> r = routes.reader ();
816 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
817 (*x)->set_control_outs (cports);
821 /* Tell all IO objects to connect themselves together */
823 IO::enable_connecting ();
825 /* Now reset all panners */
827 IO::reset_panners ();
829 /* Anyone who cares about input state, wake up and do something */
831 IOConnectionsComplete (); /* EMIT SIGNAL */
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
835 /* now handle the whole enchilada as if it was one
841 /* update mixer solo state */
847 Session::playlist_length_changed ()
849 /* we can't just increase end_location->end() if pl->get_maximum_extent()
850 if larger. if the playlist used to be the longest playlist,
851 and its now shorter, we have to decrease end_location->end(). hence,
852 we have to iterate over all diskstreams and check the
853 playlists currently in use.
859 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
861 boost::shared_ptr<Playlist> playlist;
863 if ((playlist = dstream->playlist()) != 0) {
864 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
867 /* see comment in playlist_length_changed () */
872 Session::record_enabling_legal () const
874 /* this used to be in here, but survey says.... we don't need to restrict it */
875 // if (record_status() == Recording) {
879 if (Config->get_all_safe()) {
886 Session::reset_input_monitor_state ()
888 if (transport_rolling()) {
890 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
892 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
893 if ((*i)->record_enabled ()) {
894 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
895 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
899 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
901 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
902 if ((*i)->record_enabled ()) {
903 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
904 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
911 Session::auto_punch_start_changed (Location* location)
913 replace_event (Event::PunchIn, location->start());
915 if (get_record_enabled() && Config->get_punch_in()) {
916 /* capture start has been changed, so save new pending state */
917 save_state ("", true);
922 Session::auto_punch_end_changed (Location* location)
924 nframes_t when_to_stop = location->end();
925 // when_to_stop += _worst_output_latency + _worst_input_latency;
926 replace_event (Event::PunchOut, when_to_stop);
930 Session::auto_punch_changed (Location* location)
932 nframes_t when_to_stop = location->end();
934 replace_event (Event::PunchIn, location->start());
935 //when_to_stop += _worst_output_latency + _worst_input_latency;
936 replace_event (Event::PunchOut, when_to_stop);
940 Session::auto_loop_changed (Location* location)
942 replace_event (Event::AutoLoop, location->end(), location->start());
944 if (transport_rolling() && play_loop) {
946 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
948 if (_transport_frame > location->end()) {
949 // relocate to beginning of loop
950 clear_events (Event::LocateRoll);
952 request_locate (location->start(), true);
955 else if (Config->get_seamless_loop() && !loop_changing) {
957 // schedule a locate-roll to refill the diskstreams at the
959 loop_changing = true;
961 if (location->end() > last_loopend) {
962 clear_events (Event::LocateRoll);
963 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
970 last_loopend = location->end();
975 Session::set_auto_punch_location (Location* location)
979 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
980 auto_punch_start_changed_connection.disconnect();
981 auto_punch_end_changed_connection.disconnect();
982 auto_punch_changed_connection.disconnect();
983 existing->set_auto_punch (false, this);
984 remove_event (existing->start(), Event::PunchIn);
985 clear_events (Event::PunchOut);
986 auto_punch_location_changed (0);
995 if (location->end() <= location->start()) {
996 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1000 auto_punch_start_changed_connection.disconnect();
1001 auto_punch_end_changed_connection.disconnect();
1002 auto_punch_changed_connection.disconnect();
1004 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1005 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1006 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1008 location->set_auto_punch (true, this);
1009 auto_punch_location_changed (location);
1013 Session::set_auto_loop_location (Location* location)
1017 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1018 auto_loop_start_changed_connection.disconnect();
1019 auto_loop_end_changed_connection.disconnect();
1020 auto_loop_changed_connection.disconnect();
1021 existing->set_auto_loop (false, this);
1022 remove_event (existing->end(), Event::AutoLoop);
1023 auto_loop_location_changed (0);
1028 if (location == 0) {
1032 if (location->end() <= location->start()) {
1033 error << _("Session: you can't use a mark for auto loop") << endmsg;
1037 last_loopend = location->end();
1039 auto_loop_start_changed_connection.disconnect();
1040 auto_loop_end_changed_connection.disconnect();
1041 auto_loop_changed_connection.disconnect();
1043 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1044 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1045 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1047 location->set_auto_loop (true, this);
1048 auto_loop_location_changed (location);
1052 Session::locations_added (Location* ignored)
1058 Session::locations_changed ()
1060 _locations.apply (*this, &Session::handle_locations_changed);
1064 Session::handle_locations_changed (Locations::LocationList& locations)
1066 Locations::LocationList::iterator i;
1068 bool set_loop = false;
1069 bool set_punch = false;
1071 for (i = locations.begin(); i != locations.end(); ++i) {
1075 if (location->is_auto_punch()) {
1076 set_auto_punch_location (location);
1079 if (location->is_auto_loop()) {
1080 set_auto_loop_location (location);
1087 set_auto_loop_location (0);
1090 set_auto_punch_location (0);
1097 Session::enable_record ()
1099 /* XXX really atomic compare+swap here */
1100 if (g_atomic_int_get (&_record_status) != Recording) {
1101 g_atomic_int_set (&_record_status, Recording);
1102 _last_record_location = _transport_frame;
1103 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1105 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1106 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1107 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1108 if ((*i)->record_enabled ()) {
1109 (*i)->monitor_input (true);
1114 RecordStateChanged ();
1119 Session::disable_record (bool rt_context, bool force)
1123 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1125 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1126 g_atomic_int_set (&_record_status, Disabled);
1128 if (rs == Recording) {
1129 g_atomic_int_set (&_record_status, Enabled);
1133 // FIXME: timestamp correct? [DR]
1134 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1135 // does this /need/ to be sent in all cases?
1137 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1139 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1140 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1142 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1143 if ((*i)->record_enabled ()) {
1144 (*i)->monitor_input (false);
1149 RecordStateChanged (); /* emit signal */
1152 remove_pending_capture_state ();
1158 Session::step_back_from_record ()
1160 /* XXX really atomic compare+swap here */
1161 if (g_atomic_int_get (&_record_status) == Recording) {
1162 g_atomic_int_set (&_record_status, Enabled);
1164 if (Config->get_monitoring_model() == HardwareMonitoring) {
1165 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1167 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1168 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1169 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1170 (*i)->monitor_input (false);
1178 Session::maybe_enable_record ()
1180 g_atomic_int_set (&_record_status, Enabled);
1182 /* this function is currently called from somewhere other than an RT thread.
1183 this save_state() call therefore doesn't impact anything.
1186 save_state ("", true);
1188 if (_transport_speed) {
1189 if (!Config->get_punch_in()) {
1193 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1194 RecordStateChanged (); /* EMIT SIGNAL */
1201 Session::audible_frame () const
1207 /* the first of these two possible settings for "offset"
1208 mean that the audible frame is stationary until
1209 audio emerges from the latency compensation
1212 the second means that the audible frame is stationary
1213 until audio would emerge from a physical port
1214 in the absence of any plugin latency compensation
1217 offset = _worst_output_latency;
1219 if (offset > current_block_size) {
1220 offset -= current_block_size;
1222 /* XXX is this correct? if we have no external
1223 physical connections and everything is internal
1224 then surely this is zero? still, how
1225 likely is that anyway?
1227 offset = current_block_size;
1230 if (synced_to_jack()) {
1231 tf = _engine.transport_frame();
1233 tf = _transport_frame;
1236 if (_transport_speed == 0) {
1246 if (!non_realtime_work_pending()) {
1250 /* take latency into account */
1259 Session::set_frame_rate (nframes_t frames_per_second)
1261 /** \fn void Session::set_frame_size(nframes_t)
1262 the AudioEngine object that calls this guarantees
1263 that it will not be called while we are also in
1264 ::process(). Its fine to do things that block
1268 _base_frame_rate = frames_per_second;
1272 _automation_interval = ((nframes_t) ceil ((double) frames_per_second * 0.25));
1274 // XXX we need some equivalent to this, somehow
1275 // SndFileSource::setup_standard_crossfades (frames_per_second);
1279 /* XXX need to reset/reinstantiate all LADSPA plugins */
1283 Session::set_block_size (nframes_t nframes)
1285 /* the AudioEngine guarantees
1286 that it will not be called while we are also in
1287 ::process(). It is therefore fine to do things that block
1293 current_block_size = nframes;
1295 ensure_buffers(_scratch_buffers->available());
1297 if (_gain_automation_buffer) {
1298 delete [] _gain_automation_buffer;
1300 _gain_automation_buffer = new gain_t[nframes];
1302 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1304 boost::shared_ptr<RouteList> r = routes.reader ();
1306 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1307 (*i)->set_block_size (nframes);
1310 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1311 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1312 (*i)->set_block_size (nframes);
1315 set_worst_io_latencies ();
1320 Session::set_default_fade (float steepness, float fade_msecs)
1323 nframes_t fade_frames;
1325 /* Don't allow fade of less 1 frame */
1327 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1334 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1338 default_fade_msecs = fade_msecs;
1339 default_fade_steepness = steepness;
1342 // jlc, WTF is this!
1343 Glib::RWLock::ReaderLock lm (route_lock);
1344 AudioRegion::set_default_fade (steepness, fade_frames);
1349 /* XXX have to do this at some point */
1350 /* foreach region using default fade, reset, then
1351 refill_all_diskstream_buffers ();
1356 struct RouteSorter {
1357 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1358 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1360 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1363 if (r1->fed_by.empty()) {
1364 if (r2->fed_by.empty()) {
1365 /* no ardour-based connections inbound to either route. just use signal order */
1366 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1368 /* r2 has connections, r1 does not; run r1 early */
1372 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1379 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1381 shared_ptr<Route> r2;
1383 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1384 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1388 /* make a copy of the existing list of routes that feed r1 */
1390 set<shared_ptr<Route> > existing = r1->fed_by;
1392 /* for each route that feeds r1, recurse, marking it as feeding
1396 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1399 /* r2 is a route that feeds r1 which somehow feeds base. mark
1400 base as being fed by r2
1403 rbase->fed_by.insert (r2);
1407 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1411 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1415 /* now recurse, so that we can mark base as being fed by
1416 all routes that feed r2
1419 trace_terminal (r2, rbase);
1426 Session::resort_routes ()
1428 /* don't do anything here with signals emitted
1429 by Routes while we are being destroyed.
1432 if (_state_of_the_state & Deletion) {
1439 RCUWriter<RouteList> writer (routes);
1440 shared_ptr<RouteList> r = writer.get_copy ();
1441 resort_routes_using (r);
1442 /* writer goes out of scope and forces update */
1447 Session::resort_routes_using (shared_ptr<RouteList> r)
1449 RouteList::iterator i, j;
1451 for (i = r->begin(); i != r->end(); ++i) {
1453 (*i)->fed_by.clear ();
1455 for (j = r->begin(); j != r->end(); ++j) {
1457 /* although routes can feed themselves, it will
1458 cause an endless recursive descent if we
1459 detect it. so don't bother checking for
1467 if ((*j)->feeds (*i)) {
1468 (*i)->fed_by.insert (*j);
1473 for (i = r->begin(); i != r->end(); ++i) {
1474 trace_terminal (*i, *i);
1481 cerr << "finished route resort\n";
1483 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1484 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1491 list<boost::shared_ptr<MidiTrack> >
1492 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1494 char track_name[32];
1495 uint32_t track_id = 0;
1497 uint32_t channels_used = 0;
1499 RouteList new_routes;
1500 list<boost::shared_ptr<MidiTrack> > ret;
1502 /* count existing midi tracks */
1505 shared_ptr<RouteList> r = routes.reader ();
1507 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1508 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1509 if (!(*i)->is_hidden()) {
1511 channels_used += (*i)->n_inputs().n_midi();
1519 /* check for duplicate route names, since we might have pre-existing
1520 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1521 save, close,restart,add new route - first named route is now
1529 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1531 if (route_by_name (track_name) == 0) {
1535 } while (track_id < (UINT_MAX-1));
1538 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1540 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1541 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1544 channels_used += track->n_inputs ().n_midi();
1546 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1547 track->set_remote_control_id (ntracks());
1549 new_routes.push_back (track);
1550 ret.push_back (track);
1553 catch (failed_constructor &err) {
1554 error << _("Session: could not create new midi track.") << endmsg;
1555 // XXX should we delete the tracks already created?
1563 if (!new_routes.empty()) {
1564 add_routes (new_routes, false);
1565 save_state (_current_snapshot_name);
1571 list<boost::shared_ptr<AudioTrack> >
1572 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1574 char track_name[32];
1575 uint32_t track_id = 0;
1577 uint32_t channels_used = 0;
1579 RouteList new_routes;
1580 list<boost::shared_ptr<AudioTrack> > ret;
1581 uint32_t control_id;
1583 /* count existing audio tracks */
1586 shared_ptr<RouteList> r = routes.reader ();
1588 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1589 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1590 if (!(*i)->is_hidden()) {
1592 channels_used += (*i)->n_inputs().n_audio();
1598 vector<string> physinputs;
1599 vector<string> physoutputs;
1600 uint32_t nphysical_in;
1601 uint32_t nphysical_out;
1603 _engine.get_physical_outputs (physoutputs);
1604 _engine.get_physical_inputs (physinputs);
1605 control_id = ntracks() + nbusses() + 1;
1609 /* check for duplicate route names, since we might have pre-existing
1610 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1611 save, close,restart,add new route - first named route is now
1619 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1621 if (route_by_name (track_name) == 0) {
1625 } while (track_id < (UINT_MAX-1));
1627 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1628 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1633 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1634 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1639 shared_ptr<AudioTrack> track;
1642 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1644 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1645 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1646 input_channels, output_channels)
1652 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1656 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1657 port = physinputs[(channels_used+x)%nphysical_in];
1660 if (port.length() && track->connect_input (track->input (x), port, this)) {
1666 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1670 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1671 port = physoutputs[(channels_used+x)%nphysical_out];
1672 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1674 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1678 if (port.length() && track->connect_output (track->output (x), port, this)) {
1683 channels_used += track->n_inputs ().n_audio();
1685 track->audio_diskstream()->non_realtime_input_change();
1687 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1688 track->set_remote_control_id (control_id);
1691 new_routes.push_back (track);
1692 ret.push_back (track);
1695 catch (failed_constructor &err) {
1696 error << _("Session: could not create new audio track.") << endmsg;
1699 /* we need to get rid of this, since the track failed to be created */
1700 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1703 RCUWriter<DiskstreamList> writer (diskstreams);
1704 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1705 ds->remove (track->audio_diskstream());
1712 catch (AudioEngine::PortRegistrationFailure& pfe) {
1714 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;
1717 /* we need to get rid of this, since the track failed to be created */
1718 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1721 RCUWriter<DiskstreamList> writer (diskstreams);
1722 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1723 ds->remove (track->audio_diskstream());
1734 if (!new_routes.empty()) {
1735 add_routes (new_routes, false);
1736 save_state (_current_snapshot_name);
1743 Session::set_remote_control_ids ()
1745 RemoteModel m = Config->get_remote_model();
1747 shared_ptr<RouteList> r = routes.reader ();
1749 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1750 if ( MixerOrdered == m) {
1751 long order = (*i)->order_key(N_("signal"));
1752 (*i)->set_remote_control_id( order+1 );
1753 } else if ( EditorOrdered == m) {
1754 long order = (*i)->order_key(N_("editor"));
1755 (*i)->set_remote_control_id( order+1 );
1756 } else if ( UserOrdered == m) {
1757 //do nothing ... only changes to remote id's are initiated by user
1764 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1767 uint32_t bus_id = 1;
1771 uint32_t control_id;
1773 /* count existing audio busses */
1776 shared_ptr<RouteList> r = routes.reader ();
1778 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1779 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1780 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1787 vector<string> physinputs;
1788 vector<string> physoutputs;
1790 _engine.get_physical_outputs (physoutputs);
1791 _engine.get_physical_inputs (physinputs);
1792 control_id = ntracks() + nbusses() + 1;
1797 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1801 if (route_by_name (bus_name) == 0) {
1805 } while (bus_id < (UINT_MAX-1));
1808 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1810 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1811 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1812 input_channels, output_channels)
1817 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1821 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1822 port = physinputs[((n+x)%n_physical_inputs)];
1825 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1830 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1834 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1835 port = physoutputs[((n+x)%n_physical_outputs)];
1836 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1838 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1842 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1847 bus->set_remote_control_id (control_id);
1850 ret.push_back (bus);
1854 catch (failed_constructor &err) {
1855 error << _("Session: could not create new audio route.") << endmsg;
1859 catch (AudioEngine::PortRegistrationFailure& pfe) {
1860 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;
1870 add_routes (ret, false);
1871 save_state (_current_snapshot_name);
1879 Session::add_routes (RouteList& new_routes, bool save)
1882 RCUWriter<RouteList> writer (routes);
1883 shared_ptr<RouteList> r = writer.get_copy ();
1884 r->insert (r->end(), new_routes.begin(), new_routes.end());
1885 resort_routes_using (r);
1888 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1890 boost::weak_ptr<Route> wpr (*x);
1892 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1893 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1894 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1895 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1897 if ((*x)->is_master()) {
1901 if ((*x)->is_control()) {
1902 _control_out = (*x);
1906 if (_control_out && IO::connecting_legal) {
1908 vector<string> cports;
1909 uint32_t ni = _control_out->n_inputs().n_audio();
1911 for (uint32_t n = 0; n < ni; ++n) {
1912 cports.push_back (_control_out->input(n)->name());
1915 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1916 (*x)->set_control_outs (cports);
1923 save_state (_current_snapshot_name);
1926 RouteAdded (new_routes); /* EMIT SIGNAL */
1930 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1932 /* need to do this in case we're rolling at the time, to prevent false underruns */
1933 dstream->do_refill_with_alloc ();
1935 dstream->set_block_size (current_block_size);
1938 RCUWriter<DiskstreamList> writer (diskstreams);
1939 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1940 ds->push_back (dstream);
1941 /* writer goes out of scope, copies ds back to main */
1944 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1945 /* this will connect to future changes, and check the current length */
1946 diskstream_playlist_changed (dstream);
1948 dstream->prepare ();
1953 Session::remove_route (shared_ptr<Route> route)
1956 RCUWriter<RouteList> writer (routes);
1957 shared_ptr<RouteList> rs = writer.get_copy ();
1961 /* deleting the master out seems like a dumb
1962 idea, but its more of a UI policy issue
1966 if (route == _master_out) {
1967 _master_out = shared_ptr<Route> ();
1970 if (route == _control_out) {
1971 _control_out = shared_ptr<Route> ();
1973 /* cancel control outs for all routes */
1975 vector<string> empty;
1977 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1978 (*r)->set_control_outs (empty);
1982 update_route_solo_state ();
1984 /* writer goes out of scope, forces route list update */
1988 boost::shared_ptr<Diskstream> ds;
1990 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1991 ds = t->diskstream();
1997 RCUWriter<DiskstreamList> dsl (diskstreams);
1998 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2003 find_current_end ();
2005 update_latency_compensation (false, false);
2008 // We need to disconnect the routes inputs and outputs
2009 route->disconnect_inputs(NULL);
2010 route->disconnect_outputs(NULL);
2012 /* get rid of it from the dead wood collection in the route list manager */
2014 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2018 /* try to cause everyone to drop their references */
2020 route->drop_references ();
2022 /* save the new state of the world */
2024 if (save_state (_current_snapshot_name)) {
2025 save_history (_current_snapshot_name);
2030 Session::route_mute_changed (void* src)
2036 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2038 if (solo_update_disabled) {
2044 boost::shared_ptr<Route> route = wpr.lock ();
2047 /* should not happen */
2048 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2052 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2054 shared_ptr<RouteList> r = routes.reader ();
2056 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2058 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2062 /* don't mess with busses */
2064 if (dynamic_cast<Track*>((*i).get()) == 0) {
2070 /* don't mess with tracks */
2072 if (dynamic_cast<Track*>((*i).get()) != 0) {
2077 if ((*i) != route &&
2078 ((*i)->mix_group () == 0 ||
2079 (*i)->mix_group () != route->mix_group () ||
2080 !route->mix_group ()->is_active())) {
2082 if ((*i)->soloed()) {
2084 /* if its already soloed, and solo latching is enabled,
2085 then leave it as it is.
2088 if (Config->get_solo_latched()) {
2095 solo_update_disabled = true;
2096 (*i)->set_solo (false, src);
2097 solo_update_disabled = false;
2101 bool something_soloed = false;
2102 bool same_thing_soloed = false;
2103 bool signal = false;
2105 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2106 if ((*i)->soloed()) {
2107 something_soloed = true;
2108 if (dynamic_cast<Track*>((*i).get())) {
2110 same_thing_soloed = true;
2115 same_thing_soloed = true;
2123 if (something_soloed != currently_soloing) {
2125 currently_soloing = something_soloed;
2128 modify_solo_mute (is_track, same_thing_soloed);
2131 SoloActive (currently_soloing); /* EMIT SIGNAL */
2134 SoloChanged (); /* EMIT SIGNAL */
2140 Session::update_route_solo_state ()
2143 bool is_track = false;
2144 bool signal = false;
2146 /* caller must hold RouteLock */
2148 /* this is where we actually implement solo by changing
2149 the solo mute setting of each track.
2152 shared_ptr<RouteList> r = routes.reader ();
2154 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2155 if ((*i)->soloed()) {
2157 if (dynamic_cast<Track*>((*i).get())) {
2164 if (mute != currently_soloing) {
2166 currently_soloing = mute;
2169 if (!is_track && !mute) {
2171 /* nothing is soloed */
2173 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2174 (*i)->set_solo_mute (false);
2184 modify_solo_mute (is_track, mute);
2187 SoloActive (currently_soloing);
2192 Session::modify_solo_mute (bool is_track, bool mute)
2194 shared_ptr<RouteList> r = routes.reader ();
2196 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2200 /* only alter track solo mute */
2202 if (dynamic_cast<Track*>((*i).get())) {
2203 if ((*i)->soloed()) {
2204 (*i)->set_solo_mute (!mute);
2206 (*i)->set_solo_mute (mute);
2212 /* only alter bus solo mute */
2214 if (!dynamic_cast<Track*>((*i).get())) {
2216 if ((*i)->soloed()) {
2218 (*i)->set_solo_mute (false);
2222 /* don't mute master or control outs
2223 in response to another bus solo
2226 if ((*i) != _master_out &&
2227 (*i) != _control_out) {
2228 (*i)->set_solo_mute (mute);
2239 Session::catch_up_on_solo ()
2241 /* this is called after set_state() to catch the full solo
2242 state, which can't be correctly determined on a per-route
2243 basis, but needs the global overview that only the session
2246 update_route_solo_state();
2250 Session::route_by_name (string name)
2252 shared_ptr<RouteList> r = routes.reader ();
2254 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2255 if ((*i)->name() == name) {
2260 return shared_ptr<Route> ((Route*) 0);
2264 Session::route_by_id (PBD::ID id)
2266 shared_ptr<RouteList> r = routes.reader ();
2268 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2269 if ((*i)->id() == id) {
2274 return shared_ptr<Route> ((Route*) 0);
2278 Session::route_by_remote_id (uint32_t id)
2280 shared_ptr<RouteList> r = routes.reader ();
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2283 if ((*i)->remote_control_id() == id) {
2288 return shared_ptr<Route> ((Route*) 0);
2292 Session::find_current_end ()
2294 if (_state_of_the_state & Loading) {
2298 nframes_t max = get_maximum_extent ();
2300 if (max > end_location->end()) {
2301 end_location->set_end (max);
2303 DurationChanged(); /* EMIT SIGNAL */
2308 Session::get_maximum_extent () const
2313 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2315 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2316 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2317 if ((me = pl->get_maximum_extent()) > max) {
2325 boost::shared_ptr<Diskstream>
2326 Session::diskstream_by_name (string name)
2328 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2330 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2331 if ((*i)->name() == name) {
2336 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2339 boost::shared_ptr<Diskstream>
2340 Session::diskstream_by_id (const PBD::ID& id)
2342 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2344 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2345 if ((*i)->id() == id) {
2350 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2353 /* Region management */
2356 Session::new_region_name (string old)
2358 string::size_type last_period;
2360 string::size_type len = old.length() + 64;
2363 if ((last_period = old.find_last_of ('.')) == string::npos) {
2365 /* no period present - add one explicitly */
2368 last_period = old.length() - 1;
2373 number = atoi (old.substr (last_period+1).c_str());
2377 while (number < (UINT_MAX-1)) {
2379 RegionList::const_iterator i;
2384 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2387 for (i = regions.begin(); i != regions.end(); ++i) {
2388 if (i->second->name() == sbuf) {
2393 if (i == regions.end()) {
2398 if (number != (UINT_MAX-1)) {
2402 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2407 Session::region_name (string& result, string base, bool newlevel) const
2412 assert(base.find("/") == string::npos);
2416 Glib::Mutex::Lock lm (region_lock);
2418 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2426 /* XXX this is going to be slow. optimize me later */
2431 string::size_type pos;
2433 pos = base.find_last_of ('.');
2435 /* pos may be npos, but then we just use entire base */
2437 subbase = base.substr (0, pos);
2441 bool name_taken = true;
2444 Glib::Mutex::Lock lm (region_lock);
2446 for (int n = 1; n < 5000; ++n) {
2449 snprintf (buf, sizeof (buf), ".%d", n);
2454 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2455 if (i->second->name() == result) {
2468 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2476 Session::add_region (boost::shared_ptr<Region> region)
2478 boost::shared_ptr<Region> other;
2482 Glib::Mutex::Lock lm (region_lock);
2484 RegionList::iterator x;
2486 for (x = regions.begin(); x != regions.end(); ++x) {
2490 if (region->region_list_equivalent (other)) {
2495 if (x == regions.end()) {
2497 pair<RegionList::key_type,RegionList::mapped_type> entry;
2499 entry.first = region->id();
2500 entry.second = region;
2502 pair<RegionList::iterator,bool> x = regions.insert (entry);
2514 /* mark dirty because something has changed even if we didn't
2515 add the region to the region list.
2521 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2522 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2523 RegionAdded (region); /* EMIT SIGNAL */
2528 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2530 boost::shared_ptr<Region> region (weak_region.lock ());
2536 if (what_changed & Region::HiddenChanged) {
2537 /* relay hidden changes */
2538 RegionHiddenChange (region);
2543 Session::remove_region (boost::weak_ptr<Region> weak_region)
2545 RegionList::iterator i;
2546 boost::shared_ptr<Region> region (weak_region.lock ());
2552 bool removed = false;
2555 Glib::Mutex::Lock lm (region_lock);
2557 if ((i = regions.find (region->id())) != regions.end()) {
2563 /* mark dirty because something has changed even if we didn't
2564 remove the region from the region list.
2570 RegionRemoved(region); /* EMIT SIGNAL */
2574 boost::shared_ptr<Region>
2575 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2577 RegionList::iterator i;
2578 boost::shared_ptr<Region> region;
2580 Glib::Mutex::Lock lm (region_lock);
2582 for (i = regions.begin(); i != regions.end(); ++i) {
2586 if (region->whole_file()) {
2588 if (child->source_equivalent (region)) {
2594 return boost::shared_ptr<Region> ();
2598 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2600 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2601 (*i)->get_region_list_equivalent_regions (region, result);
2605 Session::destroy_region (boost::shared_ptr<Region> region)
2607 vector<boost::shared_ptr<Source> > srcs;
2610 boost::shared_ptr<AudioRegion> aregion;
2612 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2616 if (aregion->playlist()) {
2617 aregion->playlist()->destroy_region (region);
2620 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2621 srcs.push_back (aregion->source (n));
2625 region->drop_references ();
2627 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2629 if (!(*i)->used()) {
2630 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2633 (afs)->mark_for_remove ();
2636 (*i)->drop_references ();
2638 cerr << "source was not used by any playlist\n";
2646 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2648 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2649 destroy_region (*i);
2655 Session::remove_last_capture ()
2657 list<boost::shared_ptr<Region> > r;
2659 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2661 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2662 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2665 r.insert (r.end(), l.begin(), l.end());
2670 destroy_regions (r);
2672 save_state (_current_snapshot_name);
2678 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2684 /* Source Management */
2686 Session::add_source (boost::shared_ptr<Source> source)
2688 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2689 pair<SourceMap::iterator,bool> result;
2691 entry.first = source->id();
2692 entry.second = source;
2695 Glib::Mutex::Lock lm (source_lock);
2696 result = sources.insert (entry);
2699 if (result.second) {
2700 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2706 Session::remove_source (boost::weak_ptr<Source> src)
2708 SourceMap::iterator i;
2709 boost::shared_ptr<Source> source = src.lock();
2716 Glib::Mutex::Lock lm (source_lock);
2719 Glib::Mutex::Lock lm (source_lock);
2721 if ((i = sources.find (source->id())) != sources.end()) {
2727 if (!_state_of_the_state & InCleanup) {
2729 /* save state so we don't end up with a session file
2730 referring to non-existent sources.
2733 save_state (_current_snapshot_name);
2737 boost::shared_ptr<Source>
2738 Session::source_by_id (const PBD::ID& id)
2740 Glib::Mutex::Lock lm (source_lock);
2741 SourceMap::iterator i;
2742 boost::shared_ptr<Source> source;
2744 if ((i = sources.find (id)) != sources.end()) {
2748 /* XXX search MIDI or other searches here */
2754 boost::shared_ptr<Source>
2755 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2757 Glib::Mutex::Lock lm (source_lock);
2759 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2760 cerr << "comparing " << path << " with " << i->second->name() << endl;
2761 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2763 if (afs && afs->path() == path && chn == afs->channel()) {
2768 return boost::shared_ptr<Source>();
2772 Session::peak_path_from_audio_path (string audio_path) const
2774 sys::path peakfile_path(_session_dir->peak_path());
2776 peakfile_path /= basename_nosuffix (audio_path) + peakfile_suffix;
2778 return peakfile_path.to_string();
2782 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2785 string old_basename = PBD::basename_nosuffix (oldname);
2786 string new_legalized = legalize_for_path (newname);
2788 /* note: we know (or assume) the old path is already valid */
2792 /* destructive file sources have a name of the form:
2794 /path/to/Tnnnn-NAME(%[LR])?.wav
2796 the task here is to replace NAME with the new name.
2799 /* find last slash */
2803 string::size_type slash;
2804 string::size_type dash;
2806 if ((slash = path.find_last_of ('/')) == string::npos) {
2810 dir = path.substr (0, slash+1);
2812 /* '-' is not a legal character for the NAME part of the path */
2814 if ((dash = path.find_last_of ('-')) == string::npos) {
2818 prefix = path.substr (slash+1, dash-(slash+1));
2823 path += new_legalized;
2824 path += ".wav"; /* XXX gag me with a spoon */
2828 /* non-destructive file sources have a name of the form:
2830 /path/to/NAME-nnnnn(%[LR])?.wav
2832 the task here is to replace NAME with the new name.
2837 string::size_type slash;
2838 string::size_type dash;
2839 string::size_type postfix;
2841 /* find last slash */
2843 if ((slash = path.find_last_of ('/')) == string::npos) {
2847 dir = path.substr (0, slash+1);
2849 /* '-' is not a legal character for the NAME part of the path */
2851 if ((dash = path.find_last_of ('-')) == string::npos) {
2855 suffix = path.substr (dash+1);
2857 // Suffix is now everything after the dash. Now we need to eliminate
2858 // the nnnnn part, which is done by either finding a '%' or a '.'
2860 postfix = suffix.find_last_of ("%");
2861 if (postfix == string::npos) {
2862 postfix = suffix.find_last_of ('.');
2865 if (postfix != string::npos) {
2866 suffix = suffix.substr (postfix);
2868 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2872 const uint32_t limit = 10000;
2873 char buf[PATH_MAX+1];
2875 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2877 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2879 if (access (buf, F_OK) != 0) {
2887 error << "FATAL ERROR! Could not find a " << endl;
2896 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2900 char buf[PATH_MAX+1];
2901 const uint32_t limit = 10000;
2905 legalized = legalize_for_path (name);
2907 /* find a "version" of the file name that doesn't exist in
2908 any of the possible directories.
2911 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2913 vector<space_and_path>::iterator i;
2914 uint32_t existing = 0;
2916 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2918 SessionDirectory sdir((*i).path);
2920 spath = sdir.sound_path().to_string();
2924 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2925 } else if (nchan == 2) {
2927 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2929 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2931 } else if (nchan < 26) {
2932 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2934 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2943 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2944 } else if (nchan == 2) {
2946 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2948 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2950 } else if (nchan < 26) {
2951 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2953 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2957 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2963 if (existing == 0) {
2968 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2970 throw failed_constructor();
2974 /* we now have a unique name for the file, but figure out where to
2980 SessionDirectory sdir(get_best_session_directory_for_new_source ());
2982 spath = sdir.sound_path().to_string();
2985 string::size_type pos = foo.find_last_of ('/');
2987 if (pos == string::npos) {
2990 spath += foo.substr (pos + 1);
2996 boost::shared_ptr<AudioFileSource>
2997 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2999 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3000 return boost::dynamic_pointer_cast<AudioFileSource> (
3001 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3004 // FIXME: _terrible_ code duplication
3006 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3009 string old_basename = PBD::basename_nosuffix (oldname);
3010 string new_legalized = legalize_for_path (newname);
3012 /* note: we know (or assume) the old path is already valid */
3016 /* destructive file sources have a name of the form:
3018 /path/to/Tnnnn-NAME(%[LR])?.wav
3020 the task here is to replace NAME with the new name.
3023 /* find last slash */
3027 string::size_type slash;
3028 string::size_type dash;
3030 if ((slash = path.find_last_of ('/')) == string::npos) {
3034 dir = path.substr (0, slash+1);
3036 /* '-' is not a legal character for the NAME part of the path */
3038 if ((dash = path.find_last_of ('-')) == string::npos) {
3042 prefix = path.substr (slash+1, dash-(slash+1));
3047 path += new_legalized;
3048 path += ".mid"; /* XXX gag me with a spoon */
3052 /* non-destructive file sources have a name of the form:
3054 /path/to/NAME-nnnnn(%[LR])?.wav
3056 the task here is to replace NAME with the new name.
3061 string::size_type slash;
3062 string::size_type dash;
3063 string::size_type postfix;
3065 /* find last slash */
3067 if ((slash = path.find_last_of ('/')) == string::npos) {
3071 dir = path.substr (0, slash+1);
3073 /* '-' is not a legal character for the NAME part of the path */
3075 if ((dash = path.find_last_of ('-')) == string::npos) {
3079 suffix = path.substr (dash+1);
3081 // Suffix is now everything after the dash. Now we need to eliminate
3082 // the nnnnn part, which is done by either finding a '%' or a '.'
3084 postfix = suffix.find_last_of ("%");
3085 if (postfix == string::npos) {
3086 postfix = suffix.find_last_of ('.');
3089 if (postfix != string::npos) {
3090 suffix = suffix.substr (postfix);
3092 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3096 const uint32_t limit = 10000;
3097 char buf[PATH_MAX+1];
3099 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3101 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3103 if (access (buf, F_OK) != 0) {
3111 error << "FATAL ERROR! Could not find a " << endl;
3120 Session::midi_path_from_name (string name)
3124 char buf[PATH_MAX+1];
3125 const uint32_t limit = 10000;
3129 legalized = legalize_for_path (name);
3131 /* find a "version" of the file name that doesn't exist in
3132 any of the possible directories.
3135 for (cnt = 1; cnt <= limit; ++cnt) {
3137 vector<space_and_path>::iterator i;
3138 uint32_t existing = 0;
3140 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3142 SessionDirectory sdir((*i).path);
3144 sys::path p = sdir.midi_path();
3148 spath = p.to_string();
3150 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3152 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3157 if (existing == 0) {
3162 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3163 throw failed_constructor();
3167 /* we now have a unique name for the file, but figure out where to
3173 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3175 spath = sdir.midi_path().to_string();
3178 string::size_type pos = foo.find_last_of ('/');
3180 if (pos == string::npos) {
3183 spath += foo.substr (pos + 1);
3189 boost::shared_ptr<MidiSource>
3190 Session::create_midi_source_for_session (MidiDiskstream& ds)
3192 string mpath = midi_path_from_name (ds.name());
3194 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3198 /* Playlist management */
3200 boost::shared_ptr<Playlist>
3201 Session::playlist_by_name (string name)
3203 Glib::Mutex::Lock lm (playlist_lock);
3204 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3205 if ((*i)->name() == name) {
3209 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3210 if ((*i)->name() == name) {
3215 return boost::shared_ptr<Playlist>();
3219 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3221 if (playlist->hidden()) {
3226 Glib::Mutex::Lock lm (playlist_lock);
3227 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3228 playlists.insert (playlists.begin(), playlist);
3229 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3230 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3236 PlaylistAdded (playlist); /* EMIT SIGNAL */
3240 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3243 Glib::Mutex::Lock lm (playlist_lock);
3244 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3247 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3254 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3256 boost::shared_ptr<Playlist> pl(wpl.lock());
3262 PlaylistList::iterator x;
3265 /* its not supposed to be visible */
3270 Glib::Mutex::Lock lm (playlist_lock);
3274 unused_playlists.insert (pl);
3276 if ((x = playlists.find (pl)) != playlists.end()) {
3277 playlists.erase (x);
3283 playlists.insert (pl);
3285 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3286 unused_playlists.erase (x);
3293 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3295 if (_state_of_the_state & Deletion) {
3299 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3306 Glib::Mutex::Lock lm (playlist_lock);
3308 PlaylistList::iterator i;
3310 i = find (playlists.begin(), playlists.end(), playlist);
3311 if (i != playlists.end()) {
3312 playlists.erase (i);
3315 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3316 if (i != unused_playlists.end()) {
3317 unused_playlists.erase (i);
3324 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3328 Session::set_audition (boost::shared_ptr<Region> r)
3330 pending_audition_region = r;
3331 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3332 schedule_butler_transport_work ();
3336 Session::audition_playlist ()
3338 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3339 ev->region.reset ();
3344 Session::non_realtime_set_audition ()
3346 if (!pending_audition_region) {
3347 auditioner->audition_current_playlist ();
3349 auditioner->audition_region (pending_audition_region);
3350 pending_audition_region.reset ();
3352 AuditionActive (true); /* EMIT SIGNAL */
3356 Session::audition_region (boost::shared_ptr<Region> r)
3358 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3364 Session::cancel_audition ()
3366 if (auditioner->active()) {
3367 auditioner->cancel_audition ();
3368 AuditionActive (false); /* EMIT SIGNAL */
3373 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3375 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3379 Session::remove_empty_sounds ()
3381 PathScanner scanner;
3383 vector<string *>* possible_audiofiles = scanner (_session_dir->sound_path().to_string (),
3384 Config->get_possible_audio_file_regexp (), false, true);
3386 Glib::Mutex::Lock lm (source_lock);
3388 regex_t compiled_tape_track_pattern;
3391 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3395 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3397 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3401 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3403 /* never remove files that appear to be a tape track */
3405 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3410 if (AudioFileSource::is_empty (*this, *(*i))) {
3412 unlink ((*i)->c_str());
3414 string peak_path = peak_path_from_audio_path (**i);
3415 unlink (peak_path.c_str());
3421 delete possible_audiofiles;
3425 Session::is_auditioning () const
3427 /* can be called before we have an auditioner object */
3429 return auditioner->active();
3436 Session::set_all_solo (bool yn)
3438 shared_ptr<RouteList> r = routes.reader ();
3440 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3441 if (!(*i)->is_hidden()) {
3442 (*i)->set_solo (yn, this);
3450 Session::set_all_mute (bool yn)
3452 shared_ptr<RouteList> r = routes.reader ();
3454 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3455 if (!(*i)->is_hidden()) {
3456 (*i)->set_mute (yn, this);
3464 Session::n_diskstreams () const
3468 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3470 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3471 if (!(*i)->hidden()) {
3479 Session::graph_reordered ()
3481 /* don't do this stuff if we are setting up connections
3482 from a set_state() call or creating new tracks.
3485 if (_state_of_the_state & InitialConnecting) {
3489 /* every track/bus asked for this to be handled but it was deferred because
3490 we were connecting. do it now.
3493 request_input_change_handling ();
3497 /* force all diskstreams to update their capture offset values to
3498 reflect any changes in latencies within the graph.
3501 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3503 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3504 (*i)->set_capture_offset ();
3509 Session::record_disenable_all ()
3511 record_enable_change_all (false);
3515 Session::record_enable_all ()
3517 record_enable_change_all (true);
3521 Session::record_enable_change_all (bool yn)
3523 shared_ptr<RouteList> r = routes.reader ();
3525 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3528 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3529 at->set_record_enable (yn, this);
3533 /* since we don't keep rec-enable state, don't mark session dirty */
3537 Session::add_processor (Processor* processor)
3540 PortInsert* port_insert;
3541 PluginInsert* plugin_insert;
3543 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3544 _port_inserts.insert (_port_inserts.begin(), port_insert);
3545 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3546 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3547 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3548 _sends.insert (_sends.begin(), send);
3550 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3554 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3560 Session::remove_processor (Processor* processor)
3563 PortInsert* port_insert;
3564 PluginInsert* plugin_insert;
3566 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3567 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3568 if (x != _port_inserts.end()) {
3569 insert_bitset[port_insert->bit_slot()] = false;
3570 _port_inserts.erase (x);
3572 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3573 _plugin_inserts.remove (plugin_insert);
3574 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3575 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3576 if (x != _sends.end()) {
3577 send_bitset[send->bit_slot()] = false;
3581 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3589 Session::available_capture_duration ()
3591 float sample_bytes_on_disk = 4.0; // keep gcc happy
3593 switch (Config->get_native_file_data_format()) {
3595 sample_bytes_on_disk = 4.0;
3599 sample_bytes_on_disk = 3.0;
3603 /* impossible, but keep some gcc versions happy */
3604 fatal << string_compose (_("programming error: %1"),
3605 X_("illegal native file data format"))
3610 double scale = 4096.0 / sample_bytes_on_disk;
3612 if (_total_free_4k_blocks * scale > (double) max_frames) {
3616 return (nframes_t) floor (_total_free_4k_blocks * scale);
3620 Session::add_bundle (ARDOUR::Bundle* bundle)
3623 Glib::Mutex::Lock guard (bundle_lock);
3624 _bundles.push_back (bundle);
3627 BundleAdded (bundle); /* EMIT SIGNAL */
3633 Session::remove_bundle (ARDOUR::Bundle* bundle)
3635 bool removed = false;
3638 Glib::Mutex::Lock guard (bundle_lock);
3639 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3641 if (i != _bundles.end()) {
3648 BundleRemoved (bundle); /* EMIT SIGNAL */
3655 Session::bundle_by_name (string name) const
3657 Glib::Mutex::Lock lm (bundle_lock);
3659 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3660 if ((*i)->name() == name) {
3669 Session::tempo_map_changed (Change ignored)
3675 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3676 * the given count with the current block size.
3679 Session::ensure_buffers (ChanCount howmany)
3681 if (current_block_size == 0)
3682 return; // too early? (is this ok?)
3684 // We need at least 1 MIDI scratch buffer to mix/merge
3685 if (howmany.n_midi() < 1)
3686 howmany.set_midi(1);
3688 // FIXME: JACK needs to tell us maximum MIDI buffer size
3689 // Using nasty assumption (max # events == nframes) for now
3690 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3691 _send_buffers->ensure_buffers(howmany, current_block_size);
3692 _silent_buffers->ensure_buffers(howmany, current_block_size);
3694 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3698 Session::next_insert_id ()
3700 /* this doesn't really loop forever. just think about it */
3703 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3704 if (!insert_bitset[n]) {
3705 insert_bitset[n] = true;
3711 /* none available, so resize and try again */
3713 insert_bitset.resize (insert_bitset.size() + 16, false);
3718 Session::next_send_id ()
3720 /* this doesn't really loop forever. just think about it */
3723 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3724 if (!send_bitset[n]) {
3725 send_bitset[n] = true;
3731 /* none available, so resize and try again */
3733 send_bitset.resize (send_bitset.size() + 16, false);
3738 Session::mark_send_id (uint32_t id)
3740 if (id >= send_bitset.size()) {
3741 send_bitset.resize (id+16, false);
3743 if (send_bitset[id]) {
3744 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3746 send_bitset[id] = true;
3750 Session::mark_insert_id (uint32_t id)
3752 if (id >= insert_bitset.size()) {
3753 insert_bitset.resize (id+16, false);
3755 if (insert_bitset[id]) {
3756 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3758 insert_bitset[id] = true;
3761 /* Named Selection management */
3764 Session::named_selection_by_name (string name)
3766 Glib::Mutex::Lock lm (named_selection_lock);
3767 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3768 if ((*i)->name == name) {
3776 Session::add_named_selection (NamedSelection* named_selection)
3779 Glib::Mutex::Lock lm (named_selection_lock);
3780 named_selections.insert (named_selections.begin(), named_selection);
3783 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3789 NamedSelectionAdded (); /* EMIT SIGNAL */
3793 Session::remove_named_selection (NamedSelection* named_selection)
3795 bool removed = false;
3798 Glib::Mutex::Lock lm (named_selection_lock);
3800 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3802 if (i != named_selections.end()) {
3804 named_selections.erase (i);
3811 NamedSelectionRemoved (); /* EMIT SIGNAL */
3816 Session::reset_native_file_format ()
3818 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3820 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3821 (*i)->reset_write_sources (false);
3826 Session::route_name_unique (string n) const
3828 shared_ptr<RouteList> r = routes.reader ();
3830 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3831 if ((*i)->name() == n) {
3840 Session::n_playlists () const
3842 Glib::Mutex::Lock lm (playlist_lock);
3843 return playlists.size();
3847 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3849 if (!force && howmany <= _npan_buffers) {
3853 if (_pan_automation_buffer) {
3855 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3856 delete [] _pan_automation_buffer[i];
3859 delete [] _pan_automation_buffer;
3862 _pan_automation_buffer = new pan_t*[howmany];
3864 for (uint32_t i = 0; i < howmany; ++i) {
3865 _pan_automation_buffer[i] = new pan_t[nframes];
3868 _npan_buffers = howmany;
3872 Session::freeze (InterThreadInfo& itt)
3874 shared_ptr<RouteList> r = routes.reader ();
3876 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3880 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3881 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3892 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3893 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3896 boost::shared_ptr<Playlist> playlist;
3897 boost::shared_ptr<AudioFileSource> fsource;
3899 char buf[PATH_MAX+1];
3900 ChanCount nchans(track.audio_diskstream()->n_channels());
3902 nframes_t this_chunk;
3905 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3906 const string sound_dir = sdir.sound_path().to_string();
3908 // any bigger than this seems to cause stack overflows in called functions
3909 const nframes_t chunk_size = (128 * 1024)/4;
3911 g_atomic_int_set (&processing_prohibited, 1);
3913 /* call tree *MUST* hold route_lock */
3915 if ((playlist = track.diskstream()->playlist()) == 0) {
3919 /* external redirects will be a problem */
3921 if (track.has_external_redirects()) {
3925 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3927 for (x = 0; x < 99999; ++x) {
3928 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3929 if (access (buf, F_OK) != 0) {
3935 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3940 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3941 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3944 catch (failed_constructor& err) {
3945 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3949 srcs.push_back (fsource);
3952 /* XXX need to flush all redirects */
3957 /* create a set of reasonably-sized buffers */
3958 buffers.ensure_buffers(nchans, chunk_size);
3959 buffers.set_count(nchans);
3961 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3962 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3964 afs->prepare_for_peakfile_writes ();
3967 while (to_do && !itt.cancel) {
3969 this_chunk = min (to_do, chunk_size);
3971 if (track.export_stuff (buffers, start, this_chunk)) {
3976 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3977 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3980 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3986 start += this_chunk;
3987 to_do -= this_chunk;
3989 itt.progress = (float) (1.0 - ((double) to_do / len));
3998 xnow = localtime (&now);
4000 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4001 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4004 afs->update_header (position, *xnow, now);
4005 afs->flush_header ();
4009 /* construct a region to represent the bounced material */
4011 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4012 region_name_from_path (srcs.front()->name(), true));
4019 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4020 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4023 afs->mark_for_remove ();
4026 (*src)->drop_references ();
4030 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4031 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4034 afs->done_with_peakfile_writes ();
4038 g_atomic_int_set (&processing_prohibited, 0);
4044 Session::get_silent_buffers (ChanCount count)
4046 assert(_silent_buffers->available() >= count);
4047 _silent_buffers->set_count(count);
4049 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4050 for (size_t i=0; i < count.get(*t); ++i) {
4051 _silent_buffers->get(*t, i).clear();
4055 return *_silent_buffers;
4059 Session::get_scratch_buffers (ChanCount count)
4061 assert(_scratch_buffers->available() >= count);
4062 _scratch_buffers->set_count(count);
4063 return *_scratch_buffers;
4067 Session::get_send_buffers (ChanCount count)
4069 assert(_send_buffers->available() >= count);
4070 _send_buffers->set_count(count);
4071 return *_send_buffers;
4075 Session::ntracks () const
4078 shared_ptr<RouteList> r = routes.reader ();
4080 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4081 if (dynamic_cast<Track*> ((*i).get())) {
4090 Session::nbusses () const
4093 shared_ptr<RouteList> r = routes.reader ();
4095 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4096 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4105 Session::add_automation_list(AutomationList *al)
4107 automation_lists[al->id()] = al;
4111 Session::compute_initial_length ()
4113 return _engine.frame_rate() * 60 * 5;