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 cerr << "dropping refs on a region (" << i->second->name() << " @ " << i->second << ") with UC = " << i->second.use_count() << endl;
538 i->second->drop_references ();
539 cerr << "AFTER: UC = " << i->second.use_count() << endl;
546 #ifdef TRACK_DESTRUCTION
547 cerr << "delete routes\n";
548 #endif /* TRACK_DESTRUCTION */
550 RCUWriter<RouteList> writer (routes);
551 boost::shared_ptr<RouteList> r = writer.get_copy ();
552 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
553 (*i)->drop_references ();
556 /* writer goes out of scope and updates master */
561 #ifdef TRACK_DESTRUCTION
562 cerr << "delete diskstreams\n";
563 #endif /* TRACK_DESTRUCTION */
565 RCUWriter<DiskstreamList> dwriter (diskstreams);
566 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
567 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
568 (*i)->drop_references ();
572 diskstreams.flush ();
574 #ifdef TRACK_DESTRUCTION
575 cerr << "delete audio sources\n";
576 #endif /* TRACK_DESTRUCTION */
577 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
578 SourceMap::iterator tmp;
583 i->second->drop_references ();
590 #ifdef TRACK_DESTRUCTION
591 cerr << "delete mix groups\n";
592 #endif /* TRACK_DESTRUCTION */
593 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
594 list<RouteGroup*>::iterator tmp;
604 #ifdef TRACK_DESTRUCTION
605 cerr << "delete edit groups\n";
606 #endif /* TRACK_DESTRUCTION */
607 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
608 list<RouteGroup*>::iterator tmp;
618 #ifdef TRACK_DESTRUCTION
619 cerr << "delete connections\n";
620 #endif /* TRACK_DESTRUCTION */
621 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
622 ConnectionList::iterator tmp;
632 if (butler_mixdown_buffer) {
633 delete [] butler_mixdown_buffer;
636 if (butler_gain_buffer) {
637 delete [] butler_gain_buffer;
640 Crossfade::set_buffer_size (0);
648 Session::set_worst_io_latencies ()
650 _worst_output_latency = 0;
651 _worst_input_latency = 0;
653 if (!_engine.connected()) {
657 boost::shared_ptr<RouteList> r = routes.reader ();
659 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
660 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
661 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
666 Session::when_engine_running ()
668 string first_physical_output;
670 /* we don't want to run execute this again */
672 set_block_size (_engine.frames_per_cycle());
673 set_frame_rate (_engine.frame_rate());
675 Config->map_parameters (mem_fun (*this, &Session::config_changed));
677 /* every time we reconnect, recompute worst case output latencies */
679 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
681 if (synced_to_jack()) {
682 _engine.transport_stop ();
685 if (Config->get_jack_time_master()) {
686 _engine.transport_locate (_transport_frame);
694 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
696 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
698 /* existing state for Click */
700 if (_click_io->set_state (*child->children().front()) == 0) {
702 _clicking = Config->get_clicking ();
706 error << _("could not setup Click I/O") << endmsg;
712 /* default state for Click */
714 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
716 if (first_physical_output.length()) {
717 if (_click_io->add_output_port (first_physical_output, this)) {
718 // relax, even though its an error
720 _clicking = Config->get_clicking ();
726 catch (failed_constructor& err) {
727 error << _("cannot setup Click I/O") << endmsg;
730 set_worst_io_latencies ();
733 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
736 /* Create a set of Connection objects that map
737 to the physical outputs currently available
742 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
744 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
746 Connection* c = new OutputConnection (buf, true);
749 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
754 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
756 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
758 Connection* c = new InputConnection (buf, true);
761 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
768 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
770 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
772 Connection* c = new OutputConnection (buf, true);
776 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
777 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
782 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
784 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
786 Connection* c = new InputConnection (buf, true);
790 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
791 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
800 /* create master/control ports */
805 /* force the master to ignore any later call to this */
807 if (_master_out->pending_state_node) {
808 _master_out->ports_became_legal();
811 /* no panner resets till we are through */
813 _master_out->defer_pan_reset ();
815 while (_master_out->n_inputs().get(DataType::AUDIO)
816 < _master_out->input_maximum().get(DataType::AUDIO)) {
817 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
818 error << _("cannot setup master inputs")
824 while (_master_out->n_outputs().get(DataType::AUDIO)
825 < _master_out->output_maximum().get(DataType::AUDIO)) {
826 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
827 error << _("cannot setup master outputs")
834 _master_out->allow_pan_reset ();
838 Connection* c = new OutputConnection (_("Master Out"), true);
840 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
842 c->add_connection ((int) n, _master_out->input(n)->name());
849 /* catch up on send+insert cnts */
853 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
856 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
857 if (id > insert_cnt) {
865 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
868 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
876 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
878 /* hook us up to the engine */
880 _engine.set_session (this);
885 osc->set_session (*this);
888 _state_of_the_state = Clean;
890 DirtyChanged (); /* EMIT SIGNAL */
894 Session::hookup_io ()
896 /* stop graph reordering notifications from
897 causing resorts, etc.
900 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
902 if (auditioner == 0) {
904 /* we delay creating the auditioner till now because
905 it makes its own connections to ports.
906 the engine has to be running for this to work.
910 auditioner.reset (new Auditioner (*this));
913 catch (failed_constructor& err) {
914 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
918 /* Tell all IO objects to create their ports */
925 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
926 if (_control_out->add_input_port ("", this)) {
927 error << _("cannot setup control inputs")
933 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
934 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
935 error << _("cannot set up master outputs")
943 /* Tell all IO objects to connect themselves together */
945 IO::enable_connecting ();
947 /* Now reset all panners */
949 IO::reset_panners ();
951 /* Anyone who cares about input state, wake up and do something */
953 IOConnectionsComplete (); /* EMIT SIGNAL */
955 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
957 /* now handle the whole enchilada as if it was one
963 /* update mixer solo state */
969 Session::playlist_length_changed ()
971 /* we can't just increase end_location->end() if pl->get_maximum_extent()
972 if larger. if the playlist used to be the longest playlist,
973 and its now shorter, we have to decrease end_location->end(). hence,
974 we have to iterate over all diskstreams and check the
975 playlists currently in use.
981 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
983 boost::shared_ptr<Playlist> playlist;
985 if ((playlist = dstream->playlist()) != 0) {
986 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
989 /* see comment in playlist_length_changed () */
994 Session::record_enabling_legal () const
996 /* this used to be in here, but survey says.... we don't need to restrict it */
997 // if (record_status() == Recording) {
1001 if (Config->get_all_safe()) {
1008 Session::reset_input_monitor_state ()
1010 if (transport_rolling()) {
1012 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1014 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1015 if ((*i)->record_enabled ()) {
1016 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1017 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1021 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1023 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1024 if ((*i)->record_enabled ()) {
1025 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1026 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1033 Session::auto_punch_start_changed (Location* location)
1035 replace_event (Event::PunchIn, location->start());
1037 if (get_record_enabled() && Config->get_punch_in()) {
1038 /* capture start has been changed, so save new pending state */
1039 save_state ("", true);
1044 Session::auto_punch_end_changed (Location* location)
1046 nframes_t when_to_stop = location->end();
1047 // when_to_stop += _worst_output_latency + _worst_input_latency;
1048 replace_event (Event::PunchOut, when_to_stop);
1052 Session::auto_punch_changed (Location* location)
1054 nframes_t when_to_stop = location->end();
1056 replace_event (Event::PunchIn, location->start());
1057 //when_to_stop += _worst_output_latency + _worst_input_latency;
1058 replace_event (Event::PunchOut, when_to_stop);
1062 Session::auto_loop_changed (Location* location)
1064 replace_event (Event::AutoLoop, location->end(), location->start());
1066 if (transport_rolling() && play_loop) {
1068 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1070 if (_transport_frame > location->end()) {
1071 // relocate to beginning of loop
1072 clear_events (Event::LocateRoll);
1074 request_locate (location->start(), true);
1077 else if (Config->get_seamless_loop() && !loop_changing) {
1079 // schedule a locate-roll to refill the diskstreams at the
1080 // previous loop end
1081 loop_changing = true;
1083 if (location->end() > last_loopend) {
1084 clear_events (Event::LocateRoll);
1085 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1092 last_loopend = location->end();
1097 Session::set_auto_punch_location (Location* location)
1101 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1102 auto_punch_start_changed_connection.disconnect();
1103 auto_punch_end_changed_connection.disconnect();
1104 auto_punch_changed_connection.disconnect();
1105 existing->set_auto_punch (false, this);
1106 remove_event (existing->start(), Event::PunchIn);
1107 clear_events (Event::PunchOut);
1108 auto_punch_location_changed (0);
1113 if (location == 0) {
1117 if (location->end() <= location->start()) {
1118 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1122 auto_punch_start_changed_connection.disconnect();
1123 auto_punch_end_changed_connection.disconnect();
1124 auto_punch_changed_connection.disconnect();
1126 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1127 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1128 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1130 location->set_auto_punch (true, this);
1131 auto_punch_location_changed (location);
1135 Session::set_auto_loop_location (Location* location)
1139 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1140 auto_loop_start_changed_connection.disconnect();
1141 auto_loop_end_changed_connection.disconnect();
1142 auto_loop_changed_connection.disconnect();
1143 existing->set_auto_loop (false, this);
1144 remove_event (existing->end(), Event::AutoLoop);
1145 auto_loop_location_changed (0);
1150 if (location == 0) {
1154 if (location->end() <= location->start()) {
1155 error << _("Session: you can't use a mark for auto loop") << endmsg;
1159 last_loopend = location->end();
1161 auto_loop_start_changed_connection.disconnect();
1162 auto_loop_end_changed_connection.disconnect();
1163 auto_loop_changed_connection.disconnect();
1165 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1166 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1167 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1169 location->set_auto_loop (true, this);
1170 auto_loop_location_changed (location);
1174 Session::locations_added (Location* ignored)
1180 Session::locations_changed ()
1182 _locations.apply (*this, &Session::handle_locations_changed);
1186 Session::handle_locations_changed (Locations::LocationList& locations)
1188 Locations::LocationList::iterator i;
1190 bool set_loop = false;
1191 bool set_punch = false;
1193 for (i = locations.begin(); i != locations.end(); ++i) {
1197 if (location->is_auto_punch()) {
1198 set_auto_punch_location (location);
1201 if (location->is_auto_loop()) {
1202 set_auto_loop_location (location);
1209 set_auto_loop_location (0);
1212 set_auto_punch_location (0);
1219 Session::enable_record ()
1221 /* XXX really atomic compare+swap here */
1222 if (g_atomic_int_get (&_record_status) != Recording) {
1223 g_atomic_int_set (&_record_status, Recording);
1224 _last_record_location = _transport_frame;
1225 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1227 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1228 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1229 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1230 if ((*i)->record_enabled ()) {
1231 (*i)->monitor_input (true);
1236 RecordStateChanged ();
1241 Session::disable_record (bool rt_context, bool force)
1245 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1247 if (!Config->get_latched_record_enable () || force) {
1248 g_atomic_int_set (&_record_status, Disabled);
1250 if (rs == Recording) {
1251 g_atomic_int_set (&_record_status, Enabled);
1255 // FIXME: timestamp correct? [DR]
1256 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1257 // does this /need/ to be sent in all cases?
1259 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1261 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1262 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1264 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1265 if ((*i)->record_enabled ()) {
1266 (*i)->monitor_input (false);
1271 RecordStateChanged (); /* emit signal */
1274 remove_pending_capture_state ();
1280 Session::step_back_from_record ()
1282 g_atomic_int_set (&_record_status, Enabled);
1284 if (Config->get_monitoring_model() == HardwareMonitoring) {
1285 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1287 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1288 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1289 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1290 (*i)->monitor_input (false);
1297 Session::maybe_enable_record ()
1299 g_atomic_int_set (&_record_status, Enabled);
1301 /* this function is currently called from somewhere other than an RT thread.
1302 this save_state() call therefore doesn't impact anything.
1305 save_state ("", true);
1307 if (_transport_speed) {
1308 if (!Config->get_punch_in()) {
1312 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1313 RecordStateChanged (); /* EMIT SIGNAL */
1320 Session::audible_frame () const
1326 /* the first of these two possible settings for "offset"
1327 mean that the audible frame is stationary until
1328 audio emerges from the latency compensation
1331 the second means that the audible frame is stationary
1332 until audio would emerge from a physical port
1333 in the absence of any plugin latency compensation
1336 offset = _worst_output_latency;
1338 if (offset > current_block_size) {
1339 offset -= current_block_size;
1341 /* XXX is this correct? if we have no external
1342 physical connections and everything is internal
1343 then surely this is zero? still, how
1344 likely is that anyway?
1346 offset = current_block_size;
1349 if (synced_to_jack()) {
1350 tf = _engine.transport_frame();
1352 tf = _transport_frame;
1355 if (_transport_speed == 0) {
1365 if (!non_realtime_work_pending()) {
1369 /* take latency into account */
1378 Session::set_frame_rate (nframes_t frames_per_second)
1380 /** \fn void Session::set_frame_size(nframes_t)
1381 the AudioEngine object that calls this guarantees
1382 that it will not be called while we are also in
1383 ::process(). Its fine to do things that block
1387 _base_frame_rate = frames_per_second;
1391 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1393 // XXX we need some equivalent to this, somehow
1394 // SndFileSource::setup_standard_crossfades (frames_per_second);
1398 /* XXX need to reset/reinstantiate all LADSPA plugins */
1402 Session::set_block_size (nframes_t nframes)
1404 /* the AudioEngine guarantees
1405 that it will not be called while we are also in
1406 ::process(). It is therefore fine to do things that block
1412 current_block_size = nframes;
1414 ensure_buffers(_scratch_buffers->available());
1416 if (_gain_automation_buffer) {
1417 delete [] _gain_automation_buffer;
1419 _gain_automation_buffer = new gain_t[nframes];
1421 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1423 boost::shared_ptr<RouteList> r = routes.reader ();
1425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1426 (*i)->set_block_size (nframes);
1429 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1431 (*i)->set_block_size (nframes);
1434 set_worst_io_latencies ();
1439 Session::set_default_fade (float steepness, float fade_msecs)
1442 nframes_t fade_frames;
1444 /* Don't allow fade of less 1 frame */
1446 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1453 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1457 default_fade_msecs = fade_msecs;
1458 default_fade_steepness = steepness;
1461 // jlc, WTF is this!
1462 Glib::RWLock::ReaderLock lm (route_lock);
1463 AudioRegion::set_default_fade (steepness, fade_frames);
1468 /* XXX have to do this at some point */
1469 /* foreach region using default fade, reset, then
1470 refill_all_diskstream_buffers ();
1475 struct RouteSorter {
1476 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1477 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1479 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1482 if (r1->fed_by.empty()) {
1483 if (r2->fed_by.empty()) {
1484 /* no ardour-based connections inbound to either route. just use signal order */
1485 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1487 /* r2 has connections, r1 does not; run r1 early */
1491 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1498 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1500 shared_ptr<Route> r2;
1502 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1503 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1507 /* make a copy of the existing list of routes that feed r1 */
1509 set<shared_ptr<Route> > existing = r1->fed_by;
1511 /* for each route that feeds r1, recurse, marking it as feeding
1515 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1518 /* r2 is a route that feeds r1 which somehow feeds base. mark
1519 base as being fed by r2
1522 rbase->fed_by.insert (r2);
1526 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1530 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1534 /* now recurse, so that we can mark base as being fed by
1535 all routes that feed r2
1538 trace_terminal (r2, rbase);
1545 Session::resort_routes ()
1547 /* don't do anything here with signals emitted
1548 by Routes while we are being destroyed.
1551 if (_state_of_the_state & Deletion) {
1558 RCUWriter<RouteList> writer (routes);
1559 shared_ptr<RouteList> r = writer.get_copy ();
1560 resort_routes_using (r);
1561 /* writer goes out of scope and forces update */
1566 Session::resort_routes_using (shared_ptr<RouteList> r)
1568 RouteList::iterator i, j;
1570 for (i = r->begin(); i != r->end(); ++i) {
1572 (*i)->fed_by.clear ();
1574 for (j = r->begin(); j != r->end(); ++j) {
1576 /* although routes can feed themselves, it will
1577 cause an endless recursive descent if we
1578 detect it. so don't bother checking for
1586 if ((*j)->feeds (*i)) {
1587 (*i)->fed_by.insert (*j);
1592 for (i = r->begin(); i != r->end(); ++i) {
1593 trace_terminal (*i, *i);
1600 cerr << "finished route resort\n";
1602 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1603 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1610 list<boost::shared_ptr<MidiTrack> >
1611 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1613 char track_name[32];
1614 uint32_t track_id = 0;
1616 uint32_t channels_used = 0;
1618 RouteList new_routes;
1619 list<boost::shared_ptr<MidiTrack> > ret;
1621 /* count existing midi tracks */
1624 shared_ptr<RouteList> r = routes.reader ();
1626 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1627 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1628 if (!(*i)->hidden()) {
1630 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1638 /* check for duplicate route names, since we might have pre-existing
1639 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1640 save, close,restart,add new route - first named route is now
1648 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1650 if (route_by_name (track_name) == 0) {
1654 } while (track_id < (UINT_MAX-1));
1657 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1659 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1660 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1663 channels_used += track->n_inputs ().get(DataType::MIDI);
1665 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1666 track->set_remote_control_id (ntracks());
1668 new_routes.push_back (track);
1669 ret.push_back (track);
1672 catch (failed_constructor &err) {
1673 error << _("Session: could not create new midi track.") << endmsg;
1674 // XXX should we delete the tracks already created?
1682 if (!new_routes.empty()) {
1683 add_routes (new_routes, false);
1684 save_state (_current_snapshot_name);
1690 list<boost::shared_ptr<AudioTrack> >
1691 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1693 char track_name[32];
1694 uint32_t track_id = 0;
1696 uint32_t channels_used = 0;
1698 RouteList new_routes;
1699 list<boost::shared_ptr<AudioTrack> > ret;
1700 uint32_t control_id;
1702 /* count existing audio tracks */
1705 shared_ptr<RouteList> r = routes.reader ();
1707 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1708 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1709 if (!(*i)->hidden()) {
1711 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1717 vector<string> physinputs;
1718 vector<string> physoutputs;
1719 uint32_t nphysical_in;
1720 uint32_t nphysical_out;
1722 _engine.get_physical_outputs (physoutputs);
1723 _engine.get_physical_inputs (physinputs);
1724 control_id = ntracks() + nbusses() + 1;
1728 /* check for duplicate route names, since we might have pre-existing
1729 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1730 save, close,restart,add new route - first named route is now
1738 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1740 if (route_by_name (track_name) == 0) {
1744 } while (track_id < (UINT_MAX-1));
1746 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1747 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1752 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1753 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1758 shared_ptr<AudioTrack> track;
1761 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1763 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1764 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1765 input_channels, output_channels)
1771 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1775 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1776 port = physinputs[(channels_used+x)%nphysical_in];
1779 if (port.length() && track->connect_input (track->input (x), port, this)) {
1785 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1789 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1790 port = physoutputs[(channels_used+x)%nphysical_out];
1791 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1793 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1797 if (port.length() && track->connect_output (track->output (x), port, this)) {
1802 channels_used += track->n_inputs ().get(DataType::AUDIO);
1805 vector<string> cports;
1806 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1808 for (n = 0; n < ni; ++n) {
1809 cports.push_back (_control_out->input(n)->name());
1812 track->set_control_outs (cports);
1815 // assert (current_thread != RT_thread)
1817 track->audio_diskstream()->non_realtime_input_change();
1819 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1820 track->set_remote_control_id (control_id);
1823 new_routes.push_back (track);
1824 ret.push_back (track);
1827 catch (failed_constructor &err) {
1828 error << _("Session: could not create new audio track.") << endmsg;
1831 /* we need to get rid of this, since the track failed to be created */
1832 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1835 RCUWriter<DiskstreamList> writer (diskstreams);
1836 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1837 ds->remove (track->audio_diskstream());
1844 catch (AudioEngine::PortRegistrationFailure& pfe) {
1846 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;
1849 /* we need to get rid of this, since the track failed to be created */
1850 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1853 RCUWriter<DiskstreamList> writer (diskstreams);
1854 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1855 ds->remove (track->audio_diskstream());
1866 if (!new_routes.empty()) {
1867 add_routes (new_routes, false);
1868 save_state (_current_snapshot_name);
1875 Session::set_remote_control_ids ()
1877 RemoteModel m = Config->get_remote_model();
1879 shared_ptr<RouteList> r = routes.reader ();
1881 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1882 if ( MixerOrdered == m) {
1883 long order = (*i)->order_key(N_("signal"));
1884 (*i)->set_remote_control_id( order+1 );
1885 } else if ( EditorOrdered == m) {
1886 long order = (*i)->order_key(N_("editor"));
1887 (*i)->set_remote_control_id( order+1 );
1888 } else if ( UserOrdered == m) {
1889 //do nothing ... only changes to remote id's are initiated by user
1896 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1899 uint32_t bus_id = 1;
1903 uint32_t control_id;
1905 /* count existing audio busses */
1908 shared_ptr<RouteList> r = routes.reader ();
1910 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1911 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1912 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1919 vector<string> physinputs;
1920 vector<string> physoutputs;
1922 _engine.get_physical_outputs (physoutputs);
1923 _engine.get_physical_inputs (physinputs);
1924 control_id = ntracks() + nbusses() + 1;
1929 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1931 if (route_by_name (bus_name) == 0) {
1935 } while (++bus_id < (UINT_MAX-1));
1938 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1940 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1941 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1942 input_channels, output_channels)
1947 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1951 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1952 port = physinputs[((n+x)%n_physical_inputs)];
1955 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1960 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1964 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1965 port = physoutputs[((n+x)%n_physical_outputs)];
1966 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1968 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1972 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1978 vector<string> cports;
1979 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1981 for (uint32_t n = 0; n < ni; ++n) {
1982 cports.push_back (_control_out->input(n)->name());
1984 bus->set_control_outs (cports);
1987 bus->set_remote_control_id (control_id);
1990 ret.push_back (bus);
1994 catch (failed_constructor &err) {
1995 error << _("Session: could not create new audio route.") << endmsg;
1999 catch (AudioEngine::PortRegistrationFailure& pfe) {
2000 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;
2010 add_routes (ret, false);
2011 save_state (_current_snapshot_name);
2019 Session::add_routes (RouteList& new_routes, bool save)
2022 RCUWriter<RouteList> writer (routes);
2023 shared_ptr<RouteList> r = writer.get_copy ();
2024 r->insert (r->end(), new_routes.begin(), new_routes.end());
2025 resort_routes_using (r);
2028 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2030 boost::weak_ptr<Route> wpr (*x);
2032 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2033 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2034 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2035 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2037 if ((*x)->master()) {
2041 if ((*x)->control()) {
2042 _control_out = (*x);
2049 save_state (_current_snapshot_name);
2052 RouteAdded (new_routes); /* EMIT SIGNAL */
2056 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2058 /* need to do this in case we're rolling at the time, to prevent false underruns */
2059 dstream->do_refill_with_alloc ();
2061 dstream->set_block_size (current_block_size);
2064 RCUWriter<DiskstreamList> writer (diskstreams);
2065 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2066 ds->push_back (dstream);
2067 /* writer goes out of scope, copies ds back to main */
2070 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2071 /* this will connect to future changes, and check the current length */
2072 diskstream_playlist_changed (dstream);
2074 dstream->prepare ();
2079 Session::remove_route (shared_ptr<Route> route)
2082 RCUWriter<RouteList> writer (routes);
2083 shared_ptr<RouteList> rs = writer.get_copy ();
2087 /* deleting the master out seems like a dumb
2088 idea, but its more of a UI policy issue
2092 if (route == _master_out) {
2093 _master_out = shared_ptr<Route> ();
2096 if (route == _control_out) {
2097 _control_out = shared_ptr<Route> ();
2099 /* cancel control outs for all routes */
2101 vector<string> empty;
2103 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2104 (*r)->set_control_outs (empty);
2108 update_route_solo_state ();
2110 /* writer goes out of scope, forces route list update */
2114 boost::shared_ptr<Diskstream> ds;
2116 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2117 ds = t->diskstream();
2123 RCUWriter<DiskstreamList> dsl (diskstreams);
2124 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2129 find_current_end ();
2131 update_latency_compensation (false, false);
2134 // We need to disconnect the routes inputs and outputs
2135 route->disconnect_inputs(NULL);
2136 route->disconnect_outputs(NULL);
2138 /* get rid of it from the dead wood collection in the route list manager */
2140 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2144 /* try to cause everyone to drop their references */
2146 route->drop_references ();
2148 /* save the new state of the world */
2150 if (save_state (_current_snapshot_name)) {
2151 save_history (_current_snapshot_name);
2156 Session::route_mute_changed (void* src)
2162 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2164 if (solo_update_disabled) {
2170 boost::shared_ptr<Route> route = wpr.lock ();
2173 /* should not happen */
2174 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2178 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2180 shared_ptr<RouteList> r = routes.reader ();
2182 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2184 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2188 /* don't mess with busses */
2190 if (dynamic_cast<Track*>((*i).get()) == 0) {
2196 /* don't mess with tracks */
2198 if (dynamic_cast<Track*>((*i).get()) != 0) {
2203 if ((*i) != route &&
2204 ((*i)->mix_group () == 0 ||
2205 (*i)->mix_group () != route->mix_group () ||
2206 !route->mix_group ()->is_active())) {
2208 if ((*i)->soloed()) {
2210 /* if its already soloed, and solo latching is enabled,
2211 then leave it as it is.
2214 if (Config->get_solo_latched()) {
2221 solo_update_disabled = true;
2222 (*i)->set_solo (false, src);
2223 solo_update_disabled = false;
2227 bool something_soloed = false;
2228 bool same_thing_soloed = false;
2229 bool signal = false;
2231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2232 if ((*i)->soloed()) {
2233 something_soloed = true;
2234 if (dynamic_cast<Track*>((*i).get())) {
2236 same_thing_soloed = true;
2241 same_thing_soloed = true;
2249 if (something_soloed != currently_soloing) {
2251 currently_soloing = something_soloed;
2254 modify_solo_mute (is_track, same_thing_soloed);
2257 SoloActive (currently_soloing); /* EMIT SIGNAL */
2260 SoloChanged (); /* EMIT SIGNAL */
2266 Session::update_route_solo_state ()
2269 bool is_track = false;
2270 bool signal = false;
2272 /* caller must hold RouteLock */
2274 /* this is where we actually implement solo by changing
2275 the solo mute setting of each track.
2278 shared_ptr<RouteList> r = routes.reader ();
2280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 if ((*i)->soloed()) {
2283 if (dynamic_cast<Track*>((*i).get())) {
2290 if (mute != currently_soloing) {
2292 currently_soloing = mute;
2295 if (!is_track && !mute) {
2297 /* nothing is soloed */
2299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2300 (*i)->set_solo_mute (false);
2310 modify_solo_mute (is_track, mute);
2313 SoloActive (currently_soloing);
2318 Session::modify_solo_mute (bool is_track, bool mute)
2320 shared_ptr<RouteList> r = routes.reader ();
2322 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2326 /* only alter track solo mute */
2328 if (dynamic_cast<Track*>((*i).get())) {
2329 if ((*i)->soloed()) {
2330 (*i)->set_solo_mute (!mute);
2332 (*i)->set_solo_mute (mute);
2338 /* only alter bus solo mute */
2340 if (!dynamic_cast<Track*>((*i).get())) {
2342 if ((*i)->soloed()) {
2344 (*i)->set_solo_mute (false);
2348 /* don't mute master or control outs
2349 in response to another bus solo
2352 if ((*i) != _master_out &&
2353 (*i) != _control_out) {
2354 (*i)->set_solo_mute (mute);
2365 Session::catch_up_on_solo ()
2367 /* this is called after set_state() to catch the full solo
2368 state, which can't be correctly determined on a per-route
2369 basis, but needs the global overview that only the session
2372 update_route_solo_state();
2376 Session::route_by_name (string name)
2378 shared_ptr<RouteList> r = routes.reader ();
2380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2381 if ((*i)->name() == name) {
2386 return shared_ptr<Route> ((Route*) 0);
2390 Session::route_by_id (PBD::ID id)
2392 shared_ptr<RouteList> r = routes.reader ();
2394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2395 if ((*i)->id() == id) {
2400 return shared_ptr<Route> ((Route*) 0);
2404 Session::route_by_remote_id (uint32_t id)
2406 shared_ptr<RouteList> r = routes.reader ();
2408 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2409 if ((*i)->remote_control_id() == id) {
2414 return shared_ptr<Route> ((Route*) 0);
2418 Session::find_current_end ()
2420 if (_state_of_the_state & Loading) {
2424 nframes_t max = get_maximum_extent ();
2426 if (max > end_location->end()) {
2427 end_location->set_end (max);
2429 DurationChanged(); /* EMIT SIGNAL */
2434 Session::get_maximum_extent () const
2439 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2441 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2442 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2443 if ((me = pl->get_maximum_extent()) > max) {
2451 boost::shared_ptr<Diskstream>
2452 Session::diskstream_by_name (string name)
2454 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2456 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2457 if ((*i)->name() == name) {
2462 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2465 boost::shared_ptr<Diskstream>
2466 Session::diskstream_by_id (const PBD::ID& id)
2468 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2470 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2471 if ((*i)->id() == id) {
2476 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2479 /* Region management */
2482 Session::new_region_name (string old)
2484 string::size_type last_period;
2486 string::size_type len = old.length() + 64;
2489 if ((last_period = old.find_last_of ('.')) == string::npos) {
2491 /* no period present - add one explicitly */
2494 last_period = old.length() - 1;
2499 number = atoi (old.substr (last_period+1).c_str());
2503 while (number < (UINT_MAX-1)) {
2505 RegionList::const_iterator i;
2510 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2513 for (i = regions.begin(); i != regions.end(); ++i) {
2514 if (i->second->name() == sbuf) {
2519 if (i == regions.end()) {
2524 if (number != (UINT_MAX-1)) {
2528 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2533 Session::region_name (string& result, string base, bool newlevel) const
2538 assert(base.find("/") == string::npos);
2542 Glib::Mutex::Lock lm (region_lock);
2544 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2552 /* XXX this is going to be slow. optimize me later */
2557 string::size_type pos;
2559 pos = base.find_last_of ('.');
2561 /* pos may be npos, but then we just use entire base */
2563 subbase = base.substr (0, pos);
2567 bool name_taken = true;
2570 Glib::Mutex::Lock lm (region_lock);
2572 for (int n = 1; n < 5000; ++n) {
2575 snprintf (buf, sizeof (buf), ".%d", n);
2580 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2581 if (i->second->name() == result) {
2594 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2602 Session::add_region (boost::shared_ptr<Region> region)
2604 boost::shared_ptr<Region> other;
2608 Glib::Mutex::Lock lm (region_lock);
2610 RegionList::iterator x;
2612 for (x = regions.begin(); x != regions.end(); ++x) {
2616 if (region->region_list_equivalent (other)) {
2621 if (x == regions.end()) {
2623 pair<RegionList::key_type,RegionList::mapped_type> entry;
2625 entry.first = region->id();
2626 entry.second = region;
2628 pair<RegionList::iterator,bool> x = regions.insert (entry);
2640 /* mark dirty because something has changed even if we didn't
2641 add the region to the region list.
2647 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2648 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2649 RegionAdded (region); /* EMIT SIGNAL */
2654 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2656 boost::shared_ptr<Region> region (weak_region.lock ());
2662 if (what_changed & Region::HiddenChanged) {
2663 /* relay hidden changes */
2664 RegionHiddenChange (region);
2669 Session::remove_region (boost::weak_ptr<Region> weak_region)
2671 RegionList::iterator i;
2672 boost::shared_ptr<Region> region (weak_region.lock ());
2678 bool removed = false;
2681 Glib::Mutex::Lock lm (region_lock);
2683 if ((i = regions.find (region->id())) != regions.end()) {
2689 /* mark dirty because something has changed even if we didn't
2690 remove the region from the region list.
2696 RegionRemoved(region); /* EMIT SIGNAL */
2700 boost::shared_ptr<Region>
2701 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2703 RegionList::iterator i;
2704 boost::shared_ptr<Region> region;
2706 Glib::Mutex::Lock lm (region_lock);
2708 for (i = regions.begin(); i != regions.end(); ++i) {
2712 if (region->whole_file()) {
2714 if (child->source_equivalent (region)) {
2720 return boost::shared_ptr<Region> ();
2724 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2726 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2727 (*i)->get_region_list_equivalent_regions (region, result);
2731 Session::destroy_region (boost::shared_ptr<Region> region)
2733 vector<boost::shared_ptr<Source> > srcs;
2736 boost::shared_ptr<AudioRegion> aregion;
2738 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2742 if (aregion->playlist()) {
2743 aregion->playlist()->destroy_region (region);
2746 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2747 srcs.push_back (aregion->source (n));
2751 region->drop_references ();
2753 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2755 if (!(*i)->used()) {
2756 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2759 (afs)->mark_for_remove ();
2762 (*i)->drop_references ();
2764 cerr << "source was not used by any playlist\n";
2772 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2774 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2775 destroy_region (*i);
2781 Session::remove_last_capture ()
2783 list<boost::shared_ptr<Region> > r;
2785 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2787 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2788 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2791 r.insert (r.end(), l.begin(), l.end());
2796 destroy_regions (r);
2801 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2807 /* Source Management */
2809 Session::add_source (boost::shared_ptr<Source> source)
2811 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2812 pair<SourceMap::iterator,bool> result;
2814 entry.first = source->id();
2815 entry.second = source;
2818 Glib::Mutex::Lock lm (source_lock);
2819 result = sources.insert (entry);
2822 if (result.second) {
2823 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2829 Session::remove_source (boost::weak_ptr<Source> src)
2831 SourceMap::iterator i;
2832 boost::shared_ptr<Source> source = src.lock();
2839 Glib::Mutex::Lock lm (source_lock);
2842 Glib::Mutex::Lock lm (source_lock);
2844 if ((i = sources.find (source->id())) != sources.end()) {
2850 if (!_state_of_the_state & InCleanup) {
2852 /* save state so we don't end up with a session file
2853 referring to non-existent sources.
2856 save_state (_current_snapshot_name);
2860 boost::shared_ptr<Source>
2861 Session::source_by_id (const PBD::ID& id)
2863 Glib::Mutex::Lock lm (source_lock);
2864 SourceMap::iterator i;
2865 boost::shared_ptr<Source> source;
2867 if ((i = sources.find (id)) != sources.end()) {
2871 /* XXX search MIDI or other searches here */
2877 boost::shared_ptr<Source>
2878 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2880 Glib::Mutex::Lock lm (source_lock);
2882 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2883 cerr << "comparing " << path << " with " << i->second->name() << endl;
2884 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2886 if (afs && afs->path() == path && chn == afs->channel()) {
2891 return boost::shared_ptr<Source>();
2895 Session::peak_path_from_audio_path (string audio_path) const
2900 res += PBD::basename_nosuffix (audio_path);
2907 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2910 string old_basename = PBD::basename_nosuffix (oldname);
2911 string new_legalized = legalize_for_path (newname);
2913 /* note: we know (or assume) the old path is already valid */
2917 /* destructive file sources have a name of the form:
2919 /path/to/Tnnnn-NAME(%[LR])?.wav
2921 the task here is to replace NAME with the new name.
2924 /* find last slash */
2928 string::size_type slash;
2929 string::size_type dash;
2931 if ((slash = path.find_last_of ('/')) == string::npos) {
2935 dir = path.substr (0, slash+1);
2937 /* '-' is not a legal character for the NAME part of the path */
2939 if ((dash = path.find_last_of ('-')) == string::npos) {
2943 prefix = path.substr (slash+1, dash-(slash+1));
2948 path += new_legalized;
2949 path += ".wav"; /* XXX gag me with a spoon */
2953 /* non-destructive file sources have a name of the form:
2955 /path/to/NAME-nnnnn(%[LR])?.wav
2957 the task here is to replace NAME with the new name.
2962 string::size_type slash;
2963 string::size_type dash;
2964 string::size_type postfix;
2966 /* find last slash */
2968 if ((slash = path.find_last_of ('/')) == string::npos) {
2972 dir = path.substr (0, slash+1);
2974 /* '-' is not a legal character for the NAME part of the path */
2976 if ((dash = path.find_last_of ('-')) == string::npos) {
2980 suffix = path.substr (dash+1);
2982 // Suffix is now everything after the dash. Now we need to eliminate
2983 // the nnnnn part, which is done by either finding a '%' or a '.'
2985 postfix = suffix.find_last_of ("%");
2986 if (postfix == string::npos) {
2987 postfix = suffix.find_last_of ('.');
2990 if (postfix != string::npos) {
2991 suffix = suffix.substr (postfix);
2993 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2997 const uint32_t limit = 10000;
2998 char buf[PATH_MAX+1];
3000 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3002 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3004 if (access (buf, F_OK) != 0) {
3012 error << "FATAL ERROR! Could not find a " << endl;
3021 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3025 char buf[PATH_MAX+1];
3026 const uint32_t limit = 10000;
3030 legalized = legalize_for_path (name);
3032 /* find a "version" of the file name that doesn't exist in
3033 any of the possible directories.
3036 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3038 vector<space_and_path>::iterator i;
3039 uint32_t existing = 0;
3041 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3045 spath += sound_dir (false);
3049 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3050 } else if (nchan == 2) {
3052 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3054 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3056 } else if (nchan < 26) {
3057 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3059 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3068 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3069 } else if (nchan == 2) {
3071 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3073 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3075 } else if (nchan < 26) {
3076 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3078 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3082 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3088 if (existing == 0) {
3093 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3095 throw failed_constructor();
3099 /* we now have a unique name for the file, but figure out where to
3105 spath = discover_best_sound_dir ();
3108 string::size_type pos = foo.find_last_of ('/');
3110 if (pos == string::npos) {
3113 spath += foo.substr (pos + 1);
3119 boost::shared_ptr<AudioFileSource>
3120 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3122 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
3123 return boost::dynamic_pointer_cast<AudioFileSource> (
3124 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3127 // FIXME: _terrible_ code duplication
3129 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3132 string old_basename = PBD::basename_nosuffix (oldname);
3133 string new_legalized = legalize_for_path (newname);
3135 /* note: we know (or assume) the old path is already valid */
3139 /* destructive file sources have a name of the form:
3141 /path/to/Tnnnn-NAME(%[LR])?.wav
3143 the task here is to replace NAME with the new name.
3146 /* find last slash */
3150 string::size_type slash;
3151 string::size_type dash;
3153 if ((slash = path.find_last_of ('/')) == string::npos) {
3157 dir = path.substr (0, slash+1);
3159 /* '-' is not a legal character for the NAME part of the path */
3161 if ((dash = path.find_last_of ('-')) == string::npos) {
3165 prefix = path.substr (slash+1, dash-(slash+1));
3170 path += new_legalized;
3171 path += ".mid"; /* XXX gag me with a spoon */
3175 /* non-destructive file sources have a name of the form:
3177 /path/to/NAME-nnnnn(%[LR])?.wav
3179 the task here is to replace NAME with the new name.
3184 string::size_type slash;
3185 string::size_type dash;
3186 string::size_type postfix;
3188 /* find last slash */
3190 if ((slash = path.find_last_of ('/')) == string::npos) {
3194 dir = path.substr (0, slash+1);
3196 /* '-' is not a legal character for the NAME part of the path */
3198 if ((dash = path.find_last_of ('-')) == string::npos) {
3202 suffix = path.substr (dash+1);
3204 // Suffix is now everything after the dash. Now we need to eliminate
3205 // the nnnnn part, which is done by either finding a '%' or a '.'
3207 postfix = suffix.find_last_of ("%");
3208 if (postfix == string::npos) {
3209 postfix = suffix.find_last_of ('.');
3212 if (postfix != string::npos) {
3213 suffix = suffix.substr (postfix);
3215 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3219 const uint32_t limit = 10000;
3220 char buf[PATH_MAX+1];
3222 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3224 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3226 if (access (buf, F_OK) != 0) {
3234 error << "FATAL ERROR! Could not find a " << endl;
3243 Session::midi_path_from_name (string name)
3247 char buf[PATH_MAX+1];
3248 const uint32_t limit = 10000;
3252 legalized = legalize_for_path (name);
3254 /* find a "version" of the file name that doesn't exist in
3255 any of the possible directories.
3258 for (cnt = 1; cnt <= limit; ++cnt) {
3260 vector<space_and_path>::iterator i;
3261 uint32_t existing = 0;
3263 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3267 // FIXME: different directory from audio?
3268 spath += sound_dir(false) + "/" + legalized;
3270 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3272 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3277 if (existing == 0) {
3282 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3283 throw failed_constructor();
3287 /* we now have a unique name for the file, but figure out where to
3293 // FIXME: different directory than audio?
3294 spath = discover_best_sound_dir ();
3297 string::size_type pos = foo.find_last_of ('/');
3299 if (pos == string::npos) {
3302 spath += foo.substr (pos + 1);
3308 boost::shared_ptr<MidiSource>
3309 Session::create_midi_source_for_session (MidiDiskstream& ds)
3311 string spath = midi_path_from_name (ds.name());
3313 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3317 /* Playlist management */
3319 boost::shared_ptr<Playlist>
3320 Session::playlist_by_name (string name)
3322 Glib::Mutex::Lock lm (playlist_lock);
3323 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3324 if ((*i)->name() == name) {
3328 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3329 if ((*i)->name() == name) {
3334 return boost::shared_ptr<Playlist>();
3338 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3340 if (playlist->hidden()) {
3345 Glib::Mutex::Lock lm (playlist_lock);
3346 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3347 playlists.insert (playlists.begin(), playlist);
3348 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3349 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3355 PlaylistAdded (playlist); /* EMIT SIGNAL */
3359 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3362 Glib::Mutex::Lock lm (playlist_lock);
3363 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3366 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3373 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3375 boost::shared_ptr<Playlist> pl(wpl.lock());
3381 PlaylistList::iterator x;
3384 /* its not supposed to be visible */
3389 Glib::Mutex::Lock lm (playlist_lock);
3393 unused_playlists.insert (pl);
3395 if ((x = playlists.find (pl)) != playlists.end()) {
3396 playlists.erase (x);
3402 playlists.insert (pl);
3404 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3405 unused_playlists.erase (x);
3412 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3414 if (_state_of_the_state & Deletion) {
3418 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3425 Glib::Mutex::Lock lm (playlist_lock);
3427 PlaylistList::iterator i;
3429 i = find (playlists.begin(), playlists.end(), playlist);
3430 if (i != playlists.end()) {
3431 playlists.erase (i);
3434 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3435 if (i != unused_playlists.end()) {
3436 unused_playlists.erase (i);
3443 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3447 Session::set_audition (boost::shared_ptr<Region> r)
3449 pending_audition_region = r;
3450 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3451 schedule_butler_transport_work ();
3455 Session::audition_playlist ()
3457 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3458 ev->region.reset ();
3463 Session::non_realtime_set_audition ()
3465 if (!pending_audition_region) {
3466 auditioner->audition_current_playlist ();
3468 auditioner->audition_region (pending_audition_region);
3469 pending_audition_region.reset ();
3471 AuditionActive (true); /* EMIT SIGNAL */
3475 Session::audition_region (boost::shared_ptr<Region> r)
3477 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3483 Session::cancel_audition ()
3485 if (auditioner->active()) {
3486 auditioner->cancel_audition ();
3487 AuditionActive (false); /* EMIT SIGNAL */
3492 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3494 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3498 Session::remove_empty_sounds ()
3500 PathScanner scanner;
3502 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3504 Glib::Mutex::Lock lm (source_lock);
3506 regex_t compiled_tape_track_pattern;
3509 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3513 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3515 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3519 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3521 /* never remove files that appear to be a tape track */
3523 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3528 if (AudioFileSource::is_empty (*this, *(*i))) {
3530 unlink ((*i)->c_str());
3532 string peak_path = peak_path_from_audio_path (**i);
3533 unlink (peak_path.c_str());
3539 delete possible_audiofiles;
3543 Session::is_auditioning () const
3545 /* can be called before we have an auditioner object */
3547 return auditioner->active();
3554 Session::set_all_solo (bool yn)
3556 shared_ptr<RouteList> r = routes.reader ();
3558 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3559 if (!(*i)->hidden()) {
3560 (*i)->set_solo (yn, this);
3568 Session::set_all_mute (bool yn)
3570 shared_ptr<RouteList> r = routes.reader ();
3572 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3573 if (!(*i)->hidden()) {
3574 (*i)->set_mute (yn, this);
3582 Session::n_diskstreams () const
3586 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3588 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3589 if (!(*i)->hidden()) {
3597 Session::graph_reordered ()
3599 /* don't do this stuff if we are setting up connections
3600 from a set_state() call or creating new tracks.
3603 if (_state_of_the_state & InitialConnecting) {
3607 /* every track/bus asked for this to be handled but it was deferred because
3608 we were connecting. do it now.
3611 request_input_change_handling ();
3615 /* force all diskstreams to update their capture offset values to
3616 reflect any changes in latencies within the graph.
3619 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3621 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3622 (*i)->set_capture_offset ();
3627 Session::record_disenable_all ()
3629 record_enable_change_all (false);
3633 Session::record_enable_all ()
3635 record_enable_change_all (true);
3639 Session::record_enable_change_all (bool yn)
3641 shared_ptr<RouteList> r = routes.reader ();
3643 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3646 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3647 at->set_record_enable (yn, this);
3651 /* since we don't keep rec-enable state, don't mark session dirty */
3655 Session::add_redirect (Redirect* redirect)
3659 PortInsert* port_insert;
3660 PluginInsert* plugin_insert;
3662 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3663 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3664 _port_inserts.insert (_port_inserts.begin(), port_insert);
3665 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3666 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3668 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3671 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3672 _sends.insert (_sends.begin(), send);
3674 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3678 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3684 Session::remove_redirect (Redirect* redirect)
3688 PortInsert* port_insert;
3689 PluginInsert* plugin_insert;
3691 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3692 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3693 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3694 if (x != _port_inserts.end()) {
3695 insert_bitset[port_insert->bit_slot()] = false;
3696 _port_inserts.erase (x);
3698 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3699 _plugin_inserts.remove (plugin_insert);
3701 fatal << string_compose (_("programming error: %1"),
3702 X_("unknown type of Insert deleted!"))
3706 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3707 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3708 if (x != _sends.end()) {
3709 send_bitset[send->bit_slot()] = false;
3713 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3721 Session::available_capture_duration ()
3723 float sample_bytes_on_disk = 4.0; // keep gcc happy
3725 switch (Config->get_native_file_data_format()) {
3727 sample_bytes_on_disk = 4.0;
3731 sample_bytes_on_disk = 3.0;
3735 /* impossible, but keep some gcc versions happy */
3736 fatal << string_compose (_("programming error: %1"),
3737 X_("illegal native file data format"))
3742 double scale = 4096.0 / sample_bytes_on_disk;
3744 if (_total_free_4k_blocks * scale > (double) max_frames) {
3748 return (nframes_t) floor (_total_free_4k_blocks * scale);
3752 Session::add_connection (ARDOUR::Connection* connection)
3755 Glib::Mutex::Lock guard (connection_lock);
3756 _connections.push_back (connection);
3759 ConnectionAdded (connection); /* EMIT SIGNAL */
3765 Session::remove_connection (ARDOUR::Connection* connection)
3767 bool removed = false;
3770 Glib::Mutex::Lock guard (connection_lock);
3771 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3773 if (i != _connections.end()) {
3774 _connections.erase (i);
3780 ConnectionRemoved (connection); /* EMIT SIGNAL */
3786 ARDOUR::Connection *
3787 Session::connection_by_name (string name) const
3789 Glib::Mutex::Lock lm (connection_lock);
3791 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3792 if ((*i)->name() == name) {
3801 Session::tempo_map_changed (Change ignored)
3807 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3808 * the given count with the current block size.
3811 Session::ensure_buffers (ChanCount howmany)
3813 // FIXME: NASTY assumption (midi block size == audio block size)
3814 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3815 _send_buffers->ensure_buffers(howmany, current_block_size);
3816 _silent_buffers->ensure_buffers(howmany, current_block_size);
3818 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3822 Session::next_insert_id ()
3824 /* this doesn't really loop forever. just think about it */
3827 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3828 if (!insert_bitset[n]) {
3829 insert_bitset[n] = true;
3835 /* none available, so resize and try again */
3837 insert_bitset.resize (insert_bitset.size() + 16, false);
3842 Session::next_send_id ()
3844 /* this doesn't really loop forever. just think about it */
3847 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3848 if (!send_bitset[n]) {
3849 send_bitset[n] = true;
3855 /* none available, so resize and try again */
3857 send_bitset.resize (send_bitset.size() + 16, false);
3862 Session::mark_send_id (uint32_t id)
3864 if (id >= send_bitset.size()) {
3865 send_bitset.resize (id+16, false);
3867 if (send_bitset[id]) {
3868 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3870 send_bitset[id] = true;
3874 Session::mark_insert_id (uint32_t id)
3876 if (id >= insert_bitset.size()) {
3877 insert_bitset.resize (id+16, false);
3879 if (insert_bitset[id]) {
3880 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3882 insert_bitset[id] = true;
3885 /* Named Selection management */
3888 Session::named_selection_by_name (string name)
3890 Glib::Mutex::Lock lm (named_selection_lock);
3891 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3892 if ((*i)->name == name) {
3900 Session::add_named_selection (NamedSelection* named_selection)
3903 Glib::Mutex::Lock lm (named_selection_lock);
3904 named_selections.insert (named_selections.begin(), named_selection);
3907 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3913 NamedSelectionAdded (); /* EMIT SIGNAL */
3917 Session::remove_named_selection (NamedSelection* named_selection)
3919 bool removed = false;
3922 Glib::Mutex::Lock lm (named_selection_lock);
3924 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3926 if (i != named_selections.end()) {
3928 named_selections.erase (i);
3935 NamedSelectionRemoved (); /* EMIT SIGNAL */
3940 Session::reset_native_file_format ()
3942 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3944 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3945 (*i)->reset_write_sources (false);
3950 Session::route_name_unique (string n) const
3952 shared_ptr<RouteList> r = routes.reader ();
3954 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3955 if ((*i)->name() == n) {
3964 Session::n_playlists () const
3966 Glib::Mutex::Lock lm (playlist_lock);
3967 return playlists.size();
3971 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3973 if (!force && howmany <= _npan_buffers) {
3977 if (_pan_automation_buffer) {
3979 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3980 delete [] _pan_automation_buffer[i];
3983 delete [] _pan_automation_buffer;
3986 _pan_automation_buffer = new pan_t*[howmany];
3988 for (uint32_t i = 0; i < howmany; ++i) {
3989 _pan_automation_buffer[i] = new pan_t[nframes];
3992 _npan_buffers = howmany;
3996 Session::freeze (InterThreadInfo& itt)
3998 shared_ptr<RouteList> r = routes.reader ();
4000 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4004 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4005 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4016 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
4017 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4020 boost::shared_ptr<Playlist> playlist;
4021 boost::shared_ptr<AudioFileSource> fsource;
4023 char buf[PATH_MAX+1];
4025 ChanCount nchans(track.audio_diskstream()->n_channels());
4027 nframes_t this_chunk;
4031 // any bigger than this seems to cause stack overflows in called functions
4032 const nframes_t chunk_size = (128 * 1024)/4;
4034 g_atomic_int_set (&processing_prohibited, 1);
4036 /* call tree *MUST* hold route_lock */
4038 if ((playlist = track.diskstream()->playlist()) == 0) {
4042 /* external redirects will be a problem */
4044 if (track.has_external_redirects()) {
4048 dir = discover_best_sound_dir ();
4050 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
4052 for (x = 0; x < 99999; ++x) {
4053 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4054 if (access (buf, F_OK) != 0) {
4060 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4065 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4066 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4069 catch (failed_constructor& err) {
4070 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4074 srcs.push_back (fsource);
4077 /* XXX need to flush all redirects */
4082 /* create a set of reasonably-sized buffers */
4083 buffers.ensure_buffers(nchans, chunk_size);
4084 buffers.set_count(nchans);
4086 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4087 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4089 afs->prepare_for_peakfile_writes ();
4092 while (to_do && !itt.cancel) {
4094 this_chunk = min (to_do, chunk_size);
4096 if (track.export_stuff (buffers, start, this_chunk)) {
4101 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4102 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4105 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
4111 start += this_chunk;
4112 to_do -= this_chunk;
4114 itt.progress = (float) (1.0 - ((double) to_do / len));
4123 xnow = localtime (&now);
4125 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4126 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4129 afs->update_header (position, *xnow, now);
4130 afs->flush_header ();
4134 /* construct a region to represent the bounced material */
4136 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4137 region_name_from_path (srcs.front()->name(), true));
4144 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4145 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4148 afs->mark_for_remove ();
4151 (*src)->drop_references ();
4155 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4156 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4159 afs->done_with_peakfile_writes ();
4163 g_atomic_int_set (&processing_prohibited, 0);
4171 Session::get_silent_buffers (ChanCount count)
4173 assert(_silent_buffers->available() >= count);
4174 _silent_buffers->set_count(count);
4176 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4177 for (size_t i=0; i < count.get(*t); ++i) {
4178 _silent_buffers->get(*t, i).clear();
4182 return *_silent_buffers;
4186 Session::get_scratch_buffers (ChanCount count)
4188 assert(_scratch_buffers->available() >= count);
4189 _scratch_buffers->set_count(count);
4190 return *_scratch_buffers;
4194 Session::get_send_buffers (ChanCount count)
4196 assert(_send_buffers->available() >= count);
4197 _send_buffers->set_count(count);
4198 return *_send_buffers;
4202 Session::ntracks () const
4205 shared_ptr<RouteList> r = routes.reader ();
4207 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4208 if (dynamic_cast<Track*> ((*i).get())) {
4217 Session::nbusses () const
4220 shared_ptr<RouteList> r = routes.reader ();
4222 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4223 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4232 Session::add_automation_list(AutomationList *al)
4234 automation_lists[al->id()] = al;
4238 Session::compute_initial_length ()
4240 return _engine.frame_rate() * 60 * 5;