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),
287 _total_free_4k_blocks (0),
293 if (!eng.connected()) {
294 throw failed_constructor();
297 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
299 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
300 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
302 first_stage_init (fullpath, snapshot_name);
304 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
307 if (create (new_session, mix_template, compute_initial_length())) {
309 throw failed_constructor ();
313 if (second_stage_init (new_session)) {
315 throw failed_constructor ();
318 store_recent_sessions(_name, _path);
320 bool was_dirty = dirty();
322 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
324 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
327 DirtyChanged (); /* EMIT SIGNAL */
331 Session::Session (AudioEngine &eng,
333 string snapshot_name,
334 AutoConnectOption input_ac,
335 AutoConnectOption output_ac,
336 uint32_t control_out_channels,
337 uint32_t master_out_channels,
338 uint32_t requested_physical_in,
339 uint32_t requested_physical_out,
340 nframes_t initial_length)
343 _mmc_port (default_mmc_port),
344 _mtc_port (default_mtc_port),
345 _midi_port (default_midi_port),
346 pending_events (2048),
348 diskstreams (new DiskstreamList),
349 routes (new RouteList),
350 _total_free_4k_blocks (0),
356 if (!eng.connected()) {
357 throw failed_constructor();
360 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
362 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
363 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
365 if (n_physical_audio_inputs) {
366 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
369 if (n_physical_audio_outputs) {
370 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
373 first_stage_init (fullpath, snapshot_name);
375 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
378 if (create (new_session, string(), initial_length)) {
380 throw failed_constructor ();
385 /* set up Master Out and Control Out if necessary */
390 if (control_out_channels) {
391 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
392 r->set_remote_control_id (control_id++);
397 if (master_out_channels) {
398 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
399 r->set_remote_control_id (control_id);
403 /* prohibit auto-connect to master, because there isn't one */
404 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
408 add_routes (rl, false);
413 Config->set_input_auto_connect (input_ac);
414 Config->set_output_auto_connect (output_ac);
416 if (second_stage_init (new_session)) {
418 throw failed_constructor ();
421 store_recent_sessions (_name, _path);
423 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
426 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
437 /* if we got to here, leaving pending capture state around
441 remove_pending_capture_state ();
443 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
445 _engine.remove_session ();
447 GoingAway (); /* EMIT SIGNAL */
453 /* clear history so that no references to objects are held any more */
457 /* clear state tree so that no references to objects are held any more */
463 terminate_butler_thread ();
464 terminate_midi_thread ();
466 if (click_data && click_data != default_click) {
467 delete [] click_data;
470 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
471 delete [] click_emphasis_data;
476 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
480 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
484 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
488 AudioDiskstream::free_working_buffers();
490 /* this should cause deletion of the auditioner */
492 // auditioner.reset ();
494 #undef TRACK_DESTRUCTION
495 #ifdef TRACK_DESTRUCTION
496 cerr << "delete named selections\n";
497 #endif /* TRACK_DESTRUCTION */
498 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
499 NamedSelectionList::iterator tmp;
508 #ifdef TRACK_DESTRUCTION
509 cerr << "delete playlists\n";
510 #endif /* TRACK_DESTRUCTION */
511 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
512 PlaylistList::iterator tmp;
517 (*i)->drop_references ();
522 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
523 PlaylistList::iterator tmp;
528 (*i)->drop_references ();
534 unused_playlists.clear ();
536 #ifdef TRACK_DESTRUCTION
537 cerr << "delete audio regions\n";
538 #endif /* TRACK_DESTRUCTION */
540 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
541 AudioRegionList::iterator tmp;
546 i->second->drop_references ();
551 audio_regions.clear ();
553 #ifdef TRACK_DESTRUCTION
554 cerr << "delete routes\n";
555 #endif /* TRACK_DESTRUCTION */
557 RCUWriter<RouteList> writer (routes);
558 boost::shared_ptr<RouteList> r = writer.get_copy ();
559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
560 (*i)->drop_references ();
563 /* writer goes out of scope and updates master */
568 #ifdef TRACK_DESTRUCTION
569 cerr << "delete diskstreams\n";
570 #endif /* TRACK_DESTRUCTION */
572 RCUWriter<DiskstreamList> dwriter (diskstreams);
573 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
574 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
575 (*i)->drop_references ();
579 diskstreams.flush ();
581 #ifdef TRACK_DESTRUCTION
582 cerr << "delete audio sources\n";
583 #endif /* TRACK_DESTRUCTION */
584 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
585 AudioSourceList::iterator tmp;
590 i->second->drop_references ();
594 audio_sources.clear ();
596 #ifdef TRACK_DESTRUCTION
597 cerr << "delete mix groups\n";
598 #endif /* TRACK_DESTRUCTION */
599 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
600 list<RouteGroup*>::iterator tmp;
610 #ifdef TRACK_DESTRUCTION
611 cerr << "delete edit groups\n";
612 #endif /* TRACK_DESTRUCTION */
613 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
614 list<RouteGroup*>::iterator tmp;
624 #ifdef TRACK_DESTRUCTION
625 cerr << "delete connections\n";
626 #endif /* TRACK_DESTRUCTION */
627 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
628 ConnectionList::iterator tmp;
638 if (butler_mixdown_buffer) {
639 delete [] butler_mixdown_buffer;
642 if (butler_gain_buffer) {
643 delete [] butler_gain_buffer;
646 Crossfade::set_buffer_size (0);
654 Session::set_worst_io_latencies ()
656 _worst_output_latency = 0;
657 _worst_input_latency = 0;
659 if (!_engine.connected()) {
663 boost::shared_ptr<RouteList> r = routes.reader ();
665 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
666 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
667 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
672 Session::when_engine_running ()
674 string first_physical_output;
676 /* we don't want to run execute this again */
678 BootMessage (_("Set block size and sample rate"));
680 set_block_size (_engine.frames_per_cycle());
681 set_frame_rate (_engine.frame_rate());
683 BootMessage (_("Using configuration"));
685 Config->map_parameters (mem_fun (*this, &Session::config_changed));
687 /* every time we reconnect, recompute worst case output latencies */
689 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
691 if (synced_to_jack()) {
692 _engine.transport_stop ();
695 if (Config->get_jack_time_master()) {
696 _engine.transport_locate (_transport_frame);
704 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
706 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
708 /* existing state for Click */
710 if (_click_io->set_state (*child->children().front()) == 0) {
712 _clicking = Config->get_clicking ();
716 error << _("could not setup Click I/O") << endmsg;
722 /* default state for Click */
724 first_physical_output = _engine.get_nth_physical_audio_output (0);
726 if (first_physical_output.length()) {
727 if (_click_io->add_output_port (first_physical_output, this)) {
728 // relax, even though its an error
730 _clicking = Config->get_clicking ();
736 catch (failed_constructor& err) {
737 error << _("cannot setup Click I/O") << endmsg;
740 BootMessage (_("Compute I/O Latencies"));
742 set_worst_io_latencies ();
745 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
748 /* Create a set of Connection objects that map
749 to the physical outputs currently available
752 BootMessage (_("Set up standard connections"));
756 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
758 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
760 Connection* c = new OutputConnection (buf, true);
763 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
768 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
770 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
772 Connection* c = new InputConnection (buf, true);
775 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
782 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
784 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
786 Connection* c = new OutputConnection (buf, true);
790 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
791 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
796 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
798 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
800 Connection* c = new InputConnection (buf, true);
804 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
805 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
814 /* create master/control ports */
819 /* force the master to ignore any later call to this */
821 if (_master_out->pending_state_node) {
822 _master_out->ports_became_legal();
825 /* no panner resets till we are through */
827 _master_out->defer_pan_reset ();
829 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
830 if (_master_out->add_input_port ("", this)) {
831 error << _("cannot setup master inputs")
837 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
838 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
839 error << _("cannot setup master outputs")
846 _master_out->allow_pan_reset ();
850 Connection* c = new OutputConnection (_("Master Out"), true);
852 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
854 c->add_connection ((int) n, _master_out->input(n)->name());
859 BootMessage (_("Setup signal flow and plugins"));
863 /* catch up on send+insert cnts */
865 BootMessage (_("Catch up with send/insert state"));
869 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
872 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
873 if (id > insert_cnt) {
881 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
884 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
892 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
894 /* hook us up to the engine */
896 BootMessage (_("Connect to engine"));
898 _engine.set_session (this);
903 BootMessage (_("OSC startup"));
905 osc->set_session (*this);
911 Session::hookup_io ()
913 /* stop graph reordering notifications from
914 causing resorts, etc.
917 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
920 if (auditioner == 0) {
922 /* we delay creating the auditioner till now because
923 it makes its own connections to ports.
924 the engine has to be running for this to work.
928 auditioner.reset (new Auditioner (*this));
931 catch (failed_constructor& err) {
932 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
936 /* Tell all IO objects to create their ports */
942 vector<string> cports;
944 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
945 if (_control_out->add_input_port ("", this)) {
946 error << _("cannot setup control inputs")
952 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
953 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
954 error << _("cannot set up master outputs")
962 uint32_t ni = _control_out->n_inputs();
964 for (n = 0; n < ni; ++n) {
965 cports.push_back (_control_out->input(n)->name());
968 boost::shared_ptr<RouteList> r = routes.reader ();
970 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
971 (*x)->set_control_outs (cports);
975 /* Tell all IO objects to connect themselves together */
977 IO::enable_connecting ();
979 /* Now reset all panners */
981 IO::reset_panners ();
983 /* Anyone who cares about input state, wake up and do something */
985 IOConnectionsComplete (); /* EMIT SIGNAL */
987 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
990 /* now handle the whole enchilada as if it was one
996 /* update mixer solo state */
1002 Session::playlist_length_changed ()
1004 /* we can't just increase end_location->end() if pl->get_maximum_extent()
1005 if larger. if the playlist used to be the longest playlist,
1006 and its now shorter, we have to decrease end_location->end(). hence,
1007 we have to iterate over all diskstreams and check the
1008 playlists currently in use.
1010 find_current_end ();
1014 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1016 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1023 boost::shared_ptr<Playlist> playlist;
1025 if ((playlist = dstream->playlist()) != 0) {
1026 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1029 /* see comment in playlist_length_changed () */
1030 find_current_end ();
1034 Session::record_enabling_legal () const
1036 /* this used to be in here, but survey says.... we don't need to restrict it */
1037 // if (record_status() == Recording) {
1041 if (Config->get_all_safe()) {
1048 Session::reset_input_monitor_state ()
1050 if (transport_rolling()) {
1052 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1054 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1055 if ((*i)->record_enabled ()) {
1056 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1057 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1061 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1063 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1064 if ((*i)->record_enabled ()) {
1065 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1066 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1073 Session::auto_punch_start_changed (Location* location)
1075 replace_event (Event::PunchIn, location->start());
1077 if (get_record_enabled() && Config->get_punch_in()) {
1078 /* capture start has been changed, so save new pending state */
1079 save_state ("", true);
1084 Session::auto_punch_end_changed (Location* location)
1086 nframes_t when_to_stop = location->end();
1087 // when_to_stop += _worst_output_latency + _worst_input_latency;
1088 replace_event (Event::PunchOut, when_to_stop);
1092 Session::auto_punch_changed (Location* location)
1094 nframes_t when_to_stop = location->end();
1096 replace_event (Event::PunchIn, location->start());
1097 //when_to_stop += _worst_output_latency + _worst_input_latency;
1098 replace_event (Event::PunchOut, when_to_stop);
1102 Session::auto_loop_changed (Location* location)
1104 replace_event (Event::AutoLoop, location->end(), location->start());
1106 if (transport_rolling() && play_loop) {
1108 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1110 if (_transport_frame > location->end()) {
1111 // relocate to beginning of loop
1112 clear_events (Event::LocateRoll);
1114 request_locate (location->start(), true);
1117 else if (Config->get_seamless_loop() && !loop_changing) {
1119 // schedule a locate-roll to refill the diskstreams at the
1120 // previous loop end
1121 loop_changing = true;
1123 if (location->end() > last_loopend) {
1124 clear_events (Event::LocateRoll);
1125 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1132 last_loopend = location->end();
1136 Session::set_auto_punch_location (Location* location)
1140 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1141 auto_punch_start_changed_connection.disconnect();
1142 auto_punch_end_changed_connection.disconnect();
1143 auto_punch_changed_connection.disconnect();
1144 existing->set_auto_punch (false, this);
1145 remove_event (existing->start(), Event::PunchIn);
1146 clear_events (Event::PunchOut);
1147 auto_punch_location_changed (0);
1152 if (location == 0) {
1156 if (location->end() <= location->start()) {
1157 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1161 auto_punch_start_changed_connection.disconnect();
1162 auto_punch_end_changed_connection.disconnect();
1163 auto_punch_changed_connection.disconnect();
1165 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1166 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1167 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1169 location->set_auto_punch (true, this);
1172 auto_punch_changed (location);
1174 auto_punch_location_changed (location);
1178 Session::set_auto_loop_location (Location* location)
1182 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1183 auto_loop_start_changed_connection.disconnect();
1184 auto_loop_end_changed_connection.disconnect();
1185 auto_loop_changed_connection.disconnect();
1186 existing->set_auto_loop (false, this);
1187 remove_event (existing->end(), Event::AutoLoop);
1188 auto_loop_location_changed (0);
1193 if (location == 0) {
1197 if (location->end() <= location->start()) {
1198 error << _("Session: you can't use a mark for auto loop") << endmsg;
1202 last_loopend = location->end();
1204 auto_loop_start_changed_connection.disconnect();
1205 auto_loop_end_changed_connection.disconnect();
1206 auto_loop_changed_connection.disconnect();
1208 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1209 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1210 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1212 location->set_auto_loop (true, this);
1214 /* take care of our stuff first */
1216 auto_loop_changed (location);
1218 /* now tell everyone else */
1220 auto_loop_location_changed (location);
1224 Session::locations_added (Location* ignored)
1230 Session::locations_changed ()
1232 _locations.apply (*this, &Session::handle_locations_changed);
1236 Session::handle_locations_changed (Locations::LocationList& locations)
1238 Locations::LocationList::iterator i;
1240 bool set_loop = false;
1241 bool set_punch = false;
1243 for (i = locations.begin(); i != locations.end(); ++i) {
1247 if (location->is_auto_punch()) {
1248 set_auto_punch_location (location);
1251 if (location->is_auto_loop()) {
1252 set_auto_loop_location (location);
1256 if (location->is_start()) {
1257 start_location = location;
1259 if (location->is_end()) {
1260 end_location = location;
1265 set_auto_loop_location (0);
1268 set_auto_punch_location (0);
1275 Session::enable_record ()
1277 /* XXX really atomic compare+swap here */
1278 if (g_atomic_int_get (&_record_status) != Recording) {
1279 g_atomic_int_set (&_record_status, Recording);
1280 _last_record_location = _transport_frame;
1281 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1283 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1284 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1286 if ((*i)->record_enabled ()) {
1287 (*i)->monitor_input (true);
1292 RecordStateChanged ();
1297 Session::disable_record (bool rt_context, bool force)
1301 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1303 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1304 g_atomic_int_set (&_record_status, Disabled);
1306 if (rs == Recording) {
1307 g_atomic_int_set (&_record_status, Enabled);
1311 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1313 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1314 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1316 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1317 if ((*i)->record_enabled ()) {
1318 (*i)->monitor_input (false);
1323 RecordStateChanged (); /* emit signal */
1326 remove_pending_capture_state ();
1332 Session::step_back_from_record ()
1334 /* XXX really atomic compare+swap here */
1335 if (g_atomic_int_get (&_record_status) == Recording) {
1336 g_atomic_int_set (&_record_status, Enabled);
1338 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1339 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1341 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1342 if ((*i)->record_enabled ()) {
1343 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1344 (*i)->monitor_input (false);
1352 Session::maybe_enable_record ()
1354 g_atomic_int_set (&_record_status, Enabled);
1356 /* this function is currently called from somewhere other than an RT thread.
1357 this save_state() call therefore doesn't impact anything.
1360 save_state ("", true);
1362 if (_transport_speed) {
1363 if (!Config->get_punch_in()) {
1367 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1368 RecordStateChanged (); /* EMIT SIGNAL */
1375 Session::audible_frame () const
1381 /* the first of these two possible settings for "offset"
1382 mean that the audible frame is stationary until
1383 audio emerges from the latency compensation
1386 the second means that the audible frame is stationary
1387 until audio would emerge from a physical port
1388 in the absence of any plugin latency compensation
1391 offset = _worst_output_latency;
1393 if (offset > current_block_size) {
1394 offset -= current_block_size;
1396 /* XXX is this correct? if we have no external
1397 physical connections and everything is internal
1398 then surely this is zero? still, how
1399 likely is that anyway?
1401 offset = current_block_size;
1404 if (synced_to_jack()) {
1405 tf = _engine.transport_frame();
1407 tf = _transport_frame;
1410 if (_transport_speed == 0) {
1420 if (!non_realtime_work_pending()) {
1424 /* take latency into account */
1433 Session::set_frame_rate (nframes_t frames_per_second)
1435 /** \fn void Session::set_frame_size(nframes_t)
1436 the AudioEngine object that calls this guarantees
1437 that it will not be called while we are also in
1438 ::process(). Its fine to do things that block
1442 _base_frame_rate = frames_per_second;
1446 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1450 // XXX we need some equivalent to this, somehow
1451 // SndFileSource::setup_standard_crossfades (frames_per_second);
1455 /* XXX need to reset/reinstantiate all LADSPA plugins */
1459 Session::set_block_size (nframes_t nframes)
1461 /* the AudioEngine guarantees
1462 that it will not be called while we are also in
1463 ::process(). It is therefore fine to do things that block
1468 vector<Sample*>::iterator i;
1471 current_block_size = nframes;
1473 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1477 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1481 _passthru_buffers.clear ();
1482 _silent_buffers.clear ();
1484 ensure_passthru_buffers (np);
1486 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1490 #ifdef NO_POSIX_MEMALIGN
1491 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1493 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1497 memset (*i, 0, sizeof (Sample) * current_block_size);
1501 if (_gain_automation_buffer) {
1502 delete [] _gain_automation_buffer;
1504 _gain_automation_buffer = new gain_t[nframes];
1506 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1508 boost::shared_ptr<RouteList> r = routes.reader ();
1510 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1511 (*i)->set_block_size (nframes);
1514 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1515 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1516 (*i)->set_block_size (nframes);
1519 set_worst_io_latencies ();
1524 Session::set_default_fade (float steepness, float fade_msecs)
1527 nframes_t fade_frames;
1529 /* Don't allow fade of less 1 frame */
1531 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1538 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1542 default_fade_msecs = fade_msecs;
1543 default_fade_steepness = steepness;
1546 // jlc, WTF is this!
1547 Glib::RWLock::ReaderLock lm (route_lock);
1548 AudioRegion::set_default_fade (steepness, fade_frames);
1553 /* XXX have to do this at some point */
1554 /* foreach region using default fade, reset, then
1555 refill_all_diskstream_buffers ();
1560 struct RouteSorter {
1561 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1562 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1564 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1567 if (r1->fed_by.empty()) {
1568 if (r2->fed_by.empty()) {
1569 /* no ardour-based connections inbound to either route. just use signal order */
1570 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1572 /* r2 has connections, r1 does not; run r1 early */
1576 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1583 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1585 shared_ptr<Route> r2;
1587 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1588 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1592 /* make a copy of the existing list of routes that feed r1 */
1594 set<shared_ptr<Route> > existing = r1->fed_by;
1596 /* for each route that feeds r1, recurse, marking it as feeding
1600 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1603 /* r2 is a route that feeds r1 which somehow feeds base. mark
1604 base as being fed by r2
1607 rbase->fed_by.insert (r2);
1611 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1615 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1619 /* now recurse, so that we can mark base as being fed by
1620 all routes that feed r2
1623 trace_terminal (r2, rbase);
1630 Session::resort_routes ()
1632 /* don't do anything here with signals emitted
1633 by Routes while we are being destroyed.
1636 if (_state_of_the_state & Deletion) {
1643 RCUWriter<RouteList> writer (routes);
1644 shared_ptr<RouteList> r = writer.get_copy ();
1645 resort_routes_using (r);
1646 /* writer goes out of scope and forces update */
1651 Session::resort_routes_using (shared_ptr<RouteList> r)
1653 RouteList::iterator i, j;
1655 for (i = r->begin(); i != r->end(); ++i) {
1657 (*i)->fed_by.clear ();
1659 for (j = r->begin(); j != r->end(); ++j) {
1661 /* although routes can feed themselves, it will
1662 cause an endless recursive descent if we
1663 detect it. so don't bother checking for
1671 if ((*j)->feeds (*i)) {
1672 (*i)->fed_by.insert (*j);
1677 for (i = r->begin(); i != r->end(); ++i) {
1678 trace_terminal (*i, *i);
1684 /* don't leave dangling references to routes in Route::fed_by */
1686 for (i = r->begin(); i != r->end(); ++i) {
1687 (*i)->fed_by.clear ();
1691 cerr << "finished route resort\n";
1693 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1694 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1701 list<boost::shared_ptr<AudioTrack> >
1702 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1704 char track_name[32];
1705 uint32_t track_id = 0;
1707 uint32_t channels_used = 0;
1709 RouteList new_routes;
1710 list<boost::shared_ptr<AudioTrack> > ret;
1711 uint32_t control_id;
1713 /* count existing audio tracks */
1716 shared_ptr<RouteList> r = routes.reader ();
1718 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1719 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1720 if (!(*i)->hidden()) {
1722 channels_used += (*i)->n_inputs();
1728 vector<string> physinputs;
1729 vector<string> physoutputs;
1730 uint32_t nphysical_in;
1731 uint32_t nphysical_out;
1733 _engine.get_physical_audio_outputs (physoutputs);
1734 _engine.get_physical_audio_inputs (physinputs);
1735 control_id = ntracks() + nbusses() + 1;
1739 /* check for duplicate route names, since we might have pre-existing
1740 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1741 save, close,restart,add new route - first named route is now
1749 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1751 if (route_by_name (track_name) == 0) {
1755 } while (track_id < (UINT_MAX-1));
1757 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1758 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1763 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1764 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1769 shared_ptr<AudioTrack> track;
1772 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1774 if (track->ensure_io (input_channels, output_channels, false, this)) {
1775 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1776 input_channels, output_channels)
1782 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1786 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1787 port = physinputs[(channels_used+x)%nphysical_in];
1790 if (port.length() && track->connect_input (track->input (x), port, this)) {
1796 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1800 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1801 port = physoutputs[(channels_used+x)%nphysical_out];
1802 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1804 port = _master_out->input (x%_master_out->n_inputs())->name();
1808 if (port.length() && track->connect_output (track->output (x), port, this)) {
1813 channels_used += track->n_inputs ();
1815 track->audio_diskstream()->non_realtime_input_change();
1817 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1818 track->set_remote_control_id (control_id);
1821 new_routes.push_back (track);
1822 ret.push_back (track);
1826 catch (failed_constructor &err) {
1827 error << _("Session: could not create new audio track.") << endmsg;
1830 /* we need to get rid of this, since the track failed to be created */
1831 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1834 RCUWriter<DiskstreamList> writer (diskstreams);
1835 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1836 ds->remove (track->audio_diskstream());
1843 catch (AudioEngine::PortRegistrationFailure& pfe) {
1845 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;
1848 /* we need to get rid of this, since the track failed to be created */
1849 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1852 RCUWriter<DiskstreamList> writer (diskstreams);
1853 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1854 ds->remove (track->audio_diskstream());
1865 if (!new_routes.empty()) {
1866 add_routes (new_routes, true);
1873 Session::set_remote_control_ids ()
1875 RemoteModel m = Config->get_remote_model();
1877 shared_ptr<RouteList> r = routes.reader ();
1879 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1880 if ( MixerOrdered == m) {
1881 long order = (*i)->order_key(N_("signal"));
1882 (*i)->set_remote_control_id( order+1 );
1883 } else if ( EditorOrdered == m) {
1884 long order = (*i)->order_key(N_("editor"));
1885 (*i)->set_remote_control_id( order+1 );
1886 } else if ( UserOrdered == m) {
1887 //do nothing ... only changes to remote id's are initiated by user
1894 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1897 uint32_t bus_id = 1;
1901 uint32_t control_id;
1903 /* count existing audio busses */
1906 shared_ptr<RouteList> r = routes.reader ();
1908 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1909 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1910 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1917 vector<string> physinputs;
1918 vector<string> physoutputs;
1920 _engine.get_physical_audio_outputs (physoutputs);
1921 _engine.get_physical_audio_inputs (physinputs);
1922 control_id = ntracks() + nbusses() + 1;
1927 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1931 if (route_by_name (bus_name) == 0) {
1935 } while (bus_id < (UINT_MAX-1));
1938 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1940 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1941 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1942 input_channels, output_channels)
1947 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1951 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1952 port = physinputs[((n+x)%n_physical_audio_inputs)];
1955 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1960 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1964 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1965 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1966 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1968 port = _master_out->input (x%_master_out->n_inputs())->name();
1972 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1977 bus->set_remote_control_id (control_id);
1980 ret.push_back (bus);
1984 catch (failed_constructor &err) {
1985 error << _("Session: could not create new audio route.") << endmsg;
1989 catch (AudioEngine::PortRegistrationFailure& pfe) {
1990 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;
2000 add_routes (ret, true);
2008 Session::add_routes (RouteList& new_routes, bool save)
2011 RCUWriter<RouteList> writer (routes);
2012 shared_ptr<RouteList> r = writer.get_copy ();
2013 r->insert (r->end(), new_routes.begin(), new_routes.end());
2014 resort_routes_using (r);
2017 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2019 boost::weak_ptr<Route> wpr (*x);
2021 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2022 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2023 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2024 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2026 if ((*x)->master()) {
2030 if ((*x)->control()) {
2031 _control_out = (*x);
2035 if (_control_out && IO::connecting_legal) {
2037 vector<string> cports;
2038 uint32_t ni = _control_out->n_inputs();
2041 for (n = 0; n < ni; ++n) {
2042 cports.push_back (_control_out->input(n)->name());
2045 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2046 (*x)->set_control_outs (cports);
2053 save_state (_current_snapshot_name);
2056 RouteAdded (new_routes); /* EMIT SIGNAL */
2060 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2062 /* need to do this in case we're rolling at the time, to prevent false underruns */
2063 dstream->do_refill_with_alloc ();
2065 dstream->set_block_size (current_block_size);
2068 RCUWriter<DiskstreamList> writer (diskstreams);
2069 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2070 ds->push_back (dstream);
2071 /* writer goes out of scope, copies ds back to main */
2074 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2075 boost::weak_ptr<Diskstream> (dstream)));
2076 /* this will connect to future changes, and check the current length */
2077 diskstream_playlist_changed (dstream);
2079 dstream->prepare ();
2083 Session::remove_route (shared_ptr<Route> route)
2086 RCUWriter<RouteList> writer (routes);
2087 shared_ptr<RouteList> rs = writer.get_copy ();
2091 /* deleting the master out seems like a dumb
2092 idea, but its more of a UI policy issue
2096 if (route == _master_out) {
2097 _master_out = shared_ptr<Route> ();
2100 if (route == _control_out) {
2101 _control_out = shared_ptr<Route> ();
2103 /* cancel control outs for all routes */
2105 vector<string> empty;
2107 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2108 (*r)->set_control_outs (empty);
2112 update_route_solo_state ();
2114 /* writer goes out of scope, forces route list update */
2117 // FIXME: audio specific
2119 boost::shared_ptr<AudioDiskstream> ds;
2121 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2122 ds = at->audio_diskstream();
2128 RCUWriter<DiskstreamList> dsl (diskstreams);
2129 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2133 diskstreams.flush ();
2136 find_current_end ();
2138 // We need to disconnect the routes inputs and outputs
2140 route->disconnect_inputs (0);
2141 route->disconnect_outputs (0);
2143 update_latency_compensation (false, false);
2146 /* get rid of it from the dead wood collection in the route list manager */
2148 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2152 /* try to cause everyone to drop their references */
2154 route->drop_references ();
2156 sync_order_keys (N_("session"));
2158 /* save the new state of the world */
2160 if (save_state (_current_snapshot_name)) {
2161 save_history (_current_snapshot_name);
2166 Session::route_mute_changed (void* src)
2172 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2174 if (solo_update_disabled) {
2180 boost::shared_ptr<Route> route = wpr.lock ();
2183 /* should not happen */
2184 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2188 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2190 shared_ptr<RouteList> r = routes.reader ();
2192 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2194 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2198 /* don't mess with busses */
2200 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2206 /* don't mess with tracks */
2208 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2213 if ((*i) != route &&
2214 ((*i)->mix_group () == 0 ||
2215 (*i)->mix_group () != route->mix_group () ||
2216 !route->mix_group ()->is_active())) {
2218 if ((*i)->soloed()) {
2220 /* if its already soloed, and solo latching is enabled,
2221 then leave it as it is.
2224 if (Config->get_solo_latched()) {
2231 solo_update_disabled = true;
2232 (*i)->set_solo (false, src);
2233 solo_update_disabled = false;
2237 bool something_soloed = false;
2238 bool same_thing_soloed = false;
2239 bool signal = false;
2241 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2242 if ((*i)->soloed()) {
2243 something_soloed = true;
2244 if (dynamic_cast<AudioTrack*>((*i).get())) {
2246 same_thing_soloed = true;
2251 same_thing_soloed = true;
2259 if (something_soloed != currently_soloing) {
2261 currently_soloing = something_soloed;
2264 modify_solo_mute (is_track, same_thing_soloed);
2267 SoloActive (currently_soloing); /* EMIT SIGNAL */
2270 SoloChanged (); /* EMIT SIGNAL */
2276 Session::update_route_solo_state ()
2279 bool is_track = false;
2280 bool signal = false;
2282 /* caller must hold RouteLock */
2284 /* this is where we actually implement solo by changing
2285 the solo mute setting of each track.
2288 shared_ptr<RouteList> r = routes.reader ();
2290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2291 if ((*i)->soloed()) {
2293 if (dynamic_cast<AudioTrack*>((*i).get())) {
2300 if (mute != currently_soloing) {
2302 currently_soloing = mute;
2305 if (!is_track && !mute) {
2307 /* nothing is soloed */
2309 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2310 (*i)->set_solo_mute (false);
2320 modify_solo_mute (is_track, mute);
2323 SoloActive (currently_soloing);
2328 Session::modify_solo_mute (bool is_track, bool mute)
2330 shared_ptr<RouteList> r = routes.reader ();
2332 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2336 /* only alter track solo mute */
2338 if (dynamic_cast<AudioTrack*>((*i).get())) {
2339 if ((*i)->soloed()) {
2340 (*i)->set_solo_mute (!mute);
2342 (*i)->set_solo_mute (mute);
2348 /* only alter bus solo mute */
2350 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2352 if ((*i)->soloed()) {
2354 (*i)->set_solo_mute (false);
2358 /* don't mute master or control outs
2359 in response to another bus solo
2362 if ((*i) != _master_out &&
2363 (*i) != _control_out) {
2364 (*i)->set_solo_mute (mute);
2375 Session::catch_up_on_solo ()
2377 /* this is called after set_state() to catch the full solo
2378 state, which can't be correctly determined on a per-route
2379 basis, but needs the global overview that only the session
2382 update_route_solo_state();
2386 Session::route_by_name (string name)
2388 shared_ptr<RouteList> r = routes.reader ();
2390 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2391 if ((*i)->name() == name) {
2396 return shared_ptr<Route> ((Route*) 0);
2400 Session::route_by_id (PBD::ID id)
2402 shared_ptr<RouteList> r = routes.reader ();
2404 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2405 if ((*i)->id() == id) {
2410 return shared_ptr<Route> ((Route*) 0);
2414 Session::route_by_remote_id (uint32_t id)
2416 shared_ptr<RouteList> r = routes.reader ();
2418 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2419 if ((*i)->remote_control_id() == id) {
2424 return shared_ptr<Route> ((Route*) 0);
2428 Session::find_current_end ()
2430 if (_state_of_the_state & Loading) {
2434 nframes_t max = get_maximum_extent ();
2436 if (max > end_location->end()) {
2437 end_location->set_end (max);
2439 DurationChanged(); /* EMIT SIGNAL */
2444 Session::get_maximum_extent () const
2449 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2451 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2452 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2454 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2455 if ((me = pl->get_maximum_extent()) > max) {
2463 boost::shared_ptr<Diskstream>
2464 Session::diskstream_by_name (string name)
2466 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2468 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2469 if ((*i)->name() == name) {
2474 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2477 boost::shared_ptr<Diskstream>
2478 Session::diskstream_by_id (const PBD::ID& id)
2480 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2482 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2483 if ((*i)->id() == id) {
2488 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2491 /* AudioRegion management */
2494 Session::new_region_name (string old)
2496 string::size_type last_period;
2498 string::size_type len = old.length() + 64;
2501 if ((last_period = old.find_last_of ('.')) == string::npos) {
2503 /* no period present - add one explicitly */
2506 last_period = old.length() - 1;
2511 number = atoi (old.substr (last_period+1).c_str());
2515 while (number < (UINT_MAX-1)) {
2517 AudioRegionList::const_iterator i;
2522 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2525 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2526 if (i->second->name() == sbuf) {
2531 if (i == audio_regions.end()) {
2536 if (number != (UINT_MAX-1)) {
2540 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2545 Session::region_name (string& result, string base, bool newlevel)
2552 Glib::Mutex::Lock lm (region_lock);
2554 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2563 string::size_type pos;
2565 pos = base.find_last_of ('.');
2567 /* pos may be npos, but then we just use entire base */
2569 subbase = base.substr (0, pos);
2574 Glib::Mutex::Lock lm (region_lock);
2576 map<string,uint32_t>::iterator x;
2580 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2582 region_name_map[subbase] = 1;
2585 snprintf (buf, sizeof (buf), ".%d", x->second);
2595 Session::add_region (boost::shared_ptr<Region> region)
2597 vector<boost::shared_ptr<Region> > v;
2598 v.push_back (region);
2603 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2605 boost::shared_ptr<AudioRegion> ar;
2606 boost::shared_ptr<AudioRegion> oar;
2610 Glib::Mutex::Lock lm (region_lock);
2612 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2614 boost::shared_ptr<Region> region = *ii;
2618 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2620 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2622 AudioRegionList::iterator x;
2624 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2626 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2628 if (ar->region_list_equivalent (oar)) {
2633 if (x == audio_regions.end()) {
2635 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2637 entry.first = region->id();
2640 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2651 fatal << _("programming error: ")
2652 << X_("unknown region type passed to Session::add_region()")
2660 /* mark dirty because something has changed even if we didn't
2661 add the region to the region list.
2668 vector<boost::weak_ptr<AudioRegion> > v;
2669 boost::shared_ptr<AudioRegion> first_ar;
2671 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2673 boost::shared_ptr<Region> region = *ii;
2674 boost::shared_ptr<AudioRegion> ar;
2678 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2680 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2688 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2689 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2691 update_region_name_map (region);
2695 AudioRegionsAdded (v); /* EMIT SIGNAL */
2701 Session::update_region_name_map (boost::shared_ptr<Region> region)
2703 string::size_type last_period = region->name().find_last_of ('.');
2705 if (last_period != string::npos && last_period < region->name().length() - 1) {
2707 string base = region->name().substr (0, last_period);
2708 string number = region->name().substr (last_period+1);
2709 map<string,uint32_t>::iterator x;
2711 /* note that if there is no number, we get zero from atoi,
2715 region_name_map[base] = atoi (number);
2720 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2722 boost::shared_ptr<Region> region (weak_region.lock ());
2728 if (what_changed & Region::HiddenChanged) {
2729 /* relay hidden changes */
2730 RegionHiddenChange (region);
2733 if (what_changed & NameChanged) {
2734 update_region_name_map (region);
2739 Session::remove_region (boost::weak_ptr<Region> weak_region)
2741 AudioRegionList::iterator i;
2742 boost::shared_ptr<Region> region (weak_region.lock ());
2748 boost::shared_ptr<AudioRegion> ar;
2749 bool removed = false;
2752 Glib::Mutex::Lock lm (region_lock);
2754 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2755 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2756 audio_regions.erase (i);
2762 fatal << _("programming error: ")
2763 << X_("unknown region type passed to Session::remove_region()")
2769 /* mark dirty because something has changed even if we didn't
2770 remove the region from the region list.
2776 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2780 boost::shared_ptr<AudioRegion>
2781 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2783 AudioRegionList::iterator i;
2784 boost::shared_ptr<AudioRegion> region;
2785 Glib::Mutex::Lock lm (region_lock);
2787 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2791 if (region->whole_file()) {
2793 if (child->source_equivalent (region)) {
2799 return boost::shared_ptr<AudioRegion> ();
2803 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2805 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2806 (*i)->get_region_list_equivalent_regions (region, result);
2810 Session::destroy_region (boost::shared_ptr<Region> region)
2812 vector<boost::shared_ptr<Source> > srcs;
2815 boost::shared_ptr<AudioRegion> aregion;
2817 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2821 if (aregion->playlist()) {
2822 aregion->playlist()->destroy_region (region);
2825 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2826 srcs.push_back (aregion->source (n));
2830 region->drop_references ();
2832 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2834 if (!(*i)->used()) {
2835 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2838 (afs)->mark_for_remove ();
2841 (*i)->drop_references ();
2843 cerr << "source was not used by any playlist\n";
2851 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2853 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2854 destroy_region (*i);
2860 Session::remove_last_capture ()
2862 list<boost::shared_ptr<Region> > r;
2864 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2866 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2867 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2870 r.insert (r.end(), l.begin(), l.end());
2875 destroy_regions (r);
2877 save_state (_current_snapshot_name);
2883 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2889 /* Source Management */
2892 Session::add_source (boost::shared_ptr<Source> source)
2894 boost::shared_ptr<AudioFileSource> afs;
2896 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2898 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2899 pair<AudioSourceList::iterator,bool> result;
2901 entry.first = source->id();
2905 Glib::Mutex::Lock lm (audio_source_lock);
2906 result = audio_sources.insert (entry);
2909 if (result.second) {
2910 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2914 if (Config->get_auto_analyse_audio()) {
2915 Analyser::queue_source_for_analysis (source, false);
2921 Session::remove_source (boost::weak_ptr<Source> src)
2923 AudioSourceList::iterator i;
2924 boost::shared_ptr<Source> source = src.lock();
2931 Glib::Mutex::Lock lm (audio_source_lock);
2933 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2934 audio_sources.erase (i);
2938 if (!_state_of_the_state & InCleanup) {
2940 /* save state so we don't end up with a session file
2941 referring to non-existent sources.
2944 save_state (_current_snapshot_name);
2948 boost::shared_ptr<Source>
2949 Session::source_by_id (const PBD::ID& id)
2951 Glib::Mutex::Lock lm (audio_source_lock);
2952 AudioSourceList::iterator i;
2953 boost::shared_ptr<Source> source;
2955 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2959 /* XXX search MIDI or other searches here */
2965 boost::shared_ptr<Source>
2966 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2968 Glib::Mutex::Lock lm (audio_source_lock);
2970 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2971 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2973 if (afs && afs->path() == path && chn == afs->channel()) {
2978 return boost::shared_ptr<Source>();
2982 Session::peak_path (Glib::ustring base) const
2984 return Glib::build_filename(peak_dir (), base + ".peak");
2988 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2991 string old_basename = PBD::basename_nosuffix (oldname);
2992 string new_legalized = legalize_for_path (newname);
2994 /* note: we know (or assume) the old path is already valid */
2998 /* destructive file sources have a name of the form:
3000 /path/to/Tnnnn-NAME(%[LR])?.wav
3002 the task here is to replace NAME with the new name.
3005 /* find last slash */
3009 string::size_type slash;
3010 string::size_type dash;
3012 if ((slash = path.find_last_of ('/')) == string::npos) {
3016 dir = path.substr (0, slash+1);
3018 /* '-' is not a legal character for the NAME part of the path */
3020 if ((dash = path.find_last_of ('-')) == string::npos) {
3024 prefix = path.substr (slash+1, dash-(slash+1));
3029 path += new_legalized;
3030 path += ".wav"; /* XXX gag me with a spoon */
3034 /* non-destructive file sources have a name of the form:
3036 /path/to/NAME-nnnnn(%[LR])?.wav
3038 the task here is to replace NAME with the new name.
3043 string::size_type slash;
3044 string::size_type dash;
3045 string::size_type postfix;
3047 /* find last slash */
3049 if ((slash = path.find_last_of ('/')) == string::npos) {
3053 dir = path.substr (0, slash+1);
3055 /* '-' is not a legal character for the NAME part of the path */
3057 if ((dash = path.find_last_of ('-')) == string::npos) {
3061 suffix = path.substr (dash+1);
3063 // Suffix is now everything after the dash. Now we need to eliminate
3064 // the nnnnn part, which is done by either finding a '%' or a '.'
3066 postfix = suffix.find_last_of ("%");
3067 if (postfix == string::npos) {
3068 postfix = suffix.find_last_of ('.');
3071 if (postfix != string::npos) {
3072 suffix = suffix.substr (postfix);
3074 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3078 const uint32_t limit = 10000;
3079 char buf[PATH_MAX+1];
3081 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3083 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3085 if (access (buf, F_OK) != 0) {
3093 error << "FATAL ERROR! Could not find a " << endl;
3102 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3106 char buf[PATH_MAX+1];
3107 const uint32_t limit = 10000;
3111 legalized = legalize_for_path (name);
3113 /* find a "version" of the file name that doesn't exist in
3114 any of the possible directories.
3117 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3119 vector<space_and_path>::iterator i;
3120 uint32_t existing = 0;
3122 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3126 spath += sound_dir (false);
3130 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3131 } else if (nchan == 2) {
3133 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3135 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3137 } else if (nchan < 26) {
3138 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3140 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3149 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3150 } else if (nchan == 2) {
3152 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3154 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3156 } else if (nchan < 26) {
3157 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3159 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3163 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3169 if (existing == 0) {
3174 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3176 throw failed_constructor();
3180 /* we now have a unique name for the file, but figure out where to
3186 spath = discover_best_sound_dir ();
3189 string::size_type pos = foo.find_last_of ('/');
3191 if (pos == string::npos) {
3194 spath += foo.substr (pos + 1);
3200 boost::shared_ptr<AudioFileSource>
3201 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3203 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3204 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3207 /* Playlist management */
3209 boost::shared_ptr<Playlist>
3210 Session::playlist_by_name (string name)
3212 Glib::Mutex::Lock lm (playlist_lock);
3213 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3214 if ((*i)->name() == name) {
3218 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3219 if ((*i)->name() == name) {
3224 return boost::shared_ptr<Playlist>();
3228 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3230 if (playlist->hidden()) {
3235 Glib::Mutex::Lock lm (playlist_lock);
3236 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3237 playlists.insert (playlists.begin(), playlist);
3238 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3239 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3245 PlaylistAdded (playlist); /* EMIT SIGNAL */
3249 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3252 Glib::Mutex::Lock lm (playlist_lock);
3253 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3256 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3263 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3265 boost::shared_ptr<Playlist> pl(wpl.lock());
3271 PlaylistList::iterator x;
3274 /* its not supposed to be visible */
3279 Glib::Mutex::Lock lm (playlist_lock);
3283 unused_playlists.insert (pl);
3285 if ((x = playlists.find (pl)) != playlists.end()) {
3286 playlists.erase (x);
3292 playlists.insert (pl);
3294 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3295 unused_playlists.erase (x);
3302 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3304 if (_state_of_the_state & Deletion) {
3308 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3315 Glib::Mutex::Lock lm (playlist_lock);
3317 PlaylistList::iterator i;
3319 i = find (playlists.begin(), playlists.end(), playlist);
3320 if (i != playlists.end()) {
3321 playlists.erase (i);
3324 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3325 if (i != unused_playlists.end()) {
3326 unused_playlists.erase (i);
3333 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3337 Session::set_audition (boost::shared_ptr<Region> r)
3339 pending_audition_region = r;
3340 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3341 schedule_butler_transport_work ();
3345 Session::audition_playlist ()
3347 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3348 ev->region.reset ();
3353 Session::non_realtime_set_audition ()
3355 if (!pending_audition_region) {
3356 auditioner->audition_current_playlist ();
3358 auditioner->audition_region (pending_audition_region);
3359 pending_audition_region.reset ();
3361 AuditionActive (true); /* EMIT SIGNAL */
3365 Session::audition_region (boost::shared_ptr<Region> r)
3367 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3373 Session::cancel_audition ()
3375 if (auditioner->active()) {
3376 auditioner->cancel_audition ();
3377 AuditionActive (false); /* EMIT SIGNAL */
3382 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3384 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3388 Session::remove_empty_sounds ()
3390 PathScanner scanner;
3392 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3394 Glib::Mutex::Lock lm (audio_source_lock);
3396 regex_t compiled_tape_track_pattern;
3399 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3403 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3405 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3409 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3411 /* never remove files that appear to be a tape track */
3413 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3418 if (AudioFileSource::is_empty (*this, **i)) {
3420 unlink ((*i)->c_str());
3422 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3423 unlink (peakpath.c_str());
3429 delete possible_audiofiles;
3433 Session::is_auditioning () const
3435 /* can be called before we have an auditioner object */
3437 return auditioner->active();
3444 Session::set_all_solo (bool yn)
3446 shared_ptr<RouteList> r = routes.reader ();
3448 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3449 if (!(*i)->hidden()) {
3450 (*i)->set_solo (yn, this);
3458 Session::set_all_mute (bool yn)
3460 shared_ptr<RouteList> r = routes.reader ();
3462 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3463 if (!(*i)->hidden()) {
3464 (*i)->set_mute (yn, this);
3472 Session::n_diskstreams () const
3476 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3478 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3479 if (!(*i)->hidden()) {
3487 Session::graph_reordered ()
3489 /* don't do this stuff if we are setting up connections
3490 from a set_state() call or creating new tracks.
3493 if (_state_of_the_state & InitialConnecting) {
3497 /* every track/bus asked for this to be handled but it was deferred because
3498 we were connecting. do it now.
3501 request_input_change_handling ();
3505 /* force all diskstreams to update their capture offset values to
3506 reflect any changes in latencies within the graph.
3509 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3511 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3512 (*i)->set_capture_offset ();
3517 Session::record_disenable_all ()
3519 record_enable_change_all (false);
3523 Session::record_enable_all ()
3525 record_enable_change_all (true);
3529 Session::record_enable_change_all (bool yn)
3531 shared_ptr<RouteList> r = routes.reader ();
3533 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3536 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3537 at->set_record_enable (yn, this);
3541 /* since we don't keep rec-enable state, don't mark session dirty */
3545 Session::add_redirect (Redirect* redirect)
3549 PortInsert* port_insert;
3550 PluginInsert* plugin_insert;
3552 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3553 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3554 _port_inserts.insert (_port_inserts.begin(), port_insert);
3555 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3556 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3558 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3561 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3562 _sends.insert (_sends.begin(), send);
3564 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3568 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3574 Session::remove_redirect (Redirect* redirect)
3578 PortInsert* port_insert;
3579 PluginInsert* plugin_insert;
3581 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3582 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3583 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3584 if (x != _port_inserts.end()) {
3585 insert_bitset[port_insert->bit_slot()] = false;
3586 _port_inserts.erase (x);
3588 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3589 _plugin_inserts.remove (plugin_insert);
3591 fatal << string_compose (_("programming error: %1"),
3592 X_("unknown type of Insert deleted!"))
3596 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3597 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3598 if (x != _sends.end()) {
3599 send_bitset[send->bit_slot()] = false;
3603 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3611 Session::available_capture_duration ()
3613 float sample_bytes_on_disk = 4.0; // keep gcc happy
3615 switch (Config->get_native_file_data_format()) {
3617 sample_bytes_on_disk = 4.0;
3621 sample_bytes_on_disk = 3.0;
3625 sample_bytes_on_disk = 2.0;
3629 /* impossible, but keep some gcc versions happy */
3630 fatal << string_compose (_("programming error: %1"),
3631 X_("illegal native file data format"))
3636 double scale = 4096.0 / sample_bytes_on_disk;
3638 if (_total_free_4k_blocks * scale > (double) max_frames) {
3642 return (nframes_t) floor (_total_free_4k_blocks * scale);
3646 Session::add_connection (ARDOUR::Connection* connection)
3649 Glib::Mutex::Lock guard (connection_lock);
3650 _connections.push_back (connection);
3653 ConnectionAdded (connection); /* EMIT SIGNAL */
3659 Session::remove_connection (ARDOUR::Connection* connection)
3661 bool removed = false;
3664 Glib::Mutex::Lock guard (connection_lock);
3665 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3667 if (i != _connections.end()) {
3668 _connections.erase (i);
3674 ConnectionRemoved (connection); /* EMIT SIGNAL */
3680 ARDOUR::Connection *
3681 Session::connection_by_name (string name) const
3683 Glib::Mutex::Lock lm (connection_lock);
3685 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3686 if ((*i)->name() == name) {
3695 Session::tempo_map_changed (Change ignored)
3699 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3700 (*i)->update_after_tempo_map_change ();
3703 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3704 (*i)->update_after_tempo_map_change ();
3711 Session::ensure_passthru_buffers (uint32_t howmany)
3713 if (current_block_size == 0) {
3717 while (howmany > _passthru_buffers.size()) {
3719 #ifdef NO_POSIX_MEMALIGN
3720 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3722 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3723 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3724 current_block_size, sizeof (Sample), strerror (errno))
3729 _passthru_buffers.push_back (p);
3733 #ifdef NO_POSIX_MEMALIGN
3734 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3736 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3737 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3738 current_block_size, sizeof (Sample), strerror (errno))
3743 memset (p, 0, sizeof (Sample) * current_block_size);
3744 _silent_buffers.push_back (p);
3748 #ifdef NO_POSIX_MEMALIGN
3749 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3751 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3753 memset (p, 0, sizeof (Sample) * current_block_size);
3754 _send_buffers.push_back (p);
3757 allocate_pan_automation_buffers (current_block_size, howmany, false);
3761 Session::next_insert_id ()
3763 /* this doesn't really loop forever. just think about it */
3766 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3767 if (!insert_bitset[n]) {
3768 insert_bitset[n] = true;
3774 /* none available, so resize and try again */
3776 insert_bitset.resize (insert_bitset.size() + 16, false);
3781 Session::next_send_id ()
3783 /* this doesn't really loop forever. just think about it */
3786 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3787 if (!send_bitset[n]) {
3788 send_bitset[n] = true;
3794 /* none available, so resize and try again */
3796 send_bitset.resize (send_bitset.size() + 16, false);
3801 Session::mark_send_id (uint32_t id)
3803 if (id >= send_bitset.size()) {
3804 send_bitset.resize (id+16, false);
3806 if (send_bitset[id]) {
3807 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3809 send_bitset[id] = true;
3813 Session::mark_insert_id (uint32_t id)
3815 if (id >= insert_bitset.size()) {
3816 insert_bitset.resize (id+16, false);
3818 if (insert_bitset[id]) {
3819 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3821 insert_bitset[id] = true;
3824 /* Named Selection management */
3827 Session::named_selection_by_name (string name)
3829 Glib::Mutex::Lock lm (named_selection_lock);
3830 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3831 if ((*i)->name == name) {
3839 Session::add_named_selection (NamedSelection* named_selection)
3842 Glib::Mutex::Lock lm (named_selection_lock);
3843 named_selections.insert (named_selections.begin(), named_selection);
3846 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3852 NamedSelectionAdded (); /* EMIT SIGNAL */
3856 Session::remove_named_selection (NamedSelection* named_selection)
3858 bool removed = false;
3861 Glib::Mutex::Lock lm (named_selection_lock);
3863 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3865 if (i != named_selections.end()) {
3867 named_selections.erase (i);
3874 NamedSelectionRemoved (); /* EMIT SIGNAL */
3879 Session::reset_native_file_format ()
3881 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3883 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3884 (*i)->reset_write_sources (false);
3889 Session::route_name_unique (string n) const
3891 shared_ptr<RouteList> r = routes.reader ();
3893 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3894 if ((*i)->name() == n) {
3903 Session::n_playlists () const
3905 Glib::Mutex::Lock lm (playlist_lock);
3906 return playlists.size();
3910 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3912 if (!force && howmany <= _npan_buffers) {
3916 if (_pan_automation_buffer) {
3918 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3919 delete [] _pan_automation_buffer[i];
3922 delete [] _pan_automation_buffer;
3925 _pan_automation_buffer = new pan_t*[howmany];
3927 for (uint32_t i = 0; i < howmany; ++i) {
3928 _pan_automation_buffer[i] = new pan_t[nframes];
3931 _npan_buffers = howmany;
3935 Session::freeze (InterThreadInfo& itt)
3937 shared_ptr<RouteList> r = routes.reader ();
3939 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3943 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3944 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3954 boost::shared_ptr<Region>
3955 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,
3956 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3958 boost::shared_ptr<Region> result;
3959 boost::shared_ptr<Playlist> playlist;
3960 boost::shared_ptr<AudioFileSource> fsource;
3962 char buf[PATH_MAX+1];
3966 nframes_t this_chunk;
3968 nframes_t len = end - start;
3969 vector<Sample*> buffers;
3972 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3973 end, start) << endmsg;
3977 // any bigger than this seems to cause stack overflows in called functions
3978 const nframes_t chunk_size = (128 * 1024)/4;
3980 g_atomic_int_set (&processing_prohibited, 1);
3982 /* call tree *MUST* hold route_lock */
3984 if ((playlist = track.diskstream()->playlist()) == 0) {
3988 /* external redirects will be a problem */
3990 if (track.has_external_redirects()) {
3994 nchans = track.audio_diskstream()->n_channels();
3996 dir = discover_best_sound_dir ();
3998 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
4000 for (x = 0; x < 99999; ++x) {
4001 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4002 if (access (buf, F_OK) != 0) {
4008 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4013 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
4016 catch (failed_constructor& err) {
4017 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4021 srcs.push_back (fsource);
4024 /* XXX need to flush all redirects */
4029 /* create a set of reasonably-sized buffers */
4031 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4033 #ifdef NO_POSIX_MEMALIGN
4034 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4036 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4038 buffers.push_back (b);
4041 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4042 (*src)->prepare_for_peakfile_writes ();
4045 while (to_do && !itt.cancel) {
4047 this_chunk = min (to_do, chunk_size);
4049 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
4054 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4055 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4058 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4064 start += this_chunk;
4065 to_do -= this_chunk;
4067 itt.progress = (float) (1.0 - ((double) to_do / len));
4076 xnow = localtime (&now);
4078 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4079 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4082 afs->update_header (position, *xnow, now);
4083 afs->flush_header ();
4087 /* construct a region to represent the bounced material */
4089 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4090 region_name_from_path (srcs.front()->name(), true));
4095 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4096 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4099 afs->mark_for_remove ();
4102 (*src)->drop_references ();
4106 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4107 (*src)->done_with_peakfile_writes ();
4111 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4115 g_atomic_int_set (&processing_prohibited, 0);
4123 Session::get_silent_buffers (uint32_t howmany)
4125 if (howmany > _silent_buffers.size()) {
4127 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4128 howmany, _silent_buffers.size()) << endmsg;
4130 if (howmany > 1000) {
4131 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4135 while (howmany > _silent_buffers.size()) {
4138 #ifdef NO_POSIX_MEMALIGN
4139 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4141 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
4142 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4143 current_block_size, sizeof (Sample), strerror (errno))
4148 _silent_buffers.push_back (p);
4152 for (uint32_t i = 0; i < howmany; ++i) {
4153 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4156 return _silent_buffers;
4160 Session::ntracks () const
4163 shared_ptr<RouteList> r = routes.reader ();
4165 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4166 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4175 Session::nbusses () const
4178 shared_ptr<RouteList> r = routes.reader ();
4180 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4181 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4190 Session::add_automation_list(AutomationList *al)
4192 automation_lists[al->id()] = al;
4196 Session::compute_initial_length ()
4198 return _engine.frame_rate() * 60 * 5;
4202 Session::sync_order_keys (const char* base)
4204 if (!Config->get_sync_all_route_ordering()) {
4205 /* leave order keys as they are */
4209 boost::shared_ptr<RouteList> r = routes.reader ();
4211 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4212 (*i)->sync_order_keys (base);
4215 Route::SyncOrderKeys (base); // EMIT SIGNAL