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 Session::compute_peak_t Session::compute_peak = 0;
104 Session::find_peaks_t Session::find_peaks = 0;
105 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
106 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
107 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
109 sigc::signal<int> Session::AskAboutPendingState;
110 sigc::signal<void> Session::SendFeedback;
112 sigc::signal<void> Session::SMPTEOffsetChanged;
113 sigc::signal<void> Session::StartTimeChanged;
114 sigc::signal<void> Session::EndTimeChanged;
117 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
120 char buf[PATH_MAX+1];
124 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
125 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
131 /* check to see if it exists, and what it is */
133 if (stat (str.c_str(), &statbuf)) {
134 if (errno == ENOENT) {
137 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
145 /* it exists, so it must either be the name
146 of the directory, or the name of the statefile
150 if (S_ISDIR (statbuf.st_mode)) {
152 string::size_type slash = str.find_last_of ('/');
154 if (slash == string::npos) {
156 /* a subdirectory of cwd, so statefile should be ... */
162 tmp += _statefile_suffix;
166 if (stat (tmp.c_str(), &statbuf)) {
167 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
177 /* some directory someplace in the filesystem.
178 the snapshot name is the directory name
183 snapshot = str.substr (slash+1);
187 } else if (S_ISREG (statbuf.st_mode)) {
189 string::size_type slash = str.find_last_of ('/');
190 string::size_type suffix;
192 /* remove the suffix */
194 if (slash != string::npos) {
195 snapshot = str.substr (slash+1);
200 suffix = snapshot.find (_statefile_suffix);
202 if (suffix == string::npos) {
203 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
209 snapshot = snapshot.substr (0, suffix);
211 if (slash == string::npos) {
213 /* we must be in the directory where the
214 statefile lives. get it using cwd().
217 char cwd[PATH_MAX+1];
219 if (getcwd (cwd, sizeof (cwd)) == 0) {
220 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
229 /* full path to the statefile */
231 path = str.substr (0, slash);
236 /* what type of file is it? */
237 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
243 /* its the name of a new directory. get the name
247 string::size_type slash = str.find_last_of ('/');
249 if (slash == string::npos) {
251 /* no slash, just use the name, but clean it up */
253 path = legalize_for_path (str);
259 snapshot = str.substr (slash+1);
266 Session::Session (AudioEngine &eng,
268 string snapshot_name,
269 string* mix_template)
272 _scratch_buffers(new BufferSet()),
273 _silent_buffers(new BufferSet()),
274 _send_buffers(new BufferSet()),
275 _mmc_port (default_mmc_port),
276 _mtc_port (default_mtc_port),
277 _midi_port (default_midi_port),
278 pending_events (2048),
279 //midi_requests (128), // the size of this should match the midi request pool size
280 _send_smpte_update (false),
281 diskstreams (new DiskstreamList),
282 routes (new RouteList),
283 auditioner ((Auditioner*) 0),
289 if (!eng.connected()) {
290 throw failed_constructor();
293 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
295 n_physical_outputs = _engine.n_physical_outputs();
296 n_physical_inputs = _engine.n_physical_inputs();
298 first_stage_init (fullpath, snapshot_name);
300 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
302 if (create (new_session, mix_template, compute_initial_length())) {
303 cerr << "create failed\n";
305 throw failed_constructor ();
309 if (second_stage_init (new_session)) {
311 throw failed_constructor ();
314 store_recent_sessions(_name, _path);
316 bool was_dirty = dirty();
318 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
320 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
323 DirtyChanged (); /* EMIT SIGNAL */
327 Session::Session (AudioEngine &eng,
329 string snapshot_name,
330 AutoConnectOption input_ac,
331 AutoConnectOption output_ac,
332 uint32_t control_out_channels,
333 uint32_t master_out_channels,
334 uint32_t requested_physical_in,
335 uint32_t requested_physical_out,
336 nframes_t initial_length)
339 _scratch_buffers(new BufferSet()),
340 _silent_buffers(new BufferSet()),
341 _send_buffers(new BufferSet()),
342 _mmc_port (default_mmc_port),
343 _mtc_port (default_mtc_port),
344 _midi_port (default_midi_port),
345 pending_events (2048),
346 //midi_requests (16),
347 _send_smpte_update (false),
348 diskstreams (new DiskstreamList),
349 routes (new RouteList),
355 if (!eng.connected()) {
356 throw failed_constructor();
359 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
361 n_physical_outputs = _engine.n_physical_outputs();
362 n_physical_inputs = _engine.n_physical_inputs();
364 if (n_physical_inputs) {
365 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
368 if (n_physical_outputs) {
369 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
372 first_stage_init (fullpath, snapshot_name);
374 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
377 if (create (new_session, 0, initial_length)) {
379 throw failed_constructor ();
384 /* set up Master Out and Control Out if necessary */
389 if (control_out_channels) {
390 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
391 r->set_remote_control_id (control_id++);
396 if (master_out_channels) {
397 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
398 r->set_remote_control_id (control_id);
402 /* prohibit auto-connect to master, because there isn't one */
403 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
412 Config->set_input_auto_connect (input_ac);
413 Config->set_output_auto_connect (output_ac);
415 if (second_stage_init (new_session)) {
417 throw failed_constructor ();
420 store_recent_sessions(_name, _path);
422 bool was_dirty = dirty ();
424 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
426 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
429 DirtyChanged (); /* EMIT SIGNAL */
441 /* if we got to here, leaving pending capture state around
445 remove_pending_capture_state ();
447 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
448 _engine.remove_session ();
450 GoingAway (); /* EMIT SIGNAL */
456 /* clear history so that no references to objects are held any more */
460 /* clear state tree so that no references to objects are held any more */
466 terminate_butler_thread ();
467 //terminate_midi_thread ();
469 if (click_data && click_data != default_click) {
470 delete [] click_data;
473 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
474 delete [] click_emphasis_data;
479 delete _scratch_buffers;
480 delete _silent_buffers;
481 delete _send_buffers;
483 AudioDiskstream::free_working_buffers();
485 #undef TRACK_DESTRUCTION
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete named selections\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
490 NamedSelectionList::iterator tmp;
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete playlists\n";
501 #endif /* TRACK_DESTRUCTION */
502 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
503 PlaylistList::iterator tmp;
508 (*i)->drop_references ();
513 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
514 PlaylistList::iterator tmp;
519 (*i)->drop_references ();
525 unused_playlists.clear ();
527 #ifdef TRACK_DESTRUCTION
528 cerr << "delete regions\n";
529 #endif /* TRACK_DESTRUCTION */
531 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
532 RegionList::iterator tmp;
537 i->second->drop_references ();
544 #ifdef TRACK_DESTRUCTION
545 cerr << "delete routes\n";
546 #endif /* TRACK_DESTRUCTION */
548 RCUWriter<RouteList> writer (routes);
549 boost::shared_ptr<RouteList> r = writer.get_copy ();
550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
551 (*i)->drop_references ();
554 /* writer goes out of scope and updates master */
559 #ifdef TRACK_DESTRUCTION
560 cerr << "delete diskstreams\n";
561 #endif /* TRACK_DESTRUCTION */
563 RCUWriter<DiskstreamList> dwriter (diskstreams);
564 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
565 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
566 (*i)->drop_references ();
570 diskstreams.flush ();
572 #ifdef TRACK_DESTRUCTION
573 cerr << "delete audio sources\n";
574 #endif /* TRACK_DESTRUCTION */
575 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
576 SourceMap::iterator tmp;
581 i->second->drop_references ();
588 #ifdef TRACK_DESTRUCTION
589 cerr << "delete mix groups\n";
590 #endif /* TRACK_DESTRUCTION */
591 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
592 list<RouteGroup*>::iterator tmp;
602 #ifdef TRACK_DESTRUCTION
603 cerr << "delete edit groups\n";
604 #endif /* TRACK_DESTRUCTION */
605 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
606 list<RouteGroup*>::iterator tmp;
616 #ifdef TRACK_DESTRUCTION
617 cerr << "delete connections\n";
618 #endif /* TRACK_DESTRUCTION */
619 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
620 ConnectionList::iterator tmp;
630 if (butler_mixdown_buffer) {
631 delete [] butler_mixdown_buffer;
634 if (butler_gain_buffer) {
635 delete [] butler_gain_buffer;
638 Crossfade::set_buffer_size (0);
646 Session::set_worst_io_latencies ()
648 _worst_output_latency = 0;
649 _worst_input_latency = 0;
651 if (!_engine.connected()) {
655 boost::shared_ptr<RouteList> r = routes.reader ();
657 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
658 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
659 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
664 Session::when_engine_running ()
666 string first_physical_output;
668 /* we don't want to run execute this again */
670 set_block_size (_engine.frames_per_cycle());
671 set_frame_rate (_engine.frame_rate());
673 Config->map_parameters (mem_fun (*this, &Session::config_changed));
675 /* every time we reconnect, recompute worst case output latencies */
677 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
679 if (synced_to_jack()) {
680 _engine.transport_stop ();
683 if (Config->get_jack_time_master()) {
684 _engine.transport_locate (_transport_frame);
692 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
694 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
696 /* existing state for Click */
698 if (_click_io->set_state (*child->children().front()) == 0) {
700 _clicking = Config->get_clicking ();
704 error << _("could not setup Click I/O") << endmsg;
710 /* default state for Click */
712 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
714 if (first_physical_output.length()) {
715 if (_click_io->add_output_port (first_physical_output, this)) {
716 // relax, even though its an error
718 _clicking = Config->get_clicking ();
724 catch (failed_constructor& err) {
725 error << _("cannot setup Click I/O") << endmsg;
728 set_worst_io_latencies ();
731 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
734 /* Create a set of Connection objects that map
735 to the physical outputs currently available
740 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
742 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
744 Connection* c = new OutputConnection (buf, true);
747 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
752 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
754 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
756 Connection* c = new InputConnection (buf, true);
759 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
766 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
768 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
770 Connection* c = new OutputConnection (buf, true);
774 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
775 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
780 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
782 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
784 Connection* c = new InputConnection (buf, true);
788 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
789 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
798 /* create master/control ports */
803 /* force the master to ignore any later call to this */
805 if (_master_out->pending_state_node) {
806 _master_out->ports_became_legal();
809 /* no panner resets till we are through */
811 _master_out->defer_pan_reset ();
813 while (_master_out->n_inputs().get(DataType::AUDIO)
814 < _master_out->input_maximum().get(DataType::AUDIO)) {
815 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
816 error << _("cannot setup master inputs")
822 while (_master_out->n_outputs().get(DataType::AUDIO)
823 < _master_out->output_maximum().get(DataType::AUDIO)) {
824 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
825 error << _("cannot setup master outputs")
832 _master_out->allow_pan_reset ();
836 Connection* c = new OutputConnection (_("Master Out"), true);
838 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
840 c->add_connection ((int) n, _master_out->input(n)->name());
847 /* catch up on send+insert cnts */
851 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
854 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
855 if (id > insert_cnt) {
863 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
866 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
874 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
876 /* hook us up to the engine */
878 _engine.set_session (this);
883 osc->set_session (*this);
886 _state_of_the_state = Clean;
888 DirtyChanged (); /* EMIT SIGNAL */
892 Session::hookup_io ()
894 /* stop graph reordering notifications from
895 causing resorts, etc.
898 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
900 if (auditioner == 0) {
902 /* we delay creating the auditioner till now because
903 it makes its own connections to ports.
904 the engine has to be running for this to work.
908 auditioner.reset (new Auditioner (*this));
911 catch (failed_constructor& err) {
912 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
916 /* Tell all IO objects to create their ports */
923 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
924 if (_control_out->add_input_port ("", this)) {
925 error << _("cannot setup control inputs")
931 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
932 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
933 error << _("cannot set up master outputs")
941 /* Tell all IO objects to connect themselves together */
943 IO::enable_connecting ();
945 /* Now reset all panners */
947 IO::reset_panners ();
949 /* Anyone who cares about input state, wake up and do something */
951 IOConnectionsComplete (); /* EMIT SIGNAL */
953 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
955 /* now handle the whole enchilada as if it was one
961 /* update mixer solo state */
967 Session::playlist_length_changed ()
969 /* we can't just increase end_location->end() if pl->get_maximum_extent()
970 if larger. if the playlist used to be the longest playlist,
971 and its now shorter, we have to decrease end_location->end(). hence,
972 we have to iterate over all diskstreams and check the
973 playlists currently in use.
979 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
981 boost::shared_ptr<Playlist> playlist;
983 if ((playlist = dstream->playlist()) != 0) {
984 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
987 /* see comment in playlist_length_changed () */
992 Session::record_enabling_legal () const
994 /* this used to be in here, but survey says.... we don't need to restrict it */
995 // if (record_status() == Recording) {
999 if (Config->get_all_safe()) {
1006 Session::reset_input_monitor_state ()
1008 if (transport_rolling()) {
1010 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1012 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1013 if ((*i)->record_enabled ()) {
1014 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1015 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1019 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1021 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1022 if ((*i)->record_enabled ()) {
1023 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1024 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1031 Session::auto_punch_start_changed (Location* location)
1033 replace_event (Event::PunchIn, location->start());
1035 if (get_record_enabled() && Config->get_punch_in()) {
1036 /* capture start has been changed, so save new pending state */
1037 save_state ("", true);
1042 Session::auto_punch_end_changed (Location* location)
1044 nframes_t when_to_stop = location->end();
1045 // when_to_stop += _worst_output_latency + _worst_input_latency;
1046 replace_event (Event::PunchOut, when_to_stop);
1050 Session::auto_punch_changed (Location* location)
1052 nframes_t when_to_stop = location->end();
1054 replace_event (Event::PunchIn, location->start());
1055 //when_to_stop += _worst_output_latency + _worst_input_latency;
1056 replace_event (Event::PunchOut, when_to_stop);
1060 Session::auto_loop_changed (Location* location)
1062 replace_event (Event::AutoLoop, location->end(), location->start());
1064 if (transport_rolling() && play_loop) {
1066 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1068 if (_transport_frame > location->end()) {
1069 // relocate to beginning of loop
1070 clear_events (Event::LocateRoll);
1072 request_locate (location->start(), true);
1075 else if (Config->get_seamless_loop() && !loop_changing) {
1077 // schedule a locate-roll to refill the diskstreams at the
1078 // previous loop end
1079 loop_changing = true;
1081 if (location->end() > last_loopend) {
1082 clear_events (Event::LocateRoll);
1083 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1090 last_loopend = location->end();
1095 Session::set_auto_punch_location (Location* location)
1099 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1100 auto_punch_start_changed_connection.disconnect();
1101 auto_punch_end_changed_connection.disconnect();
1102 auto_punch_changed_connection.disconnect();
1103 existing->set_auto_punch (false, this);
1104 remove_event (existing->start(), Event::PunchIn);
1105 clear_events (Event::PunchOut);
1106 auto_punch_location_changed (0);
1111 if (location == 0) {
1115 if (location->end() <= location->start()) {
1116 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1120 auto_punch_start_changed_connection.disconnect();
1121 auto_punch_end_changed_connection.disconnect();
1122 auto_punch_changed_connection.disconnect();
1124 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1125 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1126 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1128 location->set_auto_punch (true, this);
1129 auto_punch_location_changed (location);
1133 Session::set_auto_loop_location (Location* location)
1137 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1138 auto_loop_start_changed_connection.disconnect();
1139 auto_loop_end_changed_connection.disconnect();
1140 auto_loop_changed_connection.disconnect();
1141 existing->set_auto_loop (false, this);
1142 remove_event (existing->end(), Event::AutoLoop);
1143 auto_loop_location_changed (0);
1148 if (location == 0) {
1152 if (location->end() <= location->start()) {
1153 error << _("Session: you can't use a mark for auto loop") << endmsg;
1157 last_loopend = location->end();
1159 auto_loop_start_changed_connection.disconnect();
1160 auto_loop_end_changed_connection.disconnect();
1161 auto_loop_changed_connection.disconnect();
1163 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1164 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1165 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1167 location->set_auto_loop (true, this);
1168 auto_loop_location_changed (location);
1172 Session::locations_added (Location* ignored)
1178 Session::locations_changed ()
1180 _locations.apply (*this, &Session::handle_locations_changed);
1184 Session::handle_locations_changed (Locations::LocationList& locations)
1186 Locations::LocationList::iterator i;
1188 bool set_loop = false;
1189 bool set_punch = false;
1191 for (i = locations.begin(); i != locations.end(); ++i) {
1195 if (location->is_auto_punch()) {
1196 set_auto_punch_location (location);
1199 if (location->is_auto_loop()) {
1200 set_auto_loop_location (location);
1207 set_auto_loop_location (0);
1210 set_auto_punch_location (0);
1217 Session::enable_record ()
1219 /* XXX really atomic compare+swap here */
1220 if (g_atomic_int_get (&_record_status) != Recording) {
1221 g_atomic_int_set (&_record_status, Recording);
1222 _last_record_location = _transport_frame;
1223 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1225 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1226 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1227 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1228 if ((*i)->record_enabled ()) {
1229 (*i)->monitor_input (true);
1234 RecordStateChanged ();
1239 Session::disable_record (bool rt_context, bool force)
1243 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1245 if (!Config->get_latched_record_enable () || force) {
1246 g_atomic_int_set (&_record_status, Disabled);
1248 if (rs == Recording) {
1249 g_atomic_int_set (&_record_status, Enabled);
1253 // FIXME: timestamp correct? [DR]
1254 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1255 // does this /need/ to be sent in all cases?
1257 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1259 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1260 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1262 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1263 if ((*i)->record_enabled ()) {
1264 (*i)->monitor_input (false);
1269 RecordStateChanged (); /* emit signal */
1272 remove_pending_capture_state ();
1278 Session::step_back_from_record ()
1280 g_atomic_int_set (&_record_status, Enabled);
1282 if (Config->get_monitoring_model() == HardwareMonitoring) {
1283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1286 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1287 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1288 (*i)->monitor_input (false);
1295 Session::maybe_enable_record ()
1297 g_atomic_int_set (&_record_status, Enabled);
1299 /* this function is currently called from somewhere other than an RT thread.
1300 this save_state() call therefore doesn't impact anything.
1303 save_state ("", true);
1305 if (_transport_speed) {
1306 if (!Config->get_punch_in()) {
1310 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1311 RecordStateChanged (); /* EMIT SIGNAL */
1318 Session::audible_frame () const
1324 /* the first of these two possible settings for "offset"
1325 mean that the audible frame is stationary until
1326 audio emerges from the latency compensation
1329 the second means that the audible frame is stationary
1330 until audio would emerge from a physical port
1331 in the absence of any plugin latency compensation
1334 offset = _worst_output_latency;
1336 if (offset > current_block_size) {
1337 offset -= current_block_size;
1339 /* XXX is this correct? if we have no external
1340 physical connections and everything is internal
1341 then surely this is zero? still, how
1342 likely is that anyway?
1344 offset = current_block_size;
1347 if (synced_to_jack()) {
1348 tf = _engine.transport_frame();
1350 tf = _transport_frame;
1353 if (_transport_speed == 0) {
1363 if (!non_realtime_work_pending()) {
1367 /* take latency into account */
1376 Session::set_frame_rate (nframes_t frames_per_second)
1378 /** \fn void Session::set_frame_size(nframes_t)
1379 the AudioEngine object that calls this guarantees
1380 that it will not be called while we are also in
1381 ::process(). Its fine to do things that block
1385 _base_frame_rate = frames_per_second;
1389 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1391 // XXX we need some equivalent to this, somehow
1392 // SndFileSource::setup_standard_crossfades (frames_per_second);
1396 /* XXX need to reset/reinstantiate all LADSPA plugins */
1400 Session::set_block_size (nframes_t nframes)
1402 /* the AudioEngine guarantees
1403 that it will not be called while we are also in
1404 ::process(). It is therefore fine to do things that block
1410 current_block_size = nframes;
1412 ensure_buffers(_scratch_buffers->available());
1414 if (_gain_automation_buffer) {
1415 delete [] _gain_automation_buffer;
1417 _gain_automation_buffer = new gain_t[nframes];
1419 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1421 boost::shared_ptr<RouteList> r = routes.reader ();
1423 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1424 (*i)->set_block_size (nframes);
1427 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1428 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1429 (*i)->set_block_size (nframes);
1432 set_worst_io_latencies ();
1437 Session::set_default_fade (float steepness, float fade_msecs)
1440 nframes_t fade_frames;
1442 /* Don't allow fade of less 1 frame */
1444 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1451 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1455 default_fade_msecs = fade_msecs;
1456 default_fade_steepness = steepness;
1459 // jlc, WTF is this!
1460 Glib::RWLock::ReaderLock lm (route_lock);
1461 AudioRegion::set_default_fade (steepness, fade_frames);
1466 /* XXX have to do this at some point */
1467 /* foreach region using default fade, reset, then
1468 refill_all_diskstream_buffers ();
1473 struct RouteSorter {
1474 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1475 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1477 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1480 if (r1->fed_by.empty()) {
1481 if (r2->fed_by.empty()) {
1482 /* no ardour-based connections inbound to either route. just use signal order */
1483 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1485 /* r2 has connections, r1 does not; run r1 early */
1489 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1496 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1498 shared_ptr<Route> r2;
1500 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1501 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1505 /* make a copy of the existing list of routes that feed r1 */
1507 set<shared_ptr<Route> > existing = r1->fed_by;
1509 /* for each route that feeds r1, recurse, marking it as feeding
1513 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1516 /* r2 is a route that feeds r1 which somehow feeds base. mark
1517 base as being fed by r2
1520 rbase->fed_by.insert (r2);
1524 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1528 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1532 /* now recurse, so that we can mark base as being fed by
1533 all routes that feed r2
1536 trace_terminal (r2, rbase);
1543 Session::resort_routes ()
1545 /* don't do anything here with signals emitted
1546 by Routes while we are being destroyed.
1549 if (_state_of_the_state & Deletion) {
1556 RCUWriter<RouteList> writer (routes);
1557 shared_ptr<RouteList> r = writer.get_copy ();
1558 resort_routes_using (r);
1559 /* writer goes out of scope and forces update */
1564 Session::resort_routes_using (shared_ptr<RouteList> r)
1566 RouteList::iterator i, j;
1568 for (i = r->begin(); i != r->end(); ++i) {
1570 (*i)->fed_by.clear ();
1572 for (j = r->begin(); j != r->end(); ++j) {
1574 /* although routes can feed themselves, it will
1575 cause an endless recursive descent if we
1576 detect it. so don't bother checking for
1584 if ((*j)->feeds (*i)) {
1585 (*i)->fed_by.insert (*j);
1590 for (i = r->begin(); i != r->end(); ++i) {
1591 trace_terminal (*i, *i);
1598 cerr << "finished route resort\n";
1600 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1601 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1608 list<boost::shared_ptr<MidiTrack> >
1609 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1611 char track_name[32];
1612 uint32_t track_id = 0;
1614 uint32_t channels_used = 0;
1616 RouteList new_routes;
1617 list<boost::shared_ptr<MidiTrack> > ret;
1619 /* count existing midi tracks */
1622 shared_ptr<RouteList> r = routes.reader ();
1624 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1625 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1626 if (!(*i)->hidden()) {
1628 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1636 /* check for duplicate route names, since we might have pre-existing
1637 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1638 save, close,restart,add new route - first named route is now
1646 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1648 if (route_by_name (track_name) == 0) {
1652 } while (track_id < (UINT_MAX-1));
1655 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1657 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1658 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1661 channels_used += track->n_inputs ().get(DataType::MIDI);
1663 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1664 track->set_remote_control_id (ntracks());
1666 new_routes.push_back (track);
1667 ret.push_back (track);
1670 catch (failed_constructor &err) {
1671 error << _("Session: could not create new midi track.") << endmsg;
1672 // XXX should we delete the tracks already created?
1680 if (!new_routes.empty()) {
1681 add_routes (new_routes, false);
1682 save_state (_current_snapshot_name);
1688 list<boost::shared_ptr<AudioTrack> >
1689 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1691 char track_name[32];
1692 uint32_t track_id = 0;
1694 uint32_t channels_used = 0;
1696 RouteList new_routes;
1697 list<boost::shared_ptr<AudioTrack> > ret;
1698 uint32_t control_id;
1700 /* count existing audio tracks */
1703 shared_ptr<RouteList> r = routes.reader ();
1705 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1706 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1707 if (!(*i)->hidden()) {
1709 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1715 vector<string> physinputs;
1716 vector<string> physoutputs;
1717 uint32_t nphysical_in;
1718 uint32_t nphysical_out;
1720 _engine.get_physical_outputs (physoutputs);
1721 _engine.get_physical_inputs (physinputs);
1722 control_id = ntracks() + nbusses() + 1;
1726 /* check for duplicate route names, since we might have pre-existing
1727 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1728 save, close,restart,add new route - first named route is now
1736 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1738 if (route_by_name (track_name) == 0) {
1742 } while (track_id < (UINT_MAX-1));
1744 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1745 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1750 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1751 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1756 shared_ptr<AudioTrack> track;
1759 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1761 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1762 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1763 input_channels, output_channels)
1769 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1773 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1774 port = physinputs[(channels_used+x)%nphysical_in];
1777 if (port.length() && track->connect_input (track->input (x), port, this)) {
1783 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1787 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1788 port = physoutputs[(channels_used+x)%nphysical_out];
1789 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1791 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1795 if (port.length() && track->connect_output (track->output (x), port, this)) {
1800 channels_used += track->n_inputs ().get(DataType::AUDIO);
1803 vector<string> cports;
1804 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1806 for (n = 0; n < ni; ++n) {
1807 cports.push_back (_control_out->input(n)->name());
1810 track->set_control_outs (cports);
1813 // assert (current_thread != RT_thread)
1815 track->audio_diskstream()->non_realtime_input_change();
1817 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1818 track->set_remote_control_id (control_id);
1821 new_routes.push_back (track);
1822 ret.push_back (track);
1825 catch (failed_constructor &err) {
1826 error << _("Session: could not create new audio track.") << endmsg;
1829 /* we need to get rid of this, since the track failed to be created */
1830 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1833 RCUWriter<DiskstreamList> writer (diskstreams);
1834 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1835 ds->remove (track->audio_diskstream());
1842 catch (AudioEngine::PortRegistrationFailure& pfe) {
1844 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;
1847 /* we need to get rid of this, since the track failed to be created */
1848 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1851 RCUWriter<DiskstreamList> writer (diskstreams);
1852 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1853 ds->remove (track->audio_diskstream());
1864 if (!new_routes.empty()) {
1865 add_routes (new_routes, false);
1866 save_state (_current_snapshot_name);
1873 Session::set_remote_control_ids ()
1875 RemoteModel m = Config->get_remote_model();
1877 shared_ptr<RouteList> r = routes.reader ();
1879 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1880 if ( MixerOrdered == m) {
1881 long order = (*i)->order_key(N_("signal"));
1882 (*i)->set_remote_control_id( order+1 );
1883 } else if ( EditorOrdered == m) {
1884 long order = (*i)->order_key(N_("editor"));
1885 (*i)->set_remote_control_id( order+1 );
1886 } else if ( UserOrdered == m) {
1887 //do nothing ... only changes to remote id's are initiated by user
1894 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1897 uint32_t bus_id = 1;
1901 uint32_t control_id;
1903 /* count existing audio busses */
1906 shared_ptr<RouteList> r = routes.reader ();
1908 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1909 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1910 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1917 vector<string> physinputs;
1918 vector<string> physoutputs;
1920 _engine.get_physical_outputs (physoutputs);
1921 _engine.get_physical_inputs (physinputs);
1922 control_id = ntracks() + nbusses() + 1;
1927 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1929 if (route_by_name (bus_name) == 0) {
1933 } while (++bus_id < (UINT_MAX-1));
1936 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1938 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1939 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1940 input_channels, output_channels)
1945 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1949 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1950 port = physinputs[((n+x)%n_physical_inputs)];
1953 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1958 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1962 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1963 port = physoutputs[((n+x)%n_physical_outputs)];
1964 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1966 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1970 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1976 vector<string> cports;
1977 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1979 for (uint32_t n = 0; n < ni; ++n) {
1980 cports.push_back (_control_out->input(n)->name());
1982 bus->set_control_outs (cports);
1985 bus->set_remote_control_id (control_id);
1988 ret.push_back (bus);
1992 catch (failed_constructor &err) {
1993 error << _("Session: could not create new audio route.") << endmsg;
1997 catch (AudioEngine::PortRegistrationFailure& pfe) {
1998 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;
2008 add_routes (ret, false);
2009 save_state (_current_snapshot_name);
2017 Session::add_routes (RouteList& new_routes, bool save)
2020 RCUWriter<RouteList> writer (routes);
2021 shared_ptr<RouteList> r = writer.get_copy ();
2022 r->insert (r->end(), new_routes.begin(), new_routes.end());
2023 resort_routes_using (r);
2026 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2028 boost::weak_ptr<Route> wpr (*x);
2030 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2031 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2032 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2033 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2035 if ((*x)->master()) {
2039 if ((*x)->control()) {
2040 _control_out = (*x);
2047 save_state (_current_snapshot_name);
2050 RouteAdded (new_routes); /* EMIT SIGNAL */
2054 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2056 /* need to do this in case we're rolling at the time, to prevent false underruns */
2057 dstream->do_refill_with_alloc ();
2059 dstream->set_block_size (current_block_size);
2062 RCUWriter<DiskstreamList> writer (diskstreams);
2063 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2064 ds->push_back (dstream);
2065 /* writer goes out of scope, copies ds back to main */
2068 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2069 /* this will connect to future changes, and check the current length */
2070 diskstream_playlist_changed (dstream);
2072 dstream->prepare ();
2077 Session::remove_route (shared_ptr<Route> route)
2080 RCUWriter<RouteList> writer (routes);
2081 shared_ptr<RouteList> rs = writer.get_copy ();
2085 /* deleting the master out seems like a dumb
2086 idea, but its more of a UI policy issue
2090 if (route == _master_out) {
2091 _master_out = shared_ptr<Route> ();
2094 if (route == _control_out) {
2095 _control_out = shared_ptr<Route> ();
2097 /* cancel control outs for all routes */
2099 vector<string> empty;
2101 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2102 (*r)->set_control_outs (empty);
2106 update_route_solo_state ();
2108 /* writer goes out of scope, forces route list update */
2112 boost::shared_ptr<Diskstream> ds;
2114 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2115 ds = t->diskstream();
2121 RCUWriter<DiskstreamList> dsl (diskstreams);
2122 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2127 find_current_end ();
2129 update_latency_compensation (false, false);
2132 // We need to disconnect the routes inputs and outputs
2133 route->disconnect_inputs(NULL);
2134 route->disconnect_outputs(NULL);
2136 /* get rid of it from the dead wood collection in the route list manager */
2138 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2142 /* try to cause everyone to drop their references */
2144 route->drop_references ();
2146 /* save the new state of the world */
2148 if (save_state (_current_snapshot_name)) {
2149 save_history (_current_snapshot_name);
2154 Session::route_mute_changed (void* src)
2160 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2162 if (solo_update_disabled) {
2168 boost::shared_ptr<Route> route = wpr.lock ();
2171 /* should not happen */
2172 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2176 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2178 shared_ptr<RouteList> r = routes.reader ();
2180 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2182 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2186 /* don't mess with busses */
2188 if (dynamic_cast<Track*>((*i).get()) == 0) {
2194 /* don't mess with tracks */
2196 if (dynamic_cast<Track*>((*i).get()) != 0) {
2201 if ((*i) != route &&
2202 ((*i)->mix_group () == 0 ||
2203 (*i)->mix_group () != route->mix_group () ||
2204 !route->mix_group ()->is_active())) {
2206 if ((*i)->soloed()) {
2208 /* if its already soloed, and solo latching is enabled,
2209 then leave it as it is.
2212 if (Config->get_solo_latched()) {
2219 solo_update_disabled = true;
2220 (*i)->set_solo (false, src);
2221 solo_update_disabled = false;
2225 bool something_soloed = false;
2226 bool same_thing_soloed = false;
2227 bool signal = false;
2229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2230 if ((*i)->soloed()) {
2231 something_soloed = true;
2232 if (dynamic_cast<Track*>((*i).get())) {
2234 same_thing_soloed = true;
2239 same_thing_soloed = true;
2247 if (something_soloed != currently_soloing) {
2249 currently_soloing = something_soloed;
2252 modify_solo_mute (is_track, same_thing_soloed);
2255 SoloActive (currently_soloing); /* EMIT SIGNAL */
2258 SoloChanged (); /* EMIT SIGNAL */
2264 Session::update_route_solo_state ()
2267 bool is_track = false;
2268 bool signal = false;
2270 /* caller must hold RouteLock */
2272 /* this is where we actually implement solo by changing
2273 the solo mute setting of each track.
2276 shared_ptr<RouteList> r = routes.reader ();
2278 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2279 if ((*i)->soloed()) {
2281 if (dynamic_cast<Track*>((*i).get())) {
2288 if (mute != currently_soloing) {
2290 currently_soloing = mute;
2293 if (!is_track && !mute) {
2295 /* nothing is soloed */
2297 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2298 (*i)->set_solo_mute (false);
2308 modify_solo_mute (is_track, mute);
2311 SoloActive (currently_soloing);
2316 Session::modify_solo_mute (bool is_track, bool mute)
2318 shared_ptr<RouteList> r = routes.reader ();
2320 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2324 /* only alter track solo mute */
2326 if (dynamic_cast<Track*>((*i).get())) {
2327 if ((*i)->soloed()) {
2328 (*i)->set_solo_mute (!mute);
2330 (*i)->set_solo_mute (mute);
2336 /* only alter bus solo mute */
2338 if (!dynamic_cast<Track*>((*i).get())) {
2340 if ((*i)->soloed()) {
2342 (*i)->set_solo_mute (false);
2346 /* don't mute master or control outs
2347 in response to another bus solo
2350 if ((*i) != _master_out &&
2351 (*i) != _control_out) {
2352 (*i)->set_solo_mute (mute);
2363 Session::catch_up_on_solo ()
2365 /* this is called after set_state() to catch the full solo
2366 state, which can't be correctly determined on a per-route
2367 basis, but needs the global overview that only the session
2370 update_route_solo_state();
2374 Session::route_by_name (string name)
2376 shared_ptr<RouteList> r = routes.reader ();
2378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2379 if ((*i)->name() == name) {
2384 return shared_ptr<Route> ((Route*) 0);
2388 Session::route_by_id (PBD::ID id)
2390 shared_ptr<RouteList> r = routes.reader ();
2392 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2393 if ((*i)->id() == id) {
2398 return shared_ptr<Route> ((Route*) 0);
2402 Session::route_by_remote_id (uint32_t id)
2404 shared_ptr<RouteList> r = routes.reader ();
2406 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2407 if ((*i)->remote_control_id() == id) {
2412 return shared_ptr<Route> ((Route*) 0);
2416 Session::find_current_end ()
2418 if (_state_of_the_state & Loading) {
2422 nframes_t max = get_maximum_extent ();
2424 if (max > end_location->end()) {
2425 end_location->set_end (max);
2427 DurationChanged(); /* EMIT SIGNAL */
2432 Session::get_maximum_extent () const
2437 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2439 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2440 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2441 if ((me = pl->get_maximum_extent()) > max) {
2449 boost::shared_ptr<Diskstream>
2450 Session::diskstream_by_name (string name)
2452 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2454 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2455 if ((*i)->name() == name) {
2460 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2463 boost::shared_ptr<Diskstream>
2464 Session::diskstream_by_id (const PBD::ID& id)
2466 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2468 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2469 if ((*i)->id() == id) {
2474 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2477 /* Region management */
2480 Session::new_region_name (string old)
2482 string::size_type last_period;
2484 string::size_type len = old.length() + 64;
2487 if ((last_period = old.find_last_of ('.')) == string::npos) {
2489 /* no period present - add one explicitly */
2492 last_period = old.length() - 1;
2497 number = atoi (old.substr (last_period+1).c_str());
2501 while (number < (UINT_MAX-1)) {
2503 RegionList::const_iterator i;
2508 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2511 for (i = regions.begin(); i != regions.end(); ++i) {
2512 if (i->second->name() == sbuf) {
2517 if (i == regions.end()) {
2522 if (number != (UINT_MAX-1)) {
2526 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2531 Session::region_name (string& result, string base, bool newlevel) const
2536 assert(base.find("/") == string::npos);
2540 Glib::Mutex::Lock lm (region_lock);
2542 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2550 /* XXX this is going to be slow. optimize me later */
2555 string::size_type pos;
2557 pos = base.find_last_of ('.');
2559 /* pos may be npos, but then we just use entire base */
2561 subbase = base.substr (0, pos);
2565 bool name_taken = true;
2568 Glib::Mutex::Lock lm (region_lock);
2570 for (int n = 1; n < 5000; ++n) {
2573 snprintf (buf, sizeof (buf), ".%d", n);
2578 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2579 if (i->second->name() == result) {
2592 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2600 Session::add_region (boost::shared_ptr<Region> region)
2602 boost::shared_ptr<Region> other;
2606 Glib::Mutex::Lock lm (region_lock);
2608 RegionList::iterator x;
2610 for (x = regions.begin(); x != regions.end(); ++x) {
2614 if (region->region_list_equivalent (other)) {
2619 if (x == regions.end()) {
2621 pair<RegionList::key_type,RegionList::mapped_type> entry;
2623 entry.first = region->id();
2624 entry.second = region;
2626 pair<RegionList::iterator,bool> x = regions.insert (entry);
2638 /* mark dirty because something has changed even if we didn't
2639 add the region to the region list.
2645 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2646 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2647 RegionAdded (region); /* EMIT SIGNAL */
2652 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2654 boost::shared_ptr<Region> region (weak_region.lock ());
2660 if (what_changed & Region::HiddenChanged) {
2661 /* relay hidden changes */
2662 RegionHiddenChange (region);
2667 Session::remove_region (boost::weak_ptr<Region> weak_region)
2669 RegionList::iterator i;
2670 boost::shared_ptr<Region> region (weak_region.lock ());
2676 bool removed = false;
2679 Glib::Mutex::Lock lm (region_lock);
2681 if ((i = regions.find (region->id())) != regions.end()) {
2687 /* mark dirty because something has changed even if we didn't
2688 remove the region from the region list.
2694 RegionRemoved(region); /* EMIT SIGNAL */
2698 boost::shared_ptr<Region>
2699 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2701 RegionList::iterator i;
2702 boost::shared_ptr<Region> region;
2704 Glib::Mutex::Lock lm (region_lock);
2706 for (i = regions.begin(); i != regions.end(); ++i) {
2710 if (region->whole_file()) {
2712 if (child->source_equivalent (region)) {
2718 return boost::shared_ptr<Region> ();
2722 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2724 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2725 (*i)->get_region_list_equivalent_regions (region, result);
2729 Session::destroy_region (boost::shared_ptr<Region> region)
2731 vector<boost::shared_ptr<Source> > srcs;
2734 boost::shared_ptr<AudioRegion> aregion;
2736 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2740 if (aregion->playlist()) {
2741 aregion->playlist()->destroy_region (region);
2744 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2745 srcs.push_back (aregion->source (n));
2749 region->drop_references ();
2751 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2753 if (!(*i)->used()) {
2754 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2757 (afs)->mark_for_remove ();
2760 (*i)->drop_references ();
2762 cerr << "source was not used by any playlist\n";
2770 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2772 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2773 destroy_region (*i);
2779 Session::remove_last_capture ()
2781 list<boost::shared_ptr<Region> > r;
2783 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2785 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2786 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2789 r.insert (r.end(), l.begin(), l.end());
2794 destroy_regions (r);
2796 save_state (_current_snapshot_name);
2802 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2808 /* Source Management */
2810 Session::add_source (boost::shared_ptr<Source> source)
2812 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2813 pair<SourceMap::iterator,bool> result;
2815 entry.first = source->id();
2816 entry.second = source;
2819 Glib::Mutex::Lock lm (source_lock);
2820 result = sources.insert (entry);
2823 if (result.second) {
2824 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2830 Session::remove_source (boost::weak_ptr<Source> src)
2832 SourceMap::iterator i;
2833 boost::shared_ptr<Source> source = src.lock();
2840 Glib::Mutex::Lock lm (source_lock);
2843 Glib::Mutex::Lock lm (source_lock);
2845 if ((i = sources.find (source->id())) != sources.end()) {
2851 if (!_state_of_the_state & InCleanup) {
2853 /* save state so we don't end up with a session file
2854 referring to non-existent sources.
2857 save_state (_current_snapshot_name);
2861 boost::shared_ptr<Source>
2862 Session::source_by_id (const PBD::ID& id)
2864 Glib::Mutex::Lock lm (source_lock);
2865 SourceMap::iterator i;
2866 boost::shared_ptr<Source> source;
2868 if ((i = sources.find (id)) != sources.end()) {
2872 /* XXX search MIDI or other searches here */
2878 boost::shared_ptr<Source>
2879 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2881 Glib::Mutex::Lock lm (source_lock);
2883 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2884 cerr << "comparing " << path << " with " << i->second->name() << endl;
2885 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2887 if (afs && afs->path() == path && chn == afs->channel()) {
2892 return boost::shared_ptr<Source>();
2896 Session::peak_path_from_audio_path (string audio_path) const
2901 res += PBD::basename_nosuffix (audio_path);
2908 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2911 string old_basename = PBD::basename_nosuffix (oldname);
2912 string new_legalized = legalize_for_path (newname);
2914 /* note: we know (or assume) the old path is already valid */
2918 /* destructive file sources have a name of the form:
2920 /path/to/Tnnnn-NAME(%[LR])?.wav
2922 the task here is to replace NAME with the new name.
2925 /* find last slash */
2929 string::size_type slash;
2930 string::size_type dash;
2932 if ((slash = path.find_last_of ('/')) == string::npos) {
2936 dir = path.substr (0, slash+1);
2938 /* '-' is not a legal character for the NAME part of the path */
2940 if ((dash = path.find_last_of ('-')) == string::npos) {
2944 prefix = path.substr (slash+1, dash-(slash+1));
2949 path += new_legalized;
2950 path += ".wav"; /* XXX gag me with a spoon */
2954 /* non-destructive file sources have a name of the form:
2956 /path/to/NAME-nnnnn(%[LR])?.wav
2958 the task here is to replace NAME with the new name.
2963 string::size_type slash;
2964 string::size_type dash;
2965 string::size_type postfix;
2967 /* find last slash */
2969 if ((slash = path.find_last_of ('/')) == string::npos) {
2973 dir = path.substr (0, slash+1);
2975 /* '-' is not a legal character for the NAME part of the path */
2977 if ((dash = path.find_last_of ('-')) == string::npos) {
2981 suffix = path.substr (dash+1);
2983 // Suffix is now everything after the dash. Now we need to eliminate
2984 // the nnnnn part, which is done by either finding a '%' or a '.'
2986 postfix = suffix.find_last_of ("%");
2987 if (postfix == string::npos) {
2988 postfix = suffix.find_last_of ('.');
2991 if (postfix != string::npos) {
2992 suffix = suffix.substr (postfix);
2994 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2998 const uint32_t limit = 10000;
2999 char buf[PATH_MAX+1];
3001 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3003 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3005 if (access (buf, F_OK) != 0) {
3013 error << "FATAL ERROR! Could not find a " << endl;
3022 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3026 char buf[PATH_MAX+1];
3027 const uint32_t limit = 10000;
3031 legalized = legalize_for_path (name);
3033 /* find a "version" of the file name that doesn't exist in
3034 any of the possible directories.
3037 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3039 vector<space_and_path>::iterator i;
3040 uint32_t existing = 0;
3042 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3046 spath += sound_dir (false);
3050 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3051 } else if (nchan == 2) {
3053 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3055 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3057 } else if (nchan < 26) {
3058 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3060 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3069 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3070 } else if (nchan == 2) {
3072 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3074 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3076 } else if (nchan < 26) {
3077 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3079 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3083 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3089 if (existing == 0) {
3094 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3096 throw failed_constructor();
3100 /* we now have a unique name for the file, but figure out where to
3106 spath = discover_best_sound_dir ();
3109 string::size_type pos = foo.find_last_of ('/');
3111 if (pos == string::npos) {
3114 spath += foo.substr (pos + 1);
3120 boost::shared_ptr<AudioFileSource>
3121 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3123 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
3124 return boost::dynamic_pointer_cast<AudioFileSource> (
3125 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3128 // FIXME: _terrible_ code duplication
3130 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3133 string old_basename = PBD::basename_nosuffix (oldname);
3134 string new_legalized = legalize_for_path (newname);
3136 /* note: we know (or assume) the old path is already valid */
3140 /* destructive file sources have a name of the form:
3142 /path/to/Tnnnn-NAME(%[LR])?.wav
3144 the task here is to replace NAME with the new name.
3147 /* find last slash */
3151 string::size_type slash;
3152 string::size_type dash;
3154 if ((slash = path.find_last_of ('/')) == string::npos) {
3158 dir = path.substr (0, slash+1);
3160 /* '-' is not a legal character for the NAME part of the path */
3162 if ((dash = path.find_last_of ('-')) == string::npos) {
3166 prefix = path.substr (slash+1, dash-(slash+1));
3171 path += new_legalized;
3172 path += ".mid"; /* XXX gag me with a spoon */
3176 /* non-destructive file sources have a name of the form:
3178 /path/to/NAME-nnnnn(%[LR])?.wav
3180 the task here is to replace NAME with the new name.
3185 string::size_type slash;
3186 string::size_type dash;
3187 string::size_type postfix;
3189 /* find last slash */
3191 if ((slash = path.find_last_of ('/')) == string::npos) {
3195 dir = path.substr (0, slash+1);
3197 /* '-' is not a legal character for the NAME part of the path */
3199 if ((dash = path.find_last_of ('-')) == string::npos) {
3203 suffix = path.substr (dash+1);
3205 // Suffix is now everything after the dash. Now we need to eliminate
3206 // the nnnnn part, which is done by either finding a '%' or a '.'
3208 postfix = suffix.find_last_of ("%");
3209 if (postfix == string::npos) {
3210 postfix = suffix.find_last_of ('.');
3213 if (postfix != string::npos) {
3214 suffix = suffix.substr (postfix);
3216 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3220 const uint32_t limit = 10000;
3221 char buf[PATH_MAX+1];
3223 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3225 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3227 if (access (buf, F_OK) != 0) {
3235 error << "FATAL ERROR! Could not find a " << endl;
3244 Session::midi_path_from_name (string name)
3248 char buf[PATH_MAX+1];
3249 const uint32_t limit = 10000;
3253 legalized = legalize_for_path (name);
3255 /* find a "version" of the file name that doesn't exist in
3256 any of the possible directories.
3259 for (cnt = 1; cnt <= limit; ++cnt) {
3261 vector<space_and_path>::iterator i;
3262 uint32_t existing = 0;
3264 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3268 // FIXME: different directory from audio?
3269 spath += sound_dir(false) + "/" + legalized;
3271 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3273 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3278 if (existing == 0) {
3283 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3284 throw failed_constructor();
3288 /* we now have a unique name for the file, but figure out where to
3294 // FIXME: different directory than audio?
3295 spath = discover_best_sound_dir ();
3298 string::size_type pos = foo.find_last_of ('/');
3300 if (pos == string::npos) {
3303 spath += foo.substr (pos + 1);
3309 boost::shared_ptr<MidiSource>
3310 Session::create_midi_source_for_session (MidiDiskstream& ds)
3312 string spath = midi_path_from_name (ds.name());
3314 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3318 /* Playlist management */
3320 boost::shared_ptr<Playlist>
3321 Session::playlist_by_name (string name)
3323 Glib::Mutex::Lock lm (playlist_lock);
3324 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3325 if ((*i)->name() == name) {
3329 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3330 if ((*i)->name() == name) {
3335 return boost::shared_ptr<Playlist>();
3339 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3341 if (playlist->hidden()) {
3346 Glib::Mutex::Lock lm (playlist_lock);
3347 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3348 playlists.insert (playlists.begin(), playlist);
3349 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3350 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3356 PlaylistAdded (playlist); /* EMIT SIGNAL */
3360 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3363 Glib::Mutex::Lock lm (playlist_lock);
3364 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3367 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3374 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3376 boost::shared_ptr<Playlist> pl(wpl.lock());
3382 PlaylistList::iterator x;
3385 /* its not supposed to be visible */
3390 Glib::Mutex::Lock lm (playlist_lock);
3394 unused_playlists.insert (pl);
3396 if ((x = playlists.find (pl)) != playlists.end()) {
3397 playlists.erase (x);
3403 playlists.insert (pl);
3405 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3406 unused_playlists.erase (x);
3413 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3415 if (_state_of_the_state & Deletion) {
3419 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3426 Glib::Mutex::Lock lm (playlist_lock);
3428 PlaylistList::iterator i;
3430 i = find (playlists.begin(), playlists.end(), playlist);
3431 if (i != playlists.end()) {
3432 playlists.erase (i);
3435 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3436 if (i != unused_playlists.end()) {
3437 unused_playlists.erase (i);
3444 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3448 Session::set_audition (boost::shared_ptr<Region> r)
3450 pending_audition_region = r;
3451 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3452 schedule_butler_transport_work ();
3456 Session::audition_playlist ()
3458 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3459 ev->region.reset ();
3464 Session::non_realtime_set_audition ()
3466 if (!pending_audition_region) {
3467 auditioner->audition_current_playlist ();
3469 auditioner->audition_region (pending_audition_region);
3470 pending_audition_region.reset ();
3472 AuditionActive (true); /* EMIT SIGNAL */
3476 Session::audition_region (boost::shared_ptr<Region> r)
3478 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3484 Session::cancel_audition ()
3486 if (auditioner->active()) {
3487 auditioner->cancel_audition ();
3488 AuditionActive (false); /* EMIT SIGNAL */
3493 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3495 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3499 Session::remove_empty_sounds ()
3501 PathScanner scanner;
3503 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3505 Glib::Mutex::Lock lm (source_lock);
3507 regex_t compiled_tape_track_pattern;
3510 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3514 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3516 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3520 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3522 /* never remove files that appear to be a tape track */
3524 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3529 if (AudioFileSource::is_empty (*this, *(*i))) {
3531 unlink ((*i)->c_str());
3533 string peak_path = peak_path_from_audio_path (**i);
3534 unlink (peak_path.c_str());
3540 delete possible_audiofiles;
3544 Session::is_auditioning () const
3546 /* can be called before we have an auditioner object */
3548 return auditioner->active();
3555 Session::set_all_solo (bool yn)
3557 shared_ptr<RouteList> r = routes.reader ();
3559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3560 if (!(*i)->hidden()) {
3561 (*i)->set_solo (yn, this);
3569 Session::set_all_mute (bool yn)
3571 shared_ptr<RouteList> r = routes.reader ();
3573 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3574 if (!(*i)->hidden()) {
3575 (*i)->set_mute (yn, this);
3583 Session::n_diskstreams () const
3587 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3589 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3590 if (!(*i)->hidden()) {
3598 Session::graph_reordered ()
3600 /* don't do this stuff if we are setting up connections
3601 from a set_state() call or creating new tracks.
3604 if (_state_of_the_state & InitialConnecting) {
3608 /* every track/bus asked for this to be handled but it was deferred because
3609 we were connecting. do it now.
3612 request_input_change_handling ();
3616 /* force all diskstreams to update their capture offset values to
3617 reflect any changes in latencies within the graph.
3620 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3622 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3623 (*i)->set_capture_offset ();
3628 Session::record_disenable_all ()
3630 record_enable_change_all (false);
3634 Session::record_enable_all ()
3636 record_enable_change_all (true);
3640 Session::record_enable_change_all (bool yn)
3642 shared_ptr<RouteList> r = routes.reader ();
3644 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3647 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3648 at->set_record_enable (yn, this);
3652 /* since we don't keep rec-enable state, don't mark session dirty */
3656 Session::add_redirect (Redirect* redirect)
3660 PortInsert* port_insert;
3661 PluginInsert* plugin_insert;
3663 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3664 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3665 _port_inserts.insert (_port_inserts.begin(), port_insert);
3666 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3667 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3669 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3672 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3673 _sends.insert (_sends.begin(), send);
3675 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3679 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3685 Session::remove_redirect (Redirect* redirect)
3689 PortInsert* port_insert;
3690 PluginInsert* plugin_insert;
3692 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3693 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3694 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3695 if (x != _port_inserts.end()) {
3696 insert_bitset[port_insert->bit_slot()] = false;
3697 _port_inserts.erase (x);
3699 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3700 _plugin_inserts.remove (plugin_insert);
3702 fatal << string_compose (_("programming error: %1"),
3703 X_("unknown type of Insert deleted!"))
3707 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3708 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3709 if (x != _sends.end()) {
3710 send_bitset[send->bit_slot()] = false;
3714 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3722 Session::available_capture_duration ()
3724 float sample_bytes_on_disk = 4.0; // keep gcc happy
3726 switch (Config->get_native_file_data_format()) {
3728 sample_bytes_on_disk = 4.0;
3732 sample_bytes_on_disk = 3.0;
3736 /* impossible, but keep some gcc versions happy */
3737 fatal << string_compose (_("programming error: %1"),
3738 X_("illegal native file data format"))
3743 double scale = 4096.0 / sample_bytes_on_disk;
3745 if (_total_free_4k_blocks * scale > (double) max_frames) {
3749 return (nframes_t) floor (_total_free_4k_blocks * scale);
3753 Session::add_connection (ARDOUR::Connection* connection)
3756 Glib::Mutex::Lock guard (connection_lock);
3757 _connections.push_back (connection);
3760 ConnectionAdded (connection); /* EMIT SIGNAL */
3766 Session::remove_connection (ARDOUR::Connection* connection)
3768 bool removed = false;
3771 Glib::Mutex::Lock guard (connection_lock);
3772 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3774 if (i != _connections.end()) {
3775 _connections.erase (i);
3781 ConnectionRemoved (connection); /* EMIT SIGNAL */
3787 ARDOUR::Connection *
3788 Session::connection_by_name (string name) const
3790 Glib::Mutex::Lock lm (connection_lock);
3792 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3793 if ((*i)->name() == name) {
3802 Session::tempo_map_changed (Change ignored)
3808 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3809 * the given count with the current block size.
3812 Session::ensure_buffers (ChanCount howmany)
3814 // FIXME: NASTY assumption (midi block size == audio block size)
3815 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3816 _send_buffers->ensure_buffers(howmany, current_block_size);
3817 _silent_buffers->ensure_buffers(howmany, current_block_size);
3819 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3823 Session::next_insert_id ()
3825 /* this doesn't really loop forever. just think about it */
3828 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3829 if (!insert_bitset[n]) {
3830 insert_bitset[n] = true;
3836 /* none available, so resize and try again */
3838 insert_bitset.resize (insert_bitset.size() + 16, false);
3843 Session::next_send_id ()
3845 /* this doesn't really loop forever. just think about it */
3848 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3849 if (!send_bitset[n]) {
3850 send_bitset[n] = true;
3856 /* none available, so resize and try again */
3858 send_bitset.resize (send_bitset.size() + 16, false);
3863 Session::mark_send_id (uint32_t id)
3865 if (id >= send_bitset.size()) {
3866 send_bitset.resize (id+16, false);
3868 if (send_bitset[id]) {
3869 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3871 send_bitset[id] = true;
3875 Session::mark_insert_id (uint32_t id)
3877 if (id >= insert_bitset.size()) {
3878 insert_bitset.resize (id+16, false);
3880 if (insert_bitset[id]) {
3881 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3883 insert_bitset[id] = true;
3886 /* Named Selection management */
3889 Session::named_selection_by_name (string name)
3891 Glib::Mutex::Lock lm (named_selection_lock);
3892 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3893 if ((*i)->name == name) {
3901 Session::add_named_selection (NamedSelection* named_selection)
3904 Glib::Mutex::Lock lm (named_selection_lock);
3905 named_selections.insert (named_selections.begin(), named_selection);
3908 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3914 NamedSelectionAdded (); /* EMIT SIGNAL */
3918 Session::remove_named_selection (NamedSelection* named_selection)
3920 bool removed = false;
3923 Glib::Mutex::Lock lm (named_selection_lock);
3925 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3927 if (i != named_selections.end()) {
3929 named_selections.erase (i);
3936 NamedSelectionRemoved (); /* EMIT SIGNAL */
3941 Session::reset_native_file_format ()
3943 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3945 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3946 (*i)->reset_write_sources (false);
3951 Session::route_name_unique (string n) const
3953 shared_ptr<RouteList> r = routes.reader ();
3955 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3956 if ((*i)->name() == n) {
3965 Session::n_playlists () const
3967 Glib::Mutex::Lock lm (playlist_lock);
3968 return playlists.size();
3972 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3974 if (!force && howmany <= _npan_buffers) {
3978 if (_pan_automation_buffer) {
3980 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3981 delete [] _pan_automation_buffer[i];
3984 delete [] _pan_automation_buffer;
3987 _pan_automation_buffer = new pan_t*[howmany];
3989 for (uint32_t i = 0; i < howmany; ++i) {
3990 _pan_automation_buffer[i] = new pan_t[nframes];
3993 _npan_buffers = howmany;
3997 Session::freeze (InterThreadInfo& itt)
3999 shared_ptr<RouteList> r = routes.reader ();
4001 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4005 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4006 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4017 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
4018 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4021 boost::shared_ptr<Playlist> playlist;
4022 boost::shared_ptr<AudioFileSource> fsource;
4024 char buf[PATH_MAX+1];
4026 ChanCount nchans(track.audio_diskstream()->n_channels());
4028 nframes_t this_chunk;
4032 // any bigger than this seems to cause stack overflows in called functions
4033 const nframes_t chunk_size = (128 * 1024)/4;
4035 g_atomic_int_set (&processing_prohibited, 1);
4037 /* call tree *MUST* hold route_lock */
4039 if ((playlist = track.diskstream()->playlist()) == 0) {
4043 /* external redirects will be a problem */
4045 if (track.has_external_redirects()) {
4049 dir = discover_best_sound_dir ();
4051 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
4053 for (x = 0; x < 99999; ++x) {
4054 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4055 if (access (buf, F_OK) != 0) {
4061 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4066 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4067 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4070 catch (failed_constructor& err) {
4071 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4075 srcs.push_back (fsource);
4078 /* XXX need to flush all redirects */
4083 /* create a set of reasonably-sized buffers */
4084 buffers.ensure_buffers(nchans, chunk_size);
4085 buffers.set_count(nchans);
4087 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4088 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4090 afs->prepare_for_peakfile_writes ();
4093 while (to_do && !itt.cancel) {
4095 this_chunk = min (to_do, chunk_size);
4097 if (track.export_stuff (buffers, start, this_chunk)) {
4102 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4103 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4106 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
4112 start += this_chunk;
4113 to_do -= this_chunk;
4115 itt.progress = (float) (1.0 - ((double) to_do / len));
4124 xnow = localtime (&now);
4126 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4127 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4130 afs->update_header (position, *xnow, now);
4131 afs->flush_header ();
4135 /* construct a region to represent the bounced material */
4137 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4138 region_name_from_path (srcs.front()->name(), true));
4145 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4146 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4149 afs->mark_for_remove ();
4152 (*src)->drop_references ();
4156 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4157 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4160 afs->done_with_peakfile_writes ();
4164 g_atomic_int_set (&processing_prohibited, 0);
4172 Session::get_silent_buffers (ChanCount count)
4174 assert(_silent_buffers->available() >= count);
4175 _silent_buffers->set_count(count);
4177 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4178 for (size_t i=0; i < count.get(*t); ++i) {
4179 _silent_buffers->get(*t, i).clear();
4183 return *_silent_buffers;
4187 Session::get_scratch_buffers (ChanCount count)
4189 assert(_scratch_buffers->available() >= count);
4190 _scratch_buffers->set_count(count);
4191 return *_scratch_buffers;
4195 Session::get_send_buffers (ChanCount count)
4197 assert(_send_buffers->available() >= count);
4198 _send_buffers->set_count(count);
4199 return *_send_buffers;
4203 Session::ntracks () const
4206 shared_ptr<RouteList> r = routes.reader ();
4208 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4209 if (dynamic_cast<Track*> ((*i).get())) {
4218 Session::nbusses () const
4221 shared_ptr<RouteList> r = routes.reader ();
4223 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4224 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4233 Session::add_automation_list(AutomationList *al)
4235 automation_lists[al->id()] = al;
4239 Session::compute_initial_length ()
4241 return _engine.frame_rate() * 60 * 5;