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<int> Session::AskAboutPendingState;
109 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
110 sigc::signal<void> Session::SendFeedback;
112 sigc::signal<void> Session::SMPTEOffsetChanged;
113 sigc::signal<void> Session::StartTimeChanged;
114 sigc::signal<void> Session::EndTimeChanged;
117 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
120 char buf[PATH_MAX+1];
124 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
125 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
131 /* check to see if it exists, and what it is */
133 if (stat (str.c_str(), &statbuf)) {
134 if (errno == ENOENT) {
137 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
145 /* it exists, so it must either be the name
146 of the directory, or the name of the statefile
150 if (S_ISDIR (statbuf.st_mode)) {
152 string::size_type slash = str.find_last_of ('/');
154 if (slash == string::npos) {
156 /* a subdirectory of cwd, so statefile should be ... */
162 tmp += _statefile_suffix;
166 if (stat (tmp.c_str(), &statbuf)) {
167 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
177 /* some directory someplace in the filesystem.
178 the snapshot name is the directory name
183 snapshot = str.substr (slash+1);
187 } else if (S_ISREG (statbuf.st_mode)) {
189 string::size_type slash = str.find_last_of ('/');
190 string::size_type suffix;
192 /* remove the suffix */
194 if (slash != string::npos) {
195 snapshot = str.substr (slash+1);
200 suffix = snapshot.find (_statefile_suffix);
202 if (suffix == string::npos) {
203 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
209 snapshot = snapshot.substr (0, suffix);
211 if (slash == string::npos) {
213 /* we must be in the directory where the
214 statefile lives. get it using cwd().
217 char cwd[PATH_MAX+1];
219 if (getcwd (cwd, sizeof (cwd)) == 0) {
220 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
229 /* full path to the statefile */
231 path = str.substr (0, slash);
236 /* what type of file is it? */
237 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
243 /* its the name of a new directory. get the name
247 string::size_type slash = str.find_last_of ('/');
249 if (slash == string::npos) {
251 /* no slash, just use the name, but clean it up */
253 path = legalize_for_path (str);
259 snapshot = str.substr (slash+1);
266 Session::Session (AudioEngine &eng,
267 const string& fullpath,
268 const string& snapshot_name,
272 _mmc_port (default_mmc_port),
273 _mtc_port (default_mtc_port),
274 _midi_port (default_midi_port),
275 pending_events (2048),
276 midi_requests (128), // the size of this should match the midi request pool size
277 diskstreams (new DiskstreamList),
278 routes (new RouteList),
279 auditioner ((Auditioner*) 0),
285 if (!eng.connected()) {
286 throw failed_constructor();
289 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
291 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
292 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
294 first_stage_init (fullpath, snapshot_name);
296 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
299 if (create (new_session, mix_template, compute_initial_length())) {
301 throw failed_constructor ();
305 if (second_stage_init (new_session)) {
307 throw failed_constructor ();
310 store_recent_sessions(_name, _path);
312 bool was_dirty = dirty();
314 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
316 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
319 DirtyChanged (); /* EMIT SIGNAL */
323 Session::Session (AudioEngine &eng,
325 string snapshot_name,
326 AutoConnectOption input_ac,
327 AutoConnectOption output_ac,
328 uint32_t control_out_channels,
329 uint32_t master_out_channels,
330 uint32_t requested_physical_in,
331 uint32_t requested_physical_out,
332 nframes_t initial_length)
335 _mmc_port (default_mmc_port),
336 _mtc_port (default_mtc_port),
337 _midi_port (default_midi_port),
338 pending_events (2048),
340 diskstreams (new DiskstreamList),
341 routes (new RouteList),
347 if (!eng.connected()) {
348 throw failed_constructor();
351 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
353 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
354 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
356 if (n_physical_audio_inputs) {
357 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
360 if (n_physical_audio_outputs) {
361 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
364 first_stage_init (fullpath, snapshot_name);
366 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
369 if (create (new_session, string(), initial_length)) {
371 throw failed_constructor ();
376 /* set up Master Out and Control Out if necessary */
381 if (control_out_channels) {
382 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
383 r->set_remote_control_id (control_id++);
388 if (master_out_channels) {
389 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
390 r->set_remote_control_id (control_id);
394 /* prohibit auto-connect to master, because there isn't one */
395 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
399 add_routes (rl, false);
404 Config->set_input_auto_connect (input_ac);
405 Config->set_output_auto_connect (output_ac);
407 if (second_stage_init (new_session)) {
409 throw failed_constructor ();
412 store_recent_sessions (_name, _path);
414 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
417 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
428 /* if we got to here, leaving pending capture state around
432 remove_pending_capture_state ();
434 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
436 _engine.remove_session ();
438 GoingAway (); /* EMIT SIGNAL */
444 /* clear history so that no references to objects are held any more */
448 /* clear state tree so that no references to objects are held any more */
454 terminate_butler_thread ();
455 terminate_midi_thread ();
457 if (click_data && click_data != default_click) {
458 delete [] click_data;
461 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
462 delete [] click_emphasis_data;
467 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
471 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
475 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
479 AudioDiskstream::free_working_buffers();
481 /* this should cause deletion of the auditioner */
483 // auditioner.reset ();
485 #undef TRACK_DESTRUCTION
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete named selections\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
490 NamedSelectionList::iterator tmp;
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete playlists\n";
501 #endif /* TRACK_DESTRUCTION */
502 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
503 PlaylistList::iterator tmp;
508 (*i)->drop_references ();
513 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
514 PlaylistList::iterator tmp;
519 (*i)->drop_references ();
525 unused_playlists.clear ();
527 #ifdef TRACK_DESTRUCTION
528 cerr << "delete audio regions\n";
529 #endif /* TRACK_DESTRUCTION */
531 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
532 AudioRegionList::iterator tmp;
537 i->second->drop_references ();
542 audio_regions.clear ();
544 #ifdef TRACK_DESTRUCTION
545 cerr << "delete routes\n";
546 #endif /* TRACK_DESTRUCTION */
548 RCUWriter<RouteList> writer (routes);
549 boost::shared_ptr<RouteList> r = writer.get_copy ();
550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
551 (*i)->drop_references ();
554 /* writer goes out of scope and updates master */
559 #ifdef TRACK_DESTRUCTION
560 cerr << "delete diskstreams\n";
561 #endif /* TRACK_DESTRUCTION */
563 RCUWriter<DiskstreamList> dwriter (diskstreams);
564 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
565 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
566 (*i)->drop_references ();
570 diskstreams.flush ();
572 #ifdef TRACK_DESTRUCTION
573 cerr << "delete audio sources\n";
574 #endif /* TRACK_DESTRUCTION */
575 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
576 AudioSourceList::iterator tmp;
581 cerr << "Drop refs to " << i->second->name() << endl;
583 i->second->drop_references ();
590 cerr << "clear audio sources\n";
591 audio_sources.clear ();
593 #ifdef TRACK_DESTRUCTION
594 cerr << "delete mix groups\n";
595 #endif /* TRACK_DESTRUCTION */
596 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
597 list<RouteGroup*>::iterator tmp;
607 #ifdef TRACK_DESTRUCTION
608 cerr << "delete edit groups\n";
609 #endif /* TRACK_DESTRUCTION */
610 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
611 list<RouteGroup*>::iterator tmp;
621 #ifdef TRACK_DESTRUCTION
622 cerr << "delete connections\n";
623 #endif /* TRACK_DESTRUCTION */
624 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
625 ConnectionList::iterator tmp;
635 if (butler_mixdown_buffer) {
636 delete [] butler_mixdown_buffer;
639 if (butler_gain_buffer) {
640 delete [] butler_gain_buffer;
643 Crossfade::set_buffer_size (0);
651 Session::set_worst_io_latencies ()
653 _worst_output_latency = 0;
654 _worst_input_latency = 0;
656 if (!_engine.connected()) {
660 boost::shared_ptr<RouteList> r = routes.reader ();
662 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
663 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
664 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
669 Session::when_engine_running ()
671 string first_physical_output;
673 /* we don't want to run execute this again */
675 BootMessage (_("Set block size and sample rate"));
677 set_block_size (_engine.frames_per_cycle());
678 set_frame_rate (_engine.frame_rate());
680 BootMessage (_("Using configuration"));
682 Config->map_parameters (mem_fun (*this, &Session::config_changed));
684 /* every time we reconnect, recompute worst case output latencies */
686 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
688 if (synced_to_jack()) {
689 _engine.transport_stop ();
692 if (Config->get_jack_time_master()) {
693 _engine.transport_locate (_transport_frame);
701 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
703 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
705 /* existing state for Click */
707 if (_click_io->set_state (*child->children().front()) == 0) {
709 _clicking = Config->get_clicking ();
713 error << _("could not setup Click I/O") << endmsg;
719 /* default state for Click */
721 first_physical_output = _engine.get_nth_physical_audio_output (0);
723 if (first_physical_output.length()) {
724 if (_click_io->add_output_port (first_physical_output, this)) {
725 // relax, even though its an error
727 _clicking = Config->get_clicking ();
733 catch (failed_constructor& err) {
734 error << _("cannot setup Click I/O") << endmsg;
737 BootMessage (_("Compute I/O Latencies"));
739 set_worst_io_latencies ();
742 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
745 /* Create a set of Connection objects that map
746 to the physical outputs currently available
749 BootMessage (_("Set up standard connections"));
753 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
755 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
757 Connection* c = new OutputConnection (buf, true);
760 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
765 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
767 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
769 Connection* c = new InputConnection (buf, true);
772 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
779 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
781 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
783 Connection* c = new OutputConnection (buf, true);
787 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
788 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
793 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
795 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
797 Connection* c = new InputConnection (buf, true);
801 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
802 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
811 /* create master/control ports */
816 /* force the master to ignore any later call to this */
818 if (_master_out->pending_state_node) {
819 _master_out->ports_became_legal();
822 /* no panner resets till we are through */
824 _master_out->defer_pan_reset ();
826 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
827 if (_master_out->add_input_port ("", this)) {
828 error << _("cannot setup master inputs")
834 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
835 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
836 error << _("cannot setup master outputs")
843 _master_out->allow_pan_reset ();
847 Connection* c = new OutputConnection (_("Master Out"), true);
849 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
851 c->add_connection ((int) n, _master_out->input(n)->name());
856 BootMessage (_("Setup signal flow and plugins"));
860 /* catch up on send+insert cnts */
862 BootMessage (_("Catch up with send/insert state"));
866 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
869 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
870 if (id > insert_cnt) {
878 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
881 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
889 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
891 /* hook us up to the engine */
893 BootMessage (_("Connect to engine"));
895 _engine.set_session (this);
900 BootMessage (_("OSC startup"));
902 osc->set_session (*this);
908 Session::hookup_io ()
910 /* stop graph reordering notifications from
911 causing resorts, etc.
914 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
917 if (auditioner == 0) {
919 /* we delay creating the auditioner till now because
920 it makes its own connections to ports.
921 the engine has to be running for this to work.
925 auditioner.reset (new Auditioner (*this));
928 catch (failed_constructor& err) {
929 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
933 /* Tell all IO objects to create their ports */
939 vector<string> cports;
941 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
942 if (_control_out->add_input_port ("", this)) {
943 error << _("cannot setup control inputs")
949 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
950 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
951 error << _("cannot set up master outputs")
959 uint32_t ni = _control_out->n_inputs();
961 for (n = 0; n < ni; ++n) {
962 cports.push_back (_control_out->input(n)->name());
965 boost::shared_ptr<RouteList> r = routes.reader ();
967 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
968 (*x)->set_control_outs (cports);
972 /* Tell all IO objects to connect themselves together */
974 IO::enable_connecting ();
976 /* Now reset all panners */
978 IO::reset_panners ();
980 /* Anyone who cares about input state, wake up and do something */
982 IOConnectionsComplete (); /* EMIT SIGNAL */
984 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
987 /* now handle the whole enchilada as if it was one
993 /* update mixer solo state */
999 Session::playlist_length_changed ()
1001 /* we can't just increase end_location->end() if pl->get_maximum_extent()
1002 if larger. if the playlist used to be the longest playlist,
1003 and its now shorter, we have to decrease end_location->end(). hence,
1004 we have to iterate over all diskstreams and check the
1005 playlists currently in use.
1007 find_current_end ();
1011 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1013 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1020 boost::shared_ptr<Playlist> playlist;
1022 if ((playlist = dstream->playlist()) != 0) {
1023 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1026 /* see comment in playlist_length_changed () */
1027 find_current_end ();
1031 Session::record_enabling_legal () const
1033 /* this used to be in here, but survey says.... we don't need to restrict it */
1034 // if (record_status() == Recording) {
1038 if (Config->get_all_safe()) {
1045 Session::reset_input_monitor_state ()
1047 if (transport_rolling()) {
1049 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1051 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1052 if ((*i)->record_enabled ()) {
1053 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1054 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1058 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1060 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1061 if ((*i)->record_enabled ()) {
1062 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1063 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1070 Session::auto_punch_start_changed (Location* location)
1072 replace_event (Event::PunchIn, location->start());
1074 if (get_record_enabled() && Config->get_punch_in()) {
1075 /* capture start has been changed, so save new pending state */
1076 save_state ("", true);
1081 Session::auto_punch_end_changed (Location* location)
1083 nframes_t when_to_stop = location->end();
1084 // when_to_stop += _worst_output_latency + _worst_input_latency;
1085 replace_event (Event::PunchOut, when_to_stop);
1089 Session::auto_punch_changed (Location* location)
1091 nframes_t when_to_stop = location->end();
1093 replace_event (Event::PunchIn, location->start());
1094 //when_to_stop += _worst_output_latency + _worst_input_latency;
1095 replace_event (Event::PunchOut, when_to_stop);
1099 Session::auto_loop_changed (Location* location)
1101 replace_event (Event::AutoLoop, location->end(), location->start());
1103 if (transport_rolling() && play_loop) {
1105 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1107 if (_transport_frame > location->end()) {
1108 // relocate to beginning of loop
1109 clear_events (Event::LocateRoll);
1111 request_locate (location->start(), true);
1114 else if (Config->get_seamless_loop() && !loop_changing) {
1116 // schedule a locate-roll to refill the diskstreams at the
1117 // previous loop end
1118 loop_changing = true;
1120 if (location->end() > last_loopend) {
1121 clear_events (Event::LocateRoll);
1122 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1129 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);
1168 auto_punch_location_changed (location);
1172 Session::set_auto_loop_location (Location* location)
1176 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1177 auto_loop_start_changed_connection.disconnect();
1178 auto_loop_end_changed_connection.disconnect();
1179 auto_loop_changed_connection.disconnect();
1180 existing->set_auto_loop (false, this);
1181 remove_event (existing->end(), Event::AutoLoop);
1182 auto_loop_location_changed (0);
1187 if (location == 0) {
1191 if (location->end() <= location->start()) {
1192 error << _("Session: you can't use a mark for auto loop") << endmsg;
1196 last_loopend = location->end();
1198 auto_loop_start_changed_connection.disconnect();
1199 auto_loop_end_changed_connection.disconnect();
1200 auto_loop_changed_connection.disconnect();
1202 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1203 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1204 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1206 location->set_auto_loop (true, this);
1207 auto_loop_location_changed (location);
1211 Session::locations_added (Location* ignored)
1217 Session::locations_changed ()
1219 _locations.apply (*this, &Session::handle_locations_changed);
1223 Session::handle_locations_changed (Locations::LocationList& locations)
1225 Locations::LocationList::iterator i;
1227 bool set_loop = false;
1228 bool set_punch = false;
1230 for (i = locations.begin(); i != locations.end(); ++i) {
1234 if (location->is_auto_punch()) {
1235 set_auto_punch_location (location);
1238 if (location->is_auto_loop()) {
1239 set_auto_loop_location (location);
1246 set_auto_loop_location (0);
1249 set_auto_punch_location (0);
1256 Session::enable_record ()
1258 /* XXX really atomic compare+swap here */
1259 if (g_atomic_int_get (&_record_status) != Recording) {
1260 g_atomic_int_set (&_record_status, Recording);
1261 _last_record_location = _transport_frame;
1262 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1264 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1265 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1266 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1267 if ((*i)->record_enabled ()) {
1268 (*i)->monitor_input (true);
1273 RecordStateChanged ();
1278 Session::disable_record (bool rt_context, bool force)
1282 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1284 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1285 g_atomic_int_set (&_record_status, Disabled);
1287 if (rs == Recording) {
1288 g_atomic_int_set (&_record_status, Enabled);
1292 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1294 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1295 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1297 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1298 if ((*i)->record_enabled ()) {
1299 (*i)->monitor_input (false);
1304 RecordStateChanged (); /* emit signal */
1307 remove_pending_capture_state ();
1313 Session::step_back_from_record ()
1315 /* XXX really atomic compare+swap here */
1316 if (g_atomic_int_get (&_record_status) == Recording) {
1317 g_atomic_int_set (&_record_status, Enabled);
1319 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1320 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1322 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1323 if ((*i)->record_enabled ()) {
1324 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1325 (*i)->monitor_input (false);
1333 Session::maybe_enable_record ()
1335 g_atomic_int_set (&_record_status, Enabled);
1337 /* this function is currently called from somewhere other than an RT thread.
1338 this save_state() call therefore doesn't impact anything.
1341 save_state ("", true);
1343 if (_transport_speed) {
1344 if (!Config->get_punch_in()) {
1348 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1349 RecordStateChanged (); /* EMIT SIGNAL */
1356 Session::audible_frame () const
1362 /* the first of these two possible settings for "offset"
1363 mean that the audible frame is stationary until
1364 audio emerges from the latency compensation
1367 the second means that the audible frame is stationary
1368 until audio would emerge from a physical port
1369 in the absence of any plugin latency compensation
1372 offset = _worst_output_latency;
1374 if (offset > current_block_size) {
1375 offset -= current_block_size;
1377 /* XXX is this correct? if we have no external
1378 physical connections and everything is internal
1379 then surely this is zero? still, how
1380 likely is that anyway?
1382 offset = current_block_size;
1385 if (synced_to_jack()) {
1386 tf = _engine.transport_frame();
1388 tf = _transport_frame;
1391 if (_transport_speed == 0) {
1401 if (!non_realtime_work_pending()) {
1405 /* take latency into account */
1414 Session::set_frame_rate (nframes_t frames_per_second)
1416 /** \fn void Session::set_frame_size(nframes_t)
1417 the AudioEngine object that calls this guarantees
1418 that it will not be called while we are also in
1419 ::process(). Its fine to do things that block
1423 _base_frame_rate = frames_per_second;
1427 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1431 // XXX we need some equivalent to this, somehow
1432 // SndFileSource::setup_standard_crossfades (frames_per_second);
1436 /* XXX need to reset/reinstantiate all LADSPA plugins */
1440 Session::set_block_size (nframes_t nframes)
1442 /* the AudioEngine guarantees
1443 that it will not be called while we are also in
1444 ::process(). It is therefore fine to do things that block
1449 vector<Sample*>::iterator i;
1452 current_block_size = nframes;
1454 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1458 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1462 _passthru_buffers.clear ();
1463 _silent_buffers.clear ();
1465 ensure_passthru_buffers (np);
1467 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1471 #ifdef NO_POSIX_MEMALIGN
1472 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1474 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1478 memset (*i, 0, sizeof (Sample) * current_block_size);
1482 if (_gain_automation_buffer) {
1483 delete [] _gain_automation_buffer;
1485 _gain_automation_buffer = new gain_t[nframes];
1487 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1489 boost::shared_ptr<RouteList> r = routes.reader ();
1491 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1492 (*i)->set_block_size (nframes);
1495 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1496 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1497 (*i)->set_block_size (nframes);
1500 set_worst_io_latencies ();
1505 Session::set_default_fade (float steepness, float fade_msecs)
1508 nframes_t fade_frames;
1510 /* Don't allow fade of less 1 frame */
1512 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1519 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1523 default_fade_msecs = fade_msecs;
1524 default_fade_steepness = steepness;
1527 // jlc, WTF is this!
1528 Glib::RWLock::ReaderLock lm (route_lock);
1529 AudioRegion::set_default_fade (steepness, fade_frames);
1534 /* XXX have to do this at some point */
1535 /* foreach region using default fade, reset, then
1536 refill_all_diskstream_buffers ();
1541 struct RouteSorter {
1542 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1543 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1545 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1548 if (r1->fed_by.empty()) {
1549 if (r2->fed_by.empty()) {
1550 /* no ardour-based connections inbound to either route. just use signal order */
1551 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1553 /* r2 has connections, r1 does not; run r1 early */
1557 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1564 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1566 shared_ptr<Route> r2;
1568 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1569 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1573 /* make a copy of the existing list of routes that feed r1 */
1575 set<shared_ptr<Route> > existing = r1->fed_by;
1577 /* for each route that feeds r1, recurse, marking it as feeding
1581 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1584 /* r2 is a route that feeds r1 which somehow feeds base. mark
1585 base as being fed by r2
1588 rbase->fed_by.insert (r2);
1592 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1596 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1600 /* now recurse, so that we can mark base as being fed by
1601 all routes that feed r2
1604 trace_terminal (r2, rbase);
1611 Session::resort_routes ()
1613 /* don't do anything here with signals emitted
1614 by Routes while we are being destroyed.
1617 if (_state_of_the_state & Deletion) {
1624 RCUWriter<RouteList> writer (routes);
1625 shared_ptr<RouteList> r = writer.get_copy ();
1626 resort_routes_using (r);
1627 /* writer goes out of scope and forces update */
1632 Session::resort_routes_using (shared_ptr<RouteList> r)
1634 RouteList::iterator i, j;
1636 for (i = r->begin(); i != r->end(); ++i) {
1638 (*i)->fed_by.clear ();
1640 for (j = r->begin(); j != r->end(); ++j) {
1642 /* although routes can feed themselves, it will
1643 cause an endless recursive descent if we
1644 detect it. so don't bother checking for
1652 if ((*j)->feeds (*i)) {
1653 (*i)->fed_by.insert (*j);
1658 for (i = r->begin(); i != r->end(); ++i) {
1659 trace_terminal (*i, *i);
1665 /* don't leave dangling references to routes in Route::fed_by */
1667 for (i = r->begin(); i != r->end(); ++i) {
1668 (*i)->fed_by.clear ();
1672 cerr << "finished route resort\n";
1674 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1675 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1682 list<boost::shared_ptr<AudioTrack> >
1683 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1685 char track_name[32];
1686 uint32_t track_id = 0;
1688 uint32_t channels_used = 0;
1690 RouteList new_routes;
1691 list<boost::shared_ptr<AudioTrack> > ret;
1692 uint32_t control_id;
1694 /* count existing audio tracks */
1697 shared_ptr<RouteList> r = routes.reader ();
1699 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1700 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1701 if (!(*i)->hidden()) {
1703 channels_used += (*i)->n_inputs();
1709 vector<string> physinputs;
1710 vector<string> physoutputs;
1711 uint32_t nphysical_in;
1712 uint32_t nphysical_out;
1714 _engine.get_physical_audio_outputs (physoutputs);
1715 _engine.get_physical_audio_inputs (physinputs);
1716 control_id = ntracks() + nbusses() + 1;
1720 /* check for duplicate route names, since we might have pre-existing
1721 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1722 save, close,restart,add new route - first named route is now
1730 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1732 if (route_by_name (track_name) == 0) {
1736 } while (track_id < (UINT_MAX-1));
1738 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1739 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1744 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1745 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1750 shared_ptr<AudioTrack> track;
1753 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1755 if (track->ensure_io (input_channels, output_channels, false, this)) {
1756 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1757 input_channels, output_channels)
1763 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1767 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1768 port = physinputs[(channels_used+x)%nphysical_in];
1771 if (port.length() && track->connect_input (track->input (x), port, this)) {
1777 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1781 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1782 port = physoutputs[(channels_used+x)%nphysical_out];
1783 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1785 port = _master_out->input (x%_master_out->n_inputs())->name();
1789 if (port.length() && track->connect_output (track->output (x), port, this)) {
1794 channels_used += track->n_inputs ();
1796 track->audio_diskstream()->non_realtime_input_change();
1798 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1799 track->set_remote_control_id (control_id);
1802 new_routes.push_back (track);
1803 ret.push_back (track);
1807 catch (failed_constructor &err) {
1808 error << _("Session: could not create new audio track.") << endmsg;
1811 /* we need to get rid of this, since the track failed to be created */
1812 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1815 RCUWriter<DiskstreamList> writer (diskstreams);
1816 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1817 ds->remove (track->audio_diskstream());
1824 catch (AudioEngine::PortRegistrationFailure& pfe) {
1826 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;
1829 /* we need to get rid of this, since the track failed to be created */
1830 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1833 RCUWriter<DiskstreamList> writer (diskstreams);
1834 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1835 ds->remove (track->audio_diskstream());
1846 if (!new_routes.empty()) {
1847 add_routes (new_routes, true);
1854 Session::set_remote_control_ids ()
1856 RemoteModel m = Config->get_remote_model();
1858 shared_ptr<RouteList> r = routes.reader ();
1860 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1861 if ( MixerOrdered == m) {
1862 long order = (*i)->order_key(N_("signal"));
1863 (*i)->set_remote_control_id( order+1 );
1864 } else if ( EditorOrdered == m) {
1865 long order = (*i)->order_key(N_("editor"));
1866 (*i)->set_remote_control_id( order+1 );
1867 } else if ( UserOrdered == m) {
1868 //do nothing ... only changes to remote id's are initiated by user
1875 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1878 uint32_t bus_id = 1;
1882 uint32_t control_id;
1884 /* count existing audio busses */
1887 shared_ptr<RouteList> r = routes.reader ();
1889 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1890 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1891 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1898 vector<string> physinputs;
1899 vector<string> physoutputs;
1901 _engine.get_physical_audio_outputs (physoutputs);
1902 _engine.get_physical_audio_inputs (physinputs);
1903 control_id = ntracks() + nbusses() + 1;
1908 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1912 if (route_by_name (bus_name) == 0) {
1916 } while (bus_id < (UINT_MAX-1));
1919 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1921 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1922 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1923 input_channels, output_channels)
1928 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1932 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1933 port = physinputs[((n+x)%n_physical_audio_inputs)];
1936 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1941 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1945 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1946 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1947 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1949 port = _master_out->input (x%_master_out->n_inputs())->name();
1953 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1958 bus->set_remote_control_id (control_id);
1961 ret.push_back (bus);
1965 catch (failed_constructor &err) {
1966 error << _("Session: could not create new audio route.") << endmsg;
1970 catch (AudioEngine::PortRegistrationFailure& pfe) {
1971 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;
1981 add_routes (ret, true);
1989 Session::add_routes (RouteList& new_routes, bool save)
1992 RCUWriter<RouteList> writer (routes);
1993 shared_ptr<RouteList> r = writer.get_copy ();
1994 r->insert (r->end(), new_routes.begin(), new_routes.end());
1995 resort_routes_using (r);
1998 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2000 boost::weak_ptr<Route> wpr (*x);
2002 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2003 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2004 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2005 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2007 if ((*x)->master()) {
2011 if ((*x)->control()) {
2012 _control_out = (*x);
2016 if (_control_out && IO::connecting_legal) {
2018 vector<string> cports;
2019 uint32_t ni = _control_out->n_inputs();
2022 for (n = 0; n < ni; ++n) {
2023 cports.push_back (_control_out->input(n)->name());
2026 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2027 (*x)->set_control_outs (cports);
2034 save_state (_current_snapshot_name);
2037 RouteAdded (new_routes); /* EMIT SIGNAL */
2041 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2043 /* need to do this in case we're rolling at the time, to prevent false underruns */
2044 dstream->do_refill_with_alloc ();
2046 dstream->set_block_size (current_block_size);
2049 RCUWriter<DiskstreamList> writer (diskstreams);
2050 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2051 ds->push_back (dstream);
2052 /* writer goes out of scope, copies ds back to main */
2055 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2056 boost::weak_ptr<Diskstream> (dstream)));
2057 /* this will connect to future changes, and check the current length */
2058 diskstream_playlist_changed (dstream);
2060 dstream->prepare ();
2064 Session::remove_route (shared_ptr<Route> route)
2067 RCUWriter<RouteList> writer (routes);
2068 shared_ptr<RouteList> rs = writer.get_copy ();
2072 /* deleting the master out seems like a dumb
2073 idea, but its more of a UI policy issue
2077 if (route == _master_out) {
2078 _master_out = shared_ptr<Route> ();
2081 if (route == _control_out) {
2082 _control_out = shared_ptr<Route> ();
2084 /* cancel control outs for all routes */
2086 vector<string> empty;
2088 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2089 (*r)->set_control_outs (empty);
2093 update_route_solo_state ();
2095 /* writer goes out of scope, forces route list update */
2098 // FIXME: audio specific
2100 boost::shared_ptr<AudioDiskstream> ds;
2102 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2103 ds = at->audio_diskstream();
2109 RCUWriter<DiskstreamList> dsl (diskstreams);
2110 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2114 diskstreams.flush ();
2117 find_current_end ();
2119 // We need to disconnect the routes inputs and outputs
2121 route->disconnect_inputs (0);
2122 route->disconnect_outputs (0);
2124 update_latency_compensation (false, false);
2127 /* get rid of it from the dead wood collection in the route list manager */
2129 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2133 /* try to cause everyone to drop their references */
2135 route->drop_references ();
2137 /* save the new state of the world */
2139 if (save_state (_current_snapshot_name)) {
2140 save_history (_current_snapshot_name);
2145 Session::route_mute_changed (void* src)
2151 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2153 if (solo_update_disabled) {
2159 boost::shared_ptr<Route> route = wpr.lock ();
2162 /* should not happen */
2163 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2167 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2169 shared_ptr<RouteList> r = routes.reader ();
2171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2173 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2177 /* don't mess with busses */
2179 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2185 /* don't mess with tracks */
2187 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2192 if ((*i) != route &&
2193 ((*i)->mix_group () == 0 ||
2194 (*i)->mix_group () != route->mix_group () ||
2195 !route->mix_group ()->is_active())) {
2197 if ((*i)->soloed()) {
2199 /* if its already soloed, and solo latching is enabled,
2200 then leave it as it is.
2203 if (Config->get_solo_latched()) {
2210 solo_update_disabled = true;
2211 (*i)->set_solo (false, src);
2212 solo_update_disabled = false;
2216 bool something_soloed = false;
2217 bool same_thing_soloed = false;
2218 bool signal = false;
2220 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2221 if ((*i)->soloed()) {
2222 something_soloed = true;
2223 if (dynamic_cast<AudioTrack*>((*i).get())) {
2225 same_thing_soloed = true;
2230 same_thing_soloed = true;
2238 if (something_soloed != currently_soloing) {
2240 currently_soloing = something_soloed;
2243 modify_solo_mute (is_track, same_thing_soloed);
2246 SoloActive (currently_soloing); /* EMIT SIGNAL */
2249 SoloChanged (); /* EMIT SIGNAL */
2255 Session::update_route_solo_state ()
2258 bool is_track = false;
2259 bool signal = false;
2261 /* caller must hold RouteLock */
2263 /* this is where we actually implement solo by changing
2264 the solo mute setting of each track.
2267 shared_ptr<RouteList> r = routes.reader ();
2269 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2270 if ((*i)->soloed()) {
2272 if (dynamic_cast<AudioTrack*>((*i).get())) {
2279 if (mute != currently_soloing) {
2281 currently_soloing = mute;
2284 if (!is_track && !mute) {
2286 /* nothing is soloed */
2288 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 (*i)->set_solo_mute (false);
2299 modify_solo_mute (is_track, mute);
2302 SoloActive (currently_soloing);
2307 Session::modify_solo_mute (bool is_track, bool mute)
2309 shared_ptr<RouteList> r = routes.reader ();
2311 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2315 /* only alter track solo mute */
2317 if (dynamic_cast<AudioTrack*>((*i).get())) {
2318 if ((*i)->soloed()) {
2319 (*i)->set_solo_mute (!mute);
2321 (*i)->set_solo_mute (mute);
2327 /* only alter bus solo mute */
2329 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2331 if ((*i)->soloed()) {
2333 (*i)->set_solo_mute (false);
2337 /* don't mute master or control outs
2338 in response to another bus solo
2341 if ((*i) != _master_out &&
2342 (*i) != _control_out) {
2343 (*i)->set_solo_mute (mute);
2354 Session::catch_up_on_solo ()
2356 /* this is called after set_state() to catch the full solo
2357 state, which can't be correctly determined on a per-route
2358 basis, but needs the global overview that only the session
2361 update_route_solo_state();
2365 Session::route_by_name (string name)
2367 shared_ptr<RouteList> r = routes.reader ();
2369 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2370 if ((*i)->name() == name) {
2375 return shared_ptr<Route> ((Route*) 0);
2379 Session::route_by_id (PBD::ID id)
2381 shared_ptr<RouteList> r = routes.reader ();
2383 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2384 if ((*i)->id() == id) {
2389 return shared_ptr<Route> ((Route*) 0);
2393 Session::route_by_remote_id (uint32_t id)
2395 shared_ptr<RouteList> r = routes.reader ();
2397 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2398 if ((*i)->remote_control_id() == id) {
2403 return shared_ptr<Route> ((Route*) 0);
2407 Session::find_current_end ()
2409 if (_state_of_the_state & Loading) {
2413 nframes_t max = get_maximum_extent ();
2415 if (max > end_location->end()) {
2416 end_location->set_end (max);
2418 DurationChanged(); /* EMIT SIGNAL */
2423 Session::get_maximum_extent () const
2428 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2430 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2431 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2432 if ((me = pl->get_maximum_extent()) > max) {
2440 boost::shared_ptr<Diskstream>
2441 Session::diskstream_by_name (string name)
2443 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2445 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2446 if ((*i)->name() == name) {
2451 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2454 boost::shared_ptr<Diskstream>
2455 Session::diskstream_by_id (const PBD::ID& id)
2457 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2459 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2460 if ((*i)->id() == id) {
2465 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2468 /* AudioRegion management */
2471 Session::new_region_name (string old)
2473 string::size_type last_period;
2475 string::size_type len = old.length() + 64;
2478 if ((last_period = old.find_last_of ('.')) == string::npos) {
2480 /* no period present - add one explicitly */
2483 last_period = old.length() - 1;
2488 number = atoi (old.substr (last_period+1).c_str());
2492 while (number < (UINT_MAX-1)) {
2494 AudioRegionList::const_iterator i;
2499 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2502 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2503 if (i->second->name() == sbuf) {
2508 if (i == audio_regions.end()) {
2513 if (number != (UINT_MAX-1)) {
2517 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2522 Session::region_name (string& result, string base, bool newlevel) const
2529 Glib::Mutex::Lock lm (region_lock);
2531 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2539 /* XXX this is going to be slow. optimize me later */
2544 string::size_type pos;
2546 pos = base.find_last_of ('.');
2548 /* pos may be npos, but then we just use entire base */
2550 subbase = base.substr (0, pos);
2554 bool name_taken = true;
2557 Glib::Mutex::Lock lm (region_lock);
2559 for (int n = 1; n < 5000; ++n) {
2562 snprintf (buf, sizeof (buf), ".%d", n);
2567 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2568 if (i->second->name() == result) {
2581 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2589 Session::add_region (boost::shared_ptr<Region> region)
2591 vector<boost::shared_ptr<Region> > v;
2592 v.push_back (region);
2597 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2599 boost::shared_ptr<AudioRegion> ar;
2600 boost::shared_ptr<AudioRegion> oar;
2604 Glib::Mutex::Lock lm (region_lock);
2606 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2608 boost::shared_ptr<Region> region = *ii;
2612 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2614 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2616 AudioRegionList::iterator x;
2618 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2620 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2622 if (ar->region_list_equivalent (oar)) {
2627 if (x == audio_regions.end()) {
2629 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2631 entry.first = region->id();
2634 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2646 fatal << _("programming error: ")
2647 << X_("unknown region type passed to Session::add_region()")
2655 /* mark dirty because something has changed even if we didn't
2656 add the region to the region list.
2663 vector<boost::weak_ptr<AudioRegion> > v;
2664 boost::shared_ptr<AudioRegion> first_ar;
2666 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2668 boost::shared_ptr<Region> region = *ii;
2669 boost::shared_ptr<AudioRegion> ar;
2673 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2675 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2683 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2684 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2688 AudioRegionsAdded (v); /* EMIT SIGNAL */
2694 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2696 boost::shared_ptr<Region> region (weak_region.lock ());
2702 if (what_changed & Region::HiddenChanged) {
2703 /* relay hidden changes */
2704 RegionHiddenChange (region);
2709 Session::remove_region (boost::weak_ptr<Region> weak_region)
2711 AudioRegionList::iterator i;
2712 boost::shared_ptr<Region> region (weak_region.lock ());
2718 boost::shared_ptr<AudioRegion> ar;
2719 bool removed = false;
2722 Glib::Mutex::Lock lm (region_lock);
2724 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2725 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2726 audio_regions.erase (i);
2732 fatal << _("programming error: ")
2733 << X_("unknown region type passed to Session::remove_region()")
2739 /* mark dirty because something has changed even if we didn't
2740 remove the region from the region list.
2746 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2750 boost::shared_ptr<AudioRegion>
2751 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2753 AudioRegionList::iterator i;
2754 boost::shared_ptr<AudioRegion> region;
2755 Glib::Mutex::Lock lm (region_lock);
2757 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2761 if (region->whole_file()) {
2763 if (child->source_equivalent (region)) {
2769 return boost::shared_ptr<AudioRegion> ();
2773 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2775 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2776 (*i)->get_region_list_equivalent_regions (region, result);
2780 Session::destroy_region (boost::shared_ptr<Region> region)
2782 vector<boost::shared_ptr<Source> > srcs;
2785 boost::shared_ptr<AudioRegion> aregion;
2787 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2791 if (aregion->playlist()) {
2792 aregion->playlist()->destroy_region (region);
2795 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2796 srcs.push_back (aregion->source (n));
2800 region->drop_references ();
2802 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2804 if (!(*i)->used()) {
2805 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2808 (afs)->mark_for_remove ();
2811 (*i)->drop_references ();
2813 cerr << "source was not used by any playlist\n";
2821 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2823 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2824 destroy_region (*i);
2830 Session::remove_last_capture ()
2832 list<boost::shared_ptr<Region> > r;
2834 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2836 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2837 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2840 r.insert (r.end(), l.begin(), l.end());
2845 destroy_regions (r);
2847 save_state (_current_snapshot_name);
2853 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2859 /* Source Management */
2862 Session::add_source (boost::shared_ptr<Source> source)
2864 boost::shared_ptr<AudioFileSource> afs;
2866 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2868 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2869 pair<AudioSourceList::iterator,bool> result;
2871 entry.first = source->id();
2875 Glib::Mutex::Lock lm (audio_source_lock);
2876 result = audio_sources.insert (entry);
2879 if (result.second) {
2880 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2884 if (Config->get_auto_analyse_audio()) {
2885 Analyser::queue_source_for_analysis (source, false);
2891 Session::remove_source (boost::weak_ptr<Source> src)
2893 AudioSourceList::iterator i;
2894 boost::shared_ptr<Source> source = src.lock();
2900 cerr << "remove source for " << source->name() << endl;
2903 Glib::Mutex::Lock lm (audio_source_lock);
2905 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2906 audio_sources.erase (i);
2910 if (!_state_of_the_state & InCleanup) {
2912 /* save state so we don't end up with a session file
2913 referring to non-existent sources.
2916 save_state (_current_snapshot_name);
2920 boost::shared_ptr<Source>
2921 Session::source_by_id (const PBD::ID& id)
2923 Glib::Mutex::Lock lm (audio_source_lock);
2924 AudioSourceList::iterator i;
2925 boost::shared_ptr<Source> source;
2927 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2931 /* XXX search MIDI or other searches here */
2937 boost::shared_ptr<Source>
2938 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2940 Glib::Mutex::Lock lm (audio_source_lock);
2942 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2943 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2945 if (afs && afs->path() == path && chn == afs->channel()) {
2950 return boost::shared_ptr<Source>();
2954 Session::peak_path (Glib::ustring base) const
2966 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2969 string old_basename = PBD::basename_nosuffix (oldname);
2970 string new_legalized = legalize_for_path (newname);
2972 /* note: we know (or assume) the old path is already valid */
2976 /* destructive file sources have a name of the form:
2978 /path/to/Tnnnn-NAME(%[LR])?.wav
2980 the task here is to replace NAME with the new name.
2983 /* find last slash */
2987 string::size_type slash;
2988 string::size_type dash;
2990 if ((slash = path.find_last_of ('/')) == string::npos) {
2994 dir = path.substr (0, slash+1);
2996 /* '-' is not a legal character for the NAME part of the path */
2998 if ((dash = path.find_last_of ('-')) == string::npos) {
3002 prefix = path.substr (slash+1, dash-(slash+1));
3007 path += new_legalized;
3008 path += ".wav"; /* XXX gag me with a spoon */
3012 /* non-destructive file sources have a name of the form:
3014 /path/to/NAME-nnnnn(%[LR])?.wav
3016 the task here is to replace NAME with the new name.
3021 string::size_type slash;
3022 string::size_type dash;
3023 string::size_type postfix;
3025 /* find last slash */
3027 if ((slash = path.find_last_of ('/')) == string::npos) {
3031 dir = path.substr (0, slash+1);
3033 /* '-' is not a legal character for the NAME part of the path */
3035 if ((dash = path.find_last_of ('-')) == string::npos) {
3039 suffix = path.substr (dash+1);
3041 // Suffix is now everything after the dash. Now we need to eliminate
3042 // the nnnnn part, which is done by either finding a '%' or a '.'
3044 postfix = suffix.find_last_of ("%");
3045 if (postfix == string::npos) {
3046 postfix = suffix.find_last_of ('.');
3049 if (postfix != string::npos) {
3050 suffix = suffix.substr (postfix);
3052 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3056 const uint32_t limit = 10000;
3057 char buf[PATH_MAX+1];
3059 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3061 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3063 if (access (buf, F_OK) != 0) {
3071 error << "FATAL ERROR! Could not find a " << endl;
3080 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3084 char buf[PATH_MAX+1];
3085 const uint32_t limit = 10000;
3089 legalized = legalize_for_path (name);
3091 /* find a "version" of the file name that doesn't exist in
3092 any of the possible directories.
3095 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3097 vector<space_and_path>::iterator i;
3098 uint32_t existing = 0;
3100 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3104 spath += sound_dir (false);
3108 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3109 } else if (nchan == 2) {
3111 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3113 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3115 } else if (nchan < 26) {
3116 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3118 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3127 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3128 } else if (nchan == 2) {
3130 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3132 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3134 } else if (nchan < 26) {
3135 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3137 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3141 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3147 if (existing == 0) {
3152 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3154 throw failed_constructor();
3158 /* we now have a unique name for the file, but figure out where to
3164 spath = discover_best_sound_dir ();
3167 string::size_type pos = foo.find_last_of ('/');
3169 if (pos == string::npos) {
3172 spath += foo.substr (pos + 1);
3178 boost::shared_ptr<AudioFileSource>
3179 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3181 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3182 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3185 /* Playlist management */
3187 boost::shared_ptr<Playlist>
3188 Session::playlist_by_name (string name)
3190 Glib::Mutex::Lock lm (playlist_lock);
3191 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3192 if ((*i)->name() == name) {
3196 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3197 if ((*i)->name() == name) {
3202 return boost::shared_ptr<Playlist>();
3206 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3208 if (playlist->hidden()) {
3213 Glib::Mutex::Lock lm (playlist_lock);
3214 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3215 playlists.insert (playlists.begin(), playlist);
3216 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3217 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3223 PlaylistAdded (playlist); /* EMIT SIGNAL */
3227 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3230 Glib::Mutex::Lock lm (playlist_lock);
3231 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3234 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3241 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3243 boost::shared_ptr<Playlist> pl(wpl.lock());
3249 PlaylistList::iterator x;
3252 /* its not supposed to be visible */
3257 Glib::Mutex::Lock lm (playlist_lock);
3261 unused_playlists.insert (pl);
3263 if ((x = playlists.find (pl)) != playlists.end()) {
3264 playlists.erase (x);
3270 playlists.insert (pl);
3272 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3273 unused_playlists.erase (x);
3280 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3282 if (_state_of_the_state & Deletion) {
3286 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3293 Glib::Mutex::Lock lm (playlist_lock);
3295 PlaylistList::iterator i;
3297 i = find (playlists.begin(), playlists.end(), playlist);
3298 if (i != playlists.end()) {
3299 playlists.erase (i);
3302 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3303 if (i != unused_playlists.end()) {
3304 unused_playlists.erase (i);
3311 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3315 Session::set_audition (boost::shared_ptr<Region> r)
3317 pending_audition_region = r;
3318 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3319 schedule_butler_transport_work ();
3323 Session::audition_playlist ()
3325 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3326 ev->region.reset ();
3331 Session::non_realtime_set_audition ()
3333 if (!pending_audition_region) {
3334 auditioner->audition_current_playlist ();
3336 auditioner->audition_region (pending_audition_region);
3337 pending_audition_region.reset ();
3339 AuditionActive (true); /* EMIT SIGNAL */
3343 Session::audition_region (boost::shared_ptr<Region> r)
3345 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3351 Session::cancel_audition ()
3353 if (auditioner->active()) {
3354 auditioner->cancel_audition ();
3355 AuditionActive (false); /* EMIT SIGNAL */
3360 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3362 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3366 Session::remove_empty_sounds ()
3368 PathScanner scanner;
3370 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3372 Glib::Mutex::Lock lm (audio_source_lock);
3374 regex_t compiled_tape_track_pattern;
3377 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3381 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3383 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3387 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3389 /* never remove files that appear to be a tape track */
3391 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3396 if (AudioFileSource::is_empty (*this, **i)) {
3398 unlink ((*i)->c_str());
3400 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3401 unlink (peakpath.c_str());
3407 delete possible_audiofiles;
3411 Session::is_auditioning () const
3413 /* can be called before we have an auditioner object */
3415 return auditioner->active();
3422 Session::set_all_solo (bool yn)
3424 shared_ptr<RouteList> r = routes.reader ();
3426 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3427 if (!(*i)->hidden()) {
3428 (*i)->set_solo (yn, this);
3436 Session::set_all_mute (bool yn)
3438 shared_ptr<RouteList> r = routes.reader ();
3440 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3441 if (!(*i)->hidden()) {
3442 (*i)->set_mute (yn, this);
3450 Session::n_diskstreams () const
3454 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3456 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3457 if (!(*i)->hidden()) {
3465 Session::graph_reordered ()
3467 /* don't do this stuff if we are setting up connections
3468 from a set_state() call or creating new tracks.
3471 if (_state_of_the_state & InitialConnecting) {
3475 /* every track/bus asked for this to be handled but it was deferred because
3476 we were connecting. do it now.
3479 request_input_change_handling ();
3483 /* force all diskstreams to update their capture offset values to
3484 reflect any changes in latencies within the graph.
3487 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3489 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3490 (*i)->set_capture_offset ();
3495 Session::record_disenable_all ()
3497 record_enable_change_all (false);
3501 Session::record_enable_all ()
3503 record_enable_change_all (true);
3507 Session::record_enable_change_all (bool yn)
3509 shared_ptr<RouteList> r = routes.reader ();
3511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3514 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3515 at->set_record_enable (yn, this);
3519 /* since we don't keep rec-enable state, don't mark session dirty */
3523 Session::add_redirect (Redirect* redirect)
3527 PortInsert* port_insert;
3528 PluginInsert* plugin_insert;
3530 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3531 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3532 _port_inserts.insert (_port_inserts.begin(), port_insert);
3533 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3534 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3536 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3539 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3540 _sends.insert (_sends.begin(), send);
3542 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3546 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3552 Session::remove_redirect (Redirect* redirect)
3556 PortInsert* port_insert;
3557 PluginInsert* plugin_insert;
3559 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3560 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3561 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3562 if (x != _port_inserts.end()) {
3563 insert_bitset[port_insert->bit_slot()] = false;
3564 _port_inserts.erase (x);
3566 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3567 _plugin_inserts.remove (plugin_insert);
3569 fatal << string_compose (_("programming error: %1"),
3570 X_("unknown type of Insert deleted!"))
3574 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3575 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3576 if (x != _sends.end()) {
3577 send_bitset[send->bit_slot()] = false;
3581 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3589 Session::available_capture_duration ()
3591 float sample_bytes_on_disk = 4.0; // keep gcc happy
3593 switch (Config->get_native_file_data_format()) {
3595 sample_bytes_on_disk = 4.0;
3599 sample_bytes_on_disk = 3.0;
3603 sample_bytes_on_disk = 2.0;
3607 /* impossible, but keep some gcc versions happy */
3608 fatal << string_compose (_("programming error: %1"),
3609 X_("illegal native file data format"))
3614 double scale = 4096.0 / sample_bytes_on_disk;
3616 if (_total_free_4k_blocks * scale > (double) max_frames) {
3620 return (nframes_t) floor (_total_free_4k_blocks * scale);
3624 Session::add_connection (ARDOUR::Connection* connection)
3627 Glib::Mutex::Lock guard (connection_lock);
3628 _connections.push_back (connection);
3631 ConnectionAdded (connection); /* EMIT SIGNAL */
3637 Session::remove_connection (ARDOUR::Connection* connection)
3639 bool removed = false;
3642 Glib::Mutex::Lock guard (connection_lock);
3643 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3645 if (i != _connections.end()) {
3646 _connections.erase (i);
3652 ConnectionRemoved (connection); /* EMIT SIGNAL */
3658 ARDOUR::Connection *
3659 Session::connection_by_name (string name) const
3661 Glib::Mutex::Lock lm (connection_lock);
3663 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3664 if ((*i)->name() == name) {
3673 Session::tempo_map_changed (Change ignored)
3677 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3678 (*i)->update_after_tempo_map_change ();
3681 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3682 (*i)->update_after_tempo_map_change ();
3689 Session::ensure_passthru_buffers (uint32_t howmany)
3691 if (current_block_size == 0) {
3695 while (howmany > _passthru_buffers.size()) {
3697 #ifdef NO_POSIX_MEMALIGN
3698 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3700 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3701 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3702 current_block_size, sizeof (Sample), strerror (errno))
3707 _passthru_buffers.push_back (p);
3711 #ifdef NO_POSIX_MEMALIGN
3712 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3714 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4) != 0) {
3715 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3716 current_block_size, sizeof (Sample), strerror (errno))
3721 memset (p, 0, sizeof (Sample) * current_block_size);
3722 _silent_buffers.push_back (p);
3726 #ifdef NO_POSIX_MEMALIGN
3727 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3729 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3731 memset (p, 0, sizeof (Sample) * current_block_size);
3732 _send_buffers.push_back (p);
3735 allocate_pan_automation_buffers (current_block_size, howmany, false);
3739 Session::next_insert_id ()
3741 /* this doesn't really loop forever. just think about it */
3744 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3745 if (!insert_bitset[n]) {
3746 insert_bitset[n] = true;
3752 /* none available, so resize and try again */
3754 insert_bitset.resize (insert_bitset.size() + 16, false);
3759 Session::next_send_id ()
3761 /* this doesn't really loop forever. just think about it */
3764 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3765 if (!send_bitset[n]) {
3766 send_bitset[n] = true;
3772 /* none available, so resize and try again */
3774 send_bitset.resize (send_bitset.size() + 16, false);
3779 Session::mark_send_id (uint32_t id)
3781 if (id >= send_bitset.size()) {
3782 send_bitset.resize (id+16, false);
3784 if (send_bitset[id]) {
3785 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3787 send_bitset[id] = true;
3791 Session::mark_insert_id (uint32_t id)
3793 if (id >= insert_bitset.size()) {
3794 insert_bitset.resize (id+16, false);
3796 if (insert_bitset[id]) {
3797 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3799 insert_bitset[id] = true;
3802 /* Named Selection management */
3805 Session::named_selection_by_name (string name)
3807 Glib::Mutex::Lock lm (named_selection_lock);
3808 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3809 if ((*i)->name == name) {
3817 Session::add_named_selection (NamedSelection* named_selection)
3820 Glib::Mutex::Lock lm (named_selection_lock);
3821 named_selections.insert (named_selections.begin(), named_selection);
3824 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3830 NamedSelectionAdded (); /* EMIT SIGNAL */
3834 Session::remove_named_selection (NamedSelection* named_selection)
3836 bool removed = false;
3839 Glib::Mutex::Lock lm (named_selection_lock);
3841 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3843 if (i != named_selections.end()) {
3845 named_selections.erase (i);
3852 NamedSelectionRemoved (); /* EMIT SIGNAL */
3857 Session::reset_native_file_format ()
3859 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3861 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3862 (*i)->reset_write_sources (false);
3867 Session::route_name_unique (string n) const
3869 shared_ptr<RouteList> r = routes.reader ();
3871 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3872 if ((*i)->name() == n) {
3881 Session::n_playlists () const
3883 Glib::Mutex::Lock lm (playlist_lock);
3884 return playlists.size();
3888 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3890 if (!force && howmany <= _npan_buffers) {
3894 if (_pan_automation_buffer) {
3896 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3897 delete [] _pan_automation_buffer[i];
3900 delete [] _pan_automation_buffer;
3903 _pan_automation_buffer = new pan_t*[howmany];
3905 for (uint32_t i = 0; i < howmany; ++i) {
3906 _pan_automation_buffer[i] = new pan_t[nframes];
3909 _npan_buffers = howmany;
3913 Session::freeze (InterThreadInfo& itt)
3915 shared_ptr<RouteList> r = routes.reader ();
3917 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3921 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3922 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3933 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3934 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3937 boost::shared_ptr<Playlist> playlist;
3938 boost::shared_ptr<AudioFileSource> fsource;
3940 char buf[PATH_MAX+1];
3944 nframes_t this_chunk;
3946 vector<Sample*> buffers;
3948 // any bigger than this seems to cause stack overflows in called functions
3949 const nframes_t chunk_size = (128 * 1024)/4;
3951 g_atomic_int_set (&processing_prohibited, 1);
3953 /* call tree *MUST* hold route_lock */
3955 if ((playlist = track.diskstream()->playlist()) == 0) {
3959 /* external redirects will be a problem */
3961 if (track.has_external_redirects()) {
3965 nchans = track.audio_diskstream()->n_channels();
3967 dir = discover_best_sound_dir ();
3969 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3971 for (x = 0; x < 99999; ++x) {
3972 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3973 if (access (buf, F_OK) != 0) {
3979 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3984 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3987 catch (failed_constructor& err) {
3988 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3992 srcs.push_back (fsource);
3995 /* XXX need to flush all redirects */
4000 /* create a set of reasonably-sized buffers */
4002 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4004 #ifdef NO_POSIX_MEMALIGN
4005 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4007 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4009 buffers.push_back (b);
4012 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4013 (*src)->prepare_for_peakfile_writes ();
4016 while (to_do && !itt.cancel) {
4018 this_chunk = min (to_do, chunk_size);
4020 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
4025 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4026 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4029 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4035 start += this_chunk;
4036 to_do -= this_chunk;
4038 itt.progress = (float) (1.0 - ((double) to_do / len));
4047 xnow = localtime (&now);
4049 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4050 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4053 afs->update_header (position, *xnow, now);
4054 afs->flush_header ();
4058 /* construct a region to represent the bounced material */
4060 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4061 region_name_from_path (srcs.front()->name(), true));
4068 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4069 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4072 afs->mark_for_remove ();
4075 (*src)->drop_references ();
4079 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4080 (*src)->done_with_peakfile_writes ();
4084 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4088 g_atomic_int_set (&processing_prohibited, 0);
4096 Session::get_silent_buffers (uint32_t howmany)
4098 if (howmany > _silent_buffers.size()) {
4100 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4101 howmany, _silent_buffers.size()) << endmsg;
4103 if (howmany > 1000) {
4104 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4108 while (howmany > _silent_buffers.size()) {
4111 #ifdef NO_POSIX_MEMALIGN
4112 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4114 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4) != 0) {
4115 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4116 current_block_size, sizeof (Sample), strerror (errno))
4121 _silent_buffers.push_back (p);
4125 for (uint32_t i = 0; i < howmany; ++i) {
4126 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4129 return _silent_buffers;
4133 Session::ntracks () const
4136 shared_ptr<RouteList> r = routes.reader ();
4138 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4139 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4148 Session::nbusses () const
4151 shared_ptr<RouteList> r = routes.reader ();
4153 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4154 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4163 Session::add_automation_list(AutomationList *al)
4165 automation_lists[al->id()] = al;
4169 Session::compute_initial_length ()
4171 return _engine.frame_rate() * 60 * 5;
4175 Session::sync_order_keys ()
4177 if (!Config->get_sync_all_route_ordering()) {
4178 /* leave order keys as they are */
4182 boost::shared_ptr<RouteList> r = routes.reader ();
4184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4185 (*i)->sync_order_keys ();
4188 Route::SyncOrderKeys (); // EMIT SIGNAL