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>
37 #include <glibmm/fileutils.h>
39 #include <pbd/error.h>
40 #include <glibmm/thread.h>
41 #include <pbd/pathscanner.h>
42 #include <pbd/stl_delete.h>
43 #include <pbd/basename.h>
44 #include <pbd/stacktrace.h>
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/analyser.h>
50 #include <ardour/audio_diskstream.h>
51 #include <ardour/utils.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/audiofilesource.h>
55 #include <ardour/auditioner.h>
56 #include <ardour/recent_sessions.h>
57 #include <ardour/redirect.h>
58 #include <ardour/send.h>
59 #include <ardour/insert.h>
60 #include <ardour/connection.h>
61 #include <ardour/slave.h>
62 #include <ardour/tempo.h>
63 #include <ardour/audio_track.h>
64 #include <ardour/cycle_timer.h>
65 #include <ardour/named_selection.h>
66 #include <ardour/crossfade.h>
67 #include <ardour/playlist.h>
68 #include <ardour/click.h>
69 #include <ardour/data_type.h>
70 #include <ardour/source_factory.h>
71 #include <ardour/region_factory.h>
74 #include <ardour/osc.h>
80 using namespace ARDOUR;
82 using boost::shared_ptr;
85 static const int CPU_CACHE_ALIGN = 64;
87 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
90 const char* Session::_template_suffix = X_(".template");
91 const char* Session::_statefile_suffix = X_(".ardour");
92 const char* Session::_pending_suffix = X_(".pending");
93 const char* Session::old_sound_dir_name = X_("sounds");
94 const char* Session::sound_dir_name = X_("audiofiles");
95 const char* Session::peak_dir_name = X_("peaks");
96 const char* Session::dead_sound_dir_name = X_("dead_sounds");
97 const char* Session::interchange_dir_name = X_("interchange");
98 const char* Session::export_dir_name = X_("export");
100 bool Session::_disable_all_loaded_plugins = false;
102 Session::compute_peak_t Session::compute_peak = 0;
103 Session::find_peaks_t Session::find_peaks = 0;
104 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
105 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
106 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
108 sigc::signal<void,std::string> Session::Dialog;
109 sigc::signal<int> Session::AskAboutPendingState;
110 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
111 sigc::signal<void> Session::SendFeedback;
113 sigc::signal<void> Session::SMPTEOffsetChanged;
114 sigc::signal<void> Session::StartTimeChanged;
115 sigc::signal<void> Session::EndTimeChanged;
117 sigc::signal<void> Session::AutoBindingOn;
118 sigc::signal<void> Session::AutoBindingOff;
121 sigc::signal<void, std::string, std::string> Session::Exported;
124 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
127 char buf[PATH_MAX+1];
131 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
132 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
138 /* check to see if it exists, and what it is */
140 if (stat (str.c_str(), &statbuf)) {
141 if (errno == ENOENT) {
144 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
152 /* it exists, so it must either be the name
153 of the directory, or the name of the statefile
157 if (S_ISDIR (statbuf.st_mode)) {
159 string::size_type slash = str.find_last_of ('/');
161 if (slash == string::npos) {
163 /* a subdirectory of cwd, so statefile should be ... */
169 tmp += _statefile_suffix;
173 if (stat (tmp.c_str(), &statbuf)) {
174 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
184 /* some directory someplace in the filesystem.
185 the snapshot name is the directory name
190 snapshot = str.substr (slash+1);
194 } else if (S_ISREG (statbuf.st_mode)) {
196 string::size_type slash = str.find_last_of ('/');
197 string::size_type suffix;
199 /* remove the suffix */
201 if (slash != string::npos) {
202 snapshot = str.substr (slash+1);
207 suffix = snapshot.find (_statefile_suffix);
209 if (suffix == string::npos) {
210 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
216 snapshot = snapshot.substr (0, suffix);
218 if (slash == string::npos) {
220 /* we must be in the directory where the
221 statefile lives. get it using cwd().
224 char cwd[PATH_MAX+1];
226 if (getcwd (cwd, sizeof (cwd)) == 0) {
227 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
236 /* full path to the statefile */
238 path = str.substr (0, slash);
243 /* what type of file is it? */
244 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
250 /* its the name of a new directory. get the name
254 string::size_type slash = str.find_last_of ('/');
256 if (slash == string::npos) {
258 /* no slash, just use the name, but clean it up */
260 path = legalize_for_path (str);
266 snapshot = str.substr (slash+1);
273 Session::Session (AudioEngine &eng,
274 const string& fullpath,
275 const string& snapshot_name,
279 _mmc_port (default_mmc_port),
280 _mtc_port (default_mtc_port),
281 _midi_port (default_midi_port),
282 pending_events (2048),
283 midi_requests (128), // the size of this should match the midi request pool size
284 diskstreams (new DiskstreamList),
285 routes (new RouteList),
286 auditioner ((Auditioner*) 0),
292 if (!eng.connected()) {
293 throw failed_constructor();
296 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
298 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
299 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
301 first_stage_init (fullpath, snapshot_name);
303 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
306 if (create (new_session, mix_template, compute_initial_length())) {
308 throw failed_constructor ();
312 if (second_stage_init (new_session)) {
314 throw failed_constructor ();
317 store_recent_sessions(_name, _path);
319 bool was_dirty = dirty();
321 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
323 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
326 DirtyChanged (); /* EMIT SIGNAL */
330 Session::Session (AudioEngine &eng,
332 string snapshot_name,
333 AutoConnectOption input_ac,
334 AutoConnectOption output_ac,
335 uint32_t control_out_channels,
336 uint32_t master_out_channels,
337 uint32_t requested_physical_in,
338 uint32_t requested_physical_out,
339 nframes_t initial_length)
342 _mmc_port (default_mmc_port),
343 _mtc_port (default_mtc_port),
344 _midi_port (default_midi_port),
345 pending_events (2048),
347 diskstreams (new DiskstreamList),
348 routes (new RouteList),
354 if (!eng.connected()) {
355 throw failed_constructor();
358 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
360 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
361 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
363 if (n_physical_audio_inputs) {
364 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
367 if (n_physical_audio_outputs) {
368 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
371 first_stage_init (fullpath, snapshot_name);
373 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
376 if (create (new_session, string(), initial_length)) {
378 throw failed_constructor ();
383 /* set up Master Out and Control Out if necessary */
388 if (control_out_channels) {
389 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
390 r->set_remote_control_id (control_id++);
395 if (master_out_channels) {
396 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
397 r->set_remote_control_id (control_id);
401 /* prohibit auto-connect to master, because there isn't one */
402 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
406 add_routes (rl, false);
411 Config->set_input_auto_connect (input_ac);
412 Config->set_output_auto_connect (output_ac);
414 if (second_stage_init (new_session)) {
416 throw failed_constructor ();
419 store_recent_sessions (_name, _path);
421 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
424 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
435 /* if we got to here, leaving pending capture state around
439 remove_pending_capture_state ();
441 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
443 _engine.remove_session ();
445 GoingAway (); /* EMIT SIGNAL */
451 /* clear history so that no references to objects are held any more */
455 /* clear state tree so that no references to objects are held any more */
461 terminate_butler_thread ();
462 terminate_midi_thread ();
464 if (click_data && click_data != default_click) {
465 delete [] click_data;
468 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
469 delete [] click_emphasis_data;
474 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
478 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
482 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
486 AudioDiskstream::free_working_buffers();
488 /* this should cause deletion of the auditioner */
490 // auditioner.reset ();
492 #undef TRACK_DESTRUCTION
493 #ifdef TRACK_DESTRUCTION
494 cerr << "delete named selections\n";
495 #endif /* TRACK_DESTRUCTION */
496 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
497 NamedSelectionList::iterator tmp;
506 #ifdef TRACK_DESTRUCTION
507 cerr << "delete playlists\n";
508 #endif /* TRACK_DESTRUCTION */
509 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
510 PlaylistList::iterator tmp;
515 (*i)->drop_references ();
520 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
521 PlaylistList::iterator tmp;
526 (*i)->drop_references ();
532 unused_playlists.clear ();
534 #ifdef TRACK_DESTRUCTION
535 cerr << "delete audio regions\n";
536 #endif /* TRACK_DESTRUCTION */
538 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
539 AudioRegionList::iterator tmp;
544 i->second->drop_references ();
549 audio_regions.clear ();
551 #ifdef TRACK_DESTRUCTION
552 cerr << "delete routes\n";
553 #endif /* TRACK_DESTRUCTION */
555 RCUWriter<RouteList> writer (routes);
556 boost::shared_ptr<RouteList> r = writer.get_copy ();
557 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
558 (*i)->drop_references ();
561 /* writer goes out of scope and updates master */
566 #ifdef TRACK_DESTRUCTION
567 cerr << "delete diskstreams\n";
568 #endif /* TRACK_DESTRUCTION */
570 RCUWriter<DiskstreamList> dwriter (diskstreams);
571 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
572 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
573 (*i)->drop_references ();
577 diskstreams.flush ();
579 #ifdef TRACK_DESTRUCTION
580 cerr << "delete audio sources\n";
581 #endif /* TRACK_DESTRUCTION */
582 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
583 AudioSourceList::iterator tmp;
588 i->second->drop_references ();
592 audio_sources.clear ();
594 #ifdef TRACK_DESTRUCTION
595 cerr << "delete mix groups\n";
596 #endif /* TRACK_DESTRUCTION */
597 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
598 list<RouteGroup*>::iterator tmp;
608 #ifdef TRACK_DESTRUCTION
609 cerr << "delete edit groups\n";
610 #endif /* TRACK_DESTRUCTION */
611 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
612 list<RouteGroup*>::iterator tmp;
622 #ifdef TRACK_DESTRUCTION
623 cerr << "delete connections\n";
624 #endif /* TRACK_DESTRUCTION */
625 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
626 ConnectionList::iterator tmp;
636 if (butler_mixdown_buffer) {
637 delete [] butler_mixdown_buffer;
640 if (butler_gain_buffer) {
641 delete [] butler_gain_buffer;
644 Crossfade::set_buffer_size (0);
652 Session::set_worst_io_latencies ()
654 _worst_output_latency = 0;
655 _worst_input_latency = 0;
657 if (!_engine.connected()) {
661 boost::shared_ptr<RouteList> r = routes.reader ();
663 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
664 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
665 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
670 Session::when_engine_running ()
672 string first_physical_output;
674 /* we don't want to run execute this again */
676 BootMessage (_("Set block size and sample rate"));
678 set_block_size (_engine.frames_per_cycle());
679 set_frame_rate (_engine.frame_rate());
681 BootMessage (_("Using configuration"));
683 Config->map_parameters (mem_fun (*this, &Session::config_changed));
685 /* every time we reconnect, recompute worst case output latencies */
687 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
689 if (synced_to_jack()) {
690 _engine.transport_stop ();
693 if (Config->get_jack_time_master()) {
694 _engine.transport_locate (_transport_frame);
702 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
704 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
706 /* existing state for Click */
708 if (_click_io->set_state (*child->children().front()) == 0) {
710 _clicking = Config->get_clicking ();
714 error << _("could not setup Click I/O") << endmsg;
720 /* default state for Click */
722 first_physical_output = _engine.get_nth_physical_audio_output (0);
724 if (first_physical_output.length()) {
725 if (_click_io->add_output_port (first_physical_output, this)) {
726 // relax, even though its an error
728 _clicking = Config->get_clicking ();
734 catch (failed_constructor& err) {
735 error << _("cannot setup Click I/O") << endmsg;
738 BootMessage (_("Compute I/O Latencies"));
740 set_worst_io_latencies ();
743 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
746 /* Create a set of Connection objects that map
747 to the physical outputs currently available
750 BootMessage (_("Set up standard connections"));
754 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
756 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
758 Connection* c = new OutputConnection (buf, true);
761 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
766 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
768 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
770 Connection* c = new InputConnection (buf, true);
773 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
780 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
782 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
784 Connection* c = new OutputConnection (buf, true);
788 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
789 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
794 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
796 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
798 Connection* c = new InputConnection (buf, true);
802 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
803 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
812 /* create master/control ports */
817 /* force the master to ignore any later call to this */
819 if (_master_out->pending_state_node) {
820 _master_out->ports_became_legal();
823 /* no panner resets till we are through */
825 _master_out->defer_pan_reset ();
827 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
828 if (_master_out->add_input_port ("", this)) {
829 error << _("cannot setup master inputs")
835 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
836 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
837 error << _("cannot setup master outputs")
844 _master_out->allow_pan_reset ();
848 Connection* c = new OutputConnection (_("Master Out"), true);
850 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
852 c->add_connection ((int) n, _master_out->input(n)->name());
857 BootMessage (_("Setup signal flow and plugins"));
861 /* catch up on send+insert cnts */
863 BootMessage (_("Catch up with send/insert state"));
867 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
870 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
871 if (id > insert_cnt) {
879 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
882 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
890 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
892 /* hook us up to the engine */
894 BootMessage (_("Connect to engine"));
896 _engine.set_session (this);
901 BootMessage (_("OSC startup"));
903 osc->set_session (*this);
909 Session::hookup_io ()
911 /* stop graph reordering notifications from
912 causing resorts, etc.
915 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
918 if (auditioner == 0) {
920 /* we delay creating the auditioner till now because
921 it makes its own connections to ports.
922 the engine has to be running for this to work.
926 auditioner.reset (new Auditioner (*this));
929 catch (failed_constructor& err) {
930 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
934 /* Tell all IO objects to create their ports */
940 vector<string> cports;
942 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
943 if (_control_out->add_input_port ("", this)) {
944 error << _("cannot setup control inputs")
950 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
951 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
952 error << _("cannot set up master outputs")
960 uint32_t ni = _control_out->n_inputs();
962 for (n = 0; n < ni; ++n) {
963 cports.push_back (_control_out->input(n)->name());
966 boost::shared_ptr<RouteList> r = routes.reader ();
968 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
969 (*x)->set_control_outs (cports);
973 /* Tell all IO objects to connect themselves together */
975 IO::enable_connecting ();
977 /* Now reset all panners */
979 IO::reset_panners ();
981 /* Anyone who cares about input state, wake up and do something */
983 IOConnectionsComplete (); /* EMIT SIGNAL */
985 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
988 /* now handle the whole enchilada as if it was one
994 /* update mixer solo state */
1000 Session::playlist_length_changed ()
1002 /* we can't just increase end_location->end() if pl->get_maximum_extent()
1003 if larger. if the playlist used to be the longest playlist,
1004 and its now shorter, we have to decrease end_location->end(). hence,
1005 we have to iterate over all diskstreams and check the
1006 playlists currently in use.
1008 find_current_end ();
1012 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1014 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1021 boost::shared_ptr<Playlist> playlist;
1023 if ((playlist = dstream->playlist()) != 0) {
1024 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1027 /* see comment in playlist_length_changed () */
1028 find_current_end ();
1032 Session::record_enabling_legal () const
1034 /* this used to be in here, but survey says.... we don't need to restrict it */
1035 // if (record_status() == Recording) {
1039 if (Config->get_all_safe()) {
1046 Session::reset_input_monitor_state ()
1048 if (transport_rolling()) {
1050 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1052 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1053 if ((*i)->record_enabled ()) {
1054 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1055 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1059 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1061 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1062 if ((*i)->record_enabled ()) {
1063 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1064 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1071 Session::auto_punch_start_changed (Location* location)
1073 replace_event (Event::PunchIn, location->start());
1075 if (get_record_enabled() && Config->get_punch_in()) {
1076 /* capture start has been changed, so save new pending state */
1077 save_state ("", true);
1082 Session::auto_punch_end_changed (Location* location)
1084 nframes_t when_to_stop = location->end();
1085 // when_to_stop += _worst_output_latency + _worst_input_latency;
1086 replace_event (Event::PunchOut, when_to_stop);
1090 Session::auto_punch_changed (Location* location)
1092 nframes_t when_to_stop = location->end();
1094 replace_event (Event::PunchIn, location->start());
1095 //when_to_stop += _worst_output_latency + _worst_input_latency;
1096 replace_event (Event::PunchOut, when_to_stop);
1100 Session::auto_loop_changed (Location* location)
1102 replace_event (Event::AutoLoop, location->end(), location->start());
1104 if (transport_rolling() && play_loop) {
1106 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1108 if (_transport_frame > location->end()) {
1109 // relocate to beginning of loop
1110 clear_events (Event::LocateRoll);
1112 request_locate (location->start(), true);
1115 else if (Config->get_seamless_loop() && !loop_changing) {
1117 // schedule a locate-roll to refill the diskstreams at the
1118 // previous loop end
1119 loop_changing = true;
1121 if (location->end() > last_loopend) {
1122 clear_events (Event::LocateRoll);
1123 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1130 last_loopend = location->end();
1134 Session::set_auto_punch_location (Location* location)
1138 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1139 auto_punch_start_changed_connection.disconnect();
1140 auto_punch_end_changed_connection.disconnect();
1141 auto_punch_changed_connection.disconnect();
1142 existing->set_auto_punch (false, this);
1143 remove_event (existing->start(), Event::PunchIn);
1144 clear_events (Event::PunchOut);
1145 auto_punch_location_changed (0);
1150 if (location == 0) {
1154 if (location->end() <= location->start()) {
1155 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1159 auto_punch_start_changed_connection.disconnect();
1160 auto_punch_end_changed_connection.disconnect();
1161 auto_punch_changed_connection.disconnect();
1163 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1164 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1165 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1167 location->set_auto_punch (true, this);
1170 auto_punch_changed (location);
1172 auto_punch_location_changed (location);
1176 Session::set_auto_loop_location (Location* location)
1180 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1181 auto_loop_start_changed_connection.disconnect();
1182 auto_loop_end_changed_connection.disconnect();
1183 auto_loop_changed_connection.disconnect();
1184 existing->set_auto_loop (false, this);
1185 remove_event (existing->end(), Event::AutoLoop);
1186 auto_loop_location_changed (0);
1191 if (location == 0) {
1195 if (location->end() <= location->start()) {
1196 error << _("Session: you can't use a mark for auto loop") << endmsg;
1200 last_loopend = location->end();
1202 auto_loop_start_changed_connection.disconnect();
1203 auto_loop_end_changed_connection.disconnect();
1204 auto_loop_changed_connection.disconnect();
1206 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1207 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1208 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1210 location->set_auto_loop (true, this);
1212 /* take care of our stuff first */
1214 auto_loop_changed (location);
1216 /* now tell everyone else */
1218 auto_loop_location_changed (location);
1222 Session::locations_added (Location* ignored)
1228 Session::locations_changed ()
1230 _locations.apply (*this, &Session::handle_locations_changed);
1234 Session::handle_locations_changed (Locations::LocationList& locations)
1236 Locations::LocationList::iterator i;
1238 bool set_loop = false;
1239 bool set_punch = false;
1241 for (i = locations.begin(); i != locations.end(); ++i) {
1245 if (location->is_auto_punch()) {
1246 set_auto_punch_location (location);
1249 if (location->is_auto_loop()) {
1250 set_auto_loop_location (location);
1257 set_auto_loop_location (0);
1260 set_auto_punch_location (0);
1267 Session::enable_record ()
1269 /* XXX really atomic compare+swap here */
1270 if (g_atomic_int_get (&_record_status) != Recording) {
1271 g_atomic_int_set (&_record_status, Recording);
1272 _last_record_location = _transport_frame;
1273 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1275 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1276 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1277 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1278 if ((*i)->record_enabled ()) {
1279 (*i)->monitor_input (true);
1284 RecordStateChanged ();
1289 Session::disable_record (bool rt_context, bool force)
1293 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1295 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1296 g_atomic_int_set (&_record_status, Disabled);
1298 if (rs == Recording) {
1299 g_atomic_int_set (&_record_status, Enabled);
1303 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1305 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1306 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1308 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1309 if ((*i)->record_enabled ()) {
1310 (*i)->monitor_input (false);
1315 RecordStateChanged (); /* emit signal */
1318 remove_pending_capture_state ();
1324 Session::step_back_from_record ()
1326 /* XXX really atomic compare+swap here */
1327 if (g_atomic_int_get (&_record_status) == Recording) {
1328 g_atomic_int_set (&_record_status, Enabled);
1330 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1331 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1333 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1334 if ((*i)->record_enabled ()) {
1335 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1336 (*i)->monitor_input (false);
1344 Session::maybe_enable_record ()
1346 g_atomic_int_set (&_record_status, Enabled);
1348 /* this function is currently called from somewhere other than an RT thread.
1349 this save_state() call therefore doesn't impact anything.
1352 save_state ("", true);
1354 if (_transport_speed) {
1355 if (!Config->get_punch_in()) {
1359 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1360 RecordStateChanged (); /* EMIT SIGNAL */
1367 Session::audible_frame () const
1373 /* the first of these two possible settings for "offset"
1374 mean that the audible frame is stationary until
1375 audio emerges from the latency compensation
1378 the second means that the audible frame is stationary
1379 until audio would emerge from a physical port
1380 in the absence of any plugin latency compensation
1383 offset = _worst_output_latency;
1385 if (offset > current_block_size) {
1386 offset -= current_block_size;
1388 /* XXX is this correct? if we have no external
1389 physical connections and everything is internal
1390 then surely this is zero? still, how
1391 likely is that anyway?
1393 offset = current_block_size;
1396 if (synced_to_jack()) {
1397 tf = _engine.transport_frame();
1399 tf = _transport_frame;
1402 if (_transport_speed == 0) {
1412 if (!non_realtime_work_pending()) {
1416 /* take latency into account */
1425 Session::set_frame_rate (nframes_t frames_per_second)
1427 /** \fn void Session::set_frame_size(nframes_t)
1428 the AudioEngine object that calls this guarantees
1429 that it will not be called while we are also in
1430 ::process(). Its fine to do things that block
1434 _base_frame_rate = frames_per_second;
1438 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1442 // XXX we need some equivalent to this, somehow
1443 // SndFileSource::setup_standard_crossfades (frames_per_second);
1447 /* XXX need to reset/reinstantiate all LADSPA plugins */
1451 Session::set_block_size (nframes_t nframes)
1453 /* the AudioEngine guarantees
1454 that it will not be called while we are also in
1455 ::process(). It is therefore fine to do things that block
1460 vector<Sample*>::iterator i;
1463 current_block_size = nframes;
1465 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1469 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1473 _passthru_buffers.clear ();
1474 _silent_buffers.clear ();
1476 ensure_passthru_buffers (np);
1478 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1482 #ifdef NO_POSIX_MEMALIGN
1483 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1485 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1489 memset (*i, 0, sizeof (Sample) * current_block_size);
1493 if (_gain_automation_buffer) {
1494 delete [] _gain_automation_buffer;
1496 _gain_automation_buffer = new gain_t[nframes];
1498 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1500 boost::shared_ptr<RouteList> r = routes.reader ();
1502 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1503 (*i)->set_block_size (nframes);
1506 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1507 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1508 (*i)->set_block_size (nframes);
1511 set_worst_io_latencies ();
1516 Session::set_default_fade (float steepness, float fade_msecs)
1519 nframes_t fade_frames;
1521 /* Don't allow fade of less 1 frame */
1523 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1530 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1534 default_fade_msecs = fade_msecs;
1535 default_fade_steepness = steepness;
1538 // jlc, WTF is this!
1539 Glib::RWLock::ReaderLock lm (route_lock);
1540 AudioRegion::set_default_fade (steepness, fade_frames);
1545 /* XXX have to do this at some point */
1546 /* foreach region using default fade, reset, then
1547 refill_all_diskstream_buffers ();
1552 struct RouteSorter {
1553 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1554 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1556 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1559 if (r1->fed_by.empty()) {
1560 if (r2->fed_by.empty()) {
1561 /* no ardour-based connections inbound to either route. just use signal order */
1562 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1564 /* r2 has connections, r1 does not; run r1 early */
1568 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1575 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1577 shared_ptr<Route> r2;
1579 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1580 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1584 /* make a copy of the existing list of routes that feed r1 */
1586 set<shared_ptr<Route> > existing = r1->fed_by;
1588 /* for each route that feeds r1, recurse, marking it as feeding
1592 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1595 /* r2 is a route that feeds r1 which somehow feeds base. mark
1596 base as being fed by r2
1599 rbase->fed_by.insert (r2);
1603 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1607 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1611 /* now recurse, so that we can mark base as being fed by
1612 all routes that feed r2
1615 trace_terminal (r2, rbase);
1622 Session::resort_routes ()
1624 /* don't do anything here with signals emitted
1625 by Routes while we are being destroyed.
1628 if (_state_of_the_state & Deletion) {
1635 RCUWriter<RouteList> writer (routes);
1636 shared_ptr<RouteList> r = writer.get_copy ();
1637 resort_routes_using (r);
1638 /* writer goes out of scope and forces update */
1643 Session::resort_routes_using (shared_ptr<RouteList> r)
1645 RouteList::iterator i, j;
1647 for (i = r->begin(); i != r->end(); ++i) {
1649 (*i)->fed_by.clear ();
1651 for (j = r->begin(); j != r->end(); ++j) {
1653 /* although routes can feed themselves, it will
1654 cause an endless recursive descent if we
1655 detect it. so don't bother checking for
1663 if ((*j)->feeds (*i)) {
1664 (*i)->fed_by.insert (*j);
1669 for (i = r->begin(); i != r->end(); ++i) {
1670 trace_terminal (*i, *i);
1676 /* don't leave dangling references to routes in Route::fed_by */
1678 for (i = r->begin(); i != r->end(); ++i) {
1679 (*i)->fed_by.clear ();
1683 cerr << "finished route resort\n";
1685 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1686 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1693 list<boost::shared_ptr<AudioTrack> >
1694 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1696 char track_name[32];
1697 uint32_t track_id = 0;
1699 uint32_t channels_used = 0;
1701 RouteList new_routes;
1702 list<boost::shared_ptr<AudioTrack> > ret;
1703 uint32_t control_id;
1705 /* count existing audio tracks */
1708 shared_ptr<RouteList> r = routes.reader ();
1710 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1711 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1712 if (!(*i)->hidden()) {
1714 channels_used += (*i)->n_inputs();
1720 vector<string> physinputs;
1721 vector<string> physoutputs;
1722 uint32_t nphysical_in;
1723 uint32_t nphysical_out;
1725 _engine.get_physical_audio_outputs (physoutputs);
1726 _engine.get_physical_audio_inputs (physinputs);
1727 control_id = ntracks() + nbusses() + 1;
1731 /* check for duplicate route names, since we might have pre-existing
1732 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1733 save, close,restart,add new route - first named route is now
1741 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1743 if (route_by_name (track_name) == 0) {
1747 } while (track_id < (UINT_MAX-1));
1749 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1750 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1755 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1756 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1761 shared_ptr<AudioTrack> track;
1764 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1766 if (track->ensure_io (input_channels, output_channels, false, this)) {
1767 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1768 input_channels, output_channels)
1774 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1778 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1779 port = physinputs[(channels_used+x)%nphysical_in];
1782 if (port.length() && track->connect_input (track->input (x), port, this)) {
1788 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1792 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1793 port = physoutputs[(channels_used+x)%nphysical_out];
1794 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1796 port = _master_out->input (x%_master_out->n_inputs())->name();
1800 if (port.length() && track->connect_output (track->output (x), port, this)) {
1805 channels_used += track->n_inputs ();
1807 track->audio_diskstream()->non_realtime_input_change();
1809 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1810 track->set_remote_control_id (control_id);
1813 new_routes.push_back (track);
1814 ret.push_back (track);
1818 catch (failed_constructor &err) {
1819 error << _("Session: could not create new audio track.") << endmsg;
1822 /* we need to get rid of this, since the track failed to be created */
1823 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1826 RCUWriter<DiskstreamList> writer (diskstreams);
1827 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1828 ds->remove (track->audio_diskstream());
1835 catch (AudioEngine::PortRegistrationFailure& pfe) {
1837 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;
1840 /* we need to get rid of this, since the track failed to be created */
1841 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1844 RCUWriter<DiskstreamList> writer (diskstreams);
1845 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1846 ds->remove (track->audio_diskstream());
1857 if (!new_routes.empty()) {
1858 add_routes (new_routes, true);
1865 Session::set_remote_control_ids ()
1867 RemoteModel m = Config->get_remote_model();
1869 shared_ptr<RouteList> r = routes.reader ();
1871 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1872 if ( MixerOrdered == m) {
1873 long order = (*i)->order_key(N_("signal"));
1874 (*i)->set_remote_control_id( order+1 );
1875 } else if ( EditorOrdered == m) {
1876 long order = (*i)->order_key(N_("editor"));
1877 (*i)->set_remote_control_id( order+1 );
1878 } else if ( UserOrdered == m) {
1879 //do nothing ... only changes to remote id's are initiated by user
1886 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1889 uint32_t bus_id = 1;
1893 uint32_t control_id;
1895 /* count existing audio busses */
1898 shared_ptr<RouteList> r = routes.reader ();
1900 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1901 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1902 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1909 vector<string> physinputs;
1910 vector<string> physoutputs;
1912 _engine.get_physical_audio_outputs (physoutputs);
1913 _engine.get_physical_audio_inputs (physinputs);
1914 control_id = ntracks() + nbusses() + 1;
1919 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1923 if (route_by_name (bus_name) == 0) {
1927 } while (bus_id < (UINT_MAX-1));
1930 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1932 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1933 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1934 input_channels, output_channels)
1939 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1943 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1944 port = physinputs[((n+x)%n_physical_audio_inputs)];
1947 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1952 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1956 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1957 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1958 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1960 port = _master_out->input (x%_master_out->n_inputs())->name();
1964 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1969 bus->set_remote_control_id (control_id);
1972 ret.push_back (bus);
1976 catch (failed_constructor &err) {
1977 error << _("Session: could not create new audio route.") << endmsg;
1981 catch (AudioEngine::PortRegistrationFailure& pfe) {
1982 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;
1992 add_routes (ret, true);
2000 Session::add_routes (RouteList& new_routes, bool save)
2003 RCUWriter<RouteList> writer (routes);
2004 shared_ptr<RouteList> r = writer.get_copy ();
2005 r->insert (r->end(), new_routes.begin(), new_routes.end());
2006 resort_routes_using (r);
2009 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2011 boost::weak_ptr<Route> wpr (*x);
2013 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2014 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2015 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2016 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2018 if ((*x)->master()) {
2022 if ((*x)->control()) {
2023 _control_out = (*x);
2027 if (_control_out && IO::connecting_legal) {
2029 vector<string> cports;
2030 uint32_t ni = _control_out->n_inputs();
2033 for (n = 0; n < ni; ++n) {
2034 cports.push_back (_control_out->input(n)->name());
2037 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2038 (*x)->set_control_outs (cports);
2045 save_state (_current_snapshot_name);
2048 RouteAdded (new_routes); /* EMIT SIGNAL */
2052 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2054 /* need to do this in case we're rolling at the time, to prevent false underruns */
2055 dstream->do_refill_with_alloc ();
2057 dstream->set_block_size (current_block_size);
2060 RCUWriter<DiskstreamList> writer (diskstreams);
2061 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2062 ds->push_back (dstream);
2063 /* writer goes out of scope, copies ds back to main */
2066 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2067 boost::weak_ptr<Diskstream> (dstream)));
2068 /* this will connect to future changes, and check the current length */
2069 diskstream_playlist_changed (dstream);
2071 dstream->prepare ();
2075 Session::remove_route (shared_ptr<Route> route)
2078 RCUWriter<RouteList> writer (routes);
2079 shared_ptr<RouteList> rs = writer.get_copy ();
2083 /* deleting the master out seems like a dumb
2084 idea, but its more of a UI policy issue
2088 if (route == _master_out) {
2089 _master_out = shared_ptr<Route> ();
2092 if (route == _control_out) {
2093 _control_out = shared_ptr<Route> ();
2095 /* cancel control outs for all routes */
2097 vector<string> empty;
2099 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2100 (*r)->set_control_outs (empty);
2104 update_route_solo_state ();
2106 /* writer goes out of scope, forces route list update */
2109 // FIXME: audio specific
2111 boost::shared_ptr<AudioDiskstream> ds;
2113 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2114 ds = at->audio_diskstream();
2120 RCUWriter<DiskstreamList> dsl (diskstreams);
2121 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2125 diskstreams.flush ();
2128 find_current_end ();
2130 // We need to disconnect the routes inputs and outputs
2132 route->disconnect_inputs (0);
2133 route->disconnect_outputs (0);
2135 update_latency_compensation (false, false);
2138 /* get rid of it from the dead wood collection in the route list manager */
2140 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2144 /* try to cause everyone to drop their references */
2146 route->drop_references ();
2148 /* save the new state of the world */
2150 if (save_state (_current_snapshot_name)) {
2151 save_history (_current_snapshot_name);
2156 Session::route_mute_changed (void* src)
2162 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2164 if (solo_update_disabled) {
2170 boost::shared_ptr<Route> route = wpr.lock ();
2173 /* should not happen */
2174 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2178 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2180 shared_ptr<RouteList> r = routes.reader ();
2182 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2184 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2188 /* don't mess with busses */
2190 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2196 /* don't mess with tracks */
2198 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2203 if ((*i) != route &&
2204 ((*i)->mix_group () == 0 ||
2205 (*i)->mix_group () != route->mix_group () ||
2206 !route->mix_group ()->is_active())) {
2208 if ((*i)->soloed()) {
2210 /* if its already soloed, and solo latching is enabled,
2211 then leave it as it is.
2214 if (Config->get_solo_latched()) {
2221 solo_update_disabled = true;
2222 (*i)->set_solo (false, src);
2223 solo_update_disabled = false;
2227 bool something_soloed = false;
2228 bool same_thing_soloed = false;
2229 bool signal = false;
2231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2232 if ((*i)->soloed()) {
2233 something_soloed = true;
2234 if (dynamic_cast<AudioTrack*>((*i).get())) {
2236 same_thing_soloed = true;
2241 same_thing_soloed = true;
2249 if (something_soloed != currently_soloing) {
2251 currently_soloing = something_soloed;
2254 modify_solo_mute (is_track, same_thing_soloed);
2257 SoloActive (currently_soloing); /* EMIT SIGNAL */
2260 SoloChanged (); /* EMIT SIGNAL */
2266 Session::update_route_solo_state ()
2269 bool is_track = false;
2270 bool signal = false;
2272 /* caller must hold RouteLock */
2274 /* this is where we actually implement solo by changing
2275 the solo mute setting of each track.
2278 shared_ptr<RouteList> r = routes.reader ();
2280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 if ((*i)->soloed()) {
2283 if (dynamic_cast<AudioTrack*>((*i).get())) {
2290 if (mute != currently_soloing) {
2292 currently_soloing = mute;
2295 if (!is_track && !mute) {
2297 /* nothing is soloed */
2299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2300 (*i)->set_solo_mute (false);
2310 modify_solo_mute (is_track, mute);
2313 SoloActive (currently_soloing);
2318 Session::modify_solo_mute (bool is_track, bool mute)
2320 shared_ptr<RouteList> r = routes.reader ();
2322 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2326 /* only alter track solo mute */
2328 if (dynamic_cast<AudioTrack*>((*i).get())) {
2329 if ((*i)->soloed()) {
2330 (*i)->set_solo_mute (!mute);
2332 (*i)->set_solo_mute (mute);
2338 /* only alter bus solo mute */
2340 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2342 if ((*i)->soloed()) {
2344 (*i)->set_solo_mute (false);
2348 /* don't mute master or control outs
2349 in response to another bus solo
2352 if ((*i) != _master_out &&
2353 (*i) != _control_out) {
2354 (*i)->set_solo_mute (mute);
2365 Session::catch_up_on_solo ()
2367 /* this is called after set_state() to catch the full solo
2368 state, which can't be correctly determined on a per-route
2369 basis, but needs the global overview that only the session
2372 update_route_solo_state();
2376 Session::route_by_name (string name)
2378 shared_ptr<RouteList> r = routes.reader ();
2380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2381 if ((*i)->name() == name) {
2386 return shared_ptr<Route> ((Route*) 0);
2390 Session::route_by_id (PBD::ID id)
2392 shared_ptr<RouteList> r = routes.reader ();
2394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2395 if ((*i)->id() == id) {
2400 return shared_ptr<Route> ((Route*) 0);
2404 Session::route_by_remote_id (uint32_t id)
2406 shared_ptr<RouteList> r = routes.reader ();
2408 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2409 if ((*i)->remote_control_id() == id) {
2414 return shared_ptr<Route> ((Route*) 0);
2418 Session::find_current_end ()
2420 if (_state_of_the_state & Loading) {
2424 nframes_t max = get_maximum_extent ();
2426 if (max > end_location->end()) {
2427 end_location->set_end (max);
2429 DurationChanged(); /* EMIT SIGNAL */
2434 Session::get_maximum_extent () const
2439 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2441 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2442 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2443 if ((me = pl->get_maximum_extent()) > max) {
2451 boost::shared_ptr<Diskstream>
2452 Session::diskstream_by_name (string name)
2454 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2456 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2457 if ((*i)->name() == name) {
2462 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2465 boost::shared_ptr<Diskstream>
2466 Session::diskstream_by_id (const PBD::ID& id)
2468 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2470 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2471 if ((*i)->id() == id) {
2476 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2479 /* AudioRegion management */
2482 Session::new_region_name (string old)
2484 string::size_type last_period;
2486 string::size_type len = old.length() + 64;
2489 if ((last_period = old.find_last_of ('.')) == string::npos) {
2491 /* no period present - add one explicitly */
2494 last_period = old.length() - 1;
2499 number = atoi (old.substr (last_period+1).c_str());
2503 while (number < (UINT_MAX-1)) {
2505 AudioRegionList::const_iterator i;
2510 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2513 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2514 if (i->second->name() == sbuf) {
2519 if (i == audio_regions.end()) {
2524 if (number != (UINT_MAX-1)) {
2528 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2533 Session::region_name (string& result, string base, bool newlevel) const
2540 Glib::Mutex::Lock lm (region_lock);
2542 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2550 /* XXX this is going to be slow. optimize me later */
2555 string::size_type pos;
2557 pos = base.find_last_of ('.');
2559 /* pos may be npos, but then we just use entire base */
2561 subbase = base.substr (0, pos);
2565 bool name_taken = true;
2568 Glib::Mutex::Lock lm (region_lock);
2570 for (int n = 1; n < 5000; ++n) {
2573 snprintf (buf, sizeof (buf), ".%d", n);
2578 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2579 if (i->second->name() == result) {
2592 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2600 Session::add_region (boost::shared_ptr<Region> region)
2602 vector<boost::shared_ptr<Region> > v;
2603 v.push_back (region);
2608 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2610 boost::shared_ptr<AudioRegion> ar;
2611 boost::shared_ptr<AudioRegion> oar;
2615 Glib::Mutex::Lock lm (region_lock);
2617 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2619 boost::shared_ptr<Region> region = *ii;
2623 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2625 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2627 AudioRegionList::iterator x;
2629 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2631 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2633 if (ar->region_list_equivalent (oar)) {
2638 if (x == audio_regions.end()) {
2640 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2642 entry.first = region->id();
2645 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2657 fatal << _("programming error: ")
2658 << X_("unknown region type passed to Session::add_region()")
2666 /* mark dirty because something has changed even if we didn't
2667 add the region to the region list.
2674 vector<boost::weak_ptr<AudioRegion> > v;
2675 boost::shared_ptr<AudioRegion> first_ar;
2677 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2679 boost::shared_ptr<Region> region = *ii;
2680 boost::shared_ptr<AudioRegion> ar;
2684 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2686 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2694 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2695 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2699 AudioRegionsAdded (v); /* EMIT SIGNAL */
2705 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2707 boost::shared_ptr<Region> region (weak_region.lock ());
2713 if (what_changed & Region::HiddenChanged) {
2714 /* relay hidden changes */
2715 RegionHiddenChange (region);
2720 Session::remove_region (boost::weak_ptr<Region> weak_region)
2722 AudioRegionList::iterator i;
2723 boost::shared_ptr<Region> region (weak_region.lock ());
2729 boost::shared_ptr<AudioRegion> ar;
2730 bool removed = false;
2733 Glib::Mutex::Lock lm (region_lock);
2735 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2736 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2737 audio_regions.erase (i);
2743 fatal << _("programming error: ")
2744 << X_("unknown region type passed to Session::remove_region()")
2750 /* mark dirty because something has changed even if we didn't
2751 remove the region from the region list.
2757 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2761 boost::shared_ptr<AudioRegion>
2762 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2764 AudioRegionList::iterator i;
2765 boost::shared_ptr<AudioRegion> region;
2766 Glib::Mutex::Lock lm (region_lock);
2768 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2772 if (region->whole_file()) {
2774 if (child->source_equivalent (region)) {
2780 return boost::shared_ptr<AudioRegion> ();
2784 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2786 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2787 (*i)->get_region_list_equivalent_regions (region, result);
2791 Session::destroy_region (boost::shared_ptr<Region> region)
2793 vector<boost::shared_ptr<Source> > srcs;
2796 boost::shared_ptr<AudioRegion> aregion;
2798 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2802 if (aregion->playlist()) {
2803 aregion->playlist()->destroy_region (region);
2806 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2807 srcs.push_back (aregion->source (n));
2811 region->drop_references ();
2813 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2815 if (!(*i)->used()) {
2816 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2819 (afs)->mark_for_remove ();
2822 (*i)->drop_references ();
2824 cerr << "source was not used by any playlist\n";
2832 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2834 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2835 destroy_region (*i);
2841 Session::remove_last_capture ()
2843 list<boost::shared_ptr<Region> > r;
2845 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2847 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2848 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2851 r.insert (r.end(), l.begin(), l.end());
2856 destroy_regions (r);
2858 save_state (_current_snapshot_name);
2864 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2870 /* Source Management */
2873 Session::add_source (boost::shared_ptr<Source> source)
2875 boost::shared_ptr<AudioFileSource> afs;
2877 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2879 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2880 pair<AudioSourceList::iterator,bool> result;
2882 entry.first = source->id();
2886 Glib::Mutex::Lock lm (audio_source_lock);
2887 result = audio_sources.insert (entry);
2890 if (result.second) {
2891 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2895 if (Config->get_auto_analyse_audio()) {
2896 Analyser::queue_source_for_analysis (source, false);
2902 Session::remove_source (boost::weak_ptr<Source> src)
2904 AudioSourceList::iterator i;
2905 boost::shared_ptr<Source> source = src.lock();
2912 Glib::Mutex::Lock lm (audio_source_lock);
2914 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2915 audio_sources.erase (i);
2919 if (!_state_of_the_state & InCleanup) {
2921 /* save state so we don't end up with a session file
2922 referring to non-existent sources.
2925 save_state (_current_snapshot_name);
2929 boost::shared_ptr<Source>
2930 Session::source_by_id (const PBD::ID& id)
2932 Glib::Mutex::Lock lm (audio_source_lock);
2933 AudioSourceList::iterator i;
2934 boost::shared_ptr<Source> source;
2936 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2940 /* XXX search MIDI or other searches here */
2946 boost::shared_ptr<Source>
2947 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2949 Glib::Mutex::Lock lm (audio_source_lock);
2951 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2952 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2954 if (afs && afs->path() == path && chn == afs->channel()) {
2959 return boost::shared_ptr<Source>();
2963 Session::peak_path (Glib::ustring base) const
2975 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2978 string old_basename = PBD::basename_nosuffix (oldname);
2979 string new_legalized = legalize_for_path (newname);
2981 /* note: we know (or assume) the old path is already valid */
2985 /* destructive file sources have a name of the form:
2987 /path/to/Tnnnn-NAME(%[LR])?.wav
2989 the task here is to replace NAME with the new name.
2992 /* find last slash */
2996 string::size_type slash;
2997 string::size_type dash;
2999 if ((slash = path.find_last_of ('/')) == string::npos) {
3003 dir = path.substr (0, slash+1);
3005 /* '-' is not a legal character for the NAME part of the path */
3007 if ((dash = path.find_last_of ('-')) == string::npos) {
3011 prefix = path.substr (slash+1, dash-(slash+1));
3016 path += new_legalized;
3017 path += ".wav"; /* XXX gag me with a spoon */
3021 /* non-destructive file sources have a name of the form:
3023 /path/to/NAME-nnnnn(%[LR])?.wav
3025 the task here is to replace NAME with the new name.
3030 string::size_type slash;
3031 string::size_type dash;
3032 string::size_type postfix;
3034 /* find last slash */
3036 if ((slash = path.find_last_of ('/')) == string::npos) {
3040 dir = path.substr (0, slash+1);
3042 /* '-' is not a legal character for the NAME part of the path */
3044 if ((dash = path.find_last_of ('-')) == string::npos) {
3048 suffix = path.substr (dash+1);
3050 // Suffix is now everything after the dash. Now we need to eliminate
3051 // the nnnnn part, which is done by either finding a '%' or a '.'
3053 postfix = suffix.find_last_of ("%");
3054 if (postfix == string::npos) {
3055 postfix = suffix.find_last_of ('.');
3058 if (postfix != string::npos) {
3059 suffix = suffix.substr (postfix);
3061 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3065 const uint32_t limit = 10000;
3066 char buf[PATH_MAX+1];
3068 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3070 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3072 if (access (buf, F_OK) != 0) {
3080 error << "FATAL ERROR! Could not find a " << endl;
3089 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3093 char buf[PATH_MAX+1];
3094 const uint32_t limit = 10000;
3098 legalized = legalize_for_path (name);
3100 /* find a "version" of the file name that doesn't exist in
3101 any of the possible directories.
3104 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3106 vector<space_and_path>::iterator i;
3107 uint32_t existing = 0;
3109 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3113 spath += sound_dir (false);
3117 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3118 } else if (nchan == 2) {
3120 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3122 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3124 } else if (nchan < 26) {
3125 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3127 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3136 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3137 } else if (nchan == 2) {
3139 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3141 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3143 } else if (nchan < 26) {
3144 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3146 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3150 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3156 if (existing == 0) {
3161 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3163 throw failed_constructor();
3167 /* we now have a unique name for the file, but figure out where to
3173 spath = discover_best_sound_dir ();
3176 string::size_type pos = foo.find_last_of ('/');
3178 if (pos == string::npos) {
3181 spath += foo.substr (pos + 1);
3187 boost::shared_ptr<AudioFileSource>
3188 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3190 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3191 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3194 /* Playlist management */
3196 boost::shared_ptr<Playlist>
3197 Session::playlist_by_name (string name)
3199 Glib::Mutex::Lock lm (playlist_lock);
3200 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3201 if ((*i)->name() == name) {
3205 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3206 if ((*i)->name() == name) {
3211 return boost::shared_ptr<Playlist>();
3215 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3217 if (playlist->hidden()) {
3222 Glib::Mutex::Lock lm (playlist_lock);
3223 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3224 playlists.insert (playlists.begin(), playlist);
3225 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3226 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3232 PlaylistAdded (playlist); /* EMIT SIGNAL */
3236 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3239 Glib::Mutex::Lock lm (playlist_lock);
3240 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3243 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3250 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3252 boost::shared_ptr<Playlist> pl(wpl.lock());
3258 PlaylistList::iterator x;
3261 /* its not supposed to be visible */
3266 Glib::Mutex::Lock lm (playlist_lock);
3270 unused_playlists.insert (pl);
3272 if ((x = playlists.find (pl)) != playlists.end()) {
3273 playlists.erase (x);
3279 playlists.insert (pl);
3281 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3282 unused_playlists.erase (x);
3289 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3291 if (_state_of_the_state & Deletion) {
3295 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3302 Glib::Mutex::Lock lm (playlist_lock);
3304 PlaylistList::iterator i;
3306 i = find (playlists.begin(), playlists.end(), playlist);
3307 if (i != playlists.end()) {
3308 playlists.erase (i);
3311 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3312 if (i != unused_playlists.end()) {
3313 unused_playlists.erase (i);
3320 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3324 Session::set_audition (boost::shared_ptr<Region> r)
3326 pending_audition_region = r;
3327 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3328 schedule_butler_transport_work ();
3332 Session::audition_playlist ()
3334 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3335 ev->region.reset ();
3340 Session::non_realtime_set_audition ()
3342 if (!pending_audition_region) {
3343 auditioner->audition_current_playlist ();
3345 auditioner->audition_region (pending_audition_region);
3346 pending_audition_region.reset ();
3348 AuditionActive (true); /* EMIT SIGNAL */
3352 Session::audition_region (boost::shared_ptr<Region> r)
3354 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3360 Session::cancel_audition ()
3362 if (auditioner->active()) {
3363 auditioner->cancel_audition ();
3364 AuditionActive (false); /* EMIT SIGNAL */
3369 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3371 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3375 Session::remove_empty_sounds ()
3377 PathScanner scanner;
3379 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3381 Glib::Mutex::Lock lm (audio_source_lock);
3383 regex_t compiled_tape_track_pattern;
3386 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3390 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3392 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3396 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3398 /* never remove files that appear to be a tape track */
3400 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3405 if (AudioFileSource::is_empty (*this, **i)) {
3407 unlink ((*i)->c_str());
3409 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3410 unlink (peakpath.c_str());
3416 delete possible_audiofiles;
3420 Session::is_auditioning () const
3422 /* can be called before we have an auditioner object */
3424 return auditioner->active();
3431 Session::set_all_solo (bool yn)
3433 shared_ptr<RouteList> r = routes.reader ();
3435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3436 if (!(*i)->hidden()) {
3437 (*i)->set_solo (yn, this);
3445 Session::set_all_mute (bool yn)
3447 shared_ptr<RouteList> r = routes.reader ();
3449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3450 if (!(*i)->hidden()) {
3451 (*i)->set_mute (yn, this);
3459 Session::n_diskstreams () const
3463 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3465 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3466 if (!(*i)->hidden()) {
3474 Session::graph_reordered ()
3476 /* don't do this stuff if we are setting up connections
3477 from a set_state() call or creating new tracks.
3480 if (_state_of_the_state & InitialConnecting) {
3484 /* every track/bus asked for this to be handled but it was deferred because
3485 we were connecting. do it now.
3488 request_input_change_handling ();
3492 /* force all diskstreams to update their capture offset values to
3493 reflect any changes in latencies within the graph.
3496 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3498 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3499 (*i)->set_capture_offset ();
3504 Session::record_disenable_all ()
3506 record_enable_change_all (false);
3510 Session::record_enable_all ()
3512 record_enable_change_all (true);
3516 Session::record_enable_change_all (bool yn)
3518 shared_ptr<RouteList> r = routes.reader ();
3520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3523 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3524 at->set_record_enable (yn, this);
3528 /* since we don't keep rec-enable state, don't mark session dirty */
3532 Session::add_redirect (Redirect* redirect)
3536 PortInsert* port_insert;
3537 PluginInsert* plugin_insert;
3539 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3540 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3541 _port_inserts.insert (_port_inserts.begin(), port_insert);
3542 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3543 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3545 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3548 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3549 _sends.insert (_sends.begin(), send);
3551 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3555 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3561 Session::remove_redirect (Redirect* redirect)
3565 PortInsert* port_insert;
3566 PluginInsert* plugin_insert;
3568 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3569 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3570 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3571 if (x != _port_inserts.end()) {
3572 insert_bitset[port_insert->bit_slot()] = false;
3573 _port_inserts.erase (x);
3575 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3576 _plugin_inserts.remove (plugin_insert);
3578 fatal << string_compose (_("programming error: %1"),
3579 X_("unknown type of Insert deleted!"))
3583 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3584 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3585 if (x != _sends.end()) {
3586 send_bitset[send->bit_slot()] = false;
3590 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3598 Session::available_capture_duration ()
3600 float sample_bytes_on_disk = 4.0; // keep gcc happy
3602 switch (Config->get_native_file_data_format()) {
3604 sample_bytes_on_disk = 4.0;
3608 sample_bytes_on_disk = 3.0;
3612 sample_bytes_on_disk = 2.0;
3616 /* impossible, but keep some gcc versions happy */
3617 fatal << string_compose (_("programming error: %1"),
3618 X_("illegal native file data format"))
3623 double scale = 4096.0 / sample_bytes_on_disk;
3625 if (_total_free_4k_blocks * scale > (double) max_frames) {
3629 return (nframes_t) floor (_total_free_4k_blocks * scale);
3633 Session::add_connection (ARDOUR::Connection* connection)
3636 Glib::Mutex::Lock guard (connection_lock);
3637 _connections.push_back (connection);
3640 ConnectionAdded (connection); /* EMIT SIGNAL */
3646 Session::remove_connection (ARDOUR::Connection* connection)
3648 bool removed = false;
3651 Glib::Mutex::Lock guard (connection_lock);
3652 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3654 if (i != _connections.end()) {
3655 _connections.erase (i);
3661 ConnectionRemoved (connection); /* EMIT SIGNAL */
3667 ARDOUR::Connection *
3668 Session::connection_by_name (string name) const
3670 Glib::Mutex::Lock lm (connection_lock);
3672 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3673 if ((*i)->name() == name) {
3682 Session::tempo_map_changed (Change ignored)
3686 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3687 (*i)->update_after_tempo_map_change ();
3690 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3691 (*i)->update_after_tempo_map_change ();
3698 Session::ensure_passthru_buffers (uint32_t howmany)
3700 if (current_block_size == 0) {
3704 while (howmany > _passthru_buffers.size()) {
3706 #ifdef NO_POSIX_MEMALIGN
3707 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3709 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3710 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3711 current_block_size, sizeof (Sample), strerror (errno))
3716 _passthru_buffers.push_back (p);
3720 #ifdef NO_POSIX_MEMALIGN
3721 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3723 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4) != 0) {
3724 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3725 current_block_size, sizeof (Sample), strerror (errno))
3730 memset (p, 0, sizeof (Sample) * current_block_size);
3731 _silent_buffers.push_back (p);
3735 #ifdef NO_POSIX_MEMALIGN
3736 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3738 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3740 memset (p, 0, sizeof (Sample) * current_block_size);
3741 _send_buffers.push_back (p);
3744 allocate_pan_automation_buffers (current_block_size, howmany, false);
3748 Session::next_insert_id ()
3750 /* this doesn't really loop forever. just think about it */
3753 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3754 if (!insert_bitset[n]) {
3755 insert_bitset[n] = true;
3761 /* none available, so resize and try again */
3763 insert_bitset.resize (insert_bitset.size() + 16, false);
3768 Session::next_send_id ()
3770 /* this doesn't really loop forever. just think about it */
3773 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3774 if (!send_bitset[n]) {
3775 send_bitset[n] = true;
3781 /* none available, so resize and try again */
3783 send_bitset.resize (send_bitset.size() + 16, false);
3788 Session::mark_send_id (uint32_t id)
3790 if (id >= send_bitset.size()) {
3791 send_bitset.resize (id+16, false);
3793 if (send_bitset[id]) {
3794 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3796 send_bitset[id] = true;
3800 Session::mark_insert_id (uint32_t id)
3802 if (id >= insert_bitset.size()) {
3803 insert_bitset.resize (id+16, false);
3805 if (insert_bitset[id]) {
3806 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3808 insert_bitset[id] = true;
3811 /* Named Selection management */
3814 Session::named_selection_by_name (string name)
3816 Glib::Mutex::Lock lm (named_selection_lock);
3817 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3818 if ((*i)->name == name) {
3826 Session::add_named_selection (NamedSelection* named_selection)
3829 Glib::Mutex::Lock lm (named_selection_lock);
3830 named_selections.insert (named_selections.begin(), named_selection);
3833 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3839 NamedSelectionAdded (); /* EMIT SIGNAL */
3843 Session::remove_named_selection (NamedSelection* named_selection)
3845 bool removed = false;
3848 Glib::Mutex::Lock lm (named_selection_lock);
3850 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3852 if (i != named_selections.end()) {
3854 named_selections.erase (i);
3861 NamedSelectionRemoved (); /* EMIT SIGNAL */
3866 Session::reset_native_file_format ()
3868 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3870 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3871 (*i)->reset_write_sources (false);
3876 Session::route_name_unique (string n) const
3878 shared_ptr<RouteList> r = routes.reader ();
3880 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3881 if ((*i)->name() == n) {
3890 Session::n_playlists () const
3892 Glib::Mutex::Lock lm (playlist_lock);
3893 return playlists.size();
3897 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3899 if (!force && howmany <= _npan_buffers) {
3903 if (_pan_automation_buffer) {
3905 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3906 delete [] _pan_automation_buffer[i];
3909 delete [] _pan_automation_buffer;
3912 _pan_automation_buffer = new pan_t*[howmany];
3914 for (uint32_t i = 0; i < howmany; ++i) {
3915 _pan_automation_buffer[i] = new pan_t[nframes];
3918 _npan_buffers = howmany;
3922 Session::freeze (InterThreadInfo& itt)
3924 shared_ptr<RouteList> r = routes.reader ();
3926 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3930 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3931 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3942 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3943 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3946 boost::shared_ptr<Playlist> playlist;
3947 boost::shared_ptr<AudioFileSource> fsource;
3949 char buf[PATH_MAX+1];
3953 nframes_t this_chunk;
3955 vector<Sample*> buffers;
3957 // any bigger than this seems to cause stack overflows in called functions
3958 const nframes_t chunk_size = (128 * 1024)/4;
3960 g_atomic_int_set (&processing_prohibited, 1);
3962 /* call tree *MUST* hold route_lock */
3964 if ((playlist = track.diskstream()->playlist()) == 0) {
3968 /* external redirects will be a problem */
3970 if (track.has_external_redirects()) {
3974 nchans = track.audio_diskstream()->n_channels();
3976 dir = discover_best_sound_dir ();
3978 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3980 for (x = 0; x < 99999; ++x) {
3981 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3982 if (access (buf, F_OK) != 0) {
3988 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3993 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3996 catch (failed_constructor& err) {
3997 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4001 srcs.push_back (fsource);
4004 /* XXX need to flush all redirects */
4009 /* create a set of reasonably-sized buffers */
4011 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4013 #ifdef NO_POSIX_MEMALIGN
4014 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4016 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4018 buffers.push_back (b);
4021 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4022 (*src)->prepare_for_peakfile_writes ();
4025 while (to_do && !itt.cancel) {
4027 this_chunk = min (to_do, chunk_size);
4029 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
4034 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4035 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4038 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4044 start += this_chunk;
4045 to_do -= this_chunk;
4047 itt.progress = (float) (1.0 - ((double) to_do / len));
4056 xnow = localtime (&now);
4058 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4059 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4062 afs->update_header (position, *xnow, now);
4063 afs->flush_header ();
4067 /* construct a region to represent the bounced material */
4069 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4070 region_name_from_path (srcs.front()->name(), true));
4077 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4078 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4081 afs->mark_for_remove ();
4084 (*src)->drop_references ();
4088 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4089 (*src)->done_with_peakfile_writes ();
4093 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4097 g_atomic_int_set (&processing_prohibited, 0);
4105 Session::get_silent_buffers (uint32_t howmany)
4107 if (howmany > _silent_buffers.size()) {
4109 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4110 howmany, _silent_buffers.size()) << endmsg;
4112 if (howmany > 1000) {
4113 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4117 while (howmany > _silent_buffers.size()) {
4120 #ifdef NO_POSIX_MEMALIGN
4121 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4123 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4) != 0) {
4124 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4125 current_block_size, sizeof (Sample), strerror (errno))
4130 _silent_buffers.push_back (p);
4134 for (uint32_t i = 0; i < howmany; ++i) {
4135 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4138 return _silent_buffers;
4142 Session::ntracks () const
4145 shared_ptr<RouteList> r = routes.reader ();
4147 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4148 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4157 Session::nbusses () const
4160 shared_ptr<RouteList> r = routes.reader ();
4162 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4163 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4172 Session::add_automation_list(AutomationList *al)
4174 automation_lists[al->id()] = al;
4178 Session::compute_initial_length ()
4180 return _engine.frame_rate() * 60 * 5;
4184 Session::sync_order_keys ()
4186 if (!Config->get_sync_all_route_ordering()) {
4187 /* leave order keys as they are */
4191 boost::shared_ptr<RouteList> r = routes.reader ();
4193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4194 (*i)->sync_order_keys ();
4197 Route::SyncOrderKeys (); // EMIT SIGNAL