2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/utils.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/midi_diskstream.h>
53 #include <ardour/midi_playlist.h>
54 #include <ardour/midi_region.h>
55 #include <ardour/smf_source.h>
56 #include <ardour/auditioner.h>
57 #include <ardour/recent_sessions.h>
58 #include <ardour/redirect.h>
59 #include <ardour/send.h>
60 #include <ardour/insert.h>
61 #include <ardour/connection.h>
62 #include <ardour/slave.h>
63 #include <ardour/tempo.h>
64 #include <ardour/audio_track.h>
65 #include <ardour/midi_track.h>
66 #include <ardour/cycle_timer.h>
67 #include <ardour/named_selection.h>
68 #include <ardour/crossfade.h>
69 #include <ardour/playlist.h>
70 #include <ardour/click.h>
71 #include <ardour/data_type.h>
72 #include <ardour/buffer_set.h>
73 #include <ardour/source_factory.h>
74 #include <ardour/region_factory.h>
77 #include <ardour/osc.h>
83 using namespace ARDOUR;
85 using boost::shared_ptr;
88 static const int CPU_CACHE_ALIGN = 64;
90 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
93 const char* Session::_template_suffix = X_(".template");
94 const char* Session::_statefile_suffix = X_(".ardour");
95 const char* Session::_pending_suffix = X_(".pending");
96 const char* Session::old_sound_dir_name = X_("sounds");
97 const char* Session::sound_dir_name = X_("audiofiles");
98 const char* Session::peak_dir_name = X_("peaks");
99 const char* Session::dead_sound_dir_name = X_("dead_sounds");
100 const char* Session::interchange_dir_name = X_("interchange");
101 const char* Session::export_dir_name = X_("export");
103 sigc::signal<int> Session::AskAboutPendingState;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
111 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
114 char buf[PATH_MAX+1];
118 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
119 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
125 /* check to see if it exists, and what it is */
127 if (stat (str.c_str(), &statbuf)) {
128 if (errno == ENOENT) {
131 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
139 /* it exists, so it must either be the name
140 of the directory, or the name of the statefile
144 if (S_ISDIR (statbuf.st_mode)) {
146 string::size_type slash = str.find_last_of ('/');
148 if (slash == string::npos) {
150 /* a subdirectory of cwd, so statefile should be ... */
156 tmp += _statefile_suffix;
160 if (stat (tmp.c_str(), &statbuf)) {
161 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
171 /* some directory someplace in the filesystem.
172 the snapshot name is the directory name
177 snapshot = str.substr (slash+1);
181 } else if (S_ISREG (statbuf.st_mode)) {
183 string::size_type slash = str.find_last_of ('/');
184 string::size_type suffix;
186 /* remove the suffix */
188 if (slash != string::npos) {
189 snapshot = str.substr (slash+1);
194 suffix = snapshot.find (_statefile_suffix);
196 if (suffix == string::npos) {
197 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
203 snapshot = snapshot.substr (0, suffix);
205 if (slash == string::npos) {
207 /* we must be in the directory where the
208 statefile lives. get it using cwd().
211 char cwd[PATH_MAX+1];
213 if (getcwd (cwd, sizeof (cwd)) == 0) {
214 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
223 /* full path to the statefile */
225 path = str.substr (0, slash);
230 /* what type of file is it? */
231 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
237 /* its the name of a new directory. get the name
241 string::size_type slash = str.find_last_of ('/');
243 if (slash == string::npos) {
245 /* no slash, just use the name, but clean it up */
247 path = legalize_for_path (str);
253 snapshot = str.substr (slash+1);
260 Session::Session (AudioEngine &eng,
262 string snapshot_name,
263 string* mix_template)
266 _scratch_buffers(new BufferSet()),
267 _silent_buffers(new BufferSet()),
268 _send_buffers(new BufferSet()),
269 _mmc_port (default_mmc_port),
270 _mtc_port (default_mtc_port),
271 _midi_port (default_midi_port),
272 pending_events (2048),
273 //midi_requests (128), // the size of this should match the midi request pool size
274 _send_smpte_update (false),
275 diskstreams (new DiskstreamList),
276 routes (new RouteList),
277 auditioner ((Auditioner*) 0),
283 if (!eng.connected()) {
284 throw failed_constructor();
287 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
289 n_physical_outputs = _engine.n_physical_outputs();
290 n_physical_inputs = _engine.n_physical_inputs();
292 first_stage_init (fullpath, snapshot_name);
294 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
296 if (create (new_session, mix_template, compute_initial_length())) {
297 cerr << "create failed\n";
299 throw failed_constructor ();
303 if (second_stage_init (new_session)) {
305 throw failed_constructor ();
308 store_recent_sessions(_name, _path);
310 bool was_dirty = dirty();
312 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
314 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
317 DirtyChanged (); /* EMIT SIGNAL */
321 Session::Session (AudioEngine &eng,
323 string snapshot_name,
324 AutoConnectOption input_ac,
325 AutoConnectOption output_ac,
326 uint32_t control_out_channels,
327 uint32_t master_out_channels,
328 uint32_t requested_physical_in,
329 uint32_t requested_physical_out,
330 nframes_t initial_length)
333 _scratch_buffers(new BufferSet()),
334 _silent_buffers(new BufferSet()),
335 _send_buffers(new BufferSet()),
336 _mmc_port (default_mmc_port),
337 _mtc_port (default_mtc_port),
338 _midi_port (default_midi_port),
339 pending_events (2048),
340 //midi_requests (16),
341 _send_smpte_update (false),
342 diskstreams (new DiskstreamList),
343 routes (new RouteList),
349 if (!eng.connected()) {
350 throw failed_constructor();
353 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
355 n_physical_outputs = _engine.n_physical_outputs();
356 n_physical_inputs = _engine.n_physical_inputs();
358 if (n_physical_inputs) {
359 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
362 if (n_physical_outputs) {
363 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
366 first_stage_init (fullpath, snapshot_name);
368 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
371 if (create (new_session, 0, initial_length)) {
373 throw failed_constructor ();
378 /* set up Master Out and Control Out if necessary */
383 if (control_out_channels) {
384 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
385 r->set_remote_control_id (control_id++);
390 if (master_out_channels) {
391 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
392 r->set_remote_control_id (control_id);
396 /* prohibit auto-connect to master, because there isn't one */
397 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
406 Config->set_input_auto_connect (input_ac);
407 Config->set_output_auto_connect (output_ac);
409 if (second_stage_init (new_session)) {
411 throw failed_constructor ();
414 store_recent_sessions(_name, _path);
416 bool was_dirty = dirty ();
418 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
420 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
423 DirtyChanged (); /* EMIT SIGNAL */
435 /* if we got to here, leaving pending capture state around
439 remove_pending_capture_state ();
441 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
442 _engine.remove_session ();
444 GoingAway (); /* EMIT SIGNAL */
450 /* clear history so that no references to objects are held any more */
454 /* clear state tree so that no references to objects are held any more */
460 terminate_butler_thread ();
461 //terminate_midi_thread ();
463 if (click_data && click_data != default_click) {
464 delete [] click_data;
467 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
468 delete [] click_emphasis_data;
473 delete _scratch_buffers;
474 delete _silent_buffers;
475 delete _send_buffers;
477 AudioDiskstream::free_working_buffers();
479 #undef TRACK_DESTRUCTION
480 #ifdef TRACK_DESTRUCTION
481 cerr << "delete named selections\n";
482 #endif /* TRACK_DESTRUCTION */
483 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
484 NamedSelectionList::iterator tmp;
493 #ifdef TRACK_DESTRUCTION
494 cerr << "delete playlists\n";
495 #endif /* TRACK_DESTRUCTION */
496 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
497 PlaylistList::iterator tmp;
502 (*i)->drop_references ();
507 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
508 PlaylistList::iterator tmp;
513 (*i)->drop_references ();
519 unused_playlists.clear ();
521 #ifdef TRACK_DESTRUCTION
522 cerr << "delete regions\n";
523 #endif /* TRACK_DESTRUCTION */
525 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
526 RegionList::iterator tmp;
531 i->second->drop_references ();
538 #ifdef TRACK_DESTRUCTION
539 cerr << "delete routes\n";
540 #endif /* TRACK_DESTRUCTION */
542 RCUWriter<RouteList> writer (routes);
543 boost::shared_ptr<RouteList> r = writer.get_copy ();
544 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
545 (*i)->drop_references ();
548 /* writer goes out of scope and updates master */
553 #ifdef TRACK_DESTRUCTION
554 cerr << "delete diskstreams\n";
555 #endif /* TRACK_DESTRUCTION */
557 RCUWriter<DiskstreamList> dwriter (diskstreams);
558 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
559 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
560 (*i)->drop_references ();
564 diskstreams.flush ();
566 #ifdef TRACK_DESTRUCTION
567 cerr << "delete audio sources\n";
568 #endif /* TRACK_DESTRUCTION */
569 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
570 SourceMap::iterator tmp;
575 i->second->drop_references ();
582 #ifdef TRACK_DESTRUCTION
583 cerr << "delete mix groups\n";
584 #endif /* TRACK_DESTRUCTION */
585 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
586 list<RouteGroup*>::iterator tmp;
596 #ifdef TRACK_DESTRUCTION
597 cerr << "delete edit groups\n";
598 #endif /* TRACK_DESTRUCTION */
599 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
600 list<RouteGroup*>::iterator tmp;
610 #ifdef TRACK_DESTRUCTION
611 cerr << "delete connections\n";
612 #endif /* TRACK_DESTRUCTION */
613 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
614 ConnectionList::iterator tmp;
624 if (butler_mixdown_buffer) {
625 delete [] butler_mixdown_buffer;
628 if (butler_gain_buffer) {
629 delete [] butler_gain_buffer;
632 Crossfade::set_buffer_size (0);
640 Session::set_worst_io_latencies ()
642 _worst_output_latency = 0;
643 _worst_input_latency = 0;
645 if (!_engine.connected()) {
649 boost::shared_ptr<RouteList> r = routes.reader ();
651 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
652 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
653 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
658 Session::when_engine_running ()
660 string first_physical_output;
662 /* we don't want to run execute this again */
664 set_block_size (_engine.frames_per_cycle());
665 set_frame_rate (_engine.frame_rate());
667 Config->map_parameters (mem_fun (*this, &Session::config_changed));
669 /* every time we reconnect, recompute worst case output latencies */
671 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
673 if (synced_to_jack()) {
674 _engine.transport_stop ();
677 if (Config->get_jack_time_master()) {
678 _engine.transport_locate (_transport_frame);
686 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
688 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
690 /* existing state for Click */
692 if (_click_io->set_state (*child->children().front()) == 0) {
694 _clicking = Config->get_clicking ();
698 error << _("could not setup Click I/O") << endmsg;
704 /* default state for Click */
706 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
708 if (first_physical_output.length()) {
709 if (_click_io->add_output_port (first_physical_output, this)) {
710 // relax, even though its an error
712 _clicking = Config->get_clicking ();
718 catch (failed_constructor& err) {
719 error << _("cannot setup Click I/O") << endmsg;
722 set_worst_io_latencies ();
725 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
728 /* Create a set of Connection objects that map
729 to the physical outputs currently available
734 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
736 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
738 Connection* c = new OutputConnection (buf, true);
741 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
746 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
748 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
750 Connection* c = new InputConnection (buf, true);
753 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
760 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
762 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
764 Connection* c = new OutputConnection (buf, true);
768 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
769 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
774 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
776 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
778 Connection* c = new InputConnection (buf, true);
782 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
783 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
792 /* create master/control ports */
797 /* force the master to ignore any later call to this */
799 if (_master_out->pending_state_node) {
800 _master_out->ports_became_legal();
803 /* no panner resets till we are through */
805 _master_out->defer_pan_reset ();
807 while (_master_out->n_inputs().get(DataType::AUDIO)
808 < _master_out->input_maximum().get(DataType::AUDIO)) {
809 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
810 error << _("cannot setup master inputs")
816 while (_master_out->n_outputs().get(DataType::AUDIO)
817 < _master_out->output_maximum().get(DataType::AUDIO)) {
818 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
819 error << _("cannot setup master outputs")
826 _master_out->allow_pan_reset ();
830 Connection* c = new OutputConnection (_("Master Out"), true);
832 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
834 c->add_connection ((int) n, _master_out->input(n)->name());
841 /* catch up on send+insert cnts */
845 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
848 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
849 if (id > insert_cnt) {
857 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
860 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
868 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
870 /* hook us up to the engine */
872 _engine.set_session (this);
877 osc->set_session (*this);
880 _state_of_the_state = Clean;
882 DirtyChanged (); /* EMIT SIGNAL */
886 Session::hookup_io ()
888 /* stop graph reordering notifications from
889 causing resorts, etc.
892 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
894 if (auditioner == 0) {
896 /* we delay creating the auditioner till now because
897 it makes its own connections to ports.
898 the engine has to be running for this to work.
902 auditioner.reset (new Auditioner (*this));
905 catch (failed_constructor& err) {
906 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
910 /* Tell all IO objects to create their ports */
917 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
918 if (_control_out->add_input_port ("", this)) {
919 error << _("cannot setup control inputs")
925 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
926 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
927 error << _("cannot set up master outputs")
935 /* Tell all IO objects to connect themselves together */
937 IO::enable_connecting ();
939 /* Now reset all panners */
941 IO::reset_panners ();
943 /* Anyone who cares about input state, wake up and do something */
945 IOConnectionsComplete (); /* EMIT SIGNAL */
947 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
949 /* now handle the whole enchilada as if it was one
955 /* update mixer solo state */
961 Session::playlist_length_changed ()
963 /* we can't just increase end_location->end() if pl->get_maximum_extent()
964 if larger. if the playlist used to be the longest playlist,
965 and its now shorter, we have to decrease end_location->end(). hence,
966 we have to iterate over all diskstreams and check the
967 playlists currently in use.
973 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
975 boost::shared_ptr<Playlist> playlist;
977 if ((playlist = dstream->playlist()) != 0) {
978 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
981 /* see comment in playlist_length_changed () */
986 Session::record_enabling_legal () const
988 /* this used to be in here, but survey says.... we don't need to restrict it */
989 // if (record_status() == Recording) {
993 if (Config->get_all_safe()) {
1000 Session::reset_input_monitor_state ()
1002 if (transport_rolling()) {
1004 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1006 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1007 if ((*i)->record_enabled ()) {
1008 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1009 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1013 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1015 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1016 if ((*i)->record_enabled ()) {
1017 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1018 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1025 Session::auto_punch_start_changed (Location* location)
1027 replace_event (Event::PunchIn, location->start());
1029 if (get_record_enabled() && Config->get_punch_in()) {
1030 /* capture start has been changed, so save new pending state */
1031 save_state ("", true);
1036 Session::auto_punch_end_changed (Location* location)
1038 nframes_t when_to_stop = location->end();
1039 // when_to_stop += _worst_output_latency + _worst_input_latency;
1040 replace_event (Event::PunchOut, when_to_stop);
1044 Session::auto_punch_changed (Location* location)
1046 nframes_t when_to_stop = location->end();
1048 replace_event (Event::PunchIn, location->start());
1049 //when_to_stop += _worst_output_latency + _worst_input_latency;
1050 replace_event (Event::PunchOut, when_to_stop);
1054 Session::auto_loop_changed (Location* location)
1056 replace_event (Event::AutoLoop, location->end(), location->start());
1058 if (transport_rolling() && play_loop) {
1060 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1062 if (_transport_frame > location->end()) {
1063 // relocate to beginning of loop
1064 clear_events (Event::LocateRoll);
1066 request_locate (location->start(), true);
1069 else if (Config->get_seamless_loop() && !loop_changing) {
1071 // schedule a locate-roll to refill the diskstreams at the
1072 // previous loop end
1073 loop_changing = true;
1075 if (location->end() > last_loopend) {
1076 clear_events (Event::LocateRoll);
1077 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1084 last_loopend = location->end();
1089 Session::set_auto_punch_location (Location* location)
1093 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1094 auto_punch_start_changed_connection.disconnect();
1095 auto_punch_end_changed_connection.disconnect();
1096 auto_punch_changed_connection.disconnect();
1097 existing->set_auto_punch (false, this);
1098 remove_event (existing->start(), Event::PunchIn);
1099 clear_events (Event::PunchOut);
1100 auto_punch_location_changed (0);
1105 if (location == 0) {
1109 if (location->end() <= location->start()) {
1110 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1114 auto_punch_start_changed_connection.disconnect();
1115 auto_punch_end_changed_connection.disconnect();
1116 auto_punch_changed_connection.disconnect();
1118 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1119 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1120 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1122 location->set_auto_punch (true, this);
1123 auto_punch_location_changed (location);
1127 Session::set_auto_loop_location (Location* location)
1131 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1132 auto_loop_start_changed_connection.disconnect();
1133 auto_loop_end_changed_connection.disconnect();
1134 auto_loop_changed_connection.disconnect();
1135 existing->set_auto_loop (false, this);
1136 remove_event (existing->end(), Event::AutoLoop);
1137 auto_loop_location_changed (0);
1142 if (location == 0) {
1146 if (location->end() <= location->start()) {
1147 error << _("Session: you can't use a mark for auto loop") << endmsg;
1151 last_loopend = location->end();
1153 auto_loop_start_changed_connection.disconnect();
1154 auto_loop_end_changed_connection.disconnect();
1155 auto_loop_changed_connection.disconnect();
1157 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1158 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1159 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1161 location->set_auto_loop (true, this);
1162 auto_loop_location_changed (location);
1166 Session::locations_added (Location* ignored)
1172 Session::locations_changed ()
1174 _locations.apply (*this, &Session::handle_locations_changed);
1178 Session::handle_locations_changed (Locations::LocationList& locations)
1180 Locations::LocationList::iterator i;
1182 bool set_loop = false;
1183 bool set_punch = false;
1185 for (i = locations.begin(); i != locations.end(); ++i) {
1189 if (location->is_auto_punch()) {
1190 set_auto_punch_location (location);
1193 if (location->is_auto_loop()) {
1194 set_auto_loop_location (location);
1201 set_auto_loop_location (0);
1204 set_auto_punch_location (0);
1211 Session::enable_record ()
1213 /* XXX really atomic compare+swap here */
1214 if (g_atomic_int_get (&_record_status) != Recording) {
1215 g_atomic_int_set (&_record_status, Recording);
1216 _last_record_location = _transport_frame;
1217 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1219 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1220 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1221 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1222 if ((*i)->record_enabled ()) {
1223 (*i)->monitor_input (true);
1228 RecordStateChanged ();
1233 Session::disable_record (bool rt_context, bool force)
1237 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1239 if (!Config->get_latched_record_enable () || force) {
1240 g_atomic_int_set (&_record_status, Disabled);
1242 if (rs == Recording) {
1243 g_atomic_int_set (&_record_status, Enabled);
1247 // FIXME: timestamp correct? [DR]
1248 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1249 // does this /need/ to be sent in all cases?
1251 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1253 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1254 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1256 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1257 if ((*i)->record_enabled ()) {
1258 (*i)->monitor_input (false);
1263 RecordStateChanged (); /* emit signal */
1266 remove_pending_capture_state ();
1272 Session::step_back_from_record ()
1274 g_atomic_int_set (&_record_status, Enabled);
1276 if (Config->get_monitoring_model() == HardwareMonitoring) {
1277 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1279 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1280 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1281 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1282 (*i)->monitor_input (false);
1289 Session::maybe_enable_record ()
1291 g_atomic_int_set (&_record_status, Enabled);
1293 /* this function is currently called from somewhere other than an RT thread.
1294 this save_state() call therefore doesn't impact anything.
1297 save_state ("", true);
1299 if (_transport_speed) {
1300 if (!Config->get_punch_in()) {
1304 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1305 RecordStateChanged (); /* EMIT SIGNAL */
1312 Session::audible_frame () const
1318 /* the first of these two possible settings for "offset"
1319 mean that the audible frame is stationary until
1320 audio emerges from the latency compensation
1323 the second means that the audible frame is stationary
1324 until audio would emerge from a physical port
1325 in the absence of any plugin latency compensation
1328 offset = _worst_output_latency;
1330 if (offset > current_block_size) {
1331 offset -= current_block_size;
1333 /* XXX is this correct? if we have no external
1334 physical connections and everything is internal
1335 then surely this is zero? still, how
1336 likely is that anyway?
1338 offset = current_block_size;
1341 if (synced_to_jack()) {
1342 tf = _engine.transport_frame();
1344 tf = _transport_frame;
1347 if (_transport_speed == 0) {
1357 if (!non_realtime_work_pending()) {
1361 /* take latency into account */
1370 Session::set_frame_rate (nframes_t frames_per_second)
1372 /** \fn void Session::set_frame_size(nframes_t)
1373 the AudioEngine object that calls this guarantees
1374 that it will not be called while we are also in
1375 ::process(). Its fine to do things that block
1379 _base_frame_rate = frames_per_second;
1383 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1385 // XXX we need some equivalent to this, somehow
1386 // SndFileSource::setup_standard_crossfades (frames_per_second);
1390 /* XXX need to reset/reinstantiate all LADSPA plugins */
1394 Session::set_block_size (nframes_t nframes)
1396 /* the AudioEngine guarantees
1397 that it will not be called while we are also in
1398 ::process(). It is therefore fine to do things that block
1404 current_block_size = nframes;
1406 ensure_buffers(_scratch_buffers->available());
1408 if (_gain_automation_buffer) {
1409 delete [] _gain_automation_buffer;
1411 _gain_automation_buffer = new gain_t[nframes];
1413 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1415 boost::shared_ptr<RouteList> r = routes.reader ();
1417 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1418 (*i)->set_block_size (nframes);
1421 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1422 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1423 (*i)->set_block_size (nframes);
1426 set_worst_io_latencies ();
1431 Session::set_default_fade (float steepness, float fade_msecs)
1434 nframes_t fade_frames;
1436 /* Don't allow fade of less 1 frame */
1438 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1445 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1449 default_fade_msecs = fade_msecs;
1450 default_fade_steepness = steepness;
1453 // jlc, WTF is this!
1454 Glib::RWLock::ReaderLock lm (route_lock);
1455 AudioRegion::set_default_fade (steepness, fade_frames);
1460 /* XXX have to do this at some point */
1461 /* foreach region using default fade, reset, then
1462 refill_all_diskstream_buffers ();
1467 struct RouteSorter {
1468 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1469 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1471 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1474 if (r1->fed_by.empty()) {
1475 if (r2->fed_by.empty()) {
1476 /* no ardour-based connections inbound to either route. just use signal order */
1477 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1479 /* r2 has connections, r1 does not; run r1 early */
1483 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1490 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1492 shared_ptr<Route> r2;
1494 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1495 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1499 /* make a copy of the existing list of routes that feed r1 */
1501 set<shared_ptr<Route> > existing = r1->fed_by;
1503 /* for each route that feeds r1, recurse, marking it as feeding
1507 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1510 /* r2 is a route that feeds r1 which somehow feeds base. mark
1511 base as being fed by r2
1514 rbase->fed_by.insert (r2);
1518 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1522 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1526 /* now recurse, so that we can mark base as being fed by
1527 all routes that feed r2
1530 trace_terminal (r2, rbase);
1537 Session::resort_routes ()
1539 /* don't do anything here with signals emitted
1540 by Routes while we are being destroyed.
1543 if (_state_of_the_state & Deletion) {
1550 RCUWriter<RouteList> writer (routes);
1551 shared_ptr<RouteList> r = writer.get_copy ();
1552 resort_routes_using (r);
1553 /* writer goes out of scope and forces update */
1558 Session::resort_routes_using (shared_ptr<RouteList> r)
1560 RouteList::iterator i, j;
1562 for (i = r->begin(); i != r->end(); ++i) {
1564 (*i)->fed_by.clear ();
1566 for (j = r->begin(); j != r->end(); ++j) {
1568 /* although routes can feed themselves, it will
1569 cause an endless recursive descent if we
1570 detect it. so don't bother checking for
1578 if ((*j)->feeds (*i)) {
1579 (*i)->fed_by.insert (*j);
1584 for (i = r->begin(); i != r->end(); ++i) {
1585 trace_terminal (*i, *i);
1592 cerr << "finished route resort\n";
1594 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1595 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1602 list<boost::shared_ptr<MidiTrack> >
1603 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1605 char track_name[32];
1606 uint32_t track_id = 0;
1608 uint32_t channels_used = 0;
1610 RouteList new_routes;
1611 list<boost::shared_ptr<MidiTrack> > ret;
1613 /* count existing midi tracks */
1616 shared_ptr<RouteList> r = routes.reader ();
1618 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1619 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1620 if (!(*i)->hidden()) {
1622 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1630 /* check for duplicate route names, since we might have pre-existing
1631 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1632 save, close,restart,add new route - first named route is now
1640 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1642 if (route_by_name (track_name) == 0) {
1646 } while (track_id < (UINT_MAX-1));
1649 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1651 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1652 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1655 channels_used += track->n_inputs ().get(DataType::MIDI);
1657 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1658 track->set_remote_control_id (ntracks());
1660 new_routes.push_back (track);
1661 ret.push_back (track);
1664 catch (failed_constructor &err) {
1665 error << _("Session: could not create new midi track.") << endmsg;
1666 // XXX should we delete the tracks already created?
1674 if (!new_routes.empty()) {
1675 add_routes (new_routes, false);
1676 save_state (_current_snapshot_name);
1682 list<boost::shared_ptr<AudioTrack> >
1683 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1685 char track_name[32];
1686 uint32_t track_id = 0;
1688 uint32_t channels_used = 0;
1690 RouteList new_routes;
1691 list<boost::shared_ptr<AudioTrack> > ret;
1692 uint32_t control_id;
1694 /* count existing audio tracks */
1697 shared_ptr<RouteList> r = routes.reader ();
1699 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1700 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1701 if (!(*i)->hidden()) {
1703 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1709 vector<string> physinputs;
1710 vector<string> physoutputs;
1711 uint32_t nphysical_in;
1712 uint32_t nphysical_out;
1714 _engine.get_physical_outputs (physoutputs);
1715 _engine.get_physical_inputs (physinputs);
1716 control_id = ntracks() + nbusses() + 1;
1720 /* check for duplicate route names, since we might have pre-existing
1721 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1722 save, close,restart,add new route - first named route is now
1730 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1732 if (route_by_name (track_name) == 0) {
1736 } while (track_id < (UINT_MAX-1));
1738 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1739 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1744 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1745 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1750 shared_ptr<AudioTrack> track;
1753 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1755 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1756 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1757 input_channels, output_channels)
1763 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1767 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1768 port = physinputs[(channels_used+x)%nphysical_in];
1771 if (port.length() && track->connect_input (track->input (x), port, this)) {
1777 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1781 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1782 port = physoutputs[(channels_used+x)%nphysical_out];
1783 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1785 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1789 if (port.length() && track->connect_output (track->output (x), port, this)) {
1794 channels_used += track->n_inputs ().get(DataType::AUDIO);
1797 vector<string> cports;
1798 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1800 for (n = 0; n < ni; ++n) {
1801 cports.push_back (_control_out->input(n)->name());
1804 track->set_control_outs (cports);
1807 // assert (current_thread != RT_thread)
1809 track->audio_diskstream()->non_realtime_input_change();
1811 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1812 track->set_remote_control_id (control_id);
1815 new_routes.push_back (track);
1816 ret.push_back (track);
1819 catch (failed_constructor &err) {
1820 error << _("Session: could not create new audio track.") << endmsg;
1823 /* we need to get rid of this, since the track failed to be created */
1824 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1827 RCUWriter<DiskstreamList> writer (diskstreams);
1828 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1829 ds->remove (track->audio_diskstream());
1836 catch (AudioEngine::PortRegistrationFailure& pfe) {
1838 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;
1841 /* we need to get rid of this, since the track failed to be created */
1842 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1845 RCUWriter<DiskstreamList> writer (diskstreams);
1846 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1847 ds->remove (track->audio_diskstream());
1858 if (!new_routes.empty()) {
1859 add_routes (new_routes, false);
1860 save_state (_current_snapshot_name);
1867 Session::set_remote_control_ids ()
1869 RemoteModel m = Config->get_remote_model();
1871 shared_ptr<RouteList> r = routes.reader ();
1873 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1874 if ( MixerOrdered == m) {
1875 long order = (*i)->order_key(N_("signal"));
1876 (*i)->set_remote_control_id( order+1 );
1877 } else if ( EditorOrdered == m) {
1878 long order = (*i)->order_key(N_("editor"));
1879 (*i)->set_remote_control_id( order+1 );
1880 } else if ( UserOrdered == m) {
1881 //do nothing ... only changes to remote id's are initiated by user
1888 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1891 uint32_t bus_id = 1;
1895 uint32_t control_id;
1897 /* count existing audio busses */
1900 shared_ptr<RouteList> r = routes.reader ();
1902 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1903 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1904 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1911 vector<string> physinputs;
1912 vector<string> physoutputs;
1914 _engine.get_physical_outputs (physoutputs);
1915 _engine.get_physical_inputs (physinputs);
1916 control_id = ntracks() + nbusses() + 1;
1921 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1925 if (route_by_name (bus_name) == 0) {
1929 } while (bus_id < (UINT_MAX-1));
1932 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1934 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1935 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1936 input_channels, output_channels)
1941 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1945 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1946 port = physinputs[((n+x)%n_physical_inputs)];
1949 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1954 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1958 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1959 port = physoutputs[((n+x)%n_physical_outputs)];
1960 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1962 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1966 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1972 vector<string> cports;
1973 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1975 for (uint32_t n = 0; n < ni; ++n) {
1976 cports.push_back (_control_out->input(n)->name());
1978 bus->set_control_outs (cports);
1981 bus->set_remote_control_id (control_id);
1984 ret.push_back (bus);
1988 catch (failed_constructor &err) {
1989 error << _("Session: could not create new audio route.") << endmsg;
1993 catch (AudioEngine::PortRegistrationFailure& pfe) {
1994 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;
2004 add_routes (ret, false);
2005 save_state (_current_snapshot_name);
2013 Session::add_routes (RouteList& new_routes, bool save)
2016 RCUWriter<RouteList> writer (routes);
2017 shared_ptr<RouteList> r = writer.get_copy ();
2018 r->insert (r->end(), new_routes.begin(), new_routes.end());
2019 resort_routes_using (r);
2022 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2024 boost::weak_ptr<Route> wpr (*x);
2026 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2027 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2028 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2029 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2031 if ((*x)->master()) {
2035 if ((*x)->control()) {
2036 _control_out = (*x);
2043 save_state (_current_snapshot_name);
2046 RouteAdded (new_routes); /* EMIT SIGNAL */
2050 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2052 /* need to do this in case we're rolling at the time, to prevent false underruns */
2053 dstream->do_refill_with_alloc ();
2055 dstream->set_block_size (current_block_size);
2058 RCUWriter<DiskstreamList> writer (diskstreams);
2059 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2060 ds->push_back (dstream);
2061 /* writer goes out of scope, copies ds back to main */
2064 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2065 /* this will connect to future changes, and check the current length */
2066 diskstream_playlist_changed (dstream);
2068 dstream->prepare ();
2073 Session::remove_route (shared_ptr<Route> route)
2076 RCUWriter<RouteList> writer (routes);
2077 shared_ptr<RouteList> rs = writer.get_copy ();
2081 /* deleting the master out seems like a dumb
2082 idea, but its more of a UI policy issue
2086 if (route == _master_out) {
2087 _master_out = shared_ptr<Route> ();
2090 if (route == _control_out) {
2091 _control_out = shared_ptr<Route> ();
2093 /* cancel control outs for all routes */
2095 vector<string> empty;
2097 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2098 (*r)->set_control_outs (empty);
2102 update_route_solo_state ();
2104 /* writer goes out of scope, forces route list update */
2108 boost::shared_ptr<Diskstream> ds;
2110 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2111 ds = t->diskstream();
2117 RCUWriter<DiskstreamList> dsl (diskstreams);
2118 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2123 find_current_end ();
2125 update_latency_compensation (false, false);
2128 // We need to disconnect the routes inputs and outputs
2129 route->disconnect_inputs(NULL);
2130 route->disconnect_outputs(NULL);
2132 /* get rid of it from the dead wood collection in the route list manager */
2134 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2138 /* try to cause everyone to drop their references */
2140 route->drop_references ();
2142 /* save the new state of the world */
2144 if (save_state (_current_snapshot_name)) {
2145 save_history (_current_snapshot_name);
2150 Session::route_mute_changed (void* src)
2156 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2158 if (solo_update_disabled) {
2164 boost::shared_ptr<Route> route = wpr.lock ();
2167 /* should not happen */
2168 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2172 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2174 shared_ptr<RouteList> r = routes.reader ();
2176 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2178 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2182 /* don't mess with busses */
2184 if (dynamic_cast<Track*>((*i).get()) == 0) {
2190 /* don't mess with tracks */
2192 if (dynamic_cast<Track*>((*i).get()) != 0) {
2197 if ((*i) != route &&
2198 ((*i)->mix_group () == 0 ||
2199 (*i)->mix_group () != route->mix_group () ||
2200 !route->mix_group ()->is_active())) {
2202 if ((*i)->soloed()) {
2204 /* if its already soloed, and solo latching is enabled,
2205 then leave it as it is.
2208 if (Config->get_solo_latched()) {
2215 solo_update_disabled = true;
2216 (*i)->set_solo (false, src);
2217 solo_update_disabled = false;
2221 bool something_soloed = false;
2222 bool same_thing_soloed = false;
2223 bool signal = false;
2225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 if ((*i)->soloed()) {
2227 something_soloed = true;
2228 if (dynamic_cast<Track*>((*i).get())) {
2230 same_thing_soloed = true;
2235 same_thing_soloed = true;
2243 if (something_soloed != currently_soloing) {
2245 currently_soloing = something_soloed;
2248 modify_solo_mute (is_track, same_thing_soloed);
2251 SoloActive (currently_soloing); /* EMIT SIGNAL */
2254 SoloChanged (); /* EMIT SIGNAL */
2260 Session::update_route_solo_state ()
2263 bool is_track = false;
2264 bool signal = false;
2266 /* caller must hold RouteLock */
2268 /* this is where we actually implement solo by changing
2269 the solo mute setting of each track.
2272 shared_ptr<RouteList> r = routes.reader ();
2274 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2275 if ((*i)->soloed()) {
2277 if (dynamic_cast<Track*>((*i).get())) {
2284 if (mute != currently_soloing) {
2286 currently_soloing = mute;
2289 if (!is_track && !mute) {
2291 /* nothing is soloed */
2293 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2294 (*i)->set_solo_mute (false);
2304 modify_solo_mute (is_track, mute);
2307 SoloActive (currently_soloing);
2312 Session::modify_solo_mute (bool is_track, bool mute)
2314 shared_ptr<RouteList> r = routes.reader ();
2316 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2320 /* only alter track solo mute */
2322 if (dynamic_cast<Track*>((*i).get())) {
2323 if ((*i)->soloed()) {
2324 (*i)->set_solo_mute (!mute);
2326 (*i)->set_solo_mute (mute);
2332 /* only alter bus solo mute */
2334 if (!dynamic_cast<Track*>((*i).get())) {
2336 if ((*i)->soloed()) {
2338 (*i)->set_solo_mute (false);
2342 /* don't mute master or control outs
2343 in response to another bus solo
2346 if ((*i) != _master_out &&
2347 (*i) != _control_out) {
2348 (*i)->set_solo_mute (mute);
2359 Session::catch_up_on_solo ()
2361 /* this is called after set_state() to catch the full solo
2362 state, which can't be correctly determined on a per-route
2363 basis, but needs the global overview that only the session
2366 update_route_solo_state();
2370 Session::route_by_name (string name)
2372 shared_ptr<RouteList> r = routes.reader ();
2374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2375 if ((*i)->name() == name) {
2380 return shared_ptr<Route> ((Route*) 0);
2384 Session::route_by_id (PBD::ID id)
2386 shared_ptr<RouteList> r = routes.reader ();
2388 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2389 if ((*i)->id() == id) {
2394 return shared_ptr<Route> ((Route*) 0);
2398 Session::route_by_remote_id (uint32_t id)
2400 shared_ptr<RouteList> r = routes.reader ();
2402 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2403 if ((*i)->remote_control_id() == id) {
2408 return shared_ptr<Route> ((Route*) 0);
2412 Session::find_current_end ()
2414 if (_state_of_the_state & Loading) {
2418 nframes_t max = get_maximum_extent ();
2420 if (max > end_location->end()) {
2421 end_location->set_end (max);
2423 DurationChanged(); /* EMIT SIGNAL */
2428 Session::get_maximum_extent () const
2433 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2435 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2436 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2437 if ((me = pl->get_maximum_extent()) > max) {
2445 boost::shared_ptr<Diskstream>
2446 Session::diskstream_by_name (string name)
2448 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2450 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2451 if ((*i)->name() == name) {
2456 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2459 boost::shared_ptr<Diskstream>
2460 Session::diskstream_by_id (const PBD::ID& id)
2462 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2464 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2465 if ((*i)->id() == id) {
2470 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2473 /* Region management */
2476 Session::new_region_name (string old)
2478 string::size_type last_period;
2480 string::size_type len = old.length() + 64;
2483 if ((last_period = old.find_last_of ('.')) == string::npos) {
2485 /* no period present - add one explicitly */
2488 last_period = old.length() - 1;
2493 number = atoi (old.substr (last_period+1).c_str());
2497 while (number < (UINT_MAX-1)) {
2499 RegionList::const_iterator i;
2504 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2507 for (i = regions.begin(); i != regions.end(); ++i) {
2508 if (i->second->name() == sbuf) {
2513 if (i == regions.end()) {
2518 if (number != (UINT_MAX-1)) {
2522 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2527 Session::region_name (string& result, string base, bool newlevel) const
2532 assert(base.find("/") == string::npos);
2536 Glib::Mutex::Lock lm (region_lock);
2538 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2546 /* XXX this is going to be slow. optimize me later */
2551 string::size_type pos;
2553 pos = base.find_last_of ('.');
2555 /* pos may be npos, but then we just use entire base */
2557 subbase = base.substr (0, pos);
2561 bool name_taken = true;
2564 Glib::Mutex::Lock lm (region_lock);
2566 for (int n = 1; n < 5000; ++n) {
2569 snprintf (buf, sizeof (buf), ".%d", n);
2574 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2575 if (i->second->name() == result) {
2588 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2596 Session::add_region (boost::shared_ptr<Region> region)
2598 boost::shared_ptr<Region> other;
2602 Glib::Mutex::Lock lm (region_lock);
2604 RegionList::iterator x;
2606 for (x = regions.begin(); x != regions.end(); ++x) {
2610 if (region->region_list_equivalent (other)) {
2615 if (x == regions.end()) {
2617 pair<RegionList::key_type,RegionList::mapped_type> entry;
2619 entry.first = region->id();
2620 entry.second = region;
2622 pair<RegionList::iterator,bool> x = regions.insert (entry);
2634 /* mark dirty because something has changed even if we didn't
2635 add the region to the region list.
2641 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2642 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2643 RegionAdded (region); /* EMIT SIGNAL */
2648 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2650 boost::shared_ptr<Region> region (weak_region.lock ());
2656 if (what_changed & Region::HiddenChanged) {
2657 /* relay hidden changes */
2658 RegionHiddenChange (region);
2663 Session::remove_region (boost::weak_ptr<Region> weak_region)
2665 RegionList::iterator i;
2666 boost::shared_ptr<Region> region (weak_region.lock ());
2672 bool removed = false;
2675 Glib::Mutex::Lock lm (region_lock);
2677 if ((i = regions.find (region->id())) != regions.end()) {
2683 /* mark dirty because something has changed even if we didn't
2684 remove the region from the region list.
2690 RegionRemoved(region); /* EMIT SIGNAL */
2694 boost::shared_ptr<Region>
2695 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2697 RegionList::iterator i;
2698 boost::shared_ptr<Region> region;
2700 Glib::Mutex::Lock lm (region_lock);
2702 for (i = regions.begin(); i != regions.end(); ++i) {
2706 if (region->whole_file()) {
2708 if (child->source_equivalent (region)) {
2714 return boost::shared_ptr<Region> ();
2718 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2720 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2721 (*i)->get_region_list_equivalent_regions (region, result);
2725 Session::destroy_region (boost::shared_ptr<Region> region)
2727 vector<boost::shared_ptr<Source> > srcs;
2730 boost::shared_ptr<AudioRegion> aregion;
2732 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2736 if (aregion->playlist()) {
2737 aregion->playlist()->destroy_region (region);
2740 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2741 srcs.push_back (aregion->source (n));
2745 region->drop_references ();
2747 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2749 if (!(*i)->used()) {
2750 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2753 (afs)->mark_for_remove ();
2756 (*i)->drop_references ();
2758 cerr << "source was not used by any playlist\n";
2766 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2768 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2769 destroy_region (*i);
2775 Session::remove_last_capture ()
2777 list<boost::shared_ptr<Region> > r;
2779 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2781 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2782 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2785 r.insert (r.end(), l.begin(), l.end());
2790 destroy_regions (r);
2792 save_state (_current_snapshot_name);
2798 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2804 /* Source Management */
2806 Session::add_source (boost::shared_ptr<Source> source)
2808 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2809 pair<SourceMap::iterator,bool> result;
2811 entry.first = source->id();
2812 entry.second = source;
2815 Glib::Mutex::Lock lm (source_lock);
2816 result = sources.insert (entry);
2819 if (result.second) {
2820 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2826 Session::remove_source (boost::weak_ptr<Source> src)
2828 SourceMap::iterator i;
2829 boost::shared_ptr<Source> source = src.lock();
2836 Glib::Mutex::Lock lm (source_lock);
2839 Glib::Mutex::Lock lm (source_lock);
2841 if ((i = sources.find (source->id())) != sources.end()) {
2847 if (!_state_of_the_state & InCleanup) {
2849 /* save state so we don't end up with a session file
2850 referring to non-existent sources.
2853 save_state (_current_snapshot_name);
2857 boost::shared_ptr<Source>
2858 Session::source_by_id (const PBD::ID& id)
2860 Glib::Mutex::Lock lm (source_lock);
2861 SourceMap::iterator i;
2862 boost::shared_ptr<Source> source;
2864 if ((i = sources.find (id)) != sources.end()) {
2868 /* XXX search MIDI or other searches here */
2874 boost::shared_ptr<Source>
2875 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2877 Glib::Mutex::Lock lm (source_lock);
2879 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2880 cerr << "comparing " << path << " with " << i->second->name() << endl;
2881 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2883 if (afs && afs->path() == path && chn == afs->channel()) {
2888 return boost::shared_ptr<Source>();
2892 Session::peak_path_from_audio_path (string audio_path) const
2897 res += PBD::basename_nosuffix (audio_path);
2904 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2907 string old_basename = PBD::basename_nosuffix (oldname);
2908 string new_legalized = legalize_for_path (newname);
2910 /* note: we know (or assume) the old path is already valid */
2914 /* destructive file sources have a name of the form:
2916 /path/to/Tnnnn-NAME(%[LR])?.wav
2918 the task here is to replace NAME with the new name.
2921 /* find last slash */
2925 string::size_type slash;
2926 string::size_type dash;
2928 if ((slash = path.find_last_of ('/')) == string::npos) {
2932 dir = path.substr (0, slash+1);
2934 /* '-' is not a legal character for the NAME part of the path */
2936 if ((dash = path.find_last_of ('-')) == string::npos) {
2940 prefix = path.substr (slash+1, dash-(slash+1));
2945 path += new_legalized;
2946 path += ".wav"; /* XXX gag me with a spoon */
2950 /* non-destructive file sources have a name of the form:
2952 /path/to/NAME-nnnnn(%[LR])?.wav
2954 the task here is to replace NAME with the new name.
2959 string::size_type slash;
2960 string::size_type dash;
2961 string::size_type postfix;
2963 /* find last slash */
2965 if ((slash = path.find_last_of ('/')) == string::npos) {
2969 dir = path.substr (0, slash+1);
2971 /* '-' is not a legal character for the NAME part of the path */
2973 if ((dash = path.find_last_of ('-')) == string::npos) {
2977 suffix = path.substr (dash+1);
2979 // Suffix is now everything after the dash. Now we need to eliminate
2980 // the nnnnn part, which is done by either finding a '%' or a '.'
2982 postfix = suffix.find_last_of ("%");
2983 if (postfix == string::npos) {
2984 postfix = suffix.find_last_of ('.');
2987 if (postfix != string::npos) {
2988 suffix = suffix.substr (postfix);
2990 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2994 const uint32_t limit = 10000;
2995 char buf[PATH_MAX+1];
2997 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2999 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3001 if (access (buf, F_OK) != 0) {
3009 error << "FATAL ERROR! Could not find a " << endl;
3018 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3022 char buf[PATH_MAX+1];
3023 const uint32_t limit = 10000;
3027 legalized = legalize_for_path (name);
3029 /* find a "version" of the file name that doesn't exist in
3030 any of the possible directories.
3033 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3035 vector<space_and_path>::iterator i;
3036 uint32_t existing = 0;
3038 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3042 spath += sound_dir (false);
3046 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3047 } else if (nchan == 2) {
3049 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3051 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3053 } else if (nchan < 26) {
3054 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3056 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3065 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3066 } else if (nchan == 2) {
3068 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3070 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3072 } else if (nchan < 26) {
3073 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3075 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3079 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3085 if (existing == 0) {
3090 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3092 throw failed_constructor();
3096 /* we now have a unique name for the file, but figure out where to
3102 spath = discover_best_sound_dir ();
3105 string::size_type pos = foo.find_last_of ('/');
3107 if (pos == string::npos) {
3110 spath += foo.substr (pos + 1);
3116 boost::shared_ptr<AudioFileSource>
3117 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3119 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
3120 return boost::dynamic_pointer_cast<AudioFileSource> (
3121 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3124 // FIXME: _terrible_ code duplication
3126 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3129 string old_basename = PBD::basename_nosuffix (oldname);
3130 string new_legalized = legalize_for_path (newname);
3132 /* note: we know (or assume) the old path is already valid */
3136 /* destructive file sources have a name of the form:
3138 /path/to/Tnnnn-NAME(%[LR])?.wav
3140 the task here is to replace NAME with the new name.
3143 /* find last slash */
3147 string::size_type slash;
3148 string::size_type dash;
3150 if ((slash = path.find_last_of ('/')) == string::npos) {
3154 dir = path.substr (0, slash+1);
3156 /* '-' is not a legal character for the NAME part of the path */
3158 if ((dash = path.find_last_of ('-')) == string::npos) {
3162 prefix = path.substr (slash+1, dash-(slash+1));
3167 path += new_legalized;
3168 path += ".mid"; /* XXX gag me with a spoon */
3172 /* non-destructive file sources have a name of the form:
3174 /path/to/NAME-nnnnn(%[LR])?.wav
3176 the task here is to replace NAME with the new name.
3181 string::size_type slash;
3182 string::size_type dash;
3183 string::size_type postfix;
3185 /* find last slash */
3187 if ((slash = path.find_last_of ('/')) == string::npos) {
3191 dir = path.substr (0, slash+1);
3193 /* '-' is not a legal character for the NAME part of the path */
3195 if ((dash = path.find_last_of ('-')) == string::npos) {
3199 suffix = path.substr (dash+1);
3201 // Suffix is now everything after the dash. Now we need to eliminate
3202 // the nnnnn part, which is done by either finding a '%' or a '.'
3204 postfix = suffix.find_last_of ("%");
3205 if (postfix == string::npos) {
3206 postfix = suffix.find_last_of ('.');
3209 if (postfix != string::npos) {
3210 suffix = suffix.substr (postfix);
3212 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3216 const uint32_t limit = 10000;
3217 char buf[PATH_MAX+1];
3219 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3221 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3223 if (access (buf, F_OK) != 0) {
3231 error << "FATAL ERROR! Could not find a " << endl;
3240 Session::midi_path_from_name (string name)
3244 char buf[PATH_MAX+1];
3245 const uint32_t limit = 10000;
3249 legalized = legalize_for_path (name);
3251 /* find a "version" of the file name that doesn't exist in
3252 any of the possible directories.
3255 for (cnt = 1; cnt <= limit; ++cnt) {
3257 vector<space_and_path>::iterator i;
3258 uint32_t existing = 0;
3260 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3264 // FIXME: different directory from audio?
3265 spath += sound_dir(false) + "/" + legalized;
3267 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3269 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3274 if (existing == 0) {
3279 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3280 throw failed_constructor();
3284 /* we now have a unique name for the file, but figure out where to
3290 // FIXME: different directory than audio?
3291 spath = discover_best_sound_dir ();
3294 string::size_type pos = foo.find_last_of ('/');
3296 if (pos == string::npos) {
3299 spath += foo.substr (pos + 1);
3305 boost::shared_ptr<MidiSource>
3306 Session::create_midi_source_for_session (MidiDiskstream& ds)
3308 string spath = midi_path_from_name (ds.name());
3310 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3314 /* Playlist management */
3316 boost::shared_ptr<Playlist>
3317 Session::playlist_by_name (string name)
3319 Glib::Mutex::Lock lm (playlist_lock);
3320 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3321 if ((*i)->name() == name) {
3325 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3326 if ((*i)->name() == name) {
3331 return boost::shared_ptr<Playlist>();
3335 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3337 if (playlist->hidden()) {
3342 Glib::Mutex::Lock lm (playlist_lock);
3343 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3344 playlists.insert (playlists.begin(), playlist);
3345 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3346 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3352 PlaylistAdded (playlist); /* EMIT SIGNAL */
3356 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3359 Glib::Mutex::Lock lm (playlist_lock);
3360 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3363 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3370 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3372 boost::shared_ptr<Playlist> pl(wpl.lock());
3378 PlaylistList::iterator x;
3381 /* its not supposed to be visible */
3386 Glib::Mutex::Lock lm (playlist_lock);
3390 unused_playlists.insert (pl);
3392 if ((x = playlists.find (pl)) != playlists.end()) {
3393 playlists.erase (x);
3399 playlists.insert (pl);
3401 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3402 unused_playlists.erase (x);
3409 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3411 if (_state_of_the_state & Deletion) {
3415 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3422 Glib::Mutex::Lock lm (playlist_lock);
3424 PlaylistList::iterator i;
3426 i = find (playlists.begin(), playlists.end(), playlist);
3427 if (i != playlists.end()) {
3428 playlists.erase (i);
3431 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3432 if (i != unused_playlists.end()) {
3433 unused_playlists.erase (i);
3440 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3444 Session::set_audition (boost::shared_ptr<Region> r)
3446 pending_audition_region = r;
3447 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3448 schedule_butler_transport_work ();
3452 Session::audition_playlist ()
3454 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3455 ev->region.reset ();
3460 Session::non_realtime_set_audition ()
3462 if (!pending_audition_region) {
3463 auditioner->audition_current_playlist ();
3465 auditioner->audition_region (pending_audition_region);
3466 pending_audition_region.reset ();
3468 AuditionActive (true); /* EMIT SIGNAL */
3472 Session::audition_region (boost::shared_ptr<Region> r)
3474 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3480 Session::cancel_audition ()
3482 if (auditioner->active()) {
3483 auditioner->cancel_audition ();
3484 AuditionActive (false); /* EMIT SIGNAL */
3489 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3491 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3495 Session::remove_empty_sounds ()
3497 PathScanner scanner;
3499 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3501 Glib::Mutex::Lock lm (source_lock);
3503 regex_t compiled_tape_track_pattern;
3506 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3510 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3512 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3516 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3518 /* never remove files that appear to be a tape track */
3520 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3525 if (AudioFileSource::is_empty (*this, *(*i))) {
3527 unlink ((*i)->c_str());
3529 string peak_path = peak_path_from_audio_path (**i);
3530 unlink (peak_path.c_str());
3536 delete possible_audiofiles;
3540 Session::is_auditioning () const
3542 /* can be called before we have an auditioner object */
3544 return auditioner->active();
3551 Session::set_all_solo (bool yn)
3553 shared_ptr<RouteList> r = routes.reader ();
3555 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3556 if (!(*i)->hidden()) {
3557 (*i)->set_solo (yn, this);
3565 Session::set_all_mute (bool yn)
3567 shared_ptr<RouteList> r = routes.reader ();
3569 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3570 if (!(*i)->hidden()) {
3571 (*i)->set_mute (yn, this);
3579 Session::n_diskstreams () const
3583 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3585 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3586 if (!(*i)->hidden()) {
3594 Session::graph_reordered ()
3596 /* don't do this stuff if we are setting up connections
3597 from a set_state() call or creating new tracks.
3600 if (_state_of_the_state & InitialConnecting) {
3604 /* every track/bus asked for this to be handled but it was deferred because
3605 we were connecting. do it now.
3608 request_input_change_handling ();
3612 /* force all diskstreams to update their capture offset values to
3613 reflect any changes in latencies within the graph.
3616 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3618 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3619 (*i)->set_capture_offset ();
3624 Session::record_disenable_all ()
3626 record_enable_change_all (false);
3630 Session::record_enable_all ()
3632 record_enable_change_all (true);
3636 Session::record_enable_change_all (bool yn)
3638 shared_ptr<RouteList> r = routes.reader ();
3640 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3643 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3644 at->set_record_enable (yn, this);
3648 /* since we don't keep rec-enable state, don't mark session dirty */
3652 Session::add_redirect (Redirect* redirect)
3656 PortInsert* port_insert;
3657 PluginInsert* plugin_insert;
3659 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3660 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3661 _port_inserts.insert (_port_inserts.begin(), port_insert);
3662 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3663 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3665 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3668 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3669 _sends.insert (_sends.begin(), send);
3671 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3675 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3681 Session::remove_redirect (Redirect* redirect)
3685 PortInsert* port_insert;
3686 PluginInsert* plugin_insert;
3688 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3689 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3690 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3691 if (x != _port_inserts.end()) {
3692 insert_bitset[port_insert->bit_slot()] = false;
3693 _port_inserts.erase (x);
3695 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3696 _plugin_inserts.remove (plugin_insert);
3698 fatal << string_compose (_("programming error: %1"),
3699 X_("unknown type of Insert deleted!"))
3703 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3704 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3705 if (x != _sends.end()) {
3706 send_bitset[send->bit_slot()] = false;
3710 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3718 Session::available_capture_duration ()
3720 float sample_bytes_on_disk = 4.0; // keep gcc happy
3722 switch (Config->get_native_file_data_format()) {
3724 sample_bytes_on_disk = 4.0;
3728 sample_bytes_on_disk = 3.0;
3732 /* impossible, but keep some gcc versions happy */
3733 fatal << string_compose (_("programming error: %1"),
3734 X_("illegal native file data format"))
3739 double scale = 4096.0 / sample_bytes_on_disk;
3741 if (_total_free_4k_blocks * scale > (double) max_frames) {
3745 return (nframes_t) floor (_total_free_4k_blocks * scale);
3749 Session::add_connection (ARDOUR::Connection* connection)
3752 Glib::Mutex::Lock guard (connection_lock);
3753 _connections.push_back (connection);
3756 ConnectionAdded (connection); /* EMIT SIGNAL */
3762 Session::remove_connection (ARDOUR::Connection* connection)
3764 bool removed = false;
3767 Glib::Mutex::Lock guard (connection_lock);
3768 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3770 if (i != _connections.end()) {
3771 _connections.erase (i);
3777 ConnectionRemoved (connection); /* EMIT SIGNAL */
3783 ARDOUR::Connection *
3784 Session::connection_by_name (string name) const
3786 Glib::Mutex::Lock lm (connection_lock);
3788 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3789 if ((*i)->name() == name) {
3798 Session::tempo_map_changed (Change ignored)
3804 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3805 * the given count with the current block size.
3808 Session::ensure_buffers (ChanCount howmany)
3810 // FIXME: NASTY assumption (midi block size == audio block size)
3811 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3812 _send_buffers->ensure_buffers(howmany, current_block_size);
3813 _silent_buffers->ensure_buffers(howmany, current_block_size);
3815 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3819 Session::next_insert_id ()
3821 /* this doesn't really loop forever. just think about it */
3824 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3825 if (!insert_bitset[n]) {
3826 insert_bitset[n] = true;
3832 /* none available, so resize and try again */
3834 insert_bitset.resize (insert_bitset.size() + 16, false);
3839 Session::next_send_id ()
3841 /* this doesn't really loop forever. just think about it */
3844 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3845 if (!send_bitset[n]) {
3846 send_bitset[n] = true;
3852 /* none available, so resize and try again */
3854 send_bitset.resize (send_bitset.size() + 16, false);
3859 Session::mark_send_id (uint32_t id)
3861 if (id >= send_bitset.size()) {
3862 send_bitset.resize (id+16, false);
3864 if (send_bitset[id]) {
3865 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3867 send_bitset[id] = true;
3871 Session::mark_insert_id (uint32_t id)
3873 if (id >= insert_bitset.size()) {
3874 insert_bitset.resize (id+16, false);
3876 if (insert_bitset[id]) {
3877 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3879 insert_bitset[id] = true;
3882 /* Named Selection management */
3885 Session::named_selection_by_name (string name)
3887 Glib::Mutex::Lock lm (named_selection_lock);
3888 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3889 if ((*i)->name == name) {
3897 Session::add_named_selection (NamedSelection* named_selection)
3900 Glib::Mutex::Lock lm (named_selection_lock);
3901 named_selections.insert (named_selections.begin(), named_selection);
3904 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3910 NamedSelectionAdded (); /* EMIT SIGNAL */
3914 Session::remove_named_selection (NamedSelection* named_selection)
3916 bool removed = false;
3919 Glib::Mutex::Lock lm (named_selection_lock);
3921 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3923 if (i != named_selections.end()) {
3925 named_selections.erase (i);
3932 NamedSelectionRemoved (); /* EMIT SIGNAL */
3937 Session::reset_native_file_format ()
3939 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3941 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3942 (*i)->reset_write_sources (false);
3947 Session::route_name_unique (string n) const
3949 shared_ptr<RouteList> r = routes.reader ();
3951 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3952 if ((*i)->name() == n) {
3961 Session::n_playlists () const
3963 Glib::Mutex::Lock lm (playlist_lock);
3964 return playlists.size();
3968 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3970 if (!force && howmany <= _npan_buffers) {
3974 if (_pan_automation_buffer) {
3976 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3977 delete [] _pan_automation_buffer[i];
3980 delete [] _pan_automation_buffer;
3983 _pan_automation_buffer = new pan_t*[howmany];
3985 for (uint32_t i = 0; i < howmany; ++i) {
3986 _pan_automation_buffer[i] = new pan_t[nframes];
3989 _npan_buffers = howmany;
3993 Session::freeze (InterThreadInfo& itt)
3995 shared_ptr<RouteList> r = routes.reader ();
3997 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4001 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4002 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4013 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
4014 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4017 boost::shared_ptr<Playlist> playlist;
4018 boost::shared_ptr<AudioFileSource> fsource;
4020 char buf[PATH_MAX+1];
4022 ChanCount nchans(track.audio_diskstream()->n_channels());
4024 nframes_t this_chunk;
4028 // any bigger than this seems to cause stack overflows in called functions
4029 const nframes_t chunk_size = (128 * 1024)/4;
4031 g_atomic_int_set (&processing_prohibited, 1);
4033 /* call tree *MUST* hold route_lock */
4035 if ((playlist = track.diskstream()->playlist()) == 0) {
4039 /* external redirects will be a problem */
4041 if (track.has_external_redirects()) {
4045 dir = discover_best_sound_dir ();
4047 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
4049 for (x = 0; x < 99999; ++x) {
4050 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4051 if (access (buf, F_OK) != 0) {
4057 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4062 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4063 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4066 catch (failed_constructor& err) {
4067 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4071 srcs.push_back (fsource);
4074 /* XXX need to flush all redirects */
4079 /* create a set of reasonably-sized buffers */
4080 buffers.ensure_buffers(nchans, chunk_size);
4081 buffers.set_count(nchans);
4083 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4084 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4086 afs->prepare_for_peakfile_writes ();
4089 while (to_do && !itt.cancel) {
4091 this_chunk = min (to_do, chunk_size);
4093 if (track.export_stuff (buffers, start, this_chunk)) {
4098 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4099 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4102 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4108 start += this_chunk;
4109 to_do -= this_chunk;
4111 itt.progress = (float) (1.0 - ((double) to_do / len));
4120 xnow = localtime (&now);
4122 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4123 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4126 afs->update_header (position, *xnow, now);
4127 afs->flush_header ();
4131 /* construct a region to represent the bounced material */
4133 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4134 region_name_from_path (srcs.front()->name(), true));
4141 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4142 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4145 afs->mark_for_remove ();
4148 (*src)->drop_references ();
4152 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4153 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4156 afs->done_with_peakfile_writes ();
4160 g_atomic_int_set (&processing_prohibited, 0);
4168 Session::get_silent_buffers (ChanCount count)
4170 assert(_silent_buffers->available() >= count);
4171 _silent_buffers->set_count(count);
4173 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4174 for (size_t i=0; i < count.get(*t); ++i) {
4175 _silent_buffers->get(*t, i).clear();
4179 return *_silent_buffers;
4183 Session::get_scratch_buffers (ChanCount count)
4185 assert(_scratch_buffers->available() >= count);
4186 _scratch_buffers->set_count(count);
4187 return *_scratch_buffers;
4191 Session::get_send_buffers (ChanCount count)
4193 assert(_send_buffers->available() >= count);
4194 _send_buffers->set_count(count);
4195 return *_send_buffers;
4199 Session::ntracks () const
4202 shared_ptr<RouteList> r = routes.reader ();
4204 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4205 if (dynamic_cast<Track*> ((*i).get())) {
4214 Session::nbusses () const
4217 shared_ptr<RouteList> r = routes.reader ();
4219 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4220 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4229 Session::add_automation_list(AutomationList *al)
4231 automation_lists[al->id()] = al;
4235 Session::compute_initial_length ()
4237 return _engine.frame_rate() * 60 * 5;