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 () || 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 g_atomic_int_set (&_record_status, Enabled);
1295 if (Config->get_monitoring_model() == HardwareMonitoring) {
1296 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1298 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1299 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1300 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1301 (*i)->monitor_input (false);
1308 Session::maybe_enable_record ()
1310 g_atomic_int_set (&_record_status, Enabled);
1312 /* this function is currently called from somewhere other than an RT thread.
1313 this save_state() call therefore doesn't impact anything.
1316 save_state ("", true);
1318 if (_transport_speed) {
1319 if (!Config->get_punch_in()) {
1323 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1324 RecordStateChanged (); /* EMIT SIGNAL */
1331 Session::audible_frame () const
1337 /* the first of these two possible settings for "offset"
1338 mean that the audible frame is stationary until
1339 audio emerges from the latency compensation
1342 the second means that the audible frame is stationary
1343 until audio would emerge from a physical port
1344 in the absence of any plugin latency compensation
1347 offset = _worst_output_latency;
1349 if (offset > current_block_size) {
1350 offset -= current_block_size;
1352 /* XXX is this correct? if we have no external
1353 physical connections and everything is internal
1354 then surely this is zero? still, how
1355 likely is that anyway?
1357 offset = current_block_size;
1360 if (synced_to_jack()) {
1361 tf = _engine.transport_frame();
1363 tf = _transport_frame;
1366 if (_transport_speed == 0) {
1376 if (!non_realtime_work_pending()) {
1380 /* take latency into account */
1389 Session::set_frame_rate (nframes_t frames_per_second)
1391 /** \fn void Session::set_frame_size(nframes_t)
1392 the AudioEngine object that calls this guarantees
1393 that it will not be called while we are also in
1394 ::process(). Its fine to do things that block
1398 _base_frame_rate = frames_per_second;
1402 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1404 // XXX we need some equivalent to this, somehow
1405 // SndFileSource::setup_standard_crossfades (frames_per_second);
1409 /* XXX need to reset/reinstantiate all LADSPA plugins */
1413 Session::set_block_size (nframes_t nframes)
1415 /* the AudioEngine guarantees
1416 that it will not be called while we are also in
1417 ::process(). It is therefore fine to do things that block
1422 vector<Sample*>::iterator i;
1425 current_block_size = nframes;
1427 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1431 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1435 _passthru_buffers.clear ();
1436 _silent_buffers.clear ();
1438 ensure_passthru_buffers (np);
1440 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1444 #ifdef NO_POSIX_MEMALIGN
1445 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1447 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1451 memset (*i, 0, sizeof (Sample) * current_block_size);
1455 if (_gain_automation_buffer) {
1456 delete [] _gain_automation_buffer;
1458 _gain_automation_buffer = new gain_t[nframes];
1460 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1462 boost::shared_ptr<RouteList> r = routes.reader ();
1464 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1465 (*i)->set_block_size (nframes);
1468 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1469 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1470 (*i)->set_block_size (nframes);
1473 set_worst_io_latencies ();
1478 Session::set_default_fade (float steepness, float fade_msecs)
1481 nframes_t fade_frames;
1483 /* Don't allow fade of less 1 frame */
1485 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1492 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1496 default_fade_msecs = fade_msecs;
1497 default_fade_steepness = steepness;
1500 // jlc, WTF is this!
1501 Glib::RWLock::ReaderLock lm (route_lock);
1502 AudioRegion::set_default_fade (steepness, fade_frames);
1507 /* XXX have to do this at some point */
1508 /* foreach region using default fade, reset, then
1509 refill_all_diskstream_buffers ();
1514 struct RouteSorter {
1515 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1516 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1518 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1521 if (r1->fed_by.empty()) {
1522 if (r2->fed_by.empty()) {
1523 /* no ardour-based connections inbound to either route. just use signal order */
1524 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1526 /* r2 has connections, r1 does not; run r1 early */
1530 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1537 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1539 shared_ptr<Route> r2;
1541 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1542 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1546 /* make a copy of the existing list of routes that feed r1 */
1548 set<shared_ptr<Route> > existing = r1->fed_by;
1550 /* for each route that feeds r1, recurse, marking it as feeding
1554 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1557 /* r2 is a route that feeds r1 which somehow feeds base. mark
1558 base as being fed by r2
1561 rbase->fed_by.insert (r2);
1565 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1569 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1573 /* now recurse, so that we can mark base as being fed by
1574 all routes that feed r2
1577 trace_terminal (r2, rbase);
1584 Session::resort_routes ()
1586 /* don't do anything here with signals emitted
1587 by Routes while we are being destroyed.
1590 if (_state_of_the_state & Deletion) {
1597 RCUWriter<RouteList> writer (routes);
1598 shared_ptr<RouteList> r = writer.get_copy ();
1599 resort_routes_using (r);
1600 /* writer goes out of scope and forces update */
1605 Session::resort_routes_using (shared_ptr<RouteList> r)
1607 RouteList::iterator i, j;
1609 for (i = r->begin(); i != r->end(); ++i) {
1611 (*i)->fed_by.clear ();
1613 for (j = r->begin(); j != r->end(); ++j) {
1615 /* although routes can feed themselves, it will
1616 cause an endless recursive descent if we
1617 detect it. so don't bother checking for
1625 if ((*j)->feeds (*i)) {
1626 (*i)->fed_by.insert (*j);
1631 for (i = r->begin(); i != r->end(); ++i) {
1632 trace_terminal (*i, *i);
1638 /* don't leave dangling references to routes in Route::fed_by */
1640 for (i = r->begin(); i != r->end(); ++i) {
1641 (*i)->fed_by.clear ();
1645 cerr << "finished route resort\n";
1647 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1648 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1655 list<boost::shared_ptr<AudioTrack> >
1656 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1658 char track_name[32];
1659 uint32_t track_id = 0;
1661 uint32_t channels_used = 0;
1663 RouteList new_routes;
1664 list<boost::shared_ptr<AudioTrack> > ret;
1665 uint32_t control_id;
1667 /* count existing audio tracks */
1670 shared_ptr<RouteList> r = routes.reader ();
1672 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1673 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1674 if (!(*i)->hidden()) {
1676 channels_used += (*i)->n_inputs();
1682 vector<string> physinputs;
1683 vector<string> physoutputs;
1684 uint32_t nphysical_in;
1685 uint32_t nphysical_out;
1687 _engine.get_physical_outputs (physoutputs);
1688 _engine.get_physical_inputs (physinputs);
1689 control_id = ntracks() + nbusses() + 1;
1693 /* check for duplicate route names, since we might have pre-existing
1694 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1695 save, close,restart,add new route - first named route is now
1703 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1705 if (route_by_name (track_name) == 0) {
1709 } while (track_id < (UINT_MAX-1));
1711 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1712 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1717 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1718 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1723 shared_ptr<AudioTrack> track;
1726 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1728 if (track->ensure_io (input_channels, output_channels, false, this)) {
1729 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1730 input_channels, output_channels)
1736 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1740 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1741 port = physinputs[(channels_used+x)%nphysical_in];
1744 if (port.length() && track->connect_input (track->input (x), port, this)) {
1750 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1754 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1755 port = physoutputs[(channels_used+x)%nphysical_out];
1756 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1758 port = _master_out->input (x%_master_out->n_inputs())->name();
1762 if (port.length() && track->connect_output (track->output (x), port, this)) {
1767 channels_used += track->n_inputs ();
1769 track->audio_diskstream()->non_realtime_input_change();
1771 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1772 track->set_remote_control_id (control_id);
1775 new_routes.push_back (track);
1776 ret.push_back (track);
1779 catch (failed_constructor &err) {
1780 error << _("Session: could not create new audio track.") << endmsg;
1783 /* we need to get rid of this, since the track failed to be created */
1784 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1787 RCUWriter<DiskstreamList> writer (diskstreams);
1788 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1789 ds->remove (track->audio_diskstream());
1796 catch (AudioEngine::PortRegistrationFailure& pfe) {
1798 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;
1801 /* we need to get rid of this, since the track failed to be created */
1802 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1805 RCUWriter<DiskstreamList> writer (diskstreams);
1806 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1807 ds->remove (track->audio_diskstream());
1818 if (!new_routes.empty()) {
1819 add_routes (new_routes, false);
1820 save_state (_current_snapshot_name);
1827 Session::set_remote_control_ids ()
1829 RemoteModel m = Config->get_remote_model();
1831 shared_ptr<RouteList> r = routes.reader ();
1833 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1834 if ( MixerOrdered == m) {
1835 long order = (*i)->order_key(N_("signal"));
1836 (*i)->set_remote_control_id( order+1 );
1837 } else if ( EditorOrdered == m) {
1838 long order = (*i)->order_key(N_("editor"));
1839 (*i)->set_remote_control_id( order+1 );
1840 } else if ( UserOrdered == m) {
1841 //do nothing ... only changes to remote id's are initiated by user
1848 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1851 uint32_t bus_id = 1;
1855 uint32_t control_id;
1857 /* count existing audio busses */
1860 shared_ptr<RouteList> r = routes.reader ();
1862 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1863 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1864 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1871 vector<string> physinputs;
1872 vector<string> physoutputs;
1874 _engine.get_physical_outputs (physoutputs);
1875 _engine.get_physical_inputs (physinputs);
1876 control_id = ntracks() + nbusses() + 1;
1881 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1885 if (route_by_name (bus_name) == 0) {
1889 } while (bus_id < (UINT_MAX-1));
1892 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1894 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1895 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1896 input_channels, output_channels)
1901 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1905 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1906 port = physinputs[((n+x)%n_physical_inputs)];
1909 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1914 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1918 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1919 port = physoutputs[((n+x)%n_physical_outputs)];
1920 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1922 port = _master_out->input (x%_master_out->n_inputs())->name();
1926 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1931 bus->set_remote_control_id (control_id);
1934 ret.push_back (bus);
1938 catch (failed_constructor &err) {
1939 error << _("Session: could not create new audio route.") << endmsg;
1943 catch (AudioEngine::PortRegistrationFailure& pfe) {
1944 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;
1954 add_routes (ret, false);
1955 save_state (_current_snapshot_name);
1963 Session::add_routes (RouteList& new_routes, bool save)
1966 RCUWriter<RouteList> writer (routes);
1967 shared_ptr<RouteList> r = writer.get_copy ();
1968 r->insert (r->end(), new_routes.begin(), new_routes.end());
1969 resort_routes_using (r);
1972 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1974 boost::weak_ptr<Route> wpr (*x);
1976 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1977 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1978 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1979 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1981 if ((*x)->master()) {
1985 if ((*x)->control()) {
1986 _control_out = (*x);
1990 if (_control_out && IO::connecting_legal) {
1992 vector<string> cports;
1993 uint32_t ni = _control_out->n_inputs();
1996 for (n = 0; n < ni; ++n) {
1997 cports.push_back (_control_out->input(n)->name());
2000 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2001 (*x)->set_control_outs (cports);
2008 save_state (_current_snapshot_name);
2011 RouteAdded (new_routes); /* EMIT SIGNAL */
2015 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2017 /* need to do this in case we're rolling at the time, to prevent false underruns */
2018 dstream->do_refill_with_alloc ();
2020 dstream->set_block_size (current_block_size);
2023 RCUWriter<DiskstreamList> writer (diskstreams);
2024 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2025 ds->push_back (dstream);
2026 /* writer goes out of scope, copies ds back to main */
2029 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2030 boost::weak_ptr<Diskstream> (dstream)));
2031 /* this will connect to future changes, and check the current length */
2032 diskstream_playlist_changed (dstream);
2034 dstream->prepare ();
2038 Session::remove_route (shared_ptr<Route> route)
2041 RCUWriter<RouteList> writer (routes);
2042 shared_ptr<RouteList> rs = writer.get_copy ();
2046 /* deleting the master out seems like a dumb
2047 idea, but its more of a UI policy issue
2051 if (route == _master_out) {
2052 _master_out = shared_ptr<Route> ();
2055 if (route == _control_out) {
2056 _control_out = shared_ptr<Route> ();
2058 /* cancel control outs for all routes */
2060 vector<string> empty;
2062 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2063 (*r)->set_control_outs (empty);
2067 update_route_solo_state ();
2069 /* writer goes out of scope, forces route list update */
2072 // FIXME: audio specific
2074 boost::shared_ptr<AudioDiskstream> ds;
2076 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2077 ds = at->audio_diskstream();
2083 RCUWriter<DiskstreamList> dsl (diskstreams);
2084 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2088 diskstreams.flush ();
2091 find_current_end ();
2093 update_latency_compensation (false, false);
2096 // We need to disconnect the routes inputs and outputs
2098 route->disconnect_inputs (0);
2099 route->disconnect_outputs (0);
2101 /* get rid of it from the dead wood collection in the route list manager */
2103 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2107 /* try to cause everyone to drop their references */
2109 route->drop_references ();
2111 /* save the new state of the world */
2113 if (save_state (_current_snapshot_name)) {
2114 save_history (_current_snapshot_name);
2119 Session::route_mute_changed (void* src)
2125 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2127 if (solo_update_disabled) {
2133 boost::shared_ptr<Route> route = wpr.lock ();
2136 /* should not happen */
2137 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2141 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2143 shared_ptr<RouteList> r = routes.reader ();
2145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2147 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2151 /* don't mess with busses */
2153 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2159 /* don't mess with tracks */
2161 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2166 if ((*i) != route &&
2167 ((*i)->mix_group () == 0 ||
2168 (*i)->mix_group () != route->mix_group () ||
2169 !route->mix_group ()->is_active())) {
2171 if ((*i)->soloed()) {
2173 /* if its already soloed, and solo latching is enabled,
2174 then leave it as it is.
2177 if (Config->get_solo_latched()) {
2184 solo_update_disabled = true;
2185 (*i)->set_solo (false, src);
2186 solo_update_disabled = false;
2190 bool something_soloed = false;
2191 bool same_thing_soloed = false;
2192 bool signal = false;
2194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2195 if ((*i)->soloed()) {
2196 something_soloed = true;
2197 if (dynamic_cast<AudioTrack*>((*i).get())) {
2199 same_thing_soloed = true;
2204 same_thing_soloed = true;
2212 if (something_soloed != currently_soloing) {
2214 currently_soloing = something_soloed;
2217 modify_solo_mute (is_track, same_thing_soloed);
2220 SoloActive (currently_soloing); /* EMIT SIGNAL */
2223 SoloChanged (); /* EMIT SIGNAL */
2229 Session::update_route_solo_state ()
2232 bool is_track = false;
2233 bool signal = false;
2235 /* caller must hold RouteLock */
2237 /* this is where we actually implement solo by changing
2238 the solo mute setting of each track.
2241 shared_ptr<RouteList> r = routes.reader ();
2243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2244 if ((*i)->soloed()) {
2246 if (dynamic_cast<AudioTrack*>((*i).get())) {
2253 if (mute != currently_soloing) {
2255 currently_soloing = mute;
2258 if (!is_track && !mute) {
2260 /* nothing is soloed */
2262 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2263 (*i)->set_solo_mute (false);
2273 modify_solo_mute (is_track, mute);
2276 SoloActive (currently_soloing);
2281 Session::modify_solo_mute (bool is_track, bool mute)
2283 shared_ptr<RouteList> r = routes.reader ();
2285 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 /* only alter track solo mute */
2291 if (dynamic_cast<AudioTrack*>((*i).get())) {
2292 if ((*i)->soloed()) {
2293 (*i)->set_solo_mute (!mute);
2295 (*i)->set_solo_mute (mute);
2301 /* only alter bus solo mute */
2303 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2305 if ((*i)->soloed()) {
2307 (*i)->set_solo_mute (false);
2311 /* don't mute master or control outs
2312 in response to another bus solo
2315 if ((*i) != _master_out &&
2316 (*i) != _control_out) {
2317 (*i)->set_solo_mute (mute);
2328 Session::catch_up_on_solo ()
2330 /* this is called after set_state() to catch the full solo
2331 state, which can't be correctly determined on a per-route
2332 basis, but needs the global overview that only the session
2335 update_route_solo_state();
2339 Session::route_by_name (string name)
2341 shared_ptr<RouteList> r = routes.reader ();
2343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2344 if ((*i)->name() == name) {
2349 return shared_ptr<Route> ((Route*) 0);
2353 Session::route_by_id (PBD::ID id)
2355 shared_ptr<RouteList> r = routes.reader ();
2357 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2358 if ((*i)->id() == id) {
2363 return shared_ptr<Route> ((Route*) 0);
2367 Session::route_by_remote_id (uint32_t id)
2369 shared_ptr<RouteList> r = routes.reader ();
2371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2372 if ((*i)->remote_control_id() == id) {
2377 return shared_ptr<Route> ((Route*) 0);
2381 Session::find_current_end ()
2383 if (_state_of_the_state & Loading) {
2387 nframes_t max = get_maximum_extent ();
2389 if (max > end_location->end()) {
2390 end_location->set_end (max);
2392 DurationChanged(); /* EMIT SIGNAL */
2397 Session::get_maximum_extent () const
2402 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2404 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2405 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2406 if ((me = pl->get_maximum_extent()) > max) {
2414 boost::shared_ptr<Diskstream>
2415 Session::diskstream_by_name (string name)
2417 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2419 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2420 if ((*i)->name() == name) {
2425 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2428 boost::shared_ptr<Diskstream>
2429 Session::diskstream_by_id (const PBD::ID& id)
2431 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2433 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2434 if ((*i)->id() == id) {
2439 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2442 /* AudioRegion management */
2445 Session::new_region_name (string old)
2447 string::size_type last_period;
2449 string::size_type len = old.length() + 64;
2452 if ((last_period = old.find_last_of ('.')) == string::npos) {
2454 /* no period present - add one explicitly */
2457 last_period = old.length() - 1;
2462 number = atoi (old.substr (last_period+1).c_str());
2466 while (number < (UINT_MAX-1)) {
2468 AudioRegionList::const_iterator i;
2473 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2476 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2477 if (i->second->name() == sbuf) {
2482 if (i == audio_regions.end()) {
2487 if (number != (UINT_MAX-1)) {
2491 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2496 Session::region_name (string& result, string base, bool newlevel) const
2503 Glib::Mutex::Lock lm (region_lock);
2505 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2513 /* XXX this is going to be slow. optimize me later */
2518 string::size_type pos;
2520 pos = base.find_last_of ('.');
2522 /* pos may be npos, but then we just use entire base */
2524 subbase = base.substr (0, pos);
2528 bool name_taken = true;
2531 Glib::Mutex::Lock lm (region_lock);
2533 for (int n = 1; n < 5000; ++n) {
2536 snprintf (buf, sizeof (buf), ".%d", n);
2541 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2542 if (i->second->name() == result) {
2555 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2563 Session::add_region (boost::shared_ptr<Region> region)
2565 boost::shared_ptr<AudioRegion> ar;
2566 boost::shared_ptr<AudioRegion> oar;
2570 Glib::Mutex::Lock lm (region_lock);
2572 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2574 AudioRegionList::iterator x;
2576 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2578 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2580 if (ar->region_list_equivalent (oar)) {
2585 if (x == audio_regions.end()) {
2587 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2589 entry.first = region->id();
2592 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2604 fatal << _("programming error: ")
2605 << X_("unknown region type passed to Session::add_region()")
2612 /* mark dirty because something has changed even if we didn't
2613 add the region to the region list.
2619 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2620 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2621 AudioRegionAdded (ar); /* EMIT SIGNAL */
2626 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2628 boost::shared_ptr<Region> region (weak_region.lock ());
2634 if (what_changed & Region::HiddenChanged) {
2635 /* relay hidden changes */
2636 RegionHiddenChange (region);
2641 Session::remove_region (boost::weak_ptr<Region> weak_region)
2643 AudioRegionList::iterator i;
2644 boost::shared_ptr<Region> region (weak_region.lock ());
2650 boost::shared_ptr<AudioRegion> ar;
2651 bool removed = false;
2654 Glib::Mutex::Lock lm (region_lock);
2656 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2657 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2658 audio_regions.erase (i);
2664 fatal << _("programming error: ")
2665 << X_("unknown region type passed to Session::remove_region()")
2671 /* mark dirty because something has changed even if we didn't
2672 remove the region from the region list.
2678 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2682 boost::shared_ptr<AudioRegion>
2683 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2685 AudioRegionList::iterator i;
2686 boost::shared_ptr<AudioRegion> region;
2687 Glib::Mutex::Lock lm (region_lock);
2689 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2693 if (region->whole_file()) {
2695 if (child->source_equivalent (region)) {
2701 return boost::shared_ptr<AudioRegion> ();
2705 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2707 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2708 (*i)->get_region_list_equivalent_regions (region, result);
2712 Session::destroy_region (boost::shared_ptr<Region> region)
2714 vector<boost::shared_ptr<Source> > srcs;
2717 boost::shared_ptr<AudioRegion> aregion;
2719 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2723 if (aregion->playlist()) {
2724 aregion->playlist()->destroy_region (region);
2727 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2728 srcs.push_back (aregion->source (n));
2732 region->drop_references ();
2734 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2736 if (!(*i)->used()) {
2737 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2740 (afs)->mark_for_remove ();
2743 (*i)->drop_references ();
2745 cerr << "source was not used by any playlist\n";
2753 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2755 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2756 destroy_region (*i);
2762 Session::remove_last_capture ()
2764 list<boost::shared_ptr<Region> > r;
2766 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2768 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2769 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2772 r.insert (r.end(), l.begin(), l.end());
2777 destroy_regions (r);
2779 save_state (_current_snapshot_name);
2785 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2791 /* Source Management */
2794 Session::add_source (boost::shared_ptr<Source> source)
2796 boost::shared_ptr<AudioFileSource> afs;
2798 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2800 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2801 pair<AudioSourceList::iterator,bool> result;
2803 entry.first = source->id();
2807 Glib::Mutex::Lock lm (audio_source_lock);
2808 result = audio_sources.insert (entry);
2811 if (result.second) {
2812 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2820 Session::remove_source (boost::weak_ptr<Source> src)
2822 AudioSourceList::iterator i;
2823 boost::shared_ptr<Source> source = src.lock();
2830 Glib::Mutex::Lock lm (audio_source_lock);
2832 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2833 audio_sources.erase (i);
2837 if (!_state_of_the_state & InCleanup) {
2839 /* save state so we don't end up with a session file
2840 referring to non-existent sources.
2843 save_state (_current_snapshot_name);
2847 boost::shared_ptr<Source>
2848 Session::source_by_id (const PBD::ID& id)
2850 Glib::Mutex::Lock lm (audio_source_lock);
2851 AudioSourceList::iterator i;
2852 boost::shared_ptr<Source> source;
2854 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2858 /* XXX search MIDI or other searches here */
2864 boost::shared_ptr<Source>
2865 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2867 Glib::Mutex::Lock lm (audio_source_lock);
2869 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2870 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2872 if (afs && afs->path() == path && chn == afs->channel()) {
2877 return boost::shared_ptr<Source>();
2881 Session::peak_path_from_audio_path (string audio_path) const
2886 res += PBD::basename_nosuffix (audio_path);
2893 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2896 string old_basename = PBD::basename_nosuffix (oldname);
2897 string new_legalized = legalize_for_path (newname);
2899 /* note: we know (or assume) the old path is already valid */
2903 /* destructive file sources have a name of the form:
2905 /path/to/Tnnnn-NAME(%[LR])?.wav
2907 the task here is to replace NAME with the new name.
2910 /* find last slash */
2914 string::size_type slash;
2915 string::size_type dash;
2917 if ((slash = path.find_last_of ('/')) == string::npos) {
2921 dir = path.substr (0, slash+1);
2923 /* '-' is not a legal character for the NAME part of the path */
2925 if ((dash = path.find_last_of ('-')) == string::npos) {
2929 prefix = path.substr (slash+1, dash-(slash+1));
2934 path += new_legalized;
2935 path += ".wav"; /* XXX gag me with a spoon */
2939 /* non-destructive file sources have a name of the form:
2941 /path/to/NAME-nnnnn(%[LR])?.wav
2943 the task here is to replace NAME with the new name.
2948 string::size_type slash;
2949 string::size_type dash;
2950 string::size_type postfix;
2952 /* find last slash */
2954 if ((slash = path.find_last_of ('/')) == string::npos) {
2958 dir = path.substr (0, slash+1);
2960 /* '-' is not a legal character for the NAME part of the path */
2962 if ((dash = path.find_last_of ('-')) == string::npos) {
2966 suffix = path.substr (dash+1);
2968 // Suffix is now everything after the dash. Now we need to eliminate
2969 // the nnnnn part, which is done by either finding a '%' or a '.'
2971 postfix = suffix.find_last_of ("%");
2972 if (postfix == string::npos) {
2973 postfix = suffix.find_last_of ('.');
2976 if (postfix != string::npos) {
2977 suffix = suffix.substr (postfix);
2979 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2983 const uint32_t limit = 10000;
2984 char buf[PATH_MAX+1];
2986 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2988 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2990 if (access (buf, F_OK) != 0) {
2998 error << "FATAL ERROR! Could not find a " << endl;
3007 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3011 char buf[PATH_MAX+1];
3012 const uint32_t limit = 10000;
3016 legalized = legalize_for_path (name);
3018 /* find a "version" of the file name that doesn't exist in
3019 any of the possible directories.
3022 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3024 vector<space_and_path>::iterator i;
3025 uint32_t existing = 0;
3027 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3031 spath += sound_dir (false);
3035 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3036 } else if (nchan == 2) {
3038 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3040 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3042 } else if (nchan < 26) {
3043 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3045 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3054 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3055 } else if (nchan == 2) {
3057 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3059 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3061 } else if (nchan < 26) {
3062 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3064 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3068 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3074 if (existing == 0) {
3079 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3081 throw failed_constructor();
3085 /* we now have a unique name for the file, but figure out where to
3091 spath = discover_best_sound_dir ();
3094 string::size_type pos = foo.find_last_of ('/');
3096 if (pos == string::npos) {
3099 spath += foo.substr (pos + 1);
3105 boost::shared_ptr<AudioFileSource>
3106 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3108 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3109 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3112 /* Playlist management */
3114 boost::shared_ptr<Playlist>
3115 Session::playlist_by_name (string name)
3117 Glib::Mutex::Lock lm (playlist_lock);
3118 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3119 if ((*i)->name() == name) {
3123 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3124 if ((*i)->name() == name) {
3129 return boost::shared_ptr<Playlist>();
3133 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3135 if (playlist->hidden()) {
3140 Glib::Mutex::Lock lm (playlist_lock);
3141 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3142 playlists.insert (playlists.begin(), playlist);
3143 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3144 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3150 PlaylistAdded (playlist); /* EMIT SIGNAL */
3154 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3157 Glib::Mutex::Lock lm (playlist_lock);
3158 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3161 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3168 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3170 boost::shared_ptr<Playlist> pl(wpl.lock());
3176 PlaylistList::iterator x;
3179 /* its not supposed to be visible */
3184 Glib::Mutex::Lock lm (playlist_lock);
3188 unused_playlists.insert (pl);
3190 if ((x = playlists.find (pl)) != playlists.end()) {
3191 playlists.erase (x);
3197 playlists.insert (pl);
3199 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3200 unused_playlists.erase (x);
3207 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3209 if (_state_of_the_state & Deletion) {
3213 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3220 Glib::Mutex::Lock lm (playlist_lock);
3222 PlaylistList::iterator i;
3224 i = find (playlists.begin(), playlists.end(), playlist);
3225 if (i != playlists.end()) {
3226 playlists.erase (i);
3229 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3230 if (i != unused_playlists.end()) {
3231 unused_playlists.erase (i);
3238 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3242 Session::set_audition (boost::shared_ptr<Region> r)
3244 pending_audition_region = r;
3245 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3246 schedule_butler_transport_work ();
3250 Session::audition_playlist ()
3252 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3253 ev->region.reset ();
3258 Session::non_realtime_set_audition ()
3260 if (!pending_audition_region) {
3261 auditioner->audition_current_playlist ();
3263 auditioner->audition_region (pending_audition_region);
3264 pending_audition_region.reset ();
3266 AuditionActive (true); /* EMIT SIGNAL */
3270 Session::audition_region (boost::shared_ptr<Region> r)
3272 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3278 Session::cancel_audition ()
3280 if (auditioner->active()) {
3281 auditioner->cancel_audition ();
3282 AuditionActive (false); /* EMIT SIGNAL */
3287 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3289 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3293 Session::remove_empty_sounds ()
3295 PathScanner scanner;
3297 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3299 Glib::Mutex::Lock lm (audio_source_lock);
3301 regex_t compiled_tape_track_pattern;
3304 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3308 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3310 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3314 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3316 /* never remove files that appear to be a tape track */
3318 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3323 if (AudioFileSource::is_empty (*this, *(*i))) {
3325 unlink ((*i)->c_str());
3327 string peak_path = peak_path_from_audio_path (**i);
3328 unlink (peak_path.c_str());
3334 delete possible_audiofiles;
3338 Session::is_auditioning () const
3340 /* can be called before we have an auditioner object */
3342 return auditioner->active();
3349 Session::set_all_solo (bool yn)
3351 shared_ptr<RouteList> r = routes.reader ();
3353 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3354 if (!(*i)->hidden()) {
3355 (*i)->set_solo (yn, this);
3363 Session::set_all_mute (bool yn)
3365 shared_ptr<RouteList> r = routes.reader ();
3367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3368 if (!(*i)->hidden()) {
3369 (*i)->set_mute (yn, this);
3377 Session::n_diskstreams () const
3381 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3383 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3384 if (!(*i)->hidden()) {
3392 Session::graph_reordered ()
3394 /* don't do this stuff if we are setting up connections
3395 from a set_state() call or creating new tracks.
3398 if (_state_of_the_state & InitialConnecting) {
3402 /* every track/bus asked for this to be handled but it was deferred because
3403 we were connecting. do it now.
3406 request_input_change_handling ();
3410 /* force all diskstreams to update their capture offset values to
3411 reflect any changes in latencies within the graph.
3414 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3416 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3417 (*i)->set_capture_offset ();
3422 Session::record_disenable_all ()
3424 record_enable_change_all (false);
3428 Session::record_enable_all ()
3430 record_enable_change_all (true);
3434 Session::record_enable_change_all (bool yn)
3436 shared_ptr<RouteList> r = routes.reader ();
3438 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3441 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3442 at->set_record_enable (yn, this);
3446 /* since we don't keep rec-enable state, don't mark session dirty */
3450 Session::add_redirect (Redirect* redirect)
3454 PortInsert* port_insert;
3455 PluginInsert* plugin_insert;
3457 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3458 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3459 _port_inserts.insert (_port_inserts.begin(), port_insert);
3460 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3461 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3463 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3466 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3467 _sends.insert (_sends.begin(), send);
3469 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3473 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3479 Session::remove_redirect (Redirect* redirect)
3483 PortInsert* port_insert;
3484 PluginInsert* plugin_insert;
3486 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3487 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3488 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3489 if (x != _port_inserts.end()) {
3490 insert_bitset[port_insert->bit_slot()] = false;
3491 _port_inserts.erase (x);
3493 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3494 _plugin_inserts.remove (plugin_insert);
3496 fatal << string_compose (_("programming error: %1"),
3497 X_("unknown type of Insert deleted!"))
3501 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3502 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3503 if (x != _sends.end()) {
3504 send_bitset[send->bit_slot()] = false;
3508 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3516 Session::available_capture_duration ()
3518 float sample_bytes_on_disk = 4.0; // keep gcc happy
3520 switch (Config->get_native_file_data_format()) {
3522 sample_bytes_on_disk = 4.0;
3526 sample_bytes_on_disk = 3.0;
3530 /* impossible, but keep some gcc versions happy */
3531 fatal << string_compose (_("programming error: %1"),
3532 X_("illegal native file data format"))
3537 double scale = 4096.0 / sample_bytes_on_disk;
3539 if (_total_free_4k_blocks * scale > (double) max_frames) {
3543 return (nframes_t) floor (_total_free_4k_blocks * scale);
3547 Session::add_connection (ARDOUR::Connection* connection)
3550 Glib::Mutex::Lock guard (connection_lock);
3551 _connections.push_back (connection);
3554 ConnectionAdded (connection); /* EMIT SIGNAL */
3560 Session::remove_connection (ARDOUR::Connection* connection)
3562 bool removed = false;
3565 Glib::Mutex::Lock guard (connection_lock);
3566 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3568 if (i != _connections.end()) {
3569 _connections.erase (i);
3575 ConnectionRemoved (connection); /* EMIT SIGNAL */
3581 ARDOUR::Connection *
3582 Session::connection_by_name (string name) const
3584 Glib::Mutex::Lock lm (connection_lock);
3586 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3587 if ((*i)->name() == name) {
3596 Session::tempo_map_changed (Change ignored)
3603 Session::ensure_passthru_buffers (uint32_t howmany)
3605 while (howmany > _passthru_buffers.size()) {
3607 #ifdef NO_POSIX_MEMALIGN
3608 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3610 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3612 _passthru_buffers.push_back (p);
3616 #ifdef NO_POSIX_MEMALIGN
3617 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3619 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4);
3621 memset (p, 0, sizeof (Sample) * current_block_size);
3622 _silent_buffers.push_back (p);
3626 #ifdef NO_POSIX_MEMALIGN
3627 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3629 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3631 memset (p, 0, sizeof (Sample) * current_block_size);
3632 _send_buffers.push_back (p);
3635 allocate_pan_automation_buffers (current_block_size, howmany, false);
3639 Session::next_insert_id ()
3641 /* this doesn't really loop forever. just think about it */
3644 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3645 if (!insert_bitset[n]) {
3646 insert_bitset[n] = true;
3652 /* none available, so resize and try again */
3654 insert_bitset.resize (insert_bitset.size() + 16, false);
3659 Session::next_send_id ()
3661 /* this doesn't really loop forever. just think about it */
3664 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3665 if (!send_bitset[n]) {
3666 send_bitset[n] = true;
3672 /* none available, so resize and try again */
3674 send_bitset.resize (send_bitset.size() + 16, false);
3679 Session::mark_send_id (uint32_t id)
3681 if (id >= send_bitset.size()) {
3682 send_bitset.resize (id+16, false);
3684 if (send_bitset[id]) {
3685 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3687 send_bitset[id] = true;
3691 Session::mark_insert_id (uint32_t id)
3693 if (id >= insert_bitset.size()) {
3694 insert_bitset.resize (id+16, false);
3696 if (insert_bitset[id]) {
3697 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3699 insert_bitset[id] = true;
3702 /* Named Selection management */
3705 Session::named_selection_by_name (string name)
3707 Glib::Mutex::Lock lm (named_selection_lock);
3708 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3709 if ((*i)->name == name) {
3717 Session::add_named_selection (NamedSelection* named_selection)
3720 Glib::Mutex::Lock lm (named_selection_lock);
3721 named_selections.insert (named_selections.begin(), named_selection);
3724 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3730 NamedSelectionAdded (); /* EMIT SIGNAL */
3734 Session::remove_named_selection (NamedSelection* named_selection)
3736 bool removed = false;
3739 Glib::Mutex::Lock lm (named_selection_lock);
3741 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3743 if (i != named_selections.end()) {
3745 named_selections.erase (i);
3752 NamedSelectionRemoved (); /* EMIT SIGNAL */
3757 Session::reset_native_file_format ()
3759 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3761 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3762 (*i)->reset_write_sources (false);
3767 Session::route_name_unique (string n) const
3769 shared_ptr<RouteList> r = routes.reader ();
3771 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3772 if ((*i)->name() == n) {
3781 Session::n_playlists () const
3783 Glib::Mutex::Lock lm (playlist_lock);
3784 return playlists.size();
3788 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3790 if (!force && howmany <= _npan_buffers) {
3794 if (_pan_automation_buffer) {
3796 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3797 delete [] _pan_automation_buffer[i];
3800 delete [] _pan_automation_buffer;
3803 _pan_automation_buffer = new pan_t*[howmany];
3805 for (uint32_t i = 0; i < howmany; ++i) {
3806 _pan_automation_buffer[i] = new pan_t[nframes];
3809 _npan_buffers = howmany;
3813 Session::freeze (InterThreadInfo& itt)
3815 shared_ptr<RouteList> r = routes.reader ();
3817 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3821 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3822 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3833 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3834 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3837 boost::shared_ptr<Playlist> playlist;
3838 boost::shared_ptr<AudioFileSource> fsource;
3840 char buf[PATH_MAX+1];
3844 nframes_t this_chunk;
3846 vector<Sample*> buffers;
3848 // any bigger than this seems to cause stack overflows in called functions
3849 const nframes_t chunk_size = (128 * 1024)/4;
3851 g_atomic_int_set (&processing_prohibited, 1);
3853 /* call tree *MUST* hold route_lock */
3855 if ((playlist = track.diskstream()->playlist()) == 0) {
3859 /* external redirects will be a problem */
3861 if (track.has_external_redirects()) {
3865 nchans = track.audio_diskstream()->n_channels();
3867 dir = discover_best_sound_dir ();
3869 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3871 for (x = 0; x < 99999; ++x) {
3872 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3873 if (access (buf, F_OK) != 0) {
3879 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3884 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3887 catch (failed_constructor& err) {
3888 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3892 srcs.push_back (fsource);
3895 /* XXX need to flush all redirects */
3900 /* create a set of reasonably-sized buffers */
3902 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3904 #ifdef NO_POSIX_MEMALIGN
3905 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3907 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
3909 buffers.push_back (b);
3912 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3913 (*src)->prepare_for_peakfile_writes ();
3916 while (to_do && !itt.cancel) {
3918 this_chunk = min (to_do, chunk_size);
3920 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3925 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3926 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3929 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3935 start += this_chunk;
3936 to_do -= this_chunk;
3938 itt.progress = (float) (1.0 - ((double) to_do / len));
3947 xnow = localtime (&now);
3949 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3950 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3953 afs->update_header (position, *xnow, now);
3954 afs->flush_header ();
3958 /* construct a region to represent the bounced material */
3960 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3961 region_name_from_path (srcs.front()->name(), true));
3968 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3969 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3972 afs->mark_for_remove ();
3975 (*src)->drop_references ();
3979 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3980 (*src)->done_with_peakfile_writes ();
3984 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3988 g_atomic_int_set (&processing_prohibited, 0);
3996 Session::get_silent_buffers (uint32_t howmany)
3998 for (uint32_t i = 0; i < howmany; ++i) {
3999 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4001 return _silent_buffers;
4005 Session::ntracks () const
4008 shared_ptr<RouteList> r = routes.reader ();
4010 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4011 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4020 Session::nbusses () const
4023 shared_ptr<RouteList> r = routes.reader ();
4025 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4026 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4035 Session::add_automation_list(AutomationList *al)
4037 automation_lists[al->id()] = al;
4041 Session::compute_initial_length ()
4043 return _engine.frame_rate() * 60 * 5;