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 */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
45 #include <ardour/audioengine.h>
46 #include <ardour/configuration.h>
47 #include <ardour/session.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/utils.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
68 #include <ardour/source_factory.h>
69 #include <ardour/region_factory.h>
72 #include <ardour/osc.h>
78 using namespace ARDOUR;
80 using boost::shared_ptr;
83 static const int CPU_CACHE_ALIGN = 64;
85 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
88 const char* Session::_template_suffix = X_(".template");
89 const char* Session::_statefile_suffix = X_(".ardour");
90 const char* Session::_pending_suffix = X_(".pending");
91 const char* Session::old_sound_dir_name = X_("sounds");
92 const char* Session::sound_dir_name = X_("audiofiles");
93 const char* Session::peak_dir_name = X_("peaks");
94 const char* Session::dead_sound_dir_name = X_("dead_sounds");
95 const char* Session::interchange_dir_name = X_("interchange");
96 const char* Session::export_dir_name = X_("export");
98 Session::compute_peak_t Session::compute_peak = 0;
99 Session::find_peaks_t Session::find_peaks = 0;
100 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
101 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
102 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
104 sigc::signal<int> Session::AskAboutPendingState;
105 sigc::signal<void> Session::SendFeedback;
107 sigc::signal<void> Session::SMPTEOffsetChanged;
108 sigc::signal<void> Session::StartTimeChanged;
109 sigc::signal<void> Session::EndTimeChanged;
112 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
115 char buf[PATH_MAX+1];
119 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
120 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
126 /* check to see if it exists, and what it is */
128 if (stat (str.c_str(), &statbuf)) {
129 if (errno == ENOENT) {
132 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
140 /* it exists, so it must either be the name
141 of the directory, or the name of the statefile
145 if (S_ISDIR (statbuf.st_mode)) {
147 string::size_type slash = str.find_last_of ('/');
149 if (slash == string::npos) {
151 /* a subdirectory of cwd, so statefile should be ... */
157 tmp += _statefile_suffix;
161 if (stat (tmp.c_str(), &statbuf)) {
162 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
172 /* some directory someplace in the filesystem.
173 the snapshot name is the directory name
178 snapshot = str.substr (slash+1);
182 } else if (S_ISREG (statbuf.st_mode)) {
184 string::size_type slash = str.find_last_of ('/');
185 string::size_type suffix;
187 /* remove the suffix */
189 if (slash != string::npos) {
190 snapshot = str.substr (slash+1);
195 suffix = snapshot.find (_statefile_suffix);
197 if (suffix == string::npos) {
198 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
204 snapshot = snapshot.substr (0, suffix);
206 if (slash == string::npos) {
208 /* we must be in the directory where the
209 statefile lives. get it using cwd().
212 char cwd[PATH_MAX+1];
214 if (getcwd (cwd, sizeof (cwd)) == 0) {
215 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
224 /* full path to the statefile */
226 path = str.substr (0, slash);
231 /* what type of file is it? */
232 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
238 /* its the name of a new directory. get the name
242 string::size_type slash = str.find_last_of ('/');
244 if (slash == string::npos) {
246 /* no slash, just use the name, but clean it up */
248 path = legalize_for_path (str);
254 snapshot = str.substr (slash+1);
261 Session::Session (AudioEngine &eng,
263 string snapshot_name,
264 string* mix_template)
267 _mmc_port (default_mmc_port),
268 _mtc_port (default_mtc_port),
269 _midi_port (default_midi_port),
270 pending_events (2048),
271 midi_requests (128), // the size of this should match the midi request pool size
272 diskstreams (new DiskstreamList),
273 routes (new RouteList),
274 auditioner ((Auditioner*) 0),
280 if (!eng.connected()) {
281 throw failed_constructor();
284 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
286 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
287 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
289 first_stage_init (fullpath, snapshot_name);
291 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
293 if (create (new_session, mix_template, compute_initial_length())) {
294 cerr << "create failed\n";
296 throw failed_constructor ();
300 if (second_stage_init (new_session)) {
302 throw failed_constructor ();
305 store_recent_sessions(_name, _path);
307 bool was_dirty = dirty();
309 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
311 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
314 DirtyChanged (); /* EMIT SIGNAL */
318 Session::Session (AudioEngine &eng,
320 string snapshot_name,
321 AutoConnectOption input_ac,
322 AutoConnectOption output_ac,
323 uint32_t control_out_channels,
324 uint32_t master_out_channels,
325 uint32_t requested_physical_in,
326 uint32_t requested_physical_out,
327 nframes_t initial_length)
330 _mmc_port (default_mmc_port),
331 _mtc_port (default_mtc_port),
332 _midi_port (default_midi_port),
333 pending_events (2048),
335 diskstreams (new DiskstreamList),
336 routes (new RouteList),
342 if (!eng.connected()) {
343 throw failed_constructor();
346 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
348 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
349 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
351 if (n_physical_audio_inputs) {
352 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
355 if (n_physical_audio_outputs) {
356 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
359 first_stage_init (fullpath, snapshot_name);
361 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
364 if (create (new_session, 0, initial_length)) {
366 throw failed_constructor ();
371 /* set up Master Out and Control Out if necessary */
376 if (control_out_channels) {
377 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
378 r->set_remote_control_id (control_id++);
383 if (master_out_channels) {
384 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
385 r->set_remote_control_id (control_id);
389 /* prohibit auto-connect to master, because there isn't one */
390 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
399 Config->set_input_auto_connect (input_ac);
400 Config->set_output_auto_connect (output_ac);
402 if (second_stage_init (new_session)) {
404 throw failed_constructor ();
407 store_recent_sessions(_name, _path);
409 bool was_dirty = dirty ();
411 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
413 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
416 DirtyChanged (); /* EMIT SIGNAL */
428 /* if we got to here, leaving pending capture state around
432 remove_pending_capture_state ();
434 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
435 _engine.remove_session ();
437 GoingAway (); /* EMIT SIGNAL */
443 /* clear history so that no references to objects are held any more */
447 /* clear state tree so that no references to objects are held any more */
453 terminate_butler_thread ();
454 terminate_midi_thread ();
456 if (click_data && click_data != default_click) {
457 delete [] click_data;
460 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
461 delete [] click_emphasis_data;
466 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
470 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
474 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
478 AudioDiskstream::free_working_buffers();
480 /* this should cause deletion of the auditioner */
482 // auditioner.reset ();
484 #undef TRACK_DESTRUCTION
485 #ifdef TRACK_DESTRUCTION
486 cerr << "delete named selections\n";
487 #endif /* TRACK_DESTRUCTION */
488 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
489 NamedSelectionList::iterator tmp;
498 #ifdef TRACK_DESTRUCTION
499 cerr << "delete playlists\n";
500 #endif /* TRACK_DESTRUCTION */
501 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
502 PlaylistList::iterator tmp;
507 (*i)->drop_references ();
512 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
513 PlaylistList::iterator tmp;
518 (*i)->drop_references ();
524 unused_playlists.clear ();
526 #ifdef TRACK_DESTRUCTION
527 cerr << "delete audio regions\n";
528 #endif /* TRACK_DESTRUCTION */
530 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
531 AudioRegionList::iterator tmp;
536 i->second->drop_references ();
541 audio_regions.clear ();
543 #ifdef TRACK_DESTRUCTION
544 cerr << "delete routes\n";
545 #endif /* TRACK_DESTRUCTION */
547 RCUWriter<RouteList> writer (routes);
548 boost::shared_ptr<RouteList> r = writer.get_copy ();
549 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
550 (*i)->drop_references ();
553 /* writer goes out of scope and updates master */
558 #ifdef TRACK_DESTRUCTION
559 cerr << "delete diskstreams\n";
560 #endif /* TRACK_DESTRUCTION */
562 RCUWriter<DiskstreamList> dwriter (diskstreams);
563 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
564 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
565 (*i)->drop_references ();
569 diskstreams.flush ();
571 #ifdef TRACK_DESTRUCTION
572 cerr << "delete audio sources\n";
573 #endif /* TRACK_DESTRUCTION */
574 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
575 AudioSourceList::iterator tmp;
580 i->second->drop_references ();
585 audio_sources.clear ();
587 #ifdef TRACK_DESTRUCTION
588 cerr << "delete mix groups\n";
589 #endif /* TRACK_DESTRUCTION */
590 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
591 list<RouteGroup*>::iterator tmp;
601 #ifdef TRACK_DESTRUCTION
602 cerr << "delete edit groups\n";
603 #endif /* TRACK_DESTRUCTION */
604 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
605 list<RouteGroup*>::iterator tmp;
615 #ifdef TRACK_DESTRUCTION
616 cerr << "delete connections\n";
617 #endif /* TRACK_DESTRUCTION */
618 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
619 ConnectionList::iterator tmp;
629 if (butler_mixdown_buffer) {
630 delete [] butler_mixdown_buffer;
633 if (butler_gain_buffer) {
634 delete [] butler_gain_buffer;
637 Crossfade::set_buffer_size (0);
645 Session::set_worst_io_latencies ()
647 _worst_output_latency = 0;
648 _worst_input_latency = 0;
650 if (!_engine.connected()) {
654 boost::shared_ptr<RouteList> r = routes.reader ();
656 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
657 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
658 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
663 Session::when_engine_running ()
665 string first_physical_output;
667 /* we don't want to run execute this again */
669 set_block_size (_engine.frames_per_cycle());
670 set_frame_rate (_engine.frame_rate());
672 Config->map_parameters (mem_fun (*this, &Session::config_changed));
674 /* every time we reconnect, recompute worst case output latencies */
676 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
678 if (synced_to_jack()) {
679 _engine.transport_stop ();
682 if (Config->get_jack_time_master()) {
683 _engine.transport_locate (_transport_frame);
691 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
693 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
695 /* existing state for Click */
697 if (_click_io->set_state (*child->children().front()) == 0) {
699 _clicking = Config->get_clicking ();
703 error << _("could not setup Click I/O") << endmsg;
709 /* default state for Click */
711 first_physical_output = _engine.get_nth_physical_audio_output (0);
713 if (first_physical_output.length()) {
714 if (_click_io->add_output_port (first_physical_output, this)) {
715 // relax, even though its an error
717 _clicking = Config->get_clicking ();
723 catch (failed_constructor& err) {
724 error << _("cannot setup Click I/O") << endmsg;
727 set_worst_io_latencies ();
730 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
733 /* Create a set of Connection objects that map
734 to the physical outputs currently available
739 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
741 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
743 Connection* c = new OutputConnection (buf, true);
746 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
751 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
753 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
755 Connection* c = new InputConnection (buf, true);
758 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
765 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
767 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
769 Connection* c = new OutputConnection (buf, true);
773 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
774 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
779 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
781 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
783 Connection* c = new InputConnection (buf, true);
787 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
788 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
797 /* create master/control ports */
802 /* force the master to ignore any later call to this */
804 if (_master_out->pending_state_node) {
805 _master_out->ports_became_legal();
808 /* no panner resets till we are through */
810 _master_out->defer_pan_reset ();
812 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
813 if (_master_out->add_input_port ("", this)) {
814 error << _("cannot setup master inputs")
820 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
821 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
822 error << _("cannot setup master outputs")
829 _master_out->allow_pan_reset ();
833 Connection* c = new OutputConnection (_("Master Out"), true);
835 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
837 c->add_connection ((int) n, _master_out->input(n)->name());
844 /* catch up on send+insert cnts */
848 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
851 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
852 if (id > insert_cnt) {
860 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
863 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
871 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
873 /* hook us up to the engine */
875 _engine.set_session (this);
880 osc->set_session (*this);
883 _state_of_the_state = Clean;
885 DirtyChanged (); /* EMIT SIGNAL */
889 Session::hookup_io ()
891 /* stop graph reordering notifications from
892 causing resorts, etc.
895 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
897 if (auditioner == 0) {
899 /* we delay creating the auditioner till now because
900 it makes its own connections to ports.
901 the engine has to be running for this to work.
905 auditioner.reset (new Auditioner (*this));
908 catch (failed_constructor& err) {
909 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
913 /* Tell all IO objects to create their ports */
919 vector<string> cports;
921 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
922 if (_control_out->add_input_port ("", this)) {
923 error << _("cannot setup control inputs")
929 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
930 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
931 error << _("cannot set up master outputs")
939 uint32_t ni = _control_out->n_inputs();
941 for (n = 0; n < ni; ++n) {
942 cports.push_back (_control_out->input(n)->name());
945 boost::shared_ptr<RouteList> r = routes.reader ();
947 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
948 (*x)->set_control_outs (cports);
952 /* Tell all IO objects to connect themselves together */
954 IO::enable_connecting ();
956 /* Now reset all panners */
958 IO::reset_panners ();
960 /* Anyone who cares about input state, wake up and do something */
962 IOConnectionsComplete (); /* EMIT SIGNAL */
964 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
966 /* now handle the whole enchilada as if it was one
972 /* update mixer solo state */
978 Session::playlist_length_changed ()
980 /* we can't just increase end_location->end() if pl->get_maximum_extent()
981 if larger. if the playlist used to be the longest playlist,
982 and its now shorter, we have to decrease end_location->end(). hence,
983 we have to iterate over all diskstreams and check the
984 playlists currently in use.
990 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
992 boost::shared_ptr<Diskstream> dstream = wptr.lock();
999 boost::shared_ptr<Playlist> playlist;
1001 if ((playlist = dstream->playlist()) != 0) {
1002 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1005 /* see comment in playlist_length_changed () */
1006 find_current_end ();
1010 Session::record_enabling_legal () const
1012 /* this used to be in here, but survey says.... we don't need to restrict it */
1013 // if (record_status() == Recording) {
1017 if (Config->get_all_safe()) {
1024 Session::reset_input_monitor_state ()
1026 if (transport_rolling()) {
1028 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1030 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1031 if ((*i)->record_enabled ()) {
1032 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1033 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1037 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1039 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1040 if ((*i)->record_enabled ()) {
1041 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1042 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1049 Session::auto_punch_start_changed (Location* location)
1051 replace_event (Event::PunchIn, location->start());
1053 if (get_record_enabled() && Config->get_punch_in()) {
1054 /* capture start has been changed, so save new pending state */
1055 save_state ("", true);
1060 Session::auto_punch_end_changed (Location* location)
1062 nframes_t when_to_stop = location->end();
1063 // when_to_stop += _worst_output_latency + _worst_input_latency;
1064 replace_event (Event::PunchOut, when_to_stop);
1068 Session::auto_punch_changed (Location* location)
1070 nframes_t when_to_stop = location->end();
1072 replace_event (Event::PunchIn, location->start());
1073 //when_to_stop += _worst_output_latency + _worst_input_latency;
1074 replace_event (Event::PunchOut, when_to_stop);
1078 Session::auto_loop_changed (Location* location)
1080 replace_event (Event::AutoLoop, location->end(), location->start());
1082 if (transport_rolling() && play_loop) {
1084 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1086 if (_transport_frame > location->end()) {
1087 // relocate to beginning of loop
1088 clear_events (Event::LocateRoll);
1090 request_locate (location->start(), true);
1093 else if (Config->get_seamless_loop() && !loop_changing) {
1095 // schedule a locate-roll to refill the diskstreams at the
1096 // previous loop end
1097 loop_changing = true;
1099 if (location->end() > last_loopend) {
1100 clear_events (Event::LocateRoll);
1101 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1108 last_loopend = location->end();
1113 Session::set_auto_punch_location (Location* location)
1117 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1118 auto_punch_start_changed_connection.disconnect();
1119 auto_punch_end_changed_connection.disconnect();
1120 auto_punch_changed_connection.disconnect();
1121 existing->set_auto_punch (false, this);
1122 remove_event (existing->start(), Event::PunchIn);
1123 clear_events (Event::PunchOut);
1124 auto_punch_location_changed (0);
1129 if (location == 0) {
1133 if (location->end() <= location->start()) {
1134 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1138 auto_punch_start_changed_connection.disconnect();
1139 auto_punch_end_changed_connection.disconnect();
1140 auto_punch_changed_connection.disconnect();
1142 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1143 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1144 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1146 location->set_auto_punch (true, this);
1147 auto_punch_location_changed (location);
1151 Session::set_auto_loop_location (Location* location)
1155 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1156 auto_loop_start_changed_connection.disconnect();
1157 auto_loop_end_changed_connection.disconnect();
1158 auto_loop_changed_connection.disconnect();
1159 existing->set_auto_loop (false, this);
1160 remove_event (existing->end(), Event::AutoLoop);
1161 auto_loop_location_changed (0);
1166 if (location == 0) {
1170 if (location->end() <= location->start()) {
1171 error << _("Session: you can't use a mark for auto loop") << endmsg;
1175 last_loopend = location->end();
1177 auto_loop_start_changed_connection.disconnect();
1178 auto_loop_end_changed_connection.disconnect();
1179 auto_loop_changed_connection.disconnect();
1181 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1182 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1183 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1185 location->set_auto_loop (true, this);
1186 auto_loop_location_changed (location);
1190 Session::locations_added (Location* ignored)
1196 Session::locations_changed ()
1198 _locations.apply (*this, &Session::handle_locations_changed);
1202 Session::handle_locations_changed (Locations::LocationList& locations)
1204 Locations::LocationList::iterator i;
1206 bool set_loop = false;
1207 bool set_punch = false;
1209 for (i = locations.begin(); i != locations.end(); ++i) {
1213 if (location->is_auto_punch()) {
1214 set_auto_punch_location (location);
1217 if (location->is_auto_loop()) {
1218 set_auto_loop_location (location);
1225 set_auto_loop_location (0);
1228 set_auto_punch_location (0);
1235 Session::enable_record ()
1237 /* XXX really atomic compare+swap here */
1238 if (g_atomic_int_get (&_record_status) != Recording) {
1239 g_atomic_int_set (&_record_status, Recording);
1240 _last_record_location = _transport_frame;
1241 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1243 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1244 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1245 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1246 if ((*i)->record_enabled ()) {
1247 (*i)->monitor_input (true);
1252 RecordStateChanged ();
1257 Session::disable_record (bool rt_context, bool force)
1261 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1263 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1264 g_atomic_int_set (&_record_status, Disabled);
1266 if (rs == Recording) {
1267 g_atomic_int_set (&_record_status, Enabled);
1271 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1273 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1274 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1276 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1277 if ((*i)->record_enabled ()) {
1278 (*i)->monitor_input (false);
1283 RecordStateChanged (); /* emit signal */
1286 remove_pending_capture_state ();
1292 Session::step_back_from_record ()
1294 /* XXX really atomic compare+swap here */
1295 if (g_atomic_int_get (&_record_status) == Recording) {
1296 g_atomic_int_set (&_record_status, Enabled);
1298 if (Config->get_monitoring_model() == HardwareMonitoring) {
1299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1301 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1302 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1303 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1304 (*i)->monitor_input (false);
1312 Session::maybe_enable_record ()
1314 g_atomic_int_set (&_record_status, Enabled);
1316 /* this function is currently called from somewhere other than an RT thread.
1317 this save_state() call therefore doesn't impact anything.
1320 save_state ("", true);
1322 if (_transport_speed) {
1323 if (!Config->get_punch_in()) {
1327 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1328 RecordStateChanged (); /* EMIT SIGNAL */
1335 Session::audible_frame () const
1341 /* the first of these two possible settings for "offset"
1342 mean that the audible frame is stationary until
1343 audio emerges from the latency compensation
1346 the second means that the audible frame is stationary
1347 until audio would emerge from a physical port
1348 in the absence of any plugin latency compensation
1351 offset = _worst_output_latency;
1353 if (offset > current_block_size) {
1354 offset -= current_block_size;
1356 /* XXX is this correct? if we have no external
1357 physical connections and everything is internal
1358 then surely this is zero? still, how
1359 likely is that anyway?
1361 offset = current_block_size;
1364 if (synced_to_jack()) {
1365 tf = _engine.transport_frame();
1367 tf = _transport_frame;
1370 if (_transport_speed == 0) {
1380 if (!non_realtime_work_pending()) {
1384 /* take latency into account */
1393 Session::set_frame_rate (nframes_t frames_per_second)
1395 /** \fn void Session::set_frame_size(nframes_t)
1396 the AudioEngine object that calls this guarantees
1397 that it will not be called while we are also in
1398 ::process(). Its fine to do things that block
1402 _base_frame_rate = frames_per_second;
1406 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1410 // XXX we need some equivalent to this, somehow
1411 // SndFileSource::setup_standard_crossfades (frames_per_second);
1415 /* XXX need to reset/reinstantiate all LADSPA plugins */
1419 Session::set_block_size (nframes_t nframes)
1421 /* the AudioEngine guarantees
1422 that it will not be called while we are also in
1423 ::process(). It is therefore fine to do things that block
1428 vector<Sample*>::iterator i;
1431 current_block_size = nframes;
1433 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1437 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1441 _passthru_buffers.clear ();
1442 _silent_buffers.clear ();
1444 ensure_passthru_buffers (np);
1446 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1450 #ifdef NO_POSIX_MEMALIGN
1451 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1453 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1457 memset (*i, 0, sizeof (Sample) * current_block_size);
1461 if (_gain_automation_buffer) {
1462 delete [] _gain_automation_buffer;
1464 _gain_automation_buffer = new gain_t[nframes];
1466 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1468 boost::shared_ptr<RouteList> r = routes.reader ();
1470 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1471 (*i)->set_block_size (nframes);
1474 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1475 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1476 (*i)->set_block_size (nframes);
1479 set_worst_io_latencies ();
1484 Session::set_default_fade (float steepness, float fade_msecs)
1487 nframes_t fade_frames;
1489 /* Don't allow fade of less 1 frame */
1491 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1498 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1502 default_fade_msecs = fade_msecs;
1503 default_fade_steepness = steepness;
1506 // jlc, WTF is this!
1507 Glib::RWLock::ReaderLock lm (route_lock);
1508 AudioRegion::set_default_fade (steepness, fade_frames);
1513 /* XXX have to do this at some point */
1514 /* foreach region using default fade, reset, then
1515 refill_all_diskstream_buffers ();
1520 struct RouteSorter {
1521 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1522 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1524 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1527 if (r1->fed_by.empty()) {
1528 if (r2->fed_by.empty()) {
1529 /* no ardour-based connections inbound to either route. just use signal order */
1530 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1532 /* r2 has connections, r1 does not; run r1 early */
1536 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1543 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1545 shared_ptr<Route> r2;
1547 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1548 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1552 /* make a copy of the existing list of routes that feed r1 */
1554 set<shared_ptr<Route> > existing = r1->fed_by;
1556 /* for each route that feeds r1, recurse, marking it as feeding
1560 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1563 /* r2 is a route that feeds r1 which somehow feeds base. mark
1564 base as being fed by r2
1567 rbase->fed_by.insert (r2);
1571 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1575 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1579 /* now recurse, so that we can mark base as being fed by
1580 all routes that feed r2
1583 trace_terminal (r2, rbase);
1590 Session::resort_routes ()
1592 /* don't do anything here with signals emitted
1593 by Routes while we are being destroyed.
1596 if (_state_of_the_state & Deletion) {
1603 RCUWriter<RouteList> writer (routes);
1604 shared_ptr<RouteList> r = writer.get_copy ();
1605 resort_routes_using (r);
1606 /* writer goes out of scope and forces update */
1611 Session::resort_routes_using (shared_ptr<RouteList> r)
1613 RouteList::iterator i, j;
1615 for (i = r->begin(); i != r->end(); ++i) {
1617 (*i)->fed_by.clear ();
1619 for (j = r->begin(); j != r->end(); ++j) {
1621 /* although routes can feed themselves, it will
1622 cause an endless recursive descent if we
1623 detect it. so don't bother checking for
1631 if ((*j)->feeds (*i)) {
1632 (*i)->fed_by.insert (*j);
1637 for (i = r->begin(); i != r->end(); ++i) {
1638 trace_terminal (*i, *i);
1644 /* don't leave dangling references to routes in Route::fed_by */
1646 for (i = r->begin(); i != r->end(); ++i) {
1647 (*i)->fed_by.clear ();
1651 cerr << "finished route resort\n";
1653 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1654 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1661 list<boost::shared_ptr<AudioTrack> >
1662 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1664 char track_name[32];
1665 uint32_t track_id = 0;
1667 uint32_t channels_used = 0;
1669 RouteList new_routes;
1670 list<boost::shared_ptr<AudioTrack> > ret;
1671 uint32_t control_id;
1673 /* count existing audio tracks */
1676 shared_ptr<RouteList> r = routes.reader ();
1678 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1679 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1680 if (!(*i)->hidden()) {
1682 channels_used += (*i)->n_inputs();
1688 vector<string> physinputs;
1689 vector<string> physoutputs;
1690 uint32_t nphysical_in;
1691 uint32_t nphysical_out;
1693 _engine.get_physical_audio_outputs (physoutputs);
1694 _engine.get_physical_audio_inputs (physinputs);
1695 control_id = ntracks() + nbusses() + 1;
1699 /* check for duplicate route names, since we might have pre-existing
1700 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1701 save, close,restart,add new route - first named route is now
1709 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1711 if (route_by_name (track_name) == 0) {
1715 } while (track_id < (UINT_MAX-1));
1717 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1718 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1723 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1724 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1729 shared_ptr<AudioTrack> track;
1732 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1734 if (track->ensure_io (input_channels, output_channels, false, this)) {
1735 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1736 input_channels, output_channels)
1742 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1746 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1747 port = physinputs[(channels_used+x)%nphysical_in];
1750 if (port.length() && track->connect_input (track->input (x), port, this)) {
1756 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1760 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1761 port = physoutputs[(channels_used+x)%nphysical_out];
1762 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1764 port = _master_out->input (x%_master_out->n_inputs())->name();
1768 if (port.length() && track->connect_output (track->output (x), port, this)) {
1773 channels_used += track->n_inputs ();
1775 track->audio_diskstream()->non_realtime_input_change();
1777 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1778 track->set_remote_control_id (control_id);
1781 new_routes.push_back (track);
1782 ret.push_back (track);
1786 catch (failed_constructor &err) {
1787 error << _("Session: could not create new audio track.") << endmsg;
1790 /* we need to get rid of this, since the track failed to be created */
1791 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1794 RCUWriter<DiskstreamList> writer (diskstreams);
1795 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1796 ds->remove (track->audio_diskstream());
1803 catch (AudioEngine::PortRegistrationFailure& pfe) {
1805 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;
1808 /* we need to get rid of this, since the track failed to be created */
1809 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1812 RCUWriter<DiskstreamList> writer (diskstreams);
1813 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1814 ds->remove (track->audio_diskstream());
1825 if (!new_routes.empty()) {
1826 add_routes (new_routes, false);
1827 save_state (_current_snapshot_name);
1834 Session::set_remote_control_ids ()
1836 RemoteModel m = Config->get_remote_model();
1838 shared_ptr<RouteList> r = routes.reader ();
1840 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1841 if ( MixerOrdered == m) {
1842 long order = (*i)->order_key(N_("signal"));
1843 (*i)->set_remote_control_id( order+1 );
1844 } else if ( EditorOrdered == m) {
1845 long order = (*i)->order_key(N_("editor"));
1846 (*i)->set_remote_control_id( order+1 );
1847 } else if ( UserOrdered == m) {
1848 //do nothing ... only changes to remote id's are initiated by user
1855 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1858 uint32_t bus_id = 1;
1862 uint32_t control_id;
1864 /* count existing audio busses */
1867 shared_ptr<RouteList> r = routes.reader ();
1869 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1870 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1871 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1878 vector<string> physinputs;
1879 vector<string> physoutputs;
1881 _engine.get_physical_audio_outputs (physoutputs);
1882 _engine.get_physical_audio_inputs (physinputs);
1883 control_id = ntracks() + nbusses() + 1;
1888 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1892 if (route_by_name (bus_name) == 0) {
1896 } while (bus_id < (UINT_MAX-1));
1899 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1901 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1902 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1903 input_channels, output_channels)
1908 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1912 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1913 port = physinputs[((n+x)%n_physical_audio_inputs)];
1916 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1921 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1925 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1926 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1927 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1929 port = _master_out->input (x%_master_out->n_inputs())->name();
1933 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1938 bus->set_remote_control_id (control_id);
1941 ret.push_back (bus);
1945 catch (failed_constructor &err) {
1946 error << _("Session: could not create new audio route.") << endmsg;
1950 catch (AudioEngine::PortRegistrationFailure& pfe) {
1951 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;
1961 add_routes (ret, false);
1962 save_state (_current_snapshot_name);
1970 Session::add_routes (RouteList& new_routes, bool save)
1973 RCUWriter<RouteList> writer (routes);
1974 shared_ptr<RouteList> r = writer.get_copy ();
1975 r->insert (r->end(), new_routes.begin(), new_routes.end());
1976 resort_routes_using (r);
1979 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1981 boost::weak_ptr<Route> wpr (*x);
1983 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1984 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1985 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1986 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1988 if ((*x)->master()) {
1992 if ((*x)->control()) {
1993 _control_out = (*x);
1997 if (_control_out && IO::connecting_legal) {
1999 vector<string> cports;
2000 uint32_t ni = _control_out->n_inputs();
2003 for (n = 0; n < ni; ++n) {
2004 cports.push_back (_control_out->input(n)->name());
2007 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2008 (*x)->set_control_outs (cports);
2015 save_state (_current_snapshot_name);
2018 RouteAdded (new_routes); /* EMIT SIGNAL */
2022 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2024 /* need to do this in case we're rolling at the time, to prevent false underruns */
2025 dstream->do_refill_with_alloc ();
2027 dstream->set_block_size (current_block_size);
2030 RCUWriter<DiskstreamList> writer (diskstreams);
2031 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2032 ds->push_back (dstream);
2033 /* writer goes out of scope, copies ds back to main */
2036 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2037 boost::weak_ptr<Diskstream> (dstream)));
2038 /* this will connect to future changes, and check the current length */
2039 diskstream_playlist_changed (dstream);
2041 dstream->prepare ();
2045 Session::remove_route (shared_ptr<Route> route)
2048 RCUWriter<RouteList> writer (routes);
2049 shared_ptr<RouteList> rs = writer.get_copy ();
2053 /* deleting the master out seems like a dumb
2054 idea, but its more of a UI policy issue
2058 if (route == _master_out) {
2059 _master_out = shared_ptr<Route> ();
2062 if (route == _control_out) {
2063 _control_out = shared_ptr<Route> ();
2065 /* cancel control outs for all routes */
2067 vector<string> empty;
2069 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2070 (*r)->set_control_outs (empty);
2074 update_route_solo_state ();
2076 /* writer goes out of scope, forces route list update */
2079 // FIXME: audio specific
2081 boost::shared_ptr<AudioDiskstream> ds;
2083 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2084 ds = at->audio_diskstream();
2090 RCUWriter<DiskstreamList> dsl (diskstreams);
2091 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2095 diskstreams.flush ();
2098 find_current_end ();
2100 // We need to disconnect the routes inputs and outputs
2102 route->disconnect_inputs (0);
2103 route->disconnect_outputs (0);
2105 update_latency_compensation (false, false);
2108 /* get rid of it from the dead wood collection in the route list manager */
2110 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2114 /* try to cause everyone to drop their references */
2116 route->drop_references ();
2118 /* save the new state of the world */
2120 if (save_state (_current_snapshot_name)) {
2121 save_history (_current_snapshot_name);
2126 Session::route_mute_changed (void* src)
2132 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2134 if (solo_update_disabled) {
2140 boost::shared_ptr<Route> route = wpr.lock ();
2143 /* should not happen */
2144 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2148 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2150 shared_ptr<RouteList> r = routes.reader ();
2152 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2154 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2158 /* don't mess with busses */
2160 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2166 /* don't mess with tracks */
2168 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2173 if ((*i) != route &&
2174 ((*i)->mix_group () == 0 ||
2175 (*i)->mix_group () != route->mix_group () ||
2176 !route->mix_group ()->is_active())) {
2178 if ((*i)->soloed()) {
2180 /* if its already soloed, and solo latching is enabled,
2181 then leave it as it is.
2184 if (Config->get_solo_latched()) {
2191 solo_update_disabled = true;
2192 (*i)->set_solo (false, src);
2193 solo_update_disabled = false;
2197 bool something_soloed = false;
2198 bool same_thing_soloed = false;
2199 bool signal = false;
2201 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2202 if ((*i)->soloed()) {
2203 something_soloed = true;
2204 if (dynamic_cast<AudioTrack*>((*i).get())) {
2206 same_thing_soloed = true;
2211 same_thing_soloed = true;
2219 if (something_soloed != currently_soloing) {
2221 currently_soloing = something_soloed;
2224 modify_solo_mute (is_track, same_thing_soloed);
2227 SoloActive (currently_soloing); /* EMIT SIGNAL */
2230 SoloChanged (); /* EMIT SIGNAL */
2236 Session::update_route_solo_state ()
2239 bool is_track = false;
2240 bool signal = false;
2242 /* caller must hold RouteLock */
2244 /* this is where we actually implement solo by changing
2245 the solo mute setting of each track.
2248 shared_ptr<RouteList> r = routes.reader ();
2250 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2251 if ((*i)->soloed()) {
2253 if (dynamic_cast<AudioTrack*>((*i).get())) {
2260 if (mute != currently_soloing) {
2262 currently_soloing = mute;
2265 if (!is_track && !mute) {
2267 /* nothing is soloed */
2269 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2270 (*i)->set_solo_mute (false);
2280 modify_solo_mute (is_track, mute);
2283 SoloActive (currently_soloing);
2288 Session::modify_solo_mute (bool is_track, bool mute)
2290 shared_ptr<RouteList> r = routes.reader ();
2292 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2296 /* only alter track solo mute */
2298 if (dynamic_cast<AudioTrack*>((*i).get())) {
2299 if ((*i)->soloed()) {
2300 (*i)->set_solo_mute (!mute);
2302 (*i)->set_solo_mute (mute);
2308 /* only alter bus solo mute */
2310 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2312 if ((*i)->soloed()) {
2314 (*i)->set_solo_mute (false);
2318 /* don't mute master or control outs
2319 in response to another bus solo
2322 if ((*i) != _master_out &&
2323 (*i) != _control_out) {
2324 (*i)->set_solo_mute (mute);
2335 Session::catch_up_on_solo ()
2337 /* this is called after set_state() to catch the full solo
2338 state, which can't be correctly determined on a per-route
2339 basis, but needs the global overview that only the session
2342 update_route_solo_state();
2346 Session::route_by_name (string name)
2348 shared_ptr<RouteList> r = routes.reader ();
2350 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2351 if ((*i)->name() == name) {
2356 return shared_ptr<Route> ((Route*) 0);
2360 Session::route_by_id (PBD::ID id)
2362 shared_ptr<RouteList> r = routes.reader ();
2364 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2365 if ((*i)->id() == id) {
2370 return shared_ptr<Route> ((Route*) 0);
2374 Session::route_by_remote_id (uint32_t id)
2376 shared_ptr<RouteList> r = routes.reader ();
2378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2379 if ((*i)->remote_control_id() == id) {
2384 return shared_ptr<Route> ((Route*) 0);
2388 Session::find_current_end ()
2390 if (_state_of_the_state & Loading) {
2394 nframes_t max = get_maximum_extent ();
2396 if (max > end_location->end()) {
2397 end_location->set_end (max);
2399 DurationChanged(); /* EMIT SIGNAL */
2404 Session::get_maximum_extent () const
2409 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2411 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2412 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2413 if ((me = pl->get_maximum_extent()) > max) {
2421 boost::shared_ptr<Diskstream>
2422 Session::diskstream_by_name (string name)
2424 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2426 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2427 if ((*i)->name() == name) {
2432 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2435 boost::shared_ptr<Diskstream>
2436 Session::diskstream_by_id (const PBD::ID& id)
2438 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2440 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2441 if ((*i)->id() == id) {
2446 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2449 /* AudioRegion management */
2452 Session::new_region_name (string old)
2454 string::size_type last_period;
2456 string::size_type len = old.length() + 64;
2459 if ((last_period = old.find_last_of ('.')) == string::npos) {
2461 /* no period present - add one explicitly */
2464 last_period = old.length() - 1;
2469 number = atoi (old.substr (last_period+1).c_str());
2473 while (number < (UINT_MAX-1)) {
2475 AudioRegionList::const_iterator i;
2480 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2483 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2484 if (i->second->name() == sbuf) {
2489 if (i == audio_regions.end()) {
2494 if (number != (UINT_MAX-1)) {
2498 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2503 Session::region_name (string& result, string base, bool newlevel) const
2510 Glib::Mutex::Lock lm (region_lock);
2512 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2520 /* XXX this is going to be slow. optimize me later */
2525 string::size_type pos;
2527 pos = base.find_last_of ('.');
2529 /* pos may be npos, but then we just use entire base */
2531 subbase = base.substr (0, pos);
2535 bool name_taken = true;
2538 Glib::Mutex::Lock lm (region_lock);
2540 for (int n = 1; n < 5000; ++n) {
2543 snprintf (buf, sizeof (buf), ".%d", n);
2548 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2549 if (i->second->name() == result) {
2562 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2570 Session::add_region (boost::shared_ptr<Region> region)
2572 boost::shared_ptr<AudioRegion> ar;
2573 boost::shared_ptr<AudioRegion> oar;
2577 Glib::Mutex::Lock lm (region_lock);
2579 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2581 AudioRegionList::iterator x;
2583 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2585 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2587 if (ar->region_list_equivalent (oar)) {
2592 if (x == audio_regions.end()) {
2594 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2596 entry.first = region->id();
2599 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2611 fatal << _("programming error: ")
2612 << X_("unknown region type passed to Session::add_region()")
2619 /* mark dirty because something has changed even if we didn't
2620 add the region to the region list.
2626 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2627 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2628 AudioRegionAdded (ar); /* EMIT SIGNAL */
2633 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2635 boost::shared_ptr<Region> region (weak_region.lock ());
2641 if (what_changed & Region::HiddenChanged) {
2642 /* relay hidden changes */
2643 RegionHiddenChange (region);
2648 Session::remove_region (boost::weak_ptr<Region> weak_region)
2650 AudioRegionList::iterator i;
2651 boost::shared_ptr<Region> region (weak_region.lock ());
2657 boost::shared_ptr<AudioRegion> ar;
2658 bool removed = false;
2661 Glib::Mutex::Lock lm (region_lock);
2663 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2664 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2665 audio_regions.erase (i);
2671 fatal << _("programming error: ")
2672 << X_("unknown region type passed to Session::remove_region()")
2678 /* mark dirty because something has changed even if we didn't
2679 remove the region from the region list.
2685 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2689 boost::shared_ptr<AudioRegion>
2690 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2692 AudioRegionList::iterator i;
2693 boost::shared_ptr<AudioRegion> region;
2694 Glib::Mutex::Lock lm (region_lock);
2696 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2700 if (region->whole_file()) {
2702 if (child->source_equivalent (region)) {
2708 return boost::shared_ptr<AudioRegion> ();
2712 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2714 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2715 (*i)->get_region_list_equivalent_regions (region, result);
2719 Session::destroy_region (boost::shared_ptr<Region> region)
2721 vector<boost::shared_ptr<Source> > srcs;
2724 boost::shared_ptr<AudioRegion> aregion;
2726 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2730 if (aregion->playlist()) {
2731 aregion->playlist()->destroy_region (region);
2734 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2735 srcs.push_back (aregion->source (n));
2739 region->drop_references ();
2741 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2743 if (!(*i)->used()) {
2744 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2747 (afs)->mark_for_remove ();
2750 (*i)->drop_references ();
2752 cerr << "source was not used by any playlist\n";
2760 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2762 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2763 destroy_region (*i);
2769 Session::remove_last_capture ()
2771 list<boost::shared_ptr<Region> > r;
2773 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2775 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2776 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2779 r.insert (r.end(), l.begin(), l.end());
2784 destroy_regions (r);
2786 save_state (_current_snapshot_name);
2792 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2798 /* Source Management */
2801 Session::add_source (boost::shared_ptr<Source> source)
2803 boost::shared_ptr<AudioFileSource> afs;
2805 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2807 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2808 pair<AudioSourceList::iterator,bool> result;
2810 entry.first = source->id();
2814 Glib::Mutex::Lock lm (audio_source_lock);
2815 result = audio_sources.insert (entry);
2818 if (result.second) {
2819 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2827 Session::remove_source (boost::weak_ptr<Source> src)
2829 AudioSourceList::iterator i;
2830 boost::shared_ptr<Source> source = src.lock();
2837 Glib::Mutex::Lock lm (audio_source_lock);
2839 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2840 audio_sources.erase (i);
2844 if (!_state_of_the_state & InCleanup) {
2846 /* save state so we don't end up with a session file
2847 referring to non-existent sources.
2850 save_state (_current_snapshot_name);
2854 boost::shared_ptr<Source>
2855 Session::source_by_id (const PBD::ID& id)
2857 Glib::Mutex::Lock lm (audio_source_lock);
2858 AudioSourceList::iterator i;
2859 boost::shared_ptr<Source> source;
2861 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2865 /* XXX search MIDI or other searches here */
2871 boost::shared_ptr<Source>
2872 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2874 Glib::Mutex::Lock lm (audio_source_lock);
2876 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2877 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2879 if (afs && afs->path() == path && chn == afs->channel()) {
2884 return boost::shared_ptr<Source>();
2888 Session::peak_path (Glib::ustring base) const
2900 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2903 string old_basename = PBD::basename_nosuffix (oldname);
2904 string new_legalized = legalize_for_path (newname);
2906 /* note: we know (or assume) the old path is already valid */
2910 /* destructive file sources have a name of the form:
2912 /path/to/Tnnnn-NAME(%[LR])?.wav
2914 the task here is to replace NAME with the new name.
2917 /* find last slash */
2921 string::size_type slash;
2922 string::size_type dash;
2924 if ((slash = path.find_last_of ('/')) == string::npos) {
2928 dir = path.substr (0, slash+1);
2930 /* '-' is not a legal character for the NAME part of the path */
2932 if ((dash = path.find_last_of ('-')) == string::npos) {
2936 prefix = path.substr (slash+1, dash-(slash+1));
2941 path += new_legalized;
2942 path += ".wav"; /* XXX gag me with a spoon */
2946 /* non-destructive file sources have a name of the form:
2948 /path/to/NAME-nnnnn(%[LR])?.wav
2950 the task here is to replace NAME with the new name.
2955 string::size_type slash;
2956 string::size_type dash;
2957 string::size_type postfix;
2959 /* find last slash */
2961 if ((slash = path.find_last_of ('/')) == string::npos) {
2965 dir = path.substr (0, slash+1);
2967 /* '-' is not a legal character for the NAME part of the path */
2969 if ((dash = path.find_last_of ('-')) == string::npos) {
2973 suffix = path.substr (dash+1);
2975 // Suffix is now everything after the dash. Now we need to eliminate
2976 // the nnnnn part, which is done by either finding a '%' or a '.'
2978 postfix = suffix.find_last_of ("%");
2979 if (postfix == string::npos) {
2980 postfix = suffix.find_last_of ('.');
2983 if (postfix != string::npos) {
2984 suffix = suffix.substr (postfix);
2986 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2990 const uint32_t limit = 10000;
2991 char buf[PATH_MAX+1];
2993 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2995 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2997 if (access (buf, F_OK) != 0) {
3005 error << "FATAL ERROR! Could not find a " << endl;
3014 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3018 char buf[PATH_MAX+1];
3019 const uint32_t limit = 10000;
3023 legalized = legalize_for_path (name);
3025 /* find a "version" of the file name that doesn't exist in
3026 any of the possible directories.
3029 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3031 vector<space_and_path>::iterator i;
3032 uint32_t existing = 0;
3034 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3038 spath += sound_dir (false);
3042 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3043 } else if (nchan == 2) {
3045 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3047 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3049 } else if (nchan < 26) {
3050 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3052 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3061 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3062 } else if (nchan == 2) {
3064 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3066 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3068 } else if (nchan < 26) {
3069 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3071 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3075 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3081 if (existing == 0) {
3086 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3088 throw failed_constructor();
3092 /* we now have a unique name for the file, but figure out where to
3098 spath = discover_best_sound_dir ();
3101 string::size_type pos = foo.find_last_of ('/');
3103 if (pos == string::npos) {
3106 spath += foo.substr (pos + 1);
3112 boost::shared_ptr<AudioFileSource>
3113 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3115 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3116 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3119 /* Playlist management */
3121 boost::shared_ptr<Playlist>
3122 Session::playlist_by_name (string name)
3124 Glib::Mutex::Lock lm (playlist_lock);
3125 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3126 if ((*i)->name() == name) {
3130 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3131 if ((*i)->name() == name) {
3136 return boost::shared_ptr<Playlist>();
3140 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3142 if (playlist->hidden()) {
3147 Glib::Mutex::Lock lm (playlist_lock);
3148 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3149 playlists.insert (playlists.begin(), playlist);
3150 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3151 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3157 PlaylistAdded (playlist); /* EMIT SIGNAL */
3161 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3164 Glib::Mutex::Lock lm (playlist_lock);
3165 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3168 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3175 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3177 boost::shared_ptr<Playlist> pl(wpl.lock());
3183 PlaylistList::iterator x;
3186 /* its not supposed to be visible */
3191 Glib::Mutex::Lock lm (playlist_lock);
3195 unused_playlists.insert (pl);
3197 if ((x = playlists.find (pl)) != playlists.end()) {
3198 playlists.erase (x);
3204 playlists.insert (pl);
3206 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3207 unused_playlists.erase (x);
3214 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3216 if (_state_of_the_state & Deletion) {
3220 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3227 Glib::Mutex::Lock lm (playlist_lock);
3229 PlaylistList::iterator i;
3231 i = find (playlists.begin(), playlists.end(), playlist);
3232 if (i != playlists.end()) {
3233 playlists.erase (i);
3236 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3237 if (i != unused_playlists.end()) {
3238 unused_playlists.erase (i);
3245 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3249 Session::set_audition (boost::shared_ptr<Region> r)
3251 pending_audition_region = r;
3252 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3253 schedule_butler_transport_work ();
3257 Session::audition_playlist ()
3259 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3260 ev->region.reset ();
3265 Session::non_realtime_set_audition ()
3267 if (!pending_audition_region) {
3268 auditioner->audition_current_playlist ();
3270 auditioner->audition_region (pending_audition_region);
3271 pending_audition_region.reset ();
3273 AuditionActive (true); /* EMIT SIGNAL */
3277 Session::audition_region (boost::shared_ptr<Region> r)
3279 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3285 Session::cancel_audition ()
3287 if (auditioner->active()) {
3288 auditioner->cancel_audition ();
3289 AuditionActive (false); /* EMIT SIGNAL */
3294 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3296 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3300 Session::remove_empty_sounds ()
3302 PathScanner scanner;
3304 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3306 Glib::Mutex::Lock lm (audio_source_lock);
3308 regex_t compiled_tape_track_pattern;
3311 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3315 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3317 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3321 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3323 /* never remove files that appear to be a tape track */
3325 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3330 if (AudioFileSource::is_empty (*this, **i)) {
3332 unlink ((*i)->c_str());
3334 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3335 unlink (peakpath.c_str());
3341 delete possible_audiofiles;
3345 Session::is_auditioning () const
3347 /* can be called before we have an auditioner object */
3349 return auditioner->active();
3356 Session::set_all_solo (bool yn)
3358 shared_ptr<RouteList> r = routes.reader ();
3360 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3361 if (!(*i)->hidden()) {
3362 (*i)->set_solo (yn, this);
3370 Session::set_all_mute (bool yn)
3372 shared_ptr<RouteList> r = routes.reader ();
3374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3375 if (!(*i)->hidden()) {
3376 (*i)->set_mute (yn, this);
3384 Session::n_diskstreams () const
3388 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3390 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3391 if (!(*i)->hidden()) {
3399 Session::graph_reordered ()
3401 /* don't do this stuff if we are setting up connections
3402 from a set_state() call or creating new tracks.
3405 if (_state_of_the_state & InitialConnecting) {
3409 /* every track/bus asked for this to be handled but it was deferred because
3410 we were connecting. do it now.
3413 request_input_change_handling ();
3417 /* force all diskstreams to update their capture offset values to
3418 reflect any changes in latencies within the graph.
3421 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3423 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3424 (*i)->set_capture_offset ();
3429 Session::record_disenable_all ()
3431 record_enable_change_all (false);
3435 Session::record_enable_all ()
3437 record_enable_change_all (true);
3441 Session::record_enable_change_all (bool yn)
3443 shared_ptr<RouteList> r = routes.reader ();
3445 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3448 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3449 at->set_record_enable (yn, this);
3453 /* since we don't keep rec-enable state, don't mark session dirty */
3457 Session::add_redirect (Redirect* redirect)
3461 PortInsert* port_insert;
3462 PluginInsert* plugin_insert;
3464 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3465 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3466 _port_inserts.insert (_port_inserts.begin(), port_insert);
3467 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3468 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3470 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3473 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3474 _sends.insert (_sends.begin(), send);
3476 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3480 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3486 Session::remove_redirect (Redirect* redirect)
3490 PortInsert* port_insert;
3491 PluginInsert* plugin_insert;
3493 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3494 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3495 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3496 if (x != _port_inserts.end()) {
3497 insert_bitset[port_insert->bit_slot()] = false;
3498 _port_inserts.erase (x);
3500 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3501 _plugin_inserts.remove (plugin_insert);
3503 fatal << string_compose (_("programming error: %1"),
3504 X_("unknown type of Insert deleted!"))
3508 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3509 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3510 if (x != _sends.end()) {
3511 send_bitset[send->bit_slot()] = false;
3515 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3523 Session::available_capture_duration ()
3525 float sample_bytes_on_disk = 4.0; // keep gcc happy
3527 switch (Config->get_native_file_data_format()) {
3529 sample_bytes_on_disk = 4.0;
3533 sample_bytes_on_disk = 3.0;
3537 sample_bytes_on_disk = 2.0;
3541 /* impossible, but keep some gcc versions happy */
3542 fatal << string_compose (_("programming error: %1"),
3543 X_("illegal native file data format"))
3548 double scale = 4096.0 / sample_bytes_on_disk;
3550 if (_total_free_4k_blocks * scale > (double) max_frames) {
3554 return (nframes_t) floor (_total_free_4k_blocks * scale);
3558 Session::add_connection (ARDOUR::Connection* connection)
3561 Glib::Mutex::Lock guard (connection_lock);
3562 _connections.push_back (connection);
3565 ConnectionAdded (connection); /* EMIT SIGNAL */
3571 Session::remove_connection (ARDOUR::Connection* connection)
3573 bool removed = false;
3576 Glib::Mutex::Lock guard (connection_lock);
3577 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3579 if (i != _connections.end()) {
3580 _connections.erase (i);
3586 ConnectionRemoved (connection); /* EMIT SIGNAL */
3592 ARDOUR::Connection *
3593 Session::connection_by_name (string name) const
3595 Glib::Mutex::Lock lm (connection_lock);
3597 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3598 if ((*i)->name() == name) {
3607 Session::tempo_map_changed (Change ignored)
3614 Session::ensure_passthru_buffers (uint32_t howmany)
3616 while (howmany > _passthru_buffers.size()) {
3618 #ifdef NO_POSIX_MEMALIGN
3619 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3621 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3623 _passthru_buffers.push_back (p);
3627 #ifdef NO_POSIX_MEMALIGN
3628 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3630 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4);
3632 memset (p, 0, sizeof (Sample) * current_block_size);
3633 _silent_buffers.push_back (p);
3637 #ifdef NO_POSIX_MEMALIGN
3638 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3640 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3642 memset (p, 0, sizeof (Sample) * current_block_size);
3643 _send_buffers.push_back (p);
3646 allocate_pan_automation_buffers (current_block_size, howmany, false);
3650 Session::next_insert_id ()
3652 /* this doesn't really loop forever. just think about it */
3655 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3656 if (!insert_bitset[n]) {
3657 insert_bitset[n] = true;
3663 /* none available, so resize and try again */
3665 insert_bitset.resize (insert_bitset.size() + 16, false);
3670 Session::next_send_id ()
3672 /* this doesn't really loop forever. just think about it */
3675 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3676 if (!send_bitset[n]) {
3677 send_bitset[n] = true;
3683 /* none available, so resize and try again */
3685 send_bitset.resize (send_bitset.size() + 16, false);
3690 Session::mark_send_id (uint32_t id)
3692 if (id >= send_bitset.size()) {
3693 send_bitset.resize (id+16, false);
3695 if (send_bitset[id]) {
3696 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3698 send_bitset[id] = true;
3702 Session::mark_insert_id (uint32_t id)
3704 if (id >= insert_bitset.size()) {
3705 insert_bitset.resize (id+16, false);
3707 if (insert_bitset[id]) {
3708 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3710 insert_bitset[id] = true;
3713 /* Named Selection management */
3716 Session::named_selection_by_name (string name)
3718 Glib::Mutex::Lock lm (named_selection_lock);
3719 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3720 if ((*i)->name == name) {
3728 Session::add_named_selection (NamedSelection* named_selection)
3731 Glib::Mutex::Lock lm (named_selection_lock);
3732 named_selections.insert (named_selections.begin(), named_selection);
3735 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3741 NamedSelectionAdded (); /* EMIT SIGNAL */
3745 Session::remove_named_selection (NamedSelection* named_selection)
3747 bool removed = false;
3750 Glib::Mutex::Lock lm (named_selection_lock);
3752 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3754 if (i != named_selections.end()) {
3756 named_selections.erase (i);
3763 NamedSelectionRemoved (); /* EMIT SIGNAL */
3768 Session::reset_native_file_format ()
3770 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3772 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3773 (*i)->reset_write_sources (false);
3778 Session::route_name_unique (string n) const
3780 shared_ptr<RouteList> r = routes.reader ();
3782 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3783 if ((*i)->name() == n) {
3792 Session::n_playlists () const
3794 Glib::Mutex::Lock lm (playlist_lock);
3795 return playlists.size();
3799 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3801 if (!force && howmany <= _npan_buffers) {
3805 if (_pan_automation_buffer) {
3807 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3808 delete [] _pan_automation_buffer[i];
3811 delete [] _pan_automation_buffer;
3814 _pan_automation_buffer = new pan_t*[howmany];
3816 for (uint32_t i = 0; i < howmany; ++i) {
3817 _pan_automation_buffer[i] = new pan_t[nframes];
3820 _npan_buffers = howmany;
3824 Session::freeze (InterThreadInfo& itt)
3826 shared_ptr<RouteList> r = routes.reader ();
3828 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3832 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3833 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3844 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3845 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3848 boost::shared_ptr<Playlist> playlist;
3849 boost::shared_ptr<AudioFileSource> fsource;
3851 char buf[PATH_MAX+1];
3855 nframes_t this_chunk;
3857 vector<Sample*> buffers;
3859 // any bigger than this seems to cause stack overflows in called functions
3860 const nframes_t chunk_size = (128 * 1024)/4;
3862 g_atomic_int_set (&processing_prohibited, 1);
3864 /* call tree *MUST* hold route_lock */
3866 if ((playlist = track.diskstream()->playlist()) == 0) {
3870 /* external redirects will be a problem */
3872 if (track.has_external_redirects()) {
3876 nchans = track.audio_diskstream()->n_channels();
3878 dir = discover_best_sound_dir ();
3880 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3882 for (x = 0; x < 99999; ++x) {
3883 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3884 if (access (buf, F_OK) != 0) {
3890 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3895 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3898 catch (failed_constructor& err) {
3899 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3903 srcs.push_back (fsource);
3906 /* XXX need to flush all redirects */
3911 /* create a set of reasonably-sized buffers */
3913 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3915 #ifdef NO_POSIX_MEMALIGN
3916 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3918 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
3920 buffers.push_back (b);
3923 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3924 (*src)->prepare_for_peakfile_writes ();
3927 while (to_do && !itt.cancel) {
3929 this_chunk = min (to_do, chunk_size);
3931 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3936 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3937 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3940 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3946 start += this_chunk;
3947 to_do -= this_chunk;
3949 itt.progress = (float) (1.0 - ((double) to_do / len));
3958 xnow = localtime (&now);
3960 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3961 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3964 afs->update_header (position, *xnow, now);
3965 afs->flush_header ();
3969 /* construct a region to represent the bounced material */
3971 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3972 region_name_from_path (srcs.front()->name(), true));
3979 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3980 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3983 afs->mark_for_remove ();
3986 (*src)->drop_references ();
3990 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3991 (*src)->done_with_peakfile_writes ();
3995 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3999 g_atomic_int_set (&processing_prohibited, 0);
4007 Session::get_silent_buffers (uint32_t howmany)
4009 for (uint32_t i = 0; i < howmany; ++i) {
4010 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4012 return _silent_buffers;
4016 Session::ntracks () const
4019 shared_ptr<RouteList> r = routes.reader ();
4021 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4022 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4031 Session::nbusses () const
4034 shared_ptr<RouteList> r = routes.reader ();
4036 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4037 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4046 Session::add_automation_list(AutomationList *al)
4048 automation_lists[al->id()] = al;
4052 Session::compute_initial_length ()
4054 return _engine.frame_rate() * 60 * 5;
4058 Session::sync_order_keys ()
4060 if (!Config->get_sync_all_route_ordering()) {
4061 /* leave order keys as they are */
4065 boost::shared_ptr<RouteList> r = routes.reader ();
4067 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4068 (*i)->sync_order_keys ();
4071 Route::SyncOrderKeys (); // EMIT SIGNAL