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/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/auditioner.h>
53 #include <ardour/recent_sessions.h>
54 #include <ardour/redirect.h>
55 #include <ardour/send.h>
56 #include <ardour/insert.h>
57 #include <ardour/connection.h>
58 #include <ardour/slave.h>
59 #include <ardour/tempo.h>
60 #include <ardour/audio_track.h>
61 #include <ardour/cycle_timer.h>
62 #include <ardour/named_selection.h>
63 #include <ardour/crossfade.h>
64 #include <ardour/playlist.h>
65 #include <ardour/click.h>
66 #include <ardour/data_type.h>
67 #include <ardour/source_factory.h>
68 #include <ardour/region_factory.h>
71 #include <ardour/osc.h>
77 using namespace ARDOUR;
79 using boost::shared_ptr;
82 static const int CPU_CACHE_ALIGN = 64;
84 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
87 const char* Session::_template_suffix = X_(".template");
88 const char* Session::_statefile_suffix = X_(".ardour");
89 const char* Session::_pending_suffix = X_(".pending");
90 const char* Session::old_sound_dir_name = X_("sounds");
91 const char* Session::sound_dir_name = X_("audiofiles");
92 const char* Session::peak_dir_name = X_("peaks");
93 const char* Session::dead_sound_dir_name = X_("dead_sounds");
94 const char* Session::interchange_dir_name = X_("interchange");
95 const char* Session::export_dir_name = X_("export");
97 Session::compute_peak_t Session::compute_peak = 0;
98 Session::find_peaks_t Session::find_peaks = 0;
99 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
100 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
101 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
103 sigc::signal<int> Session::AskAboutPendingState;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
111 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
114 char buf[PATH_MAX+1];
118 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
119 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
125 /* check to see if it exists, and what it is */
127 if (stat (str.c_str(), &statbuf)) {
128 if (errno == ENOENT) {
131 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
139 /* it exists, so it must either be the name
140 of the directory, or the name of the statefile
144 if (S_ISDIR (statbuf.st_mode)) {
146 string::size_type slash = str.find_last_of ('/');
148 if (slash == string::npos) {
150 /* a subdirectory of cwd, so statefile should be ... */
156 tmp += _statefile_suffix;
160 if (stat (tmp.c_str(), &statbuf)) {
161 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
171 /* some directory someplace in the filesystem.
172 the snapshot name is the directory name
177 snapshot = str.substr (slash+1);
181 } else if (S_ISREG (statbuf.st_mode)) {
183 string::size_type slash = str.find_last_of ('/');
184 string::size_type suffix;
186 /* remove the suffix */
188 if (slash != string::npos) {
189 snapshot = str.substr (slash+1);
194 suffix = snapshot.find (_statefile_suffix);
196 if (suffix == string::npos) {
197 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
203 snapshot = snapshot.substr (0, suffix);
205 if (slash == string::npos) {
207 /* we must be in the directory where the
208 statefile lives. get it using cwd().
211 char cwd[PATH_MAX+1];
213 if (getcwd (cwd, sizeof (cwd)) == 0) {
214 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
223 /* full path to the statefile */
225 path = str.substr (0, slash);
230 /* what type of file is it? */
231 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
237 /* its the name of a new directory. get the name
241 string::size_type slash = str.find_last_of ('/');
243 if (slash == string::npos) {
245 /* no slash, just use the name, but clean it up */
247 path = legalize_for_path (str);
253 snapshot = str.substr (slash+1);
260 Session::Session (AudioEngine &eng,
262 string snapshot_name,
263 string* mix_template)
266 _mmc_port (default_mmc_port),
267 _mtc_port (default_mtc_port),
268 _midi_port (default_midi_port),
269 pending_events (2048),
270 midi_requests (128), // the size of this should match the midi request pool size
271 diskstreams (new DiskstreamList),
272 routes (new RouteList),
273 auditioner ((Auditioner*) 0),
279 if (!eng.connected()) {
280 throw failed_constructor();
283 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
285 n_physical_outputs = _engine.n_physical_outputs();
286 n_physical_inputs = _engine.n_physical_inputs();
288 first_stage_init (fullpath, snapshot_name);
290 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
292 if (create (new_session, mix_template, compute_initial_length())) {
293 cerr << "create failed\n";
295 throw failed_constructor ();
299 if (second_stage_init (new_session)) {
301 throw failed_constructor ();
304 store_recent_sessions(_name, _path);
306 bool was_dirty = dirty();
308 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
310 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
313 DirtyChanged (); /* EMIT SIGNAL */
317 Session::Session (AudioEngine &eng,
319 string snapshot_name,
320 AutoConnectOption input_ac,
321 AutoConnectOption output_ac,
322 uint32_t control_out_channels,
323 uint32_t master_out_channels,
324 uint32_t requested_physical_in,
325 uint32_t requested_physical_out,
326 nframes_t initial_length)
329 _mmc_port (default_mmc_port),
330 _mtc_port (default_mtc_port),
331 _midi_port (default_midi_port),
332 pending_events (2048),
334 diskstreams (new DiskstreamList),
335 routes (new RouteList),
341 if (!eng.connected()) {
342 throw failed_constructor();
345 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
347 n_physical_outputs = _engine.n_physical_outputs();
348 n_physical_inputs = _engine.n_physical_inputs();
350 if (n_physical_inputs) {
351 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
354 if (n_physical_outputs) {
355 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
358 first_stage_init (fullpath, snapshot_name);
360 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
363 if (create (new_session, 0, initial_length)) {
365 throw failed_constructor ();
370 /* set up Master Out and Control Out if necessary */
375 if (control_out_channels) {
376 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
377 r->set_remote_control_id (control_id++);
382 if (master_out_channels) {
383 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
384 r->set_remote_control_id (control_id);
388 /* prohibit auto-connect to master, because there isn't one */
389 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
398 Config->set_input_auto_connect (input_ac);
399 Config->set_output_auto_connect (output_ac);
401 if (second_stage_init (new_session)) {
403 throw failed_constructor ();
406 store_recent_sessions(_name, _path);
408 bool was_dirty = dirty ();
410 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
412 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
415 DirtyChanged (); /* EMIT SIGNAL */
427 /* if we got to here, leaving pending capture state around
431 remove_pending_capture_state ();
433 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
434 _engine.remove_session ();
436 GoingAway (); /* EMIT SIGNAL */
442 /* clear history so that no references to objects are held any more */
446 /* clear state tree so that no references to objects are held any more */
452 terminate_butler_thread ();
453 terminate_midi_thread ();
455 if (click_data && click_data != default_click) {
456 delete [] click_data;
459 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
460 delete [] click_emphasis_data;
465 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
469 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
473 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
477 AudioDiskstream::free_working_buffers();
479 /* this should cause deletion of the auditioner */
481 // auditioner.reset ();
483 #undef TRACK_DESTRUCTION
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete named selections\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
488 NamedSelectionList::iterator tmp;
497 #ifdef TRACK_DESTRUCTION
498 cerr << "delete playlists\n";
499 #endif /* TRACK_DESTRUCTION */
500 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
501 PlaylistList::iterator tmp;
506 (*i)->drop_references ();
511 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
512 PlaylistList::iterator tmp;
517 (*i)->drop_references ();
523 unused_playlists.clear ();
525 #ifdef TRACK_DESTRUCTION
526 cerr << "delete audio regions\n";
527 #endif /* TRACK_DESTRUCTION */
529 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
530 AudioRegionList::iterator tmp;
535 i->second->drop_references ();
540 audio_regions.clear ();
542 #ifdef TRACK_DESTRUCTION
543 cerr << "delete routes\n";
544 #endif /* TRACK_DESTRUCTION */
546 RCUWriter<RouteList> writer (routes);
547 boost::shared_ptr<RouteList> r = writer.get_copy ();
548 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
549 (*i)->drop_references ();
552 /* writer goes out of scope and updates master */
557 #ifdef TRACK_DESTRUCTION
558 cerr << "delete diskstreams\n";
559 #endif /* TRACK_DESTRUCTION */
561 RCUWriter<DiskstreamList> dwriter (diskstreams);
562 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
563 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
564 (*i)->drop_references ();
568 diskstreams.flush ();
570 #ifdef TRACK_DESTRUCTION
571 cerr << "delete audio sources\n";
572 #endif /* TRACK_DESTRUCTION */
573 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
574 AudioSourceList::iterator tmp;
579 i->second->drop_references ();
584 audio_sources.clear ();
586 #ifdef TRACK_DESTRUCTION
587 cerr << "delete mix groups\n";
588 #endif /* TRACK_DESTRUCTION */
589 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
590 list<RouteGroup*>::iterator tmp;
600 #ifdef TRACK_DESTRUCTION
601 cerr << "delete edit groups\n";
602 #endif /* TRACK_DESTRUCTION */
603 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
604 list<RouteGroup*>::iterator tmp;
614 #ifdef TRACK_DESTRUCTION
615 cerr << "delete connections\n";
616 #endif /* TRACK_DESTRUCTION */
617 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
618 ConnectionList::iterator tmp;
628 if (butler_mixdown_buffer) {
629 delete [] butler_mixdown_buffer;
632 if (butler_gain_buffer) {
633 delete [] butler_gain_buffer;
636 Crossfade::set_buffer_size (0);
644 Session::set_worst_io_latencies ()
646 _worst_output_latency = 0;
647 _worst_input_latency = 0;
649 if (!_engine.connected()) {
653 boost::shared_ptr<RouteList> r = routes.reader ();
655 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
656 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
657 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
662 Session::when_engine_running ()
664 string first_physical_output;
666 /* we don't want to run execute this again */
668 set_block_size (_engine.frames_per_cycle());
669 set_frame_rate (_engine.frame_rate());
671 Config->map_parameters (mem_fun (*this, &Session::config_changed));
673 /* every time we reconnect, recompute worst case output latencies */
675 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
677 if (synced_to_jack()) {
678 _engine.transport_stop ();
681 if (Config->get_jack_time_master()) {
682 _engine.transport_locate (_transport_frame);
690 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
692 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
694 /* existing state for Click */
696 if (_click_io->set_state (*child->children().front()) == 0) {
698 _clicking = Config->get_clicking ();
702 error << _("could not setup Click I/O") << endmsg;
708 /* default state for Click */
710 first_physical_output = _engine.get_nth_physical_output (0);
712 if (first_physical_output.length()) {
713 if (_click_io->add_output_port (first_physical_output, this)) {
714 // relax, even though its an error
716 _clicking = Config->get_clicking ();
722 catch (failed_constructor& err) {
723 error << _("cannot setup Click I/O") << endmsg;
726 set_worst_io_latencies ();
729 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
732 /* Create a set of Connection objects that map
733 to the physical outputs currently available
738 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
740 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
742 Connection* c = new OutputConnection (buf, true);
745 c->add_connection (0, _engine.get_nth_physical_output (np));
750 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
752 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
754 Connection* c = new InputConnection (buf, true);
757 c->add_connection (0, _engine.get_nth_physical_input (np));
764 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
766 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
768 Connection* c = new OutputConnection (buf, true);
772 c->add_connection (0, _engine.get_nth_physical_output (np));
773 c->add_connection (1, _engine.get_nth_physical_output (np+1));
778 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
780 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
782 Connection* c = new InputConnection (buf, true);
786 c->add_connection (0, _engine.get_nth_physical_input (np));
787 c->add_connection (1, _engine.get_nth_physical_input (np+1));
796 /* create master/control ports */
801 /* force the master to ignore any later call to this */
803 if (_master_out->pending_state_node) {
804 _master_out->ports_became_legal();
807 /* no panner resets till we are through */
809 _master_out->defer_pan_reset ();
811 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
812 if (_master_out->add_input_port ("", this)) {
813 error << _("cannot setup master inputs")
819 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
820 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
821 error << _("cannot setup master outputs")
828 _master_out->allow_pan_reset ();
832 Connection* c = new OutputConnection (_("Master Out"), true);
834 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
836 c->add_connection ((int) n, _master_out->input(n)->name());
843 /* catch up on send+insert cnts */
847 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
850 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
851 if (id > insert_cnt) {
859 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
862 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
870 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
872 /* hook us up to the engine */
874 _engine.set_session (this);
879 osc->set_session (*this);
882 _state_of_the_state = Clean;
884 DirtyChanged (); /* EMIT SIGNAL */
888 Session::hookup_io ()
890 /* stop graph reordering notifications from
891 causing resorts, etc.
894 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
896 if (auditioner == 0) {
898 /* we delay creating the auditioner till now because
899 it makes its own connections to ports.
900 the engine has to be running for this to work.
904 auditioner.reset (new Auditioner (*this));
907 catch (failed_constructor& err) {
908 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
912 /* Tell all IO objects to create their ports */
918 vector<string> cports;
920 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
921 if (_control_out->add_input_port ("", this)) {
922 error << _("cannot setup control inputs")
928 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
929 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
930 error << _("cannot set up master outputs")
938 uint32_t ni = _control_out->n_inputs();
940 for (n = 0; n < ni; ++n) {
941 cports.push_back (_control_out->input(n)->name());
944 boost::shared_ptr<RouteList> r = routes.reader ();
946 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
947 (*x)->set_control_outs (cports);
951 /* Tell all IO objects to connect themselves together */
953 IO::enable_connecting ();
955 /* Now reset all panners */
957 IO::reset_panners ();
959 /* Anyone who cares about input state, wake up and do something */
961 IOConnectionsComplete (); /* EMIT SIGNAL */
963 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
965 /* now handle the whole enchilada as if it was one
971 /* update mixer solo state */
977 Session::playlist_length_changed ()
979 /* we can't just increase end_location->end() if pl->get_maximum_extent()
980 if larger. if the playlist used to be the longest playlist,
981 and its now shorter, we have to decrease end_location->end(). hence,
982 we have to iterate over all diskstreams and check the
983 playlists currently in use.
989 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
991 boost::shared_ptr<Diskstream> dstream = wptr.lock();
998 boost::shared_ptr<Playlist> playlist;
1000 if ((playlist = dstream->playlist()) != 0) {
1001 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1004 /* see comment in playlist_length_changed () */
1005 find_current_end ();
1009 Session::record_enabling_legal () const
1011 /* this used to be in here, but survey says.... we don't need to restrict it */
1012 // if (record_status() == Recording) {
1016 if (Config->get_all_safe()) {
1023 Session::reset_input_monitor_state ()
1025 if (transport_rolling()) {
1027 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1029 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1030 if ((*i)->record_enabled ()) {
1031 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1032 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1036 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1038 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1039 if ((*i)->record_enabled ()) {
1040 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1041 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1048 Session::auto_punch_start_changed (Location* location)
1050 replace_event (Event::PunchIn, location->start());
1052 if (get_record_enabled() && Config->get_punch_in()) {
1053 /* capture start has been changed, so save new pending state */
1054 save_state ("", true);
1059 Session::auto_punch_end_changed (Location* location)
1061 nframes_t when_to_stop = location->end();
1062 // when_to_stop += _worst_output_latency + _worst_input_latency;
1063 replace_event (Event::PunchOut, when_to_stop);
1067 Session::auto_punch_changed (Location* location)
1069 nframes_t when_to_stop = location->end();
1071 replace_event (Event::PunchIn, location->start());
1072 //when_to_stop += _worst_output_latency + _worst_input_latency;
1073 replace_event (Event::PunchOut, when_to_stop);
1077 Session::auto_loop_changed (Location* location)
1079 replace_event (Event::AutoLoop, location->end(), location->start());
1081 if (transport_rolling() && play_loop) {
1083 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1085 if (_transport_frame > location->end()) {
1086 // relocate to beginning of loop
1087 clear_events (Event::LocateRoll);
1089 request_locate (location->start(), true);
1092 else if (Config->get_seamless_loop() && !loop_changing) {
1094 // schedule a locate-roll to refill the diskstreams at the
1095 // previous loop end
1096 loop_changing = true;
1098 if (location->end() > last_loopend) {
1099 clear_events (Event::LocateRoll);
1100 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1107 last_loopend = location->end();
1112 Session::set_auto_punch_location (Location* location)
1116 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1117 auto_punch_start_changed_connection.disconnect();
1118 auto_punch_end_changed_connection.disconnect();
1119 auto_punch_changed_connection.disconnect();
1120 existing->set_auto_punch (false, this);
1121 remove_event (existing->start(), Event::PunchIn);
1122 clear_events (Event::PunchOut);
1123 auto_punch_location_changed (0);
1128 if (location == 0) {
1132 if (location->end() <= location->start()) {
1133 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1137 auto_punch_start_changed_connection.disconnect();
1138 auto_punch_end_changed_connection.disconnect();
1139 auto_punch_changed_connection.disconnect();
1141 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1142 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1143 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1145 location->set_auto_punch (true, this);
1146 auto_punch_location_changed (location);
1150 Session::set_auto_loop_location (Location* location)
1154 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1155 auto_loop_start_changed_connection.disconnect();
1156 auto_loop_end_changed_connection.disconnect();
1157 auto_loop_changed_connection.disconnect();
1158 existing->set_auto_loop (false, this);
1159 remove_event (existing->end(), Event::AutoLoop);
1160 auto_loop_location_changed (0);
1165 if (location == 0) {
1169 if (location->end() <= location->start()) {
1170 error << _("Session: you can't use a mark for auto loop") << endmsg;
1174 last_loopend = location->end();
1176 auto_loop_start_changed_connection.disconnect();
1177 auto_loop_end_changed_connection.disconnect();
1178 auto_loop_changed_connection.disconnect();
1180 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1181 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1182 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1184 location->set_auto_loop (true, this);
1185 auto_loop_location_changed (location);
1189 Session::locations_added (Location* ignored)
1195 Session::locations_changed ()
1197 _locations.apply (*this, &Session::handle_locations_changed);
1201 Session::handle_locations_changed (Locations::LocationList& locations)
1203 Locations::LocationList::iterator i;
1205 bool set_loop = false;
1206 bool set_punch = false;
1208 for (i = locations.begin(); i != locations.end(); ++i) {
1212 if (location->is_auto_punch()) {
1213 set_auto_punch_location (location);
1216 if (location->is_auto_loop()) {
1217 set_auto_loop_location (location);
1224 set_auto_loop_location (0);
1227 set_auto_punch_location (0);
1234 Session::enable_record ()
1236 /* XXX really atomic compare+swap here */
1237 if (g_atomic_int_get (&_record_status) != Recording) {
1238 g_atomic_int_set (&_record_status, Recording);
1239 _last_record_location = _transport_frame;
1240 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1242 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1243 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1244 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1245 if ((*i)->record_enabled ()) {
1246 (*i)->monitor_input (true);
1251 RecordStateChanged ();
1256 Session::disable_record (bool rt_context, bool force)
1260 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1262 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1263 g_atomic_int_set (&_record_status, Disabled);
1265 if (rs == Recording) {
1266 g_atomic_int_set (&_record_status, Enabled);
1270 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1272 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1273 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1275 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1276 if ((*i)->record_enabled ()) {
1277 (*i)->monitor_input (false);
1282 RecordStateChanged (); /* emit signal */
1285 remove_pending_capture_state ();
1291 Session::step_back_from_record ()
1293 /* XXX really atomic compare+swap here */
1294 if (g_atomic_int_get (&_record_status) == Recording) {
1295 g_atomic_int_set (&_record_status, Enabled);
1297 if (Config->get_monitoring_model() == HardwareMonitoring) {
1298 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1300 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1301 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1302 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1303 (*i)->monitor_input (false);
1311 Session::maybe_enable_record ()
1313 g_atomic_int_set (&_record_status, Enabled);
1315 /* this function is currently called from somewhere other than an RT thread.
1316 this save_state() call therefore doesn't impact anything.
1319 save_state ("", true);
1321 if (_transport_speed) {
1322 if (!Config->get_punch_in()) {
1326 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1327 RecordStateChanged (); /* EMIT SIGNAL */
1334 Session::audible_frame () const
1340 /* the first of these two possible settings for "offset"
1341 mean that the audible frame is stationary until
1342 audio emerges from the latency compensation
1345 the second means that the audible frame is stationary
1346 until audio would emerge from a physical port
1347 in the absence of any plugin latency compensation
1350 offset = _worst_output_latency;
1352 if (offset > current_block_size) {
1353 offset -= current_block_size;
1355 /* XXX is this correct? if we have no external
1356 physical connections and everything is internal
1357 then surely this is zero? still, how
1358 likely is that anyway?
1360 offset = current_block_size;
1363 if (synced_to_jack()) {
1364 tf = _engine.transport_frame();
1366 tf = _transport_frame;
1369 if (_transport_speed == 0) {
1379 if (!non_realtime_work_pending()) {
1383 /* take latency into account */
1392 Session::set_frame_rate (nframes_t frames_per_second)
1394 /** \fn void Session::set_frame_size(nframes_t)
1395 the AudioEngine object that calls this guarantees
1396 that it will not be called while we are also in
1397 ::process(). Its fine to do things that block
1401 _base_frame_rate = frames_per_second;
1405 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1407 // XXX we need some equivalent to this, somehow
1408 // SndFileSource::setup_standard_crossfades (frames_per_second);
1412 /* XXX need to reset/reinstantiate all LADSPA plugins */
1416 Session::set_block_size (nframes_t nframes)
1418 /* the AudioEngine guarantees
1419 that it will not be called while we are also in
1420 ::process(). It is therefore fine to do things that block
1425 vector<Sample*>::iterator i;
1428 current_block_size = nframes;
1430 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1434 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1438 _passthru_buffers.clear ();
1439 _silent_buffers.clear ();
1441 ensure_passthru_buffers (np);
1443 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1447 #ifdef NO_POSIX_MEMALIGN
1448 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1450 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1454 memset (*i, 0, sizeof (Sample) * current_block_size);
1458 if (_gain_automation_buffer) {
1459 delete [] _gain_automation_buffer;
1461 _gain_automation_buffer = new gain_t[nframes];
1463 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1465 boost::shared_ptr<RouteList> r = routes.reader ();
1467 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1468 (*i)->set_block_size (nframes);
1471 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1472 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1473 (*i)->set_block_size (nframes);
1476 set_worst_io_latencies ();
1481 Session::set_default_fade (float steepness, float fade_msecs)
1484 nframes_t fade_frames;
1486 /* Don't allow fade of less 1 frame */
1488 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1495 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1499 default_fade_msecs = fade_msecs;
1500 default_fade_steepness = steepness;
1503 // jlc, WTF is this!
1504 Glib::RWLock::ReaderLock lm (route_lock);
1505 AudioRegion::set_default_fade (steepness, fade_frames);
1510 /* XXX have to do this at some point */
1511 /* foreach region using default fade, reset, then
1512 refill_all_diskstream_buffers ();
1517 struct RouteSorter {
1518 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1519 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1521 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1524 if (r1->fed_by.empty()) {
1525 if (r2->fed_by.empty()) {
1526 /* no ardour-based connections inbound to either route. just use signal order */
1527 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1529 /* r2 has connections, r1 does not; run r1 early */
1533 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1540 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1542 shared_ptr<Route> r2;
1544 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1545 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1549 /* make a copy of the existing list of routes that feed r1 */
1551 set<shared_ptr<Route> > existing = r1->fed_by;
1553 /* for each route that feeds r1, recurse, marking it as feeding
1557 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1560 /* r2 is a route that feeds r1 which somehow feeds base. mark
1561 base as being fed by r2
1564 rbase->fed_by.insert (r2);
1568 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1572 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1576 /* now recurse, so that we can mark base as being fed by
1577 all routes that feed r2
1580 trace_terminal (r2, rbase);
1587 Session::resort_routes ()
1589 /* don't do anything here with signals emitted
1590 by Routes while we are being destroyed.
1593 if (_state_of_the_state & Deletion) {
1600 RCUWriter<RouteList> writer (routes);
1601 shared_ptr<RouteList> r = writer.get_copy ();
1602 resort_routes_using (r);
1603 /* writer goes out of scope and forces update */
1608 Session::resort_routes_using (shared_ptr<RouteList> r)
1610 RouteList::iterator i, j;
1612 for (i = r->begin(); i != r->end(); ++i) {
1614 (*i)->fed_by.clear ();
1616 for (j = r->begin(); j != r->end(); ++j) {
1618 /* although routes can feed themselves, it will
1619 cause an endless recursive descent if we
1620 detect it. so don't bother checking for
1628 if ((*j)->feeds (*i)) {
1629 (*i)->fed_by.insert (*j);
1634 for (i = r->begin(); i != r->end(); ++i) {
1635 trace_terminal (*i, *i);
1641 /* don't leave dangling references to routes in Route::fed_by */
1643 for (i = r->begin(); i != r->end(); ++i) {
1644 (*i)->fed_by.clear ();
1648 cerr << "finished route resort\n";
1650 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1651 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1658 list<boost::shared_ptr<AudioTrack> >
1659 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1661 char track_name[32];
1662 uint32_t track_id = 0;
1664 uint32_t channels_used = 0;
1666 RouteList new_routes;
1667 list<boost::shared_ptr<AudioTrack> > ret;
1668 uint32_t control_id;
1670 /* count existing audio tracks */
1673 shared_ptr<RouteList> r = routes.reader ();
1675 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1676 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1677 if (!(*i)->hidden()) {
1679 channels_used += (*i)->n_inputs();
1685 vector<string> physinputs;
1686 vector<string> physoutputs;
1687 uint32_t nphysical_in;
1688 uint32_t nphysical_out;
1690 _engine.get_physical_outputs (physoutputs);
1691 _engine.get_physical_inputs (physinputs);
1692 control_id = ntracks() + nbusses() + 1;
1696 /* check for duplicate route names, since we might have pre-existing
1697 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1698 save, close,restart,add new route - first named route is now
1706 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1708 if (route_by_name (track_name) == 0) {
1712 } while (track_id < (UINT_MAX-1));
1714 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1715 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1720 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1721 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1726 shared_ptr<AudioTrack> track;
1729 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1731 if (track->ensure_io (input_channels, output_channels, false, this)) {
1732 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1733 input_channels, output_channels)
1739 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1743 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1744 port = physinputs[(channels_used+x)%nphysical_in];
1747 if (port.length() && track->connect_input (track->input (x), port, this)) {
1753 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1757 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1758 port = physoutputs[(channels_used+x)%nphysical_out];
1759 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1761 port = _master_out->input (x%_master_out->n_inputs())->name();
1765 if (port.length() && track->connect_output (track->output (x), port, this)) {
1770 channels_used += track->n_inputs ();
1772 track->audio_diskstream()->non_realtime_input_change();
1774 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1775 track->set_remote_control_id (control_id);
1778 new_routes.push_back (track);
1779 ret.push_back (track);
1782 catch (failed_constructor &err) {
1783 error << _("Session: could not create new audio track.") << endmsg;
1786 /* we need to get rid of this, since the track failed to be created */
1787 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1790 RCUWriter<DiskstreamList> writer (diskstreams);
1791 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1792 ds->remove (track->audio_diskstream());
1799 catch (AudioEngine::PortRegistrationFailure& pfe) {
1801 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;
1804 /* we need to get rid of this, since the track failed to be created */
1805 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1808 RCUWriter<DiskstreamList> writer (diskstreams);
1809 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1810 ds->remove (track->audio_diskstream());
1821 if (!new_routes.empty()) {
1822 add_routes (new_routes, false);
1823 save_state (_current_snapshot_name);
1830 Session::set_remote_control_ids ()
1832 RemoteModel m = Config->get_remote_model();
1834 shared_ptr<RouteList> r = routes.reader ();
1836 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1837 if ( MixerOrdered == m) {
1838 long order = (*i)->order_key(N_("signal"));
1839 (*i)->set_remote_control_id( order+1 );
1840 } else if ( EditorOrdered == m) {
1841 long order = (*i)->order_key(N_("editor"));
1842 (*i)->set_remote_control_id( order+1 );
1843 } else if ( UserOrdered == m) {
1844 //do nothing ... only changes to remote id's are initiated by user
1851 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1854 uint32_t bus_id = 1;
1858 uint32_t control_id;
1860 /* count existing audio busses */
1863 shared_ptr<RouteList> r = routes.reader ();
1865 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1866 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1867 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1874 vector<string> physinputs;
1875 vector<string> physoutputs;
1877 _engine.get_physical_outputs (physoutputs);
1878 _engine.get_physical_inputs (physinputs);
1879 control_id = ntracks() + nbusses() + 1;
1884 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1888 if (route_by_name (bus_name) == 0) {
1892 } while (bus_id < (UINT_MAX-1));
1895 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1897 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1898 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1899 input_channels, output_channels)
1904 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1908 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1909 port = physinputs[((n+x)%n_physical_inputs)];
1912 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1917 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1921 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1922 port = physoutputs[((n+x)%n_physical_outputs)];
1923 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1925 port = _master_out->input (x%_master_out->n_inputs())->name();
1929 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1934 bus->set_remote_control_id (control_id);
1937 ret.push_back (bus);
1941 catch (failed_constructor &err) {
1942 error << _("Session: could not create new audio route.") << endmsg;
1946 catch (AudioEngine::PortRegistrationFailure& pfe) {
1947 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;
1957 add_routes (ret, false);
1958 save_state (_current_snapshot_name);
1966 Session::add_routes (RouteList& new_routes, bool save)
1969 RCUWriter<RouteList> writer (routes);
1970 shared_ptr<RouteList> r = writer.get_copy ();
1971 r->insert (r->end(), new_routes.begin(), new_routes.end());
1972 resort_routes_using (r);
1975 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1977 boost::weak_ptr<Route> wpr (*x);
1979 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1980 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1981 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1982 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1984 if ((*x)->master()) {
1988 if ((*x)->control()) {
1989 _control_out = (*x);
1993 if (_control_out && IO::connecting_legal) {
1995 vector<string> cports;
1996 uint32_t ni = _control_out->n_inputs();
1999 for (n = 0; n < ni; ++n) {
2000 cports.push_back (_control_out->input(n)->name());
2003 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2004 (*x)->set_control_outs (cports);
2011 save_state (_current_snapshot_name);
2014 RouteAdded (new_routes); /* EMIT SIGNAL */
2018 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2020 /* need to do this in case we're rolling at the time, to prevent false underruns */
2021 dstream->do_refill_with_alloc ();
2023 dstream->set_block_size (current_block_size);
2026 RCUWriter<DiskstreamList> writer (diskstreams);
2027 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2028 ds->push_back (dstream);
2029 /* writer goes out of scope, copies ds back to main */
2032 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2033 boost::weak_ptr<Diskstream> (dstream)));
2034 /* this will connect to future changes, and check the current length */
2035 diskstream_playlist_changed (dstream);
2037 dstream->prepare ();
2041 Session::remove_route (shared_ptr<Route> route)
2044 RCUWriter<RouteList> writer (routes);
2045 shared_ptr<RouteList> rs = writer.get_copy ();
2049 /* deleting the master out seems like a dumb
2050 idea, but its more of a UI policy issue
2054 if (route == _master_out) {
2055 _master_out = shared_ptr<Route> ();
2058 if (route == _control_out) {
2059 _control_out = shared_ptr<Route> ();
2061 /* cancel control outs for all routes */
2063 vector<string> empty;
2065 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2066 (*r)->set_control_outs (empty);
2070 update_route_solo_state ();
2072 /* writer goes out of scope, forces route list update */
2075 // FIXME: audio specific
2077 boost::shared_ptr<AudioDiskstream> ds;
2079 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2080 ds = at->audio_diskstream();
2086 RCUWriter<DiskstreamList> dsl (diskstreams);
2087 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2091 diskstreams.flush ();
2094 find_current_end ();
2096 update_latency_compensation (false, false);
2099 // We need to disconnect the routes inputs and outputs
2101 route->disconnect_inputs (0);
2102 route->disconnect_outputs (0);
2104 /* get rid of it from the dead wood collection in the route list manager */
2106 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2110 /* try to cause everyone to drop their references */
2112 route->drop_references ();
2114 /* save the new state of the world */
2116 if (save_state (_current_snapshot_name)) {
2117 save_history (_current_snapshot_name);
2122 Session::route_mute_changed (void* src)
2128 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2130 if (solo_update_disabled) {
2136 boost::shared_ptr<Route> route = wpr.lock ();
2139 /* should not happen */
2140 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2144 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2146 shared_ptr<RouteList> r = routes.reader ();
2148 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2150 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2154 /* don't mess with busses */
2156 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2162 /* don't mess with tracks */
2164 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2169 if ((*i) != route &&
2170 ((*i)->mix_group () == 0 ||
2171 (*i)->mix_group () != route->mix_group () ||
2172 !route->mix_group ()->is_active())) {
2174 if ((*i)->soloed()) {
2176 /* if its already soloed, and solo latching is enabled,
2177 then leave it as it is.
2180 if (Config->get_solo_latched()) {
2187 solo_update_disabled = true;
2188 (*i)->set_solo (false, src);
2189 solo_update_disabled = false;
2193 bool something_soloed = false;
2194 bool same_thing_soloed = false;
2195 bool signal = false;
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 if ((*i)->soloed()) {
2199 something_soloed = true;
2200 if (dynamic_cast<AudioTrack*>((*i).get())) {
2202 same_thing_soloed = true;
2207 same_thing_soloed = true;
2215 if (something_soloed != currently_soloing) {
2217 currently_soloing = something_soloed;
2220 modify_solo_mute (is_track, same_thing_soloed);
2223 SoloActive (currently_soloing); /* EMIT SIGNAL */
2226 SoloChanged (); /* EMIT SIGNAL */
2232 Session::update_route_solo_state ()
2235 bool is_track = false;
2236 bool signal = false;
2238 /* caller must hold RouteLock */
2240 /* this is where we actually implement solo by changing
2241 the solo mute setting of each track.
2244 shared_ptr<RouteList> r = routes.reader ();
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2247 if ((*i)->soloed()) {
2249 if (dynamic_cast<AudioTrack*>((*i).get())) {
2256 if (mute != currently_soloing) {
2258 currently_soloing = mute;
2261 if (!is_track && !mute) {
2263 /* nothing is soloed */
2265 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2266 (*i)->set_solo_mute (false);
2276 modify_solo_mute (is_track, mute);
2279 SoloActive (currently_soloing);
2284 Session::modify_solo_mute (bool is_track, bool mute)
2286 shared_ptr<RouteList> r = routes.reader ();
2288 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2292 /* only alter track solo mute */
2294 if (dynamic_cast<AudioTrack*>((*i).get())) {
2295 if ((*i)->soloed()) {
2296 (*i)->set_solo_mute (!mute);
2298 (*i)->set_solo_mute (mute);
2304 /* only alter bus solo mute */
2306 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2308 if ((*i)->soloed()) {
2310 (*i)->set_solo_mute (false);
2314 /* don't mute master or control outs
2315 in response to another bus solo
2318 if ((*i) != _master_out &&
2319 (*i) != _control_out) {
2320 (*i)->set_solo_mute (mute);
2331 Session::catch_up_on_solo ()
2333 /* this is called after set_state() to catch the full solo
2334 state, which can't be correctly determined on a per-route
2335 basis, but needs the global overview that only the session
2338 update_route_solo_state();
2342 Session::route_by_name (string name)
2344 shared_ptr<RouteList> r = routes.reader ();
2346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2347 if ((*i)->name() == name) {
2352 return shared_ptr<Route> ((Route*) 0);
2356 Session::route_by_id (PBD::ID id)
2358 shared_ptr<RouteList> r = routes.reader ();
2360 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2361 if ((*i)->id() == id) {
2366 return shared_ptr<Route> ((Route*) 0);
2370 Session::route_by_remote_id (uint32_t id)
2372 shared_ptr<RouteList> r = routes.reader ();
2374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2375 if ((*i)->remote_control_id() == id) {
2380 return shared_ptr<Route> ((Route*) 0);
2384 Session::find_current_end ()
2386 if (_state_of_the_state & Loading) {
2390 nframes_t max = get_maximum_extent ();
2392 if (max > end_location->end()) {
2393 end_location->set_end (max);
2395 DurationChanged(); /* EMIT SIGNAL */
2400 Session::get_maximum_extent () const
2405 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2407 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2408 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2409 if ((me = pl->get_maximum_extent()) > max) {
2417 boost::shared_ptr<Diskstream>
2418 Session::diskstream_by_name (string name)
2420 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2422 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2423 if ((*i)->name() == name) {
2428 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2431 boost::shared_ptr<Diskstream>
2432 Session::diskstream_by_id (const PBD::ID& id)
2434 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2436 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2437 if ((*i)->id() == id) {
2442 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2445 /* AudioRegion management */
2448 Session::new_region_name (string old)
2450 string::size_type last_period;
2452 string::size_type len = old.length() + 64;
2455 if ((last_period = old.find_last_of ('.')) == string::npos) {
2457 /* no period present - add one explicitly */
2460 last_period = old.length() - 1;
2465 number = atoi (old.substr (last_period+1).c_str());
2469 while (number < (UINT_MAX-1)) {
2471 AudioRegionList::const_iterator i;
2476 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2479 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2480 if (i->second->name() == sbuf) {
2485 if (i == audio_regions.end()) {
2490 if (number != (UINT_MAX-1)) {
2494 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2499 Session::region_name (string& result, string base, bool newlevel) const
2506 Glib::Mutex::Lock lm (region_lock);
2508 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2516 /* XXX this is going to be slow. optimize me later */
2521 string::size_type pos;
2523 pos = base.find_last_of ('.');
2525 /* pos may be npos, but then we just use entire base */
2527 subbase = base.substr (0, pos);
2531 bool name_taken = true;
2534 Glib::Mutex::Lock lm (region_lock);
2536 for (int n = 1; n < 5000; ++n) {
2539 snprintf (buf, sizeof (buf), ".%d", n);
2544 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2545 if (i->second->name() == result) {
2558 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2566 Session::add_region (boost::shared_ptr<Region> region)
2568 boost::shared_ptr<AudioRegion> ar;
2569 boost::shared_ptr<AudioRegion> oar;
2573 Glib::Mutex::Lock lm (region_lock);
2575 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2577 AudioRegionList::iterator x;
2579 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2581 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2583 if (ar->region_list_equivalent (oar)) {
2588 if (x == audio_regions.end()) {
2590 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2592 entry.first = region->id();
2595 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2607 fatal << _("programming error: ")
2608 << X_("unknown region type passed to Session::add_region()")
2615 /* mark dirty because something has changed even if we didn't
2616 add the region to the region list.
2622 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2623 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2624 AudioRegionAdded (ar); /* EMIT SIGNAL */
2629 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2631 boost::shared_ptr<Region> region (weak_region.lock ());
2637 if (what_changed & Region::HiddenChanged) {
2638 /* relay hidden changes */
2639 RegionHiddenChange (region);
2644 Session::remove_region (boost::weak_ptr<Region> weak_region)
2646 AudioRegionList::iterator i;
2647 boost::shared_ptr<Region> region (weak_region.lock ());
2653 boost::shared_ptr<AudioRegion> ar;
2654 bool removed = false;
2657 Glib::Mutex::Lock lm (region_lock);
2659 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2660 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2661 audio_regions.erase (i);
2667 fatal << _("programming error: ")
2668 << X_("unknown region type passed to Session::remove_region()")
2674 /* mark dirty because something has changed even if we didn't
2675 remove the region from the region list.
2681 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2685 boost::shared_ptr<AudioRegion>
2686 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2688 AudioRegionList::iterator i;
2689 boost::shared_ptr<AudioRegion> region;
2690 Glib::Mutex::Lock lm (region_lock);
2692 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2696 if (region->whole_file()) {
2698 if (child->source_equivalent (region)) {
2704 return boost::shared_ptr<AudioRegion> ();
2708 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2710 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2711 (*i)->get_region_list_equivalent_regions (region, result);
2715 Session::destroy_region (boost::shared_ptr<Region> region)
2717 vector<boost::shared_ptr<Source> > srcs;
2720 boost::shared_ptr<AudioRegion> aregion;
2722 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2726 if (aregion->playlist()) {
2727 aregion->playlist()->destroy_region (region);
2730 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2731 srcs.push_back (aregion->source (n));
2735 region->drop_references ();
2737 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2739 if (!(*i)->used()) {
2740 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2743 (afs)->mark_for_remove ();
2746 (*i)->drop_references ();
2748 cerr << "source was not used by any playlist\n";
2756 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2758 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2759 destroy_region (*i);
2765 Session::remove_last_capture ()
2767 list<boost::shared_ptr<Region> > r;
2769 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2771 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2772 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2775 r.insert (r.end(), l.begin(), l.end());
2780 destroy_regions (r);
2782 save_state (_current_snapshot_name);
2788 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2794 /* Source Management */
2797 Session::add_source (boost::shared_ptr<Source> source)
2799 boost::shared_ptr<AudioFileSource> afs;
2801 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2803 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2804 pair<AudioSourceList::iterator,bool> result;
2806 entry.first = source->id();
2810 Glib::Mutex::Lock lm (audio_source_lock);
2811 result = audio_sources.insert (entry);
2814 if (result.second) {
2815 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2823 Session::remove_source (boost::weak_ptr<Source> src)
2825 AudioSourceList::iterator i;
2826 boost::shared_ptr<Source> source = src.lock();
2833 Glib::Mutex::Lock lm (audio_source_lock);
2835 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2836 audio_sources.erase (i);
2840 if (!_state_of_the_state & InCleanup) {
2842 /* save state so we don't end up with a session file
2843 referring to non-existent sources.
2846 save_state (_current_snapshot_name);
2850 boost::shared_ptr<Source>
2851 Session::source_by_id (const PBD::ID& id)
2853 Glib::Mutex::Lock lm (audio_source_lock);
2854 AudioSourceList::iterator i;
2855 boost::shared_ptr<Source> source;
2857 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2861 /* XXX search MIDI or other searches here */
2867 boost::shared_ptr<Source>
2868 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2870 Glib::Mutex::Lock lm (audio_source_lock);
2872 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2873 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2875 if (afs && afs->path() == path && chn == afs->channel()) {
2880 return boost::shared_ptr<Source>();
2884 Session::peak_path_from_audio_path (string audio_path) const
2889 res += PBD::basename_nosuffix (audio_path);
2896 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2899 string old_basename = PBD::basename_nosuffix (oldname);
2900 string new_legalized = legalize_for_path (newname);
2902 /* note: we know (or assume) the old path is already valid */
2906 /* destructive file sources have a name of the form:
2908 /path/to/Tnnnn-NAME(%[LR])?.wav
2910 the task here is to replace NAME with the new name.
2913 /* find last slash */
2917 string::size_type slash;
2918 string::size_type dash;
2920 if ((slash = path.find_last_of ('/')) == string::npos) {
2924 dir = path.substr (0, slash+1);
2926 /* '-' is not a legal character for the NAME part of the path */
2928 if ((dash = path.find_last_of ('-')) == string::npos) {
2932 prefix = path.substr (slash+1, dash-(slash+1));
2937 path += new_legalized;
2938 path += ".wav"; /* XXX gag me with a spoon */
2942 /* non-destructive file sources have a name of the form:
2944 /path/to/NAME-nnnnn(%[LR])?.wav
2946 the task here is to replace NAME with the new name.
2951 string::size_type slash;
2952 string::size_type dash;
2953 string::size_type postfix;
2955 /* find last slash */
2957 if ((slash = path.find_last_of ('/')) == string::npos) {
2961 dir = path.substr (0, slash+1);
2963 /* '-' is not a legal character for the NAME part of the path */
2965 if ((dash = path.find_last_of ('-')) == string::npos) {
2969 suffix = path.substr (dash+1);
2971 // Suffix is now everything after the dash. Now we need to eliminate
2972 // the nnnnn part, which is done by either finding a '%' or a '.'
2974 postfix = suffix.find_last_of ("%");
2975 if (postfix == string::npos) {
2976 postfix = suffix.find_last_of ('.');
2979 if (postfix != string::npos) {
2980 suffix = suffix.substr (postfix);
2982 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2986 const uint32_t limit = 10000;
2987 char buf[PATH_MAX+1];
2989 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2991 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2993 if (access (buf, F_OK) != 0) {
3001 error << "FATAL ERROR! Could not find a " << endl;
3010 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3014 char buf[PATH_MAX+1];
3015 const uint32_t limit = 10000;
3019 legalized = legalize_for_path (name);
3021 /* find a "version" of the file name that doesn't exist in
3022 any of the possible directories.
3025 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3027 vector<space_and_path>::iterator i;
3028 uint32_t existing = 0;
3030 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3034 spath += sound_dir (false);
3038 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3039 } else if (nchan == 2) {
3041 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3043 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3045 } else if (nchan < 26) {
3046 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3048 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3057 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3058 } else if (nchan == 2) {
3060 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3062 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3064 } else if (nchan < 26) {
3065 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3067 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3071 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3077 if (existing == 0) {
3082 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3084 throw failed_constructor();
3088 /* we now have a unique name for the file, but figure out where to
3094 spath = discover_best_sound_dir ();
3097 string::size_type pos = foo.find_last_of ('/');
3099 if (pos == string::npos) {
3102 spath += foo.substr (pos + 1);
3108 boost::shared_ptr<AudioFileSource>
3109 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3111 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3112 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3115 /* Playlist management */
3117 boost::shared_ptr<Playlist>
3118 Session::playlist_by_name (string name)
3120 Glib::Mutex::Lock lm (playlist_lock);
3121 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3122 if ((*i)->name() == name) {
3126 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3127 if ((*i)->name() == name) {
3132 return boost::shared_ptr<Playlist>();
3136 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3138 if (playlist->hidden()) {
3143 Glib::Mutex::Lock lm (playlist_lock);
3144 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3145 playlists.insert (playlists.begin(), playlist);
3146 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3147 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3153 PlaylistAdded (playlist); /* EMIT SIGNAL */
3157 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3160 Glib::Mutex::Lock lm (playlist_lock);
3161 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3164 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3171 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3173 boost::shared_ptr<Playlist> pl(wpl.lock());
3179 PlaylistList::iterator x;
3182 /* its not supposed to be visible */
3187 Glib::Mutex::Lock lm (playlist_lock);
3191 unused_playlists.insert (pl);
3193 if ((x = playlists.find (pl)) != playlists.end()) {
3194 playlists.erase (x);
3200 playlists.insert (pl);
3202 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3203 unused_playlists.erase (x);
3210 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3212 if (_state_of_the_state & Deletion) {
3216 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3223 Glib::Mutex::Lock lm (playlist_lock);
3225 PlaylistList::iterator i;
3227 i = find (playlists.begin(), playlists.end(), playlist);
3228 if (i != playlists.end()) {
3229 playlists.erase (i);
3232 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3233 if (i != unused_playlists.end()) {
3234 unused_playlists.erase (i);
3241 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3245 Session::set_audition (boost::shared_ptr<Region> r)
3247 pending_audition_region = r;
3248 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3249 schedule_butler_transport_work ();
3253 Session::audition_playlist ()
3255 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3256 ev->region.reset ();
3261 Session::non_realtime_set_audition ()
3263 if (!pending_audition_region) {
3264 auditioner->audition_current_playlist ();
3266 auditioner->audition_region (pending_audition_region);
3267 pending_audition_region.reset ();
3269 AuditionActive (true); /* EMIT SIGNAL */
3273 Session::audition_region (boost::shared_ptr<Region> r)
3275 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3281 Session::cancel_audition ()
3283 if (auditioner->active()) {
3284 auditioner->cancel_audition ();
3285 AuditionActive (false); /* EMIT SIGNAL */
3290 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3292 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3296 Session::remove_empty_sounds ()
3298 PathScanner scanner;
3300 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3302 Glib::Mutex::Lock lm (audio_source_lock);
3304 regex_t compiled_tape_track_pattern;
3307 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3311 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3313 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3317 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3319 /* never remove files that appear to be a tape track */
3321 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3326 if (AudioFileSource::is_empty (*this, *(*i))) {
3328 unlink ((*i)->c_str());
3330 string peak_path = peak_path_from_audio_path (**i);
3331 unlink (peak_path.c_str());
3337 delete possible_audiofiles;
3341 Session::is_auditioning () const
3343 /* can be called before we have an auditioner object */
3345 return auditioner->active();
3352 Session::set_all_solo (bool yn)
3354 shared_ptr<RouteList> r = routes.reader ();
3356 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3357 if (!(*i)->hidden()) {
3358 (*i)->set_solo (yn, this);
3366 Session::set_all_mute (bool yn)
3368 shared_ptr<RouteList> r = routes.reader ();
3370 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3371 if (!(*i)->hidden()) {
3372 (*i)->set_mute (yn, this);
3380 Session::n_diskstreams () const
3384 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3386 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3387 if (!(*i)->hidden()) {
3395 Session::graph_reordered ()
3397 /* don't do this stuff if we are setting up connections
3398 from a set_state() call or creating new tracks.
3401 if (_state_of_the_state & InitialConnecting) {
3405 /* every track/bus asked for this to be handled but it was deferred because
3406 we were connecting. do it now.
3409 request_input_change_handling ();
3413 /* force all diskstreams to update their capture offset values to
3414 reflect any changes in latencies within the graph.
3417 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3419 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3420 (*i)->set_capture_offset ();
3425 Session::record_disenable_all ()
3427 record_enable_change_all (false);
3431 Session::record_enable_all ()
3433 record_enable_change_all (true);
3437 Session::record_enable_change_all (bool yn)
3439 shared_ptr<RouteList> r = routes.reader ();
3441 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3444 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3445 at->set_record_enable (yn, this);
3449 /* since we don't keep rec-enable state, don't mark session dirty */
3453 Session::add_redirect (Redirect* redirect)
3457 PortInsert* port_insert;
3458 PluginInsert* plugin_insert;
3460 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3461 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3462 _port_inserts.insert (_port_inserts.begin(), port_insert);
3463 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3464 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3466 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3469 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3470 _sends.insert (_sends.begin(), send);
3472 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3476 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3482 Session::remove_redirect (Redirect* redirect)
3486 PortInsert* port_insert;
3487 PluginInsert* plugin_insert;
3489 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3490 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3491 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3492 if (x != _port_inserts.end()) {
3493 insert_bitset[port_insert->bit_slot()] = false;
3494 _port_inserts.erase (x);
3496 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3497 _plugin_inserts.remove (plugin_insert);
3499 fatal << string_compose (_("programming error: %1"),
3500 X_("unknown type of Insert deleted!"))
3504 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3505 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3506 if (x != _sends.end()) {
3507 send_bitset[send->bit_slot()] = false;
3511 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3519 Session::available_capture_duration ()
3521 float sample_bytes_on_disk = 4.0; // keep gcc happy
3523 switch (Config->get_native_file_data_format()) {
3525 sample_bytes_on_disk = 4.0;
3529 sample_bytes_on_disk = 3.0;
3533 /* impossible, but keep some gcc versions happy */
3534 fatal << string_compose (_("programming error: %1"),
3535 X_("illegal native file data format"))
3540 double scale = 4096.0 / sample_bytes_on_disk;
3542 if (_total_free_4k_blocks * scale > (double) max_frames) {
3546 return (nframes_t) floor (_total_free_4k_blocks * scale);
3550 Session::add_connection (ARDOUR::Connection* connection)
3553 Glib::Mutex::Lock guard (connection_lock);
3554 _connections.push_back (connection);
3557 ConnectionAdded (connection); /* EMIT SIGNAL */
3563 Session::remove_connection (ARDOUR::Connection* connection)
3565 bool removed = false;
3568 Glib::Mutex::Lock guard (connection_lock);
3569 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3571 if (i != _connections.end()) {
3572 _connections.erase (i);
3578 ConnectionRemoved (connection); /* EMIT SIGNAL */
3584 ARDOUR::Connection *
3585 Session::connection_by_name (string name) const
3587 Glib::Mutex::Lock lm (connection_lock);
3589 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3590 if ((*i)->name() == name) {
3599 Session::tempo_map_changed (Change ignored)
3606 Session::ensure_passthru_buffers (uint32_t howmany)
3608 while (howmany > _passthru_buffers.size()) {
3610 #ifdef NO_POSIX_MEMALIGN
3611 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3613 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3615 _passthru_buffers.push_back (p);
3619 #ifdef NO_POSIX_MEMALIGN
3620 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3622 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4);
3624 memset (p, 0, sizeof (Sample) * current_block_size);
3625 _silent_buffers.push_back (p);
3629 #ifdef NO_POSIX_MEMALIGN
3630 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3632 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3634 memset (p, 0, sizeof (Sample) * current_block_size);
3635 _send_buffers.push_back (p);
3638 allocate_pan_automation_buffers (current_block_size, howmany, false);
3642 Session::next_insert_id ()
3644 /* this doesn't really loop forever. just think about it */
3647 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3648 if (!insert_bitset[n]) {
3649 insert_bitset[n] = true;
3655 /* none available, so resize and try again */
3657 insert_bitset.resize (insert_bitset.size() + 16, false);
3662 Session::next_send_id ()
3664 /* this doesn't really loop forever. just think about it */
3667 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3668 if (!send_bitset[n]) {
3669 send_bitset[n] = true;
3675 /* none available, so resize and try again */
3677 send_bitset.resize (send_bitset.size() + 16, false);
3682 Session::mark_send_id (uint32_t id)
3684 if (id >= send_bitset.size()) {
3685 send_bitset.resize (id+16, false);
3687 if (send_bitset[id]) {
3688 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3690 send_bitset[id] = true;
3694 Session::mark_insert_id (uint32_t id)
3696 if (id >= insert_bitset.size()) {
3697 insert_bitset.resize (id+16, false);
3699 if (insert_bitset[id]) {
3700 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3702 insert_bitset[id] = true;
3705 /* Named Selection management */
3708 Session::named_selection_by_name (string name)
3710 Glib::Mutex::Lock lm (named_selection_lock);
3711 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3712 if ((*i)->name == name) {
3720 Session::add_named_selection (NamedSelection* named_selection)
3723 Glib::Mutex::Lock lm (named_selection_lock);
3724 named_selections.insert (named_selections.begin(), named_selection);
3727 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3733 NamedSelectionAdded (); /* EMIT SIGNAL */
3737 Session::remove_named_selection (NamedSelection* named_selection)
3739 bool removed = false;
3742 Glib::Mutex::Lock lm (named_selection_lock);
3744 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3746 if (i != named_selections.end()) {
3748 named_selections.erase (i);
3755 NamedSelectionRemoved (); /* EMIT SIGNAL */
3760 Session::reset_native_file_format ()
3762 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3764 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3765 (*i)->reset_write_sources (false);
3770 Session::route_name_unique (string n) const
3772 shared_ptr<RouteList> r = routes.reader ();
3774 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3775 if ((*i)->name() == n) {
3784 Session::n_playlists () const
3786 Glib::Mutex::Lock lm (playlist_lock);
3787 return playlists.size();
3791 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3793 if (!force && howmany <= _npan_buffers) {
3797 if (_pan_automation_buffer) {
3799 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3800 delete [] _pan_automation_buffer[i];
3803 delete [] _pan_automation_buffer;
3806 _pan_automation_buffer = new pan_t*[howmany];
3808 for (uint32_t i = 0; i < howmany; ++i) {
3809 _pan_automation_buffer[i] = new pan_t[nframes];
3812 _npan_buffers = howmany;
3816 Session::freeze (InterThreadInfo& itt)
3818 shared_ptr<RouteList> r = routes.reader ();
3820 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3824 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3825 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3836 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3837 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3840 boost::shared_ptr<Playlist> playlist;
3841 boost::shared_ptr<AudioFileSource> fsource;
3843 char buf[PATH_MAX+1];
3847 nframes_t this_chunk;
3849 vector<Sample*> buffers;
3851 // any bigger than this seems to cause stack overflows in called functions
3852 const nframes_t chunk_size = (128 * 1024)/4;
3854 g_atomic_int_set (&processing_prohibited, 1);
3856 /* call tree *MUST* hold route_lock */
3858 if ((playlist = track.diskstream()->playlist()) == 0) {
3862 /* external redirects will be a problem */
3864 if (track.has_external_redirects()) {
3868 nchans = track.audio_diskstream()->n_channels();
3870 dir = discover_best_sound_dir ();
3872 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3874 for (x = 0; x < 99999; ++x) {
3875 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3876 if (access (buf, F_OK) != 0) {
3882 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3887 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3890 catch (failed_constructor& err) {
3891 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3895 srcs.push_back (fsource);
3898 /* XXX need to flush all redirects */
3903 /* create a set of reasonably-sized buffers */
3905 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3907 #ifdef NO_POSIX_MEMALIGN
3908 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3910 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
3912 buffers.push_back (b);
3915 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3916 (*src)->prepare_for_peakfile_writes ();
3919 while (to_do && !itt.cancel) {
3921 this_chunk = min (to_do, chunk_size);
3923 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3928 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3929 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3932 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3938 start += this_chunk;
3939 to_do -= this_chunk;
3941 itt.progress = (float) (1.0 - ((double) to_do / len));
3950 xnow = localtime (&now);
3952 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3953 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3956 afs->update_header (position, *xnow, now);
3957 afs->flush_header ();
3961 /* construct a region to represent the bounced material */
3963 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3964 region_name_from_path (srcs.front()->name(), true));
3971 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3972 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3975 afs->mark_for_remove ();
3978 (*src)->drop_references ();
3982 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3983 (*src)->done_with_peakfile_writes ();
3987 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3991 g_atomic_int_set (&processing_prohibited, 0);
3999 Session::get_silent_buffers (uint32_t howmany)
4001 for (uint32_t i = 0; i < howmany; ++i) {
4002 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4004 return _silent_buffers;
4008 Session::ntracks () const
4011 shared_ptr<RouteList> r = routes.reader ();
4013 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4014 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4023 Session::nbusses () const
4026 shared_ptr<RouteList> r = routes.reader ();
4028 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4029 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4038 Session::add_automation_list(AutomationList *al)
4040 automation_lists[al->id()] = al;
4044 Session::compute_initial_length ()
4046 return _engine.frame_rate() * 60 * 5;