2 Copyright (C) 1999-2010 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.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/threads.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/basename.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/convert.h"
42 #include "pbd/convert.h"
43 #include "pbd/error.h"
44 #include "pbd/file_utils.h"
46 #include "pbd/search_path.h"
47 #include "pbd/stacktrace.h"
48 #include "pbd/stl_delete.h"
49 #include "pbd/unwind.h"
51 #include "ardour/amp.h"
52 #include "ardour/analyser.h"
53 #include "ardour/async_midi_port.h"
54 #include "ardour/audio_buffer.h"
55 #include "ardour/audio_diskstream.h"
56 #include "ardour/audio_port.h"
57 #include "ardour/audio_track.h"
58 #include "ardour/audioengine.h"
59 #include "ardour/audiofilesource.h"
60 #include "ardour/auditioner.h"
61 #include "ardour/buffer_manager.h"
62 #include "ardour/buffer_set.h"
63 #include "ardour/bundle.h"
64 #include "ardour/butler.h"
65 #include "ardour/click.h"
66 #include "ardour/control_protocol_manager.h"
67 #include "ardour/data_type.h"
68 #include "ardour/debug.h"
69 #include "ardour/directory_names.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/graph.h"
72 #include "ardour/midiport_manager.h"
73 #include "ardour/scene_changer.h"
74 #include "ardour/midi_track.h"
75 #include "ardour/midi_ui.h"
76 #include "ardour/operations.h"
77 #include "ardour/playlist.h"
78 #include "ardour/plugin.h"
79 #include "ardour/plugin_insert.h"
80 #include "ardour/process_thread.h"
81 #include "ardour/profile.h"
82 #include "ardour/rc_configuration.h"
83 #include "ardour/recent_sessions.h"
84 #include "ardour/region.h"
85 #include "ardour/region_factory.h"
86 #include "ardour/route_graph.h"
87 #include "ardour/route_group.h"
88 #include "ardour/route_sorters.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_playlists.h"
93 #include "ardour/smf_source.h"
94 #include "ardour/source_factory.h"
95 #include "ardour/speakers.h"
96 #include "ardour/tempo.h"
97 #include "ardour/track.h"
98 #include "ardour/user_bundle.h"
99 #include "ardour/utils.h"
101 #include "midi++/port.h"
102 #include "midi++/mmc.h"
113 using namespace ARDOUR;
116 bool Session::_disable_all_loaded_plugins = false;
118 PBD::Signal1<int,uint32_t> Session::AudioEngineSetupRequired;
119 PBD::Signal1<void,std::string> Session::Dialog;
120 PBD::Signal0<int> Session::AskAboutPendingState;
121 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
122 PBD::Signal0<void> Session::SendFeedback;
123 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
125 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
126 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
127 PBD::Signal2<void,std::string, std::string> Session::Exported;
128 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
129 PBD::Signal0<void> Session::Quit;
130 PBD::Signal0<void> Session::FeedbackDetected;
131 PBD::Signal0<void> Session::SuccessfulGraphSort;
132 PBD::Signal2<void,std::string,std::string> Session::VersionMismatch;
134 const framecnt_t Session::bounce_chunk_size = 65536;
135 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
136 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
138 /** @param snapshot_name Snapshot name, without .ardour suffix */
139 Session::Session (AudioEngine &eng,
140 const string& fullpath,
141 const string& snapshot_name,
142 BusProfile* bus_profile,
144 : playlists (new SessionPlaylists)
146 , process_function (&Session::process_with_events)
147 , _bounce_processing_active (false)
148 , waiting_for_sync_offset (false)
149 , _base_frame_rate (0)
150 , _current_frame_rate (0)
151 , _nominal_frame_rate (0)
152 , transport_sub_state (0)
153 , _record_status (Disabled)
154 , _transport_frame (0)
155 , _session_range_location (0)
158 , _transport_speed (0)
159 , _default_transport_speed (1.0)
160 , _last_transport_speed (0)
161 , _target_transport_speed (0.0)
162 , auto_play_legal (false)
163 , _last_slave_transport_frame (0)
164 , maximum_output_latency (0)
165 , _requested_return_frame (-1)
166 , current_block_size (0)
167 , _worst_output_latency (0)
168 , _worst_input_latency (0)
169 , _worst_track_latency (0)
170 , _have_captured (false)
171 , _non_soloed_outs_muted (false)
173 , _solo_isolated_cnt (0)
175 , _was_seamless (Config->get_seamless_loop ())
176 , _under_nsm_control (false)
178 , delta_accumulator_cnt (0)
179 , average_slave_delta (1800) // !!! why 1800 ???
181 , have_first_delta_accumulator (false)
182 , _slave_state (Stopped)
183 , post_export_sync (false)
184 , post_export_position (0)
186 , _export_started (false)
187 , _export_rolling (false)
188 , _pre_export_mmc_enabled (false)
189 , _name (snapshot_name)
191 , _send_qf_mtc (false)
192 , _pframes_since_last_mtc (0)
193 , session_midi_feedback (0)
195 , loop_changing (false)
197 , _session_dir (new SessionDirectory (fullpath))
198 , _current_snapshot_name (snapshot_name)
200 , state_was_pending (false)
201 , _state_of_the_state (StateOfTheState(CannotSave|InitialConnecting|Loading))
203 , _save_queued (false)
204 , _last_roll_location (0)
205 , _last_roll_or_reversal_location (0)
206 , _last_record_location (0)
207 , pending_locate_roll (false)
208 , pending_locate_frame (0)
209 , pending_locate_flush (false)
210 , pending_abort (false)
211 , pending_auto_loop (false)
212 , _butler (new Butler (*this))
213 , _post_transport_work (0)
214 , cumulative_rf_motion (0)
216 , _locations (new Locations (*this))
217 , _ignore_skips_updates (false)
218 , _rt_thread_active (false)
219 , _rt_emit_pending (false)
221 , outbound_mtc_timecode_frame (0)
222 , next_quarter_frame_to_send (-1)
223 , _frames_per_timecode_frame (0)
224 , _frames_per_hour (0)
225 , _timecode_frames_per_hour (0)
226 , last_timecode_valid (false)
227 , last_timecode_when (0)
228 , _send_timecode_update (false)
240 , ltc_timecode_offset (0)
241 , ltc_timecode_negative_offset (false)
242 , midi_control_ui (0)
244 , _all_route_group (new RouteGroup (*this, "all"))
245 , routes (new RouteList)
246 , _adding_routes_in_progress (false)
247 , _route_deletion_in_progress (false)
248 , destructive_index (0)
249 , _track_number_decimals(1)
250 , solo_update_disabled (false)
251 , default_fade_steepness (0)
252 , default_fade_msecs (0)
253 , _total_free_4k_blocks (0)
254 , _total_free_4k_blocks_uncertain (false)
255 , no_questions_about_missing_files (false)
258 , _bundles (new BundleList)
259 , _bundle_xml_node (0)
263 , click_emphasis_data (0)
265 , click_emphasis_length (0)
266 , _clicks_cleared (0)
267 , _play_range (false)
269 , first_file_data_format_reset (true)
270 , first_file_header_format_reset (true)
271 , have_looped (false)
272 , _have_rec_enabled_track (false)
273 , _have_rec_disabled_track (true)
275 , _suspend_timecode_transmission (0)
276 , _speakers (new Speakers)
278 , ignore_route_processor_changes (false)
285 pthread_mutex_init (&_rt_emit_mutex, 0);
286 pthread_cond_init (&_rt_emit_cond, 0);
288 pre_engine_init (fullpath);
291 if (ensure_engine (sr)) {
293 throw failed_constructor ();
296 if (create (mix_template, bus_profile)) {
298 throw failed_constructor ();
301 /* if a mix template was provided, then ::create() will
302 * have copied it into the session and we need to load it
303 * so that we have the state ready for ::set_state()
304 * after the engine is started.
306 * Note that we do NOT try to get the sample rate from
307 * the template at this time, though doing so would
308 * be easy if we decided this was an appropriate part
312 if (!mix_template.empty()) {
313 if (load_state (_current_snapshot_name)) {
314 throw failed_constructor ();
316 store_recent_templates (mix_template);
319 /* load default session properties - if any */
324 if (load_state (_current_snapshot_name)) {
325 throw failed_constructor ();
328 /* try to get sample rate from XML state so that we
329 * can influence the SR if we set up the audio
334 const XMLProperty* prop;
335 if ((prop = state_tree->root()->property (X_("sample-rate"))) != 0) {
336 sr = atoi (prop->value());
340 if (ensure_engine (sr)) {
342 throw failed_constructor ();
346 if (post_engine_init ()) {
348 throw failed_constructor ();
351 store_recent_sessions (_name, _path);
353 bool was_dirty = dirty();
355 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
357 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
358 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
361 DirtyChanged (); /* EMIT SIGNAL */
364 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
365 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
369 emit_thread_start ();
371 /* hook us up to the engine since we are now completely constructed */
373 BootMessage (_("Connect to engine"));
375 _engine.set_session (this);
376 _engine.reset_timebase ();
378 BootMessage (_("Session loading complete"));
391 Session::ensure_engine (uint32_t desired_sample_rate)
393 if (_engine.current_backend() == 0) {
394 /* backend is unknown ... */
395 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
396 if (r.get_value_or (-1) != 0) {
399 } else if (_engine.setup_required()) {
400 /* backend is known, but setup is needed */
401 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
402 if (r.get_value_or (-1) != 0) {
405 } else if (!_engine.running()) {
406 if (_engine.start()) {
411 /* at this point the engine should be running
414 if (!_engine.running()) {
418 return immediately_post_engine ();
423 Session::immediately_post_engine ()
425 /* Do various initializations that should take place directly after we
426 * know that the engine is running, but before we either create a
427 * session or set state for an existing one.
430 if (how_many_dsp_threads () > 1) {
431 /* For now, only create the graph if we are using >1 DSP threads, as
432 it is a bit slower than the old code with 1 thread.
434 _process_graph.reset (new Graph (*this));
437 /* every time we reconnect, recompute worst case output latencies */
439 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
441 if (synced_to_engine()) {
442 _engine.transport_stop ();
445 if (config.get_jack_time_master()) {
446 _engine.transport_locate (_transport_frame);
450 BootMessage (_("Set up LTC"));
452 BootMessage (_("Set up Click"));
454 BootMessage (_("Set up standard connections"));
458 catch (failed_constructor& err) {
462 /* TODO, connect in different thread. (PortRegisteredOrUnregistered may be in RT context)
464 _engine.PortRegisteredOrUnregistered.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
472 vector<void*> debug_pointers;
474 /* if we got to here, leaving pending capture state around
478 remove_pending_capture_state ();
480 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
482 /* disconnect from any and all signals that we are connected to */
486 _engine.remove_session ();
488 /* deregister all ports - there will be no process or any other
489 * callbacks from the engine any more.
492 Port::PortDrop (); /* EMIT SIGNAL */
496 /* clear history so that no references to objects are held any more */
500 /* clear state tree so that no references to objects are held any more */
505 /* reset dynamic state version back to default */
507 Stateful::loading_state_version = 0;
509 _butler->drop_references ();
513 delete _all_route_group;
515 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
516 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
520 if (click_data != default_click) {
521 delete [] click_data;
524 if (click_emphasis_data != default_click_emphasis) {
525 delete [] click_emphasis_data;
530 /* need to remove auditioner before monitoring section
531 * otherwise it is re-connected */
534 /* drop references to routes held by the monitoring section
535 * specifically _monitor_out aux/listen references */
536 remove_monitor_section();
538 /* clear out any pending dead wood from RCU managed objects */
543 AudioDiskstream::free_working_buffers();
545 /* tell everyone who is still standing that we're about to die */
548 /* tell everyone to drop references and delete objects as we go */
550 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
551 RegionFactory::delete_all_regions ();
553 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
555 /* reset these three references to special routes before we do the usual route delete thing */
557 _master_out.reset ();
558 _monitor_out.reset ();
561 RCUWriter<RouteList> writer (routes);
562 boost::shared_ptr<RouteList> r = writer.get_copy ();
564 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
565 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
566 (*i)->drop_references ();
570 /* writer goes out of scope and updates master */
575 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
576 Glib::Threads::Mutex::Lock lm (source_lock);
577 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
578 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
579 i->second->drop_references ();
585 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
588 emit_thread_terminate ();
590 pthread_cond_destroy (&_rt_emit_cond);
591 pthread_mutex_destroy (&_rt_emit_mutex);
593 delete _scene_changer; _scene_changer = 0;
594 delete midi_control_ui; midi_control_ui = 0;
596 delete _mmc; _mmc = 0;
597 delete _midi_ports; _midi_ports = 0;
598 delete _locations; _locations = 0;
602 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
604 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
605 boost_debug_list_ptrs ();
610 Session::setup_ltc ()
614 _ltc_input.reset (new IO (*this, X_("LTC In"), IO::Input));
615 _ltc_output.reset (new IO (*this, X_("LTC Out"), IO::Output));
617 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC In"))) != 0) {
618 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
621 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
622 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
624 reconnect_ltc_input ();
627 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC Out"))) != 0) {
628 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
631 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
632 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
634 reconnect_ltc_output ();
637 /* fix up names of LTC ports because we don't want the normal
638 * IO style of NAME/TYPE-{in,out}N
641 _ltc_input->nth (0)->set_name (X_("LTC-in"));
642 _ltc_output->nth (0)->set_name (X_("LTC-out"));
646 Session::setup_click ()
649 _click_io.reset (new ClickIO (*this, X_("Click")));
650 _click_gain.reset (new Amp (*this));
651 _click_gain->activate ();
653 setup_click_state (state_tree->root());
655 setup_click_state (0);
660 Session::setup_click_state (const XMLNode* node)
662 const XMLNode* child = 0;
664 if (node && (child = find_named_node (*node, "Click")) != 0) {
666 /* existing state for Click */
669 if (Stateful::loading_state_version < 3000) {
670 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
672 const XMLNodeList& children (child->children());
673 XMLNodeList::const_iterator i = children.begin();
674 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
676 if (i != children.end()) {
677 c = _click_gain->set_state (**i, Stateful::loading_state_version);
683 _clicking = Config->get_clicking ();
687 error << _("could not setup Click I/O") << endmsg;
694 /* default state for Click: dual-mono to first 2 physical outputs */
697 _engine.get_physical_outputs (DataType::AUDIO, outs);
699 for (uint32_t physport = 0; physport < 2; ++physport) {
700 if (outs.size() > physport) {
701 if (_click_io->add_port (outs[physport], this)) {
702 // relax, even though its an error
707 if (_click_io->n_ports () > ChanCount::ZERO) {
708 _clicking = Config->get_clicking ();
714 Session::setup_bundles ()
718 RCUWriter<BundleList> writer (_bundles);
719 boost::shared_ptr<BundleList> b = writer.get_copy ();
720 for (BundleList::iterator i = b->begin(); i != b->end();) {
721 if (boost::dynamic_pointer_cast<UserBundle>(*i)) {
729 vector<string> inputs[DataType::num_types];
730 vector<string> outputs[DataType::num_types];
731 for (uint32_t i = 0; i < DataType::num_types; ++i) {
732 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
733 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
736 /* Create a set of Bundle objects that map
737 to the physical I/O currently available. We create both
738 mono and stereo bundles, so that the common cases of mono
739 and stereo tracks get bundles to put in their mixer strip
740 in / out menus. There may be a nicer way of achieving that;
741 it doesn't really scale that well to higher channel counts
744 /* mono output bundles */
746 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
748 std::string pn = _engine.get_pretty_name_by_name (outputs[DataType::AUDIO][np]);
750 snprintf (buf, sizeof (buf), _("out %s"), pn.substr(0,12).c_str());
752 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
755 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
756 c->add_channel (_("mono"), DataType::AUDIO);
757 c->set_port (0, outputs[DataType::AUDIO][np]);
759 add_bundle (c, false);
762 /* stereo output bundles */
764 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
765 if (np + 1 < outputs[DataType::AUDIO].size()) {
767 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
768 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
769 c->add_channel (_("L"), DataType::AUDIO);
770 c->set_port (0, outputs[DataType::AUDIO][np]);
771 c->add_channel (_("R"), DataType::AUDIO);
772 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
774 add_bundle (c, false);
778 /* mono input bundles */
780 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
782 std::string pn = _engine.get_pretty_name_by_name (inputs[DataType::AUDIO][np]);
784 snprintf (buf, sizeof (buf), _("in %s"), pn.substr(0,12).c_str());
786 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
789 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
790 c->add_channel (_("mono"), DataType::AUDIO);
791 c->set_port (0, inputs[DataType::AUDIO][np]);
793 add_bundle (c, false);
796 /* stereo input bundles */
798 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
799 if (np + 1 < inputs[DataType::AUDIO].size()) {
801 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
803 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
804 c->add_channel (_("L"), DataType::AUDIO);
805 c->set_port (0, inputs[DataType::AUDIO][np]);
806 c->add_channel (_("R"), DataType::AUDIO);
807 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
809 add_bundle (c, false);
813 /* MIDI input bundles */
815 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
816 string n = inputs[DataType::MIDI][np];
817 std::string pn = _engine.get_pretty_name_by_name (n);
821 boost::erase_first (n, X_("alsa_pcm:"));
823 boost::shared_ptr<Bundle> c (new Bundle (n, false));
824 c->add_channel ("", DataType::MIDI);
825 c->set_port (0, inputs[DataType::MIDI][np]);
826 add_bundle (c, false);
829 /* MIDI output bundles */
831 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
832 string n = outputs[DataType::MIDI][np];
833 std::string pn = _engine.get_pretty_name_by_name (n);
837 boost::erase_first (n, X_("alsa_pcm:"));
839 boost::shared_ptr<Bundle> c (new Bundle (n, true));
840 c->add_channel ("", DataType::MIDI);
841 c->set_port (0, outputs[DataType::MIDI][np]);
842 add_bundle (c, false);
845 // we trust the backend to only calls us if there's a change
846 BundleAddedOrRemoved (); /* EMIT SIGNAL */
850 Session::auto_connect_master_bus ()
852 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
856 /* if requested auto-connect the outputs to the first N physical ports.
859 uint32_t limit = _master_out->n_outputs().n_total();
860 vector<string> outputs[DataType::num_types];
862 for (uint32_t i = 0; i < DataType::num_types; ++i) {
863 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
866 for (uint32_t n = 0; n < limit; ++n) {
867 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
869 if (outputs[p->type()].size() > n) {
870 connect_to = outputs[p->type()][n];
873 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
874 if (_master_out->output()->connect (p, connect_to, this)) {
875 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
884 Session::remove_monitor_section ()
890 /* force reversion to Solo-In-Place */
891 Config->set_solo_control_is_listen_control (false);
893 /* if we are auditioning, cancel it ... this is a workaround
894 to a problem (auditioning does not execute the process graph,
895 which is needed to remove routes when using >1 core for processing)
900 /* Hold process lock while doing this so that we don't hear bits and
901 * pieces of audio as we work on each route.
904 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
906 /* Connect tracks to monitor section. Note that in an
907 existing session, the internal sends will already exist, but we want the
908 routes to notice that they connect to the control out specifically.
912 boost::shared_ptr<RouteList> r = routes.reader ();
913 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
915 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
917 if ((*x)->is_monitor()) {
919 } else if ((*x)->is_master()) {
922 (*x)->remove_aux_or_listen (_monitor_out);
927 remove_route (_monitor_out);
928 auto_connect_master_bus ();
931 auditioner->connect ();
936 Session::add_monitor_section ()
940 if (_monitor_out || !_master_out) {
944 boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), Route::MonitorOut, DataType::AUDIO));
950 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
951 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
954 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
955 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
956 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
960 add_routes (rl, false, false, false);
962 assert (_monitor_out);
964 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
965 are undefined, at best.
968 uint32_t limit = _monitor_out->n_inputs().n_audio();
972 /* connect the inputs to the master bus outputs. this
973 * represents a separate data feed from the internal sends from
974 * each route. as of jan 2011, it allows the monitor section to
975 * conditionally ignore either the internal sends or the normal
976 * input feed, but we should really find a better way to do
980 _master_out->output()->disconnect (this);
982 for (uint32_t n = 0; n < limit; ++n) {
983 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
984 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
987 string connect_to = o->name();
988 if (_monitor_out->input()->connect (p, connect_to, this)) {
989 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
997 /* if monitor section is not connected, connect it to physical outs
1000 if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
1002 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1004 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1007 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1009 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1010 Config->get_monitor_bus_preferred_bundle())
1016 /* Monitor bus is audio only */
1018 vector<string> outputs[DataType::num_types];
1020 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1021 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1024 uint32_t mod = outputs[DataType::AUDIO].size();
1025 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1029 for (uint32_t n = 0; n < limit; ++n) {
1031 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1033 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1034 connect_to = outputs[DataType::AUDIO][n % mod];
1037 if (!connect_to.empty()) {
1038 if (_monitor_out->output()->connect (p, connect_to, this)) {
1039 error << string_compose (
1040 _("cannot connect control output %1 to %2"),
1051 /* Hold process lock while doing this so that we don't hear bits and
1052 * pieces of audio as we work on each route.
1055 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1057 /* Connect tracks to monitor section. Note that in an
1058 existing session, the internal sends will already exist, but we want the
1059 routes to notice that they connect to the control out specifically.
1063 boost::shared_ptr<RouteList> rls = routes.reader ();
1065 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
1067 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1069 if ((*x)->is_monitor()) {
1071 } else if ((*x)->is_master()) {
1074 (*x)->enable_monitor_send ();
1079 auditioner->connect ();
1084 Session::reset_monitor_section ()
1086 /* Process lock should be held by the caller.*/
1088 if (!_monitor_out) {
1092 uint32_t limit = _master_out->n_outputs().n_audio();
1094 /* connect the inputs to the master bus outputs. this
1095 * represents a separate data feed from the internal sends from
1096 * each route. as of jan 2011, it allows the monitor section to
1097 * conditionally ignore either the internal sends or the normal
1098 * input feed, but we should really find a better way to do
1102 _master_out->output()->disconnect (this);
1103 _monitor_out->output()->disconnect (this);
1105 _monitor_out->input()->ensure_io (_master_out->output()->n_ports(), false, this);
1106 _monitor_out->output()->ensure_io (_master_out->output()->n_ports(), false, this);
1108 for (uint32_t n = 0; n < limit; ++n) {
1109 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1110 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1113 string connect_to = o->name();
1114 if (_monitor_out->input()->connect (p, connect_to, this)) {
1115 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1122 /* connect monitor section to physical outs
1125 if (Config->get_auto_connect_standard_busses()) {
1127 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1129 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1132 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1134 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1135 Config->get_monitor_bus_preferred_bundle())
1141 /* Monitor bus is audio only */
1143 vector<string> outputs[DataType::num_types];
1145 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1146 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1149 uint32_t mod = outputs[DataType::AUDIO].size();
1150 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1154 for (uint32_t n = 0; n < limit; ++n) {
1156 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1158 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1159 connect_to = outputs[DataType::AUDIO][n % mod];
1162 if (!connect_to.empty()) {
1163 if (_monitor_out->output()->connect (p, connect_to, this)) {
1164 error << string_compose (
1165 _("cannot connect control output %1 to %2"),
1176 /* Connect tracks to monitor section. Note that in an
1177 existing session, the internal sends will already exist, but we want the
1178 routes to notice that they connect to the control out specifically.
1182 boost::shared_ptr<RouteList> rls = routes.reader ();
1184 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
1186 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1188 if ((*x)->is_monitor()) {
1190 } else if ((*x)->is_master()) {
1193 (*x)->enable_monitor_send ();
1199 Session::hookup_io ()
1201 /* stop graph reordering notifications from
1202 causing resorts, etc.
1205 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
1209 /* we delay creating the auditioner till now because
1210 it makes its own connections to ports.
1214 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
1216 throw failed_constructor ();
1218 a->use_new_diskstream ();
1222 catch (failed_constructor& err) {
1223 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
1227 /* load bundles, which we may have postponed earlier on */
1228 if (_bundle_xml_node) {
1229 load_bundles (*_bundle_xml_node);
1230 delete _bundle_xml_node;
1233 /* Tell all IO objects to connect themselves together */
1235 IO::enable_connecting ();
1237 /* Now tell all "floating" ports to connect to whatever
1238 they should be connected to.
1241 AudioEngine::instance()->reconnect_ports ();
1243 /* Anyone who cares about input state, wake up and do something */
1245 IOConnectionsComplete (); /* EMIT SIGNAL */
1247 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
1249 /* now handle the whole enchilada as if it was one
1250 graph reorder event.
1255 /* update the full solo state, which can't be
1256 correctly determined on a per-route basis, but
1257 needs the global overview that only the session
1261 update_route_solo_state ();
1265 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
1267 boost::shared_ptr<Track> track = wp.lock ();
1272 boost::shared_ptr<Playlist> playlist;
1274 if ((playlist = track->playlist()) != 0) {
1275 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
1276 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
1277 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
1282 Session::record_enabling_legal () const
1284 /* this used to be in here, but survey says.... we don't need to restrict it */
1285 // if (record_status() == Recording) {
1289 if (Config->get_all_safe()) {
1296 Session::set_track_monitor_input_status (bool yn)
1298 boost::shared_ptr<RouteList> rl = routes.reader ();
1299 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1300 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
1301 if (tr && tr->record_enabled ()) {
1302 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1303 tr->request_input_monitoring (yn);
1309 Session::auto_punch_start_changed (Location* location)
1311 replace_event (SessionEvent::PunchIn, location->start());
1313 if (get_record_enabled() && config.get_punch_in()) {
1314 /* capture start has been changed, so save new pending state */
1315 save_state ("", true);
1320 Session::auto_punch_end_changed (Location* location)
1322 framepos_t when_to_stop = location->end();
1323 // when_to_stop += _worst_output_latency + _worst_input_latency;
1324 replace_event (SessionEvent::PunchOut, when_to_stop);
1328 Session::auto_punch_changed (Location* location)
1330 framepos_t when_to_stop = location->end();
1332 replace_event (SessionEvent::PunchIn, location->start());
1333 //when_to_stop += _worst_output_latency + _worst_input_latency;
1334 replace_event (SessionEvent::PunchOut, when_to_stop);
1337 /** @param loc A loop location.
1338 * @param pos Filled in with the start time of the required fade-out (in session frames).
1339 * @param length Filled in with the length of the required fade-out.
1342 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
1344 pos = max (loc->start(), loc->end() - 64);
1345 length = loc->end() - pos;
1349 Session::auto_loop_changed (Location* location)
1351 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
1354 auto_loop_declick_range (location, dcp, dcl);
1356 if (transport_rolling() && play_loop) {
1358 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
1360 // if (_transport_frame > location->end()) {
1362 if (_transport_frame < location->start() || _transport_frame > location->end()) {
1363 // relocate to beginning of loop
1364 clear_events (SessionEvent::LocateRoll);
1366 request_locate (location->start(), true);
1369 else if (Config->get_seamless_loop() && !loop_changing) {
1371 // schedule a locate-roll to refill the diskstreams at the
1372 // previous loop end
1373 loop_changing = true;
1375 if (location->end() > last_loopend) {
1376 clear_events (SessionEvent::LocateRoll);
1377 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1383 clear_events (SessionEvent::AutoLoopDeclick);
1384 clear_events (SessionEvent::AutoLoop);
1387 last_loopend = location->end();
1392 Session::set_auto_punch_location (Location* location)
1396 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1397 punch_connections.drop_connections();
1398 existing->set_auto_punch (false, this);
1399 remove_event (existing->start(), SessionEvent::PunchIn);
1400 clear_events (SessionEvent::PunchOut);
1401 auto_punch_location_changed (0);
1406 if (location == 0) {
1410 if (location->end() <= location->start()) {
1411 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1415 punch_connections.drop_connections ();
1417 location->StartChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, location));
1418 location->EndChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, location));
1419 location->Changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, location));
1421 location->set_auto_punch (true, this);
1423 auto_punch_changed (location);
1425 auto_punch_location_changed (location);
1429 Session::set_session_extents (framepos_t start, framepos_t end)
1432 if ((existing = _locations->session_range_location()) == 0) {
1433 //if there is no existing session, we need to make a new session location (should never happen)
1434 existing = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1438 error << _("Session: you can't use that location for session start/end)") << endmsg;
1442 existing->set( start, end );
1448 Session::set_auto_loop_location (Location* location)
1452 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1453 loop_connections.drop_connections ();
1454 existing->set_auto_loop (false, this);
1455 remove_event (existing->end(), SessionEvent::AutoLoop);
1458 auto_loop_declick_range (existing, dcp, dcl);
1459 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1460 auto_loop_location_changed (0);
1465 if (location == 0) {
1469 if (location->end() <= location->start()) {
1470 error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
1474 last_loopend = location->end();
1476 loop_connections.drop_connections ();
1478 location->StartChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1479 location->EndChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1480 location->Changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1482 location->set_auto_loop (true, this);
1484 /* take care of our stuff first */
1486 auto_loop_changed (location);
1488 /* now tell everyone else */
1490 auto_loop_location_changed (location);
1494 Session::update_loop (Location*)
1500 Session::update_marks (Location*)
1506 Session::update_skips (Location* loc, bool consolidate)
1508 if (_ignore_skips_updates) {
1512 Locations::LocationList skips;
1515 PBD::Unwinder<bool> uw (_ignore_skips_updates, true);
1516 consolidate_skips (loc);
1519 sync_locations_to_skips ();
1525 Session::consolidate_skips (Location* loc)
1527 Locations::LocationList all_locations = _locations->list ();
1529 for (Locations::LocationList::iterator l = all_locations.begin(); l != all_locations.end(); ) {
1531 if (!(*l)->is_skip ()) {
1536 /* don't test against self */
1543 switch (Evoral::coverage ((*l)->start(), (*l)->end(), loc->start(), loc->end())) {
1544 case Evoral::OverlapInternal:
1545 case Evoral::OverlapExternal:
1546 case Evoral::OverlapStart:
1547 case Evoral::OverlapEnd:
1548 /* adjust new location to cover existing one */
1549 loc->set_start (min (loc->start(), (*l)->start()));
1550 loc->set_end (max (loc->end(), (*l)->end()));
1551 /* we don't need this one any more */
1552 _locations->remove (*l);
1553 /* the location has been deleted, so remove reference to it in our local list */
1554 l = all_locations.erase (l);
1557 case Evoral::OverlapNone:
1565 Session::sync_locations_to_skips ()
1567 /* This happens asynchronously (in the audioengine thread). After the clear is done, we will call
1568 * Session::_sync_locations_to_skips() from the audioengine thread.
1570 clear_events (SessionEvent::Skip, boost::bind (&Session::_sync_locations_to_skips, this));
1574 Session::_sync_locations_to_skips ()
1576 /* called as a callback after existing Skip events have been cleared from a realtime audioengine thread */
1578 Locations::LocationList const & locs (_locations->list());
1580 for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) {
1582 Location* location = *i;
1584 if (location->is_skip() && location->is_skipping()) {
1585 SessionEvent* ev = new SessionEvent (SessionEvent::Skip, SessionEvent::Add, location->start(), location->end(), 1.0);
1593 Session::location_added (Location *location)
1595 if (location->is_auto_punch()) {
1596 set_auto_punch_location (location);
1599 if (location->is_auto_loop()) {
1600 set_auto_loop_location (location);
1603 if (location->is_session_range()) {
1604 /* no need for any signal handling or event setting with the session range,
1605 because we keep a direct reference to it and use its start/end directly.
1607 _session_range_location = location;
1610 if (location->is_mark()) {
1611 /* listen for per-location signals that require us to do any * global updates for marks */
1613 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1614 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1615 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1616 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1619 if (location->is_skip()) {
1620 /* listen for per-location signals that require us to update skip-locate events */
1622 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1623 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1624 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1625 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, false));
1627 update_skips (location, true);
1634 Session::location_removed (Location *location)
1636 if (location->is_auto_loop()) {
1637 set_auto_loop_location (0);
1638 set_track_loop (false);
1641 if (location->is_auto_punch()) {
1642 set_auto_punch_location (0);
1645 if (location->is_session_range()) {
1646 /* this is never supposed to happen */
1647 error << _("programming error: session range removed!") << endl;
1650 if (location->is_skip()) {
1652 update_skips (location, false);
1659 Session::locations_changed ()
1661 _locations->apply (*this, &Session::_locations_changed);
1665 Session::_locations_changed (const Locations::LocationList& locations)
1667 /* There was some mass-change in the Locations object.
1669 We might be re-adding a location here but it doesn't actually matter
1670 for all the locations that the Session takes an interest in.
1673 for (Locations::LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
1674 location_added (*i);
1679 Session::enable_record ()
1681 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1682 /* no recording at anything except normal speed */
1687 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1689 if (rs == Recording) {
1693 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1695 _last_record_location = _transport_frame;
1696 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1698 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1699 set_track_monitor_input_status (true);
1702 RecordStateChanged ();
1709 Session::disable_record (bool rt_context, bool force)
1713 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1715 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1716 g_atomic_int_set (&_record_status, Disabled);
1717 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1719 if (rs == Recording) {
1720 g_atomic_int_set (&_record_status, Enabled);
1724 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1725 set_track_monitor_input_status (false);
1728 RecordStateChanged (); /* emit signal */
1731 remove_pending_capture_state ();
1737 Session::step_back_from_record ()
1739 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1741 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1742 set_track_monitor_input_status (false);
1745 RecordStateChanged (); /* emit signal */
1750 Session::maybe_enable_record ()
1752 if (_step_editors > 0) {
1756 g_atomic_int_set (&_record_status, Enabled);
1758 /* This function is currently called from somewhere other than an RT thread.
1759 This save_state() call therefore doesn't impact anything. Doing it here
1760 means that we save pending state of which sources the next record will use,
1761 which gives us some chance of recovering from a crash during the record.
1764 save_state ("", true);
1766 if (_transport_speed) {
1767 if (!config.get_punch_in()) {
1771 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1772 RecordStateChanged (); /* EMIT SIGNAL */
1779 Session::audible_frame () const
1785 offset = worst_playback_latency ();
1787 if (synced_to_engine()) {
1788 /* Note: this is basically just sync-to-JACK */
1789 tf = _engine.transport_frame();
1791 tf = _transport_frame;
1796 if (!non_realtime_work_pending()) {
1800 /* Check to see if we have passed the first guaranteed
1801 audible frame past our last start position. if not,
1802 return that last start point because in terms
1803 of audible frames, we have not moved yet.
1805 `Start position' in this context means the time we last
1806 either started, located, or changed transport direction.
1809 if (_transport_speed > 0.0f) {
1811 if (!play_loop || !have_looped) {
1812 if (tf < _last_roll_or_reversal_location + offset) {
1813 return _last_roll_or_reversal_location;
1821 } else if (_transport_speed < 0.0f) {
1823 /* XXX wot? no backward looping? */
1825 if (tf > _last_roll_or_reversal_location - offset) {
1826 return _last_roll_or_reversal_location;
1838 Session::set_frame_rate (framecnt_t frames_per_second)
1840 /** \fn void Session::set_frame_size(framecnt_t)
1841 the AudioEngine object that calls this guarantees
1842 that it will not be called while we are also in
1843 ::process(). Its fine to do things that block
1847 _base_frame_rate = frames_per_second;
1848 _nominal_frame_rate = frames_per_second;
1854 // XXX we need some equivalent to this, somehow
1855 // SndFileSource::setup_standard_crossfades (frames_per_second);
1859 /* XXX need to reset/reinstantiate all LADSPA plugins */
1863 Session::set_block_size (pframes_t nframes)
1865 /* the AudioEngine guarantees
1866 that it will not be called while we are also in
1867 ::process(). It is therefore fine to do things that block
1872 current_block_size = nframes;
1876 boost::shared_ptr<RouteList> r = routes.reader ();
1878 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1879 (*i)->set_block_size (nframes);
1882 boost::shared_ptr<RouteList> rl = routes.reader ();
1883 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1884 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1886 tr->set_block_size (nframes);
1890 set_worst_io_latencies ();
1896 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1898 boost::shared_ptr<Route> r2;
1900 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1901 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1905 /* make a copy of the existing list of routes that feed r1 */
1907 Route::FedBy existing (r1->fed_by());
1909 /* for each route that feeds r1, recurse, marking it as feeding
1913 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1914 if (!(r2 = i->r.lock ())) {
1915 /* (*i) went away, ignore it */
1919 /* r2 is a route that feeds r1 which somehow feeds base. mark
1920 base as being fed by r2
1923 rbase->add_fed_by (r2, i->sends_only);
1927 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1931 if (r1->feeds (r2) && r2->feeds (r1)) {
1935 /* now recurse, so that we can mark base as being fed by
1936 all routes that feed r2
1939 trace_terminal (r2, rbase);
1946 Session::resort_routes ()
1948 /* don't do anything here with signals emitted
1949 by Routes during initial setup or while we
1950 are being destroyed.
1953 if (_state_of_the_state & (InitialConnecting | Deletion)) {
1958 RCUWriter<RouteList> writer (routes);
1959 boost::shared_ptr<RouteList> r = writer.get_copy ();
1960 resort_routes_using (r);
1961 /* writer goes out of scope and forces update */
1965 boost::shared_ptr<RouteList> rl = routes.reader ();
1966 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1967 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1969 const Route::FedBy& fb ((*i)->fed_by());
1971 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1972 boost::shared_ptr<Route> sf = f->r.lock();
1974 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1982 /** This is called whenever we need to rebuild the graph of how we will process
1984 * @param r List of routes, in any order.
1988 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1990 /* We are going to build a directed graph of our routes;
1991 this is where the edges of that graph are put.
1996 /* Go through all routes doing two things:
1998 * 1. Collect the edges of the route graph. Each of these edges
1999 * is a pair of routes, one of which directly feeds the other
2000 * either by a JACK connection or by an internal send.
2002 * 2. Begin the process of making routes aware of which other
2003 * routes directly or indirectly feed them. This information
2004 * is used by the solo code.
2007 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2009 /* Clear out the route's list of direct or indirect feeds */
2010 (*i)->clear_fed_by ();
2012 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
2014 bool via_sends_only;
2016 /* See if this *j feeds *i according to the current state of the JACK
2017 connections and internal sends.
2019 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
2020 /* add the edge to the graph (part #1) */
2021 edges.add (*j, *i, via_sends_only);
2022 /* tell the route (for part #2) */
2023 (*i)->add_fed_by (*j, via_sends_only);
2028 /* Attempt a topological sort of the route graph */
2029 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
2031 if (sorted_routes) {
2032 /* We got a satisfactory topological sort, so there is no feedback;
2035 Note: the process graph rechain does not require a
2036 topologically-sorted list, but hey ho.
2038 if (_process_graph) {
2039 _process_graph->rechain (sorted_routes, edges);
2042 _current_route_graph = edges;
2044 /* Complete the building of the routes' lists of what directly
2045 or indirectly feeds them.
2047 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2048 trace_terminal (*i, *i);
2051 *r = *sorted_routes;
2054 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
2055 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2056 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
2057 (*i)->name(), (*i)->order_key ()));
2061 SuccessfulGraphSort (); /* EMIT SIGNAL */
2064 /* The topological sort failed, so we have a problem. Tell everyone
2065 and stick to the old graph; this will continue to be processed, so
2066 until the feedback is fixed, what is played back will not quite
2067 reflect what is actually connected. Note also that we do not
2068 do trace_terminal here, as it would fail due to an endless recursion,
2069 so the solo code will think that everything is still connected
2073 FeedbackDetected (); /* EMIT SIGNAL */
2078 /** Find a route name starting with \a base, maybe followed by the
2079 * lowest \a id. \a id will always be added if \a definitely_add_number
2080 * is true on entry; otherwise it will only be added if required
2081 * to make the name unique.
2083 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
2084 * The available route name with the lowest ID will be used, and \a id
2085 * will be set to the ID.
2087 * \return false if a route name could not be found, and \a track_name
2088 * and \a id do not reflect a free route name.
2091 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
2093 if (!definitely_add_number && route_by_name (base) == 0) {
2094 /* juse use the base */
2095 snprintf (name, name_len, "%s", base.c_str());
2100 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
2102 if (route_by_name (name) == 0) {
2108 } while (id < (UINT_MAX-1));
2113 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
2115 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
2117 in = ChanCount::ZERO;
2118 out = ChanCount::ZERO;
2120 boost::shared_ptr<RouteList> r = routes.reader ();
2122 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2123 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2124 if (tr && !tr->is_auditioner()) {
2125 in += tr->n_inputs();
2126 out += tr->n_outputs();
2131 /** Caller must not hold process lock
2132 * @param name_template string to use for the start of the name, or "" to use "MIDI".
2133 * @param instrument plugin info for the instrument to insert pre-fader, if any
2135 list<boost::shared_ptr<MidiTrack> >
2136 Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
2137 TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
2139 char track_name[32];
2140 uint32_t track_id = 0;
2142 RouteList new_routes;
2143 list<boost::shared_ptr<MidiTrack> > ret;
2145 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
2148 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
2149 error << "cannot find name for new midi track" << endmsg;
2153 boost::shared_ptr<MidiTrack> track;
2156 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
2158 if (track->init ()) {
2162 track->use_new_diskstream();
2164 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
2165 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
2168 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2169 if (track->input()->ensure_io (input, false, this)) {
2170 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
2174 if (track->output()->ensure_io (output, false, this)) {
2175 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
2180 track->non_realtime_input_change();
2183 route_group->add (track);
2186 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
2188 if (Config->get_remote_model() == UserOrdered) {
2189 track->set_remote_control_id (next_control_id());
2192 new_routes.push_back (track);
2193 ret.push_back (track);
2196 catch (failed_constructor &err) {
2197 error << _("Session: could not create new midi track.") << endmsg;
2201 catch (AudioEngine::PortRegistrationFailure& pfe) {
2203 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with more ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
2211 if (!new_routes.empty()) {
2212 StateProtector sp (this);
2213 if (Profile->get_trx()) {
2214 add_routes (new_routes, false, false, false);
2216 add_routes (new_routes, true, true, false);
2220 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
2221 PluginPtr plugin = instrument->load (*this);
2222 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
2223 (*r)->add_processor (p, PreFader);
2233 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
2235 boost::shared_ptr<Route> midi_track (wmt.lock());
2241 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
2243 if (change.after.n_audio() <= change.before.n_audio()) {
2247 /* new audio ports: make sure the audio goes somewhere useful,
2248 unless the user has no-auto-connect selected.
2250 The existing ChanCounts don't matter for this call as they are only
2251 to do with matching input and output indices, and we are only changing
2257 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
2261 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
2262 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
2263 * @param output_start As \a input_start, but for outputs.
2266 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
2267 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
2269 if (!IO::connecting_legal) {
2273 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
2279 /* If both inputs and outputs are auto-connected to physical ports,
2280 use the max of input and output offsets to ensure auto-connected
2281 port numbers always match up (e.g. the first audio input and the
2282 first audio output of the route will have the same physical
2283 port number). Otherwise just use the lowest input or output
2287 DEBUG_TRACE (DEBUG::Graph,
2288 string_compose("Auto-connect: existing in = %1 out = %2\n",
2289 existing_inputs, existing_outputs));
2291 const bool in_out_physical =
2292 (Config->get_input_auto_connect() & AutoConnectPhysical)
2293 && (Config->get_output_auto_connect() & AutoConnectPhysical)
2296 const ChanCount in_offset = in_out_physical
2297 ? ChanCount::max(existing_inputs, existing_outputs)
2300 const ChanCount out_offset = in_out_physical
2301 ? ChanCount::max(existing_inputs, existing_outputs)
2304 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2305 vector<string> physinputs;
2306 vector<string> physoutputs;
2308 _engine.get_physical_outputs (*t, physoutputs);
2309 _engine.get_physical_inputs (*t, physinputs);
2311 if (!physinputs.empty() && connect_inputs) {
2312 uint32_t nphysical_in = physinputs.size();
2314 DEBUG_TRACE (DEBUG::Graph,
2315 string_compose("There are %1 physical inputs of type %2\n",
2318 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
2321 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
2322 DEBUG_TRACE (DEBUG::Graph,
2323 string_compose("Get index %1 + %2 % %3 = %4\n",
2324 in_offset.get(*t), i, nphysical_in,
2325 (in_offset.get(*t) + i) % nphysical_in));
2326 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
2329 DEBUG_TRACE (DEBUG::Graph,
2330 string_compose("Connect route %1 IN to %2\n",
2331 route->name(), port));
2333 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
2337 ChanCount one_added (*t, 1);
2338 existing_inputs += one_added;
2342 if (!physoutputs.empty()) {
2343 uint32_t nphysical_out = physoutputs.size();
2344 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
2347 if ((*t) == DataType::MIDI && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
2348 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
2349 } else if ((*t) == DataType::AUDIO && (Config->get_output_auto_connect() & AutoConnectMaster)) {
2350 /* master bus is audio only */
2351 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
2352 port = _master_out->input()->ports().port(*t,
2353 i % _master_out->input()->n_ports().get(*t))->name();
2357 DEBUG_TRACE (DEBUG::Graph,
2358 string_compose("Connect route %1 OUT to %2\n",
2359 route->name(), port));
2361 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
2365 ChanCount one_added (*t, 1);
2366 existing_outputs += one_added;
2373 Session::reconnect_existing_routes (bool withLock, bool reconnect_master, bool reconnect_inputs, bool reconnect_outputs)
2375 /* TRX does stuff here, ardour does not (but probably should). This is called after an engine reset (in particular).
2379 #ifdef USE_TRACKS_CODE_FEATURES
2382 Session::reconnect_midi_scene_ports(bool inputs)
2385 scene_in()->disconnect_all ();
2387 std::vector<EngineStateController::MidiPortState> midi_port_states;
2388 EngineStateController::instance()->get_physical_midi_input_states (midi_port_states);
2390 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2392 for (; state_iter != midi_port_states.end(); ++state_iter) {
2393 if (state_iter->active && state_iter->available && state_iter->connected) {
2394 scene_in()->connect (state_iter->name);
2399 scene_out()->disconnect_all ();
2401 std::vector<EngineStateController::MidiPortState> midi_port_states;
2402 EngineStateController::instance()->get_physical_midi_output_states (midi_port_states);
2404 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2406 for (; state_iter != midi_port_states.end(); ++state_iter) {
2407 if (state_iter->active && state_iter->available && state_iter->connected) {
2408 scene_out()->connect (state_iter->name);
2417 /** Caller must not hold process lock
2418 * @param name_template string to use for the start of the name, or "" to use "Audio".
2420 list< boost::shared_ptr<AudioTrack> >
2421 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
2422 uint32_t how_many, string name_template)
2424 char track_name[32];
2425 uint32_t track_id = 0;
2427 RouteList new_routes;
2428 list<boost::shared_ptr<AudioTrack> > ret;
2430 string name_pattern;
2432 if (Profile->get_trx() ) {
2433 name_pattern = "Track ";
2435 name_pattern = "Audio ";
2438 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _(name_pattern.c_str() );
2442 if (!find_route_name (name_template.empty() ? _(name_pattern.c_str()) : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
2443 error << "cannot find name for new audio track" << endmsg;
2447 boost::shared_ptr<AudioTrack> track;
2450 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
2452 if (track->init ()) {
2456 track->use_new_diskstream();
2458 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
2459 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
2462 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2464 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
2465 error << string_compose (
2466 _("cannot configure %1 in/%2 out configuration for new audio track"),
2467 input_channels, output_channels)
2472 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
2473 error << string_compose (
2474 _("cannot configure %1 in/%2 out configuration for new audio track"),
2475 input_channels, output_channels)
2482 route_group->add (track);
2485 track->non_realtime_input_change();
2487 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
2488 if (Config->get_remote_model() == UserOrdered) {
2489 track->set_remote_control_id (next_control_id());
2492 new_routes.push_back (track);
2493 ret.push_back (track);
2496 catch (failed_constructor &err) {
2497 error << _("Session: could not create new audio track.") << endmsg;
2501 catch (AudioEngine::PortRegistrationFailure& pfe) {
2503 error << pfe.what() << endmsg;
2511 if (!new_routes.empty()) {
2512 StateProtector sp (this);
2513 if (Profile->get_trx()) {
2514 add_routes (new_routes, false, false, false);
2516 add_routes (new_routes, true, true, false);
2523 /** Caller must not hold process lock.
2524 * @param name_template string to use for the start of the name, or "" to use "Bus".
2527 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
2530 uint32_t bus_id = 0;
2534 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
2537 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
2538 error << "cannot find name for new audio bus" << endmsg;
2543 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
2549 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
2550 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
2553 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2555 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
2556 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2557 input_channels, output_channels)
2563 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
2564 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2565 input_channels, output_channels)
2572 route_group->add (bus);
2574 if (Config->get_remote_model() == UserOrdered) {
2575 bus->set_remote_control_id (next_control_id());
2578 bus->add_internal_return ();
2580 ret.push_back (bus);
2586 catch (failed_constructor &err) {
2587 error << _("Session: could not create new audio route.") << endmsg;
2591 catch (AudioEngine::PortRegistrationFailure& pfe) {
2592 error << pfe.what() << endmsg;
2602 StateProtector sp (this);
2603 if (Profile->get_trx()) {
2604 add_routes (ret, false, false, false);
2606 add_routes (ret, false, true, true); // autoconnect // outputs only
2615 Session::new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name_base)
2618 uint32_t control_id;
2620 uint32_t number = 0;
2621 const uint32_t being_added = how_many;
2623 if (!tree.read (template_path.c_str())) {
2627 XMLNode* node = tree.root();
2629 IO::disable_connecting ();
2631 control_id = next_control_id ();
2635 XMLNode node_copy (*node);
2637 /* Remove IDs of everything so that new ones are used */
2638 node_copy.remove_property_recursively (X_("id"));
2643 if (!name_base.empty()) {
2645 /* if we're adding more than one routes, force
2646 * all the names of the new routes to be
2647 * numbered, via the final parameter.
2650 if (!find_route_name (name_base.c_str(), ++number, name, sizeof(name), (being_added > 1))) {
2651 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2657 string const route_name = node_copy.property(X_("name"))->value ();
2659 /* generate a new name by adding a number to the end of the template name */
2660 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2661 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2662 abort(); /*NOTREACHED*/
2666 /* set this name in the XML description that we are about to use */
2667 Route::set_name_in_state (node_copy, name);
2669 /* trim bitslots from listen sends so that new ones are used */
2670 XMLNodeList children = node_copy.children ();
2671 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2672 if ((*i)->name() == X_("Processor")) {
2673 XMLProperty* role = (*i)->property (X_("role"));
2674 if (role && role->value() == X_("Listen")) {
2675 (*i)->remove_property (X_("bitslot"));
2680 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2683 error << _("Session: cannot create track/bus from template description") << endmsg;
2687 if (boost::dynamic_pointer_cast<Track>(route)) {
2688 /* force input/output change signals so that the new diskstream
2689 picks up the configuration of the route. During session
2690 loading this normally happens in a different way.
2693 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2695 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2696 change.after = route->input()->n_ports();
2697 route->input()->changed (change, this);
2698 change.after = route->output()->n_ports();
2699 route->output()->changed (change, this);
2702 route->set_remote_control_id (control_id);
2705 ret.push_back (route);
2708 catch (failed_constructor &err) {
2709 error << _("Session: could not create new route from template") << endmsg;
2713 catch (AudioEngine::PortRegistrationFailure& pfe) {
2714 error << pfe.what() << endmsg;
2723 StateProtector sp (this);
2724 if (Profile->get_trx()) {
2725 add_routes (ret, false, false, false);
2727 add_routes (ret, true, true, false);
2729 IO::enable_connecting ();
2736 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2739 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
2740 add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
2743 error << _("Adding new tracks/busses failed") << endmsg;
2748 update_latency (true);
2749 update_latency (false);
2754 save_state (_current_snapshot_name);
2757 reassign_track_numbers();
2759 update_route_record_state ();
2761 RouteAdded (new_routes); /* EMIT SIGNAL */
2765 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
2767 ChanCount existing_inputs;
2768 ChanCount existing_outputs;
2769 uint32_t order = next_control_id();
2771 if (_order_hint > -1) {
2772 order = _order_hint;
2776 count_existing_track_channels (existing_inputs, existing_outputs);
2779 RCUWriter<RouteList> writer (routes);
2780 boost::shared_ptr<RouteList> r = writer.get_copy ();
2781 r->insert (r->end(), new_routes.begin(), new_routes.end());
2783 /* if there is no control out and we're not in the middle of loading,
2784 resort the graph here. if there is a control out, we will resort
2785 toward the end of this method. if we are in the middle of loading,
2786 we will resort when done.
2789 if (!_monitor_out && IO::connecting_legal) {
2790 resort_routes_using (r);
2794 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2796 boost::weak_ptr<Route> wpr (*x);
2797 boost::shared_ptr<Route> r (*x);
2799 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2800 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2801 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2802 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2803 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2804 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2806 if (r->is_master()) {
2810 if (r->is_monitor()) {
2814 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2816 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2817 track_playlist_changed (boost::weak_ptr<Track> (tr));
2818 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_route_record_state, this));
2820 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2822 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2823 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2828 if (input_auto_connect || output_auto_connect) {
2829 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2832 /* order keys are a GUI responsibility but we need to set up
2833 reasonable defaults because they also affect the remote control
2834 ID in most situations.
2837 if (!r->has_order_key ()) {
2838 if (r->is_auditioner()) {
2839 /* use an arbitrarily high value */
2840 r->set_order_key (UINT_MAX);
2842 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
2843 r->set_order_key (order);
2851 if (_monitor_out && IO::connecting_legal) {
2852 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2854 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2855 if ((*x)->is_monitor()) {
2857 } else if ((*x)->is_master()) {
2860 (*x)->enable_monitor_send ();
2867 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2869 boost::shared_ptr<RouteList> r = routes.reader ();
2870 boost::shared_ptr<Send> s;
2872 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2873 if ((s = (*i)->internal_send_for (dest)) != 0) {
2874 s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO);
2880 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2882 boost::shared_ptr<RouteList> r = routes.reader ();
2883 boost::shared_ptr<Send> s;
2885 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2886 if ((s = (*i)->internal_send_for (dest)) != 0) {
2887 s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY);
2893 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2895 boost::shared_ptr<RouteList> r = routes.reader ();
2896 boost::shared_ptr<Send> s;
2898 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2899 if ((s = (*i)->internal_send_for (dest)) != 0) {
2900 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2905 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2907 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2909 boost::shared_ptr<RouteList> r = routes.reader ();
2910 boost::shared_ptr<RouteList> t (new RouteList);
2912 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2913 /* no MIDI sends because there are no MIDI busses yet */
2914 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2919 add_internal_sends (dest, p, t);
2923 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2925 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2926 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2931 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2933 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2937 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2939 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2943 if (!dest->internal_return()) {
2944 dest->add_internal_return ();
2947 sender->add_aux_send (dest, before);
2954 Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
2956 { // RCU Writer scope
2957 RCUWriter<RouteList> writer (routes);
2958 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2961 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
2963 if (*iter == _master_out) {
2967 (*iter)->set_solo (false, this);
2971 /* deleting the master out seems like a dumb
2972 idea, but its more of a UI policy issue
2976 if (*iter == _master_out) {
2977 _master_out = boost::shared_ptr<Route> ();
2980 if (*iter == _monitor_out) {
2981 _monitor_out.reset ();
2984 update_route_solo_state ();
2986 // We need to disconnect the route's inputs and outputs
2988 (*iter)->input()->disconnect (0);
2989 (*iter)->output()->disconnect (0);
2991 /* if the route had internal sends sending to it, remove them */
2992 if ((*iter)->internal_return()) {
2994 boost::shared_ptr<RouteList> r = routes.reader ();
2995 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2996 boost::shared_ptr<Send> s = (*i)->internal_send_for (*iter);
2998 (*i)->remove_processor (s);
3003 /* if the monitoring section had a pointer to this route, remove it */
3004 if (_monitor_out && !(*iter)->is_master() && !(*iter)->is_monitor()) {
3005 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3006 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
3007 (*iter)->remove_aux_or_listen (_monitor_out);
3010 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*iter);
3011 if (mt && mt->step_editing()) {
3012 if (_step_editors > 0) {
3017 RouteAddedOrRemoved (false); /* EMIT SIGNAL */
3020 /* writer goes out of scope, forces route list update */
3022 } // end of RCU Writer scope
3024 update_latency_compensation ();
3027 /* Re-sort routes to remove the graph's current references to the one that is
3028 * going away, then flush old references out of the graph.
3029 * Wave Tracks: reconnect routes
3032 if (ARDOUR::Profile->get_trx () ) {
3033 reconnect_existing_routes(true, false);
3038 if (_process_graph) {
3039 _process_graph->clear_other_chain ();
3042 /* get rid of it from the dead wood collection in the route list manager */
3043 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
3047 /* try to cause everyone to drop their references
3048 * and unregister ports from the backend
3050 PBD::Unwinder<bool> uw_flag (_route_deletion_in_progress, true);
3052 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3053 (*iter)->drop_references ();
3056 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
3058 /* save the new state of the world */
3060 if (save_state (_current_snapshot_name)) {
3061 save_history (_current_snapshot_name);
3064 reassign_track_numbers();
3065 update_route_record_state ();
3069 Session::remove_route (boost::shared_ptr<Route> route)
3071 boost::shared_ptr<RouteList> rl (new RouteList);
3072 rl->push_back (route);
3077 Session::route_mute_changed (void* /*src*/)
3083 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
3085 boost::shared_ptr<Route> route = wpr.lock();
3087 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
3091 if (route->listening_via_monitor ()) {
3093 if (Config->get_exclusive_solo()) {
3094 /* new listen: disable all other listen */
3095 boost::shared_ptr<RouteList> r = routes.reader ();
3096 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3097 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
3100 (*i)->set_listen (false, this);
3106 } else if (_listen_cnt > 0) {
3111 update_route_solo_state ();
3114 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
3116 boost::shared_ptr<Route> route = wpr.lock ();
3119 /* should not happen */
3120 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
3124 bool send_changed = false;
3126 if (route->solo_isolated()) {
3127 if (_solo_isolated_cnt == 0) {
3128 send_changed = true;
3130 _solo_isolated_cnt++;
3131 } else if (_solo_isolated_cnt > 0) {
3132 _solo_isolated_cnt--;
3133 if (_solo_isolated_cnt == 0) {
3134 send_changed = true;
3139 IsolatedChanged (); /* EMIT SIGNAL */
3144 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
3146 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
3148 if (!self_solo_change) {
3149 // session doesn't care about changes to soloed-by-others
3153 if (solo_update_disabled) {
3155 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
3159 boost::shared_ptr<Route> route = wpr.lock ();
3162 boost::shared_ptr<RouteList> r = routes.reader ();
3165 if (route->self_soloed()) {
3171 RouteGroup* rg = route->route_group ();
3172 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
3174 if (delta == 1 && Config->get_exclusive_solo()) {
3176 /* new solo: disable all other solos, but not the group if its solo-enabled */
3178 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3179 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
3180 (leave_group_alone && ((*i)->route_group() == rg))) {
3183 (*i)->set_solo (false, this);
3187 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
3189 solo_update_disabled = true;
3191 RouteList uninvolved;
3193 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
3195 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3196 bool via_sends_only;
3197 bool in_signal_flow;
3199 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
3200 (leave_group_alone && ((*i)->route_group() == rg))) {
3204 in_signal_flow = false;
3206 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
3208 if ((*i)->feeds (route, &via_sends_only)) {
3209 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
3210 if (!via_sends_only) {
3211 if (!route->soloed_by_others_upstream()) {
3212 (*i)->mod_solo_by_others_downstream (delta);
3215 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
3217 in_signal_flow = true;
3219 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
3222 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
3224 if (route->feeds (*i, &via_sends_only)) {
3225 /* propagate solo upstream only if routing other than
3226 sends is involved, but do consider the other route
3227 (*i) to be part of the signal flow even if only
3230 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
3234 route->soloed_by_others_downstream(),
3235 route->soloed_by_others_upstream()));
3236 if (!via_sends_only) {
3237 if (!route->soloed_by_others_downstream()) {
3238 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
3239 (*i)->mod_solo_by_others_upstream (delta);
3241 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
3244 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
3246 in_signal_flow = true;
3248 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
3251 if (!in_signal_flow) {
3252 uninvolved.push_back (*i);
3256 solo_update_disabled = false;
3257 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
3259 update_route_solo_state (r);
3261 /* now notify that the mute state of the routes not involved in the signal
3262 pathway of the just-solo-changed route may have altered.
3265 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
3266 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
3267 (*i)->act_on_mute ();
3268 (*i)->mute_changed (this);
3271 SoloChanged (); /* EMIT SIGNAL */
3276 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
3278 /* now figure out if anything that matters is soloed (or is "listening")*/
3280 bool something_soloed = false;
3281 uint32_t listeners = 0;
3282 uint32_t isolated = 0;
3285 r = routes.reader();
3288 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3289 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner() && (*i)->self_soloed()) {
3290 something_soloed = true;
3293 if (!(*i)->is_auditioner() && (*i)->listening_via_monitor()) {
3294 if (Config->get_solo_control_is_listen_control()) {
3297 (*i)->set_listen (false, this);
3301 if ((*i)->solo_isolated()) {
3306 if (something_soloed != _non_soloed_outs_muted) {
3307 _non_soloed_outs_muted = something_soloed;
3308 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
3311 _listen_cnt = listeners;
3313 if (isolated != _solo_isolated_cnt) {
3314 _solo_isolated_cnt = isolated;
3315 IsolatedChanged (); /* EMIT SIGNAL */
3318 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
3319 something_soloed, listeners, isolated));
3322 boost::shared_ptr<RouteList>
3323 Session::get_routes_with_internal_returns() const
3325 boost::shared_ptr<RouteList> r = routes.reader ();
3326 boost::shared_ptr<RouteList> rl (new RouteList);
3328 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3329 if ((*i)->internal_return ()) {
3337 Session::io_name_is_legal (const std::string& name)
3339 boost::shared_ptr<RouteList> r = routes.reader ();
3341 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3342 if ((*i)->name() == name) {
3346 if ((*i)->has_io_processor_named (name)) {
3355 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
3358 vector<string> connections;
3360 /* if we are passed only a single route and we're not told to turn
3361 * others off, then just do the simple thing.
3364 if (flip_others == false && rl->size() == 1) {
3365 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
3367 mt->set_input_active (onoff);
3372 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
3374 PortSet& ps ((*rt)->input()->ports());
3376 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
3377 p->get_connections (connections);
3380 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
3381 routes_using_input_from (*s, rl2);
3384 /* scan all relevant routes to see if others are on or off */
3386 bool others_are_already_on = false;
3388 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
3390 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
3396 if ((*r) != (*rt)) {
3397 if (mt->input_active()) {
3398 others_are_already_on = true;
3401 /* this one needs changing */
3402 mt->set_input_active (onoff);
3408 /* globally reverse other routes */
3410 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
3411 if ((*r) != (*rt)) {
3412 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
3414 mt->set_input_active (!others_are_already_on);
3423 Session::routes_using_input_from (const string& str, RouteList& rl)
3425 boost::shared_ptr<RouteList> r = routes.reader();
3427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3428 if ((*i)->input()->connected_to (str)) {
3434 boost::shared_ptr<Route>
3435 Session::route_by_name (string name)
3437 boost::shared_ptr<RouteList> r = routes.reader ();
3439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3440 if ((*i)->name() == name) {
3445 return boost::shared_ptr<Route> ((Route*) 0);
3448 boost::shared_ptr<Route>
3449 Session::route_by_id (PBD::ID id)
3451 boost::shared_ptr<RouteList> r = routes.reader ();
3453 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3454 if ((*i)->id() == id) {
3459 return boost::shared_ptr<Route> ((Route*) 0);
3462 boost::shared_ptr<Track>
3463 Session::track_by_diskstream_id (PBD::ID id)
3465 boost::shared_ptr<RouteList> r = routes.reader ();
3467 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3468 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
3469 if (t && t->using_diskstream_id (id)) {
3474 return boost::shared_ptr<Track> ();
3477 boost::shared_ptr<Route>
3478 Session::route_by_remote_id (uint32_t id)
3480 boost::shared_ptr<RouteList> r = routes.reader ();
3482 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3483 if ((*i)->remote_control_id() == id) {
3488 return boost::shared_ptr<Route> ((Route*) 0);
3493 Session::reassign_track_numbers ()
3497 RouteList r (*(routes.reader ()));
3498 SignalOrderRouteSorter sorter;
3501 StateProtector sp (this);
3503 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
3504 if (boost::dynamic_pointer_cast<Track> (*i)) {
3505 (*i)->set_track_number(++tn);
3507 else if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
3508 (*i)->set_track_number(--bn);
3511 const uint32_t decimals = ceilf (log10f (tn + 1));
3512 const bool decimals_changed = _track_number_decimals != decimals;
3513 _track_number_decimals = decimals;
3515 if (decimals_changed && config.get_track_name_number ()) {
3516 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
3517 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
3519 t->resync_track_name();
3522 // trigger GUI re-layout
3523 config.ParameterChanged("track-name-number");
3528 Session::playlist_region_added (boost::weak_ptr<Region> w)
3530 boost::shared_ptr<Region> r = w.lock ();
3535 /* These are the operations that are currently in progress... */
3536 list<GQuark> curr = _current_trans_quarks;
3539 /* ...and these are the operations during which we want to update
3540 the session range location markers.
3543 ops.push_back (Operations::capture);
3544 ops.push_back (Operations::paste);
3545 ops.push_back (Operations::duplicate_region);
3546 ops.push_back (Operations::insert_file);
3547 ops.push_back (Operations::insert_region);
3548 ops.push_back (Operations::drag_region_brush);
3549 ops.push_back (Operations::region_drag);
3550 ops.push_back (Operations::selection_grab);
3551 ops.push_back (Operations::region_fill);
3552 ops.push_back (Operations::fill_selection);
3553 ops.push_back (Operations::create_region);
3554 ops.push_back (Operations::region_copy);
3555 ops.push_back (Operations::fixed_time_region_copy);
3558 /* See if any of the current operations match the ones that we want */
3560 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
3562 /* If so, update the session range markers */
3564 maybe_update_session_range (r->position (), r->last_frame ());
3568 /** Update the session range markers if a is before the current start or
3569 * b is after the current end.
3572 Session::maybe_update_session_range (framepos_t a, framepos_t b)
3574 if (_state_of_the_state & Loading) {
3578 if (_session_range_location == 0) {
3580 add_session_range_location (a, b);
3584 if (a < _session_range_location->start()) {
3585 _session_range_location->set_start (a);
3588 if (b > _session_range_location->end()) {
3589 _session_range_location->set_end (b);
3595 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
3597 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
3598 maybe_update_session_range (i->to, i->to + i->length);
3603 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
3605 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
3606 maybe_update_session_range (i->from, i->to);
3610 /* Region management */
3612 boost::shared_ptr<Region>
3613 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
3615 const RegionFactory::RegionMap& regions (RegionFactory::regions());
3616 RegionFactory::RegionMap::const_iterator i;
3617 boost::shared_ptr<Region> region;
3619 Glib::Threads::Mutex::Lock lm (region_lock);
3621 for (i = regions.begin(); i != regions.end(); ++i) {
3625 if (region->whole_file()) {
3627 if (child->source_equivalent (region)) {
3633 return boost::shared_ptr<Region> ();
3637 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
3639 set<boost::shared_ptr<Region> > relevant_regions;
3641 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
3642 RegionFactory::get_regions_using_source (*s, relevant_regions);
3645 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
3646 set<boost::shared_ptr<Region> >::iterator tmp;
3651 playlists->destroy_region (*r);
3652 RegionFactory::map_remove (*r);
3654 (*r)->drop_sources ();
3655 (*r)->drop_references ();
3657 relevant_regions.erase (r);
3662 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
3665 Glib::Threads::Mutex::Lock ls (source_lock);
3666 /* remove from the main source list */
3667 sources.erase ((*s)->id());
3670 (*s)->mark_for_remove ();
3671 (*s)->drop_references ();
3680 Session::remove_last_capture ()
3682 list<boost::shared_ptr<Source> > srcs;
3684 boost::shared_ptr<RouteList> rl = routes.reader ();
3685 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3686 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3691 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
3694 srcs.insert (srcs.end(), l.begin(), l.end());
3699 destroy_sources (srcs);
3701 save_state (_current_snapshot_name);
3706 /* Source Management */
3709 Session::add_source (boost::shared_ptr<Source> source)
3711 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3712 pair<SourceMap::iterator,bool> result;
3714 entry.first = source->id();
3715 entry.second = source;
3718 Glib::Threads::Mutex::Lock lm (source_lock);
3719 result = sources.insert (entry);
3722 if (result.second) {
3724 /* yay, new source */
3726 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3729 if (!fs->within_session()) {
3730 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3736 boost::shared_ptr<AudioFileSource> afs;
3738 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3739 if (Config->get_auto_analyse_audio()) {
3740 Analyser::queue_source_for_analysis (source, false);
3744 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3749 Session::remove_source (boost::weak_ptr<Source> src)
3751 if (_state_of_the_state & Deletion) {
3755 SourceMap::iterator i;
3756 boost::shared_ptr<Source> source = src.lock();
3763 Glib::Threads::Mutex::Lock lm (source_lock);
3765 if ((i = sources.find (source->id())) != sources.end()) {
3770 if (!(_state_of_the_state & StateOfTheState (InCleanup|Loading))) {
3772 /* save state so we don't end up with a session file
3773 referring to non-existent sources.
3776 save_state (_current_snapshot_name);
3780 boost::shared_ptr<Source>
3781 Session::source_by_id (const PBD::ID& id)
3783 Glib::Threads::Mutex::Lock lm (source_lock);
3784 SourceMap::iterator i;
3785 boost::shared_ptr<Source> source;
3787 if ((i = sources.find (id)) != sources.end()) {
3794 boost::shared_ptr<AudioFileSource>
3795 Session::audio_source_by_path_and_channel (const string& path, uint16_t chn) const
3797 /* Restricted to audio files because only audio sources have channel
3801 Glib::Threads::Mutex::Lock lm (source_lock);
3803 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3804 boost::shared_ptr<AudioFileSource> afs
3805 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3807 if (afs && afs->path() == path && chn == afs->channel()) {
3812 return boost::shared_ptr<AudioFileSource>();
3815 boost::shared_ptr<MidiSource>
3816 Session::midi_source_by_path (const std::string& path) const
3818 /* Restricted to MIDI files because audio sources require a channel
3819 for unique identification, in addition to a path.
3822 Glib::Threads::Mutex::Lock lm (source_lock);
3824 for (SourceMap::const_iterator s = sources.begin(); s != sources.end(); ++s) {
3825 boost::shared_ptr<MidiSource> ms
3826 = boost::dynamic_pointer_cast<MidiSource>(s->second);
3827 boost::shared_ptr<FileSource> fs
3828 = boost::dynamic_pointer_cast<FileSource>(s->second);
3830 if (ms && fs && fs->path() == path) {
3835 return boost::shared_ptr<MidiSource>();
3839 Session::count_sources_by_origin (const string& path)
3842 Glib::Threads::Mutex::Lock lm (source_lock);
3844 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3845 boost::shared_ptr<FileSource> fs
3846 = boost::dynamic_pointer_cast<FileSource>(i->second);
3848 if (fs && fs->origin() == path) {
3857 Session::peak_path (string base) const
3859 if (Glib::path_is_absolute (base)) {
3861 /* rip the session dir from the audiofile source */
3863 string session_path;
3864 string interchange_dir_string = string (interchange_dir_name) + G_DIR_SEPARATOR;
3865 bool in_another_session = true;
3867 if (base.find (interchange_dir_string) != string::npos) {
3869 session_path = Glib::path_get_dirname (base); /* now ends in audiofiles */
3870 session_path = Glib::path_get_dirname (session_path); /* now ends in session name */
3871 session_path = Glib::path_get_dirname (session_path); /* now ends in interchange */
3872 session_path = Glib::path_get_dirname (session_path); /* now has session path */
3874 /* see if it is within our session */
3876 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3877 if (i->path == session_path) {
3878 in_another_session = false;
3883 in_another_session = false;
3887 if (in_another_session) {
3888 SessionDirectory sd (session_path);
3889 return Glib::build_filename (sd.peak_path(), Glib::path_get_basename (base) + peakfile_suffix);
3893 base = Glib::path_get_basename (base);
3894 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3898 Session::new_audio_source_path_for_embedded (const std::string& path)
3902 * we know that the filename is already unique because it exists
3903 * out in the filesystem.
3905 * However, when we bring it into the session, we could get a
3908 * Eg. two embedded files:
3913 * When merged into session, these collide.
3915 * There will not be a conflict with in-memory sources
3916 * because when the source was created we already picked
3917 * a unique name for it.
3919 * This collision is not likely to be common, but we have to guard
3920 * against it. So, if there is a collision, take the md5 hash of the
3921 * the path, and use that as the filename instead.
3924 SessionDirectory sdir (get_best_session_directory_for_new_audio());
3925 string base = Glib::path_get_basename (path);
3926 string newpath = Glib::build_filename (sdir.sound_path(), base);
3928 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3932 md5.digestString (path.c_str());
3933 md5.writeToString ();
3934 base = md5.digestChars;
3936 string ext = get_suffix (path);
3943 newpath = Glib::build_filename (sdir.sound_path(), base);
3945 /* if this collides, we're screwed */
3947 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3948 error << string_compose (_("Merging embedded file %1: name collision AND md5 hash collision!"), path) << endmsg;
3957 /** Return true if there are no audio file sources that use @param name as
3958 * the filename component of their path.
3960 * Return false otherwise.
3962 * This method MUST ONLY be used to check in-session, mono files since it
3963 * hard-codes the channel of the audio file source we are looking for as zero.
3965 * If/when Ardour supports native files in non-mono formats, the logic here
3966 * will need to be revisited.
3969 Session::audio_source_name_is_unique (const string& name)
3971 std::vector<string> sdirs = source_search_path (DataType::AUDIO);
3972 vector<space_and_path>::iterator i;
3973 uint32_t existing = 0;
3975 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
3977 /* note that we search *without* the extension so that
3978 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3979 in the event that this new name is required for
3980 a file format change.
3983 const string spath = *i;
3985 if (matching_unsuffixed_filename_exists_in (spath, name)) {
3990 /* it is possible that we have the path already
3991 * assigned to a source that has not yet been written
3992 * (ie. the write source for a diskstream). we have to
3993 * check this in order to make sure that our candidate
3994 * path isn't used again, because that can lead to
3995 * two Sources point to the same file with different
3996 * notions of their removability.
4000 string possible_path = Glib::build_filename (spath, name);
4002 if (audio_source_by_path_and_channel (possible_path, 0)) {
4008 return (existing == 0);
4012 Session::format_audio_source_name (const string& legalized_base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required, uint32_t cnt, bool related_exists)
4015 const string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
4019 sstr << setfill ('0') << setw (4) << cnt;
4020 sstr << legalized_base;
4022 sstr << legalized_base;
4024 if (take_required || related_exists) {
4036 } else if (nchan > 2) {
4041 /* XXX what? more than 26 channels! */
4052 /** Return a unique name based on \a base for a new internal audio source */
4054 Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required)
4057 string possible_name;
4058 const uint32_t limit = 9999; // arbitrary limit on number of files with the same basic name
4060 bool some_related_source_name_exists = false;
4062 legalized = legalize_for_path (base);
4064 // Find a "version" of the base name that doesn't exist in any of the possible directories.
4066 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
4068 possible_name = format_audio_source_name (legalized, nchan, chan, destructive, take_required, cnt, some_related_source_name_exists);
4070 if (audio_source_name_is_unique (possible_name)) {
4074 some_related_source_name_exists = true;
4077 error << string_compose(
4078 _("There are already %1 recordings for %2, which I consider too many."),
4079 limit, base) << endmsg;
4081 throw failed_constructor();
4085 /* We've established that the new name does not exist in any session
4086 * directory, so now find out which one we should use for this new
4090 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4092 std::string s = Glib::build_filename (sdir.sound_path(), possible_name);
4097 /** Return a unique name based on `base` for a new internal MIDI source */
4099 Session::new_midi_source_path (const string& base)
4102 char buf[PATH_MAX+1];
4103 const uint32_t limit = 10000;
4105 string possible_path;
4106 string possible_name;
4109 legalized = legalize_for_path (base);
4111 // Find a "version" of the file name that doesn't exist in any of the possible directories.
4112 std::vector<string> sdirs = source_search_path(DataType::MIDI);
4114 /* - the main session folder is the first in the vector.
4115 * - after checking all locations for file-name uniqueness,
4116 * we keep the one from the last iteration as new file name
4117 * - midi files are small and should just be kept in the main session-folder
4119 * -> reverse the array, check main session folder last and use that as location
4122 std::reverse(sdirs.begin(), sdirs.end());
4124 for (cnt = 1; cnt <= limit; ++cnt) {
4126 vector<space_and_path>::iterator i;
4127 uint32_t existing = 0;
4129 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4131 snprintf (buf, sizeof(buf), "%s-%u.mid", legalized.c_str(), cnt);
4132 possible_name = buf;
4134 possible_path = Glib::build_filename (*i, possible_name);
4136 if (Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
4140 if (midi_source_by_path (possible_path)) {
4145 if (existing == 0) {
4150 error << string_compose(
4151 _("There are already %1 recordings for %2, which I consider too many."),
4152 limit, base) << endmsg;
4158 /* No need to "find best location" for software/app-based RAID, because
4159 MIDI is so small that we always put it in the same place.
4162 return possible_path;
4166 /** Create a new within-session audio source */
4167 boost::shared_ptr<AudioFileSource>
4168 Session::create_audio_source_for_session (size_t n_chans, string const & base, uint32_t chan, bool destructive)
4170 const string path = new_audio_source_path (base, n_chans, chan, destructive, true);
4172 if (!path.empty()) {
4173 return boost::dynamic_pointer_cast<AudioFileSource> (
4174 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
4176 throw failed_constructor ();
4180 /** Create a new within-session MIDI source */
4181 boost::shared_ptr<MidiSource>
4182 Session::create_midi_source_for_session (string const & basic_name)
4184 const string path = new_midi_source_path (basic_name);
4186 if (!path.empty()) {
4187 return boost::dynamic_pointer_cast<SMFSource> (
4188 SourceFactory::createWritable (
4189 DataType::MIDI, *this, path, false, frame_rate()));
4191 throw failed_constructor ();
4195 /** Create a new within-session MIDI source */
4196 boost::shared_ptr<MidiSource>
4197 Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
4199 /* the caller passes in the track the source will be used in,
4200 so that we can keep the numbering sane.
4202 Rationale: a track with the name "Foo" that has had N
4203 captures carried out so far will ALREADY have a write source
4204 named "Foo-N+1.mid" waiting to be used for the next capture.
4206 If we call new_midi_source_name() we will get "Foo-N+2". But
4207 there is no region corresponding to "Foo-N+1", so when
4208 "Foo-N+2" appears in the track, the gap presents the user
4209 with odd behaviour - why did it skip past Foo-N+1?
4211 We could explain this to the user in some odd way, but
4212 instead we rename "Foo-N+1.mid" as "Foo-N+2.mid", and then
4215 If that attempted rename fails, we get "Foo-N+2.mid" anyway.
4218 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (track);
4220 std::string name = track->steal_write_source_name ();
4223 return boost::shared_ptr<MidiSource>();
4226 /* MIDI files are small, just put them in the first location of the
4227 session source search path.
4230 const string path = Glib::build_filename (source_search_path (DataType::MIDI).front(), name);
4232 return boost::dynamic_pointer_cast<SMFSource> (
4233 SourceFactory::createWritable (
4234 DataType::MIDI, *this, path, false, frame_rate()));
4239 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
4241 if (playlist->hidden()) {
4245 playlists->add (playlist);
4248 playlist->release();
4255 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
4257 if (_state_of_the_state & Deletion) {
4261 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
4267 playlists->remove (playlist);
4273 Session::set_audition (boost::shared_ptr<Region> r)
4275 pending_audition_region = r;
4276 add_post_transport_work (PostTransportAudition);
4277 _butler->schedule_transport_work ();
4281 Session::audition_playlist ()
4283 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
4284 ev->region.reset ();
4289 Session::non_realtime_set_audition ()
4291 assert (pending_audition_region);
4292 auditioner->audition_region (pending_audition_region);
4293 pending_audition_region.reset ();
4294 AuditionActive (true); /* EMIT SIGNAL */
4298 Session::audition_region (boost::shared_ptr<Region> r)
4300 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
4306 Session::cancel_audition ()
4311 if (auditioner->auditioning()) {
4312 auditioner->cancel_audition ();
4313 AuditionActive (false); /* EMIT SIGNAL */
4318 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
4320 if (a->is_monitor()) {
4323 if (b->is_monitor()) {
4326 return a->order_key () < b->order_key ();
4330 Session::is_auditioning () const
4332 /* can be called before we have an auditioner object */
4334 return auditioner->auditioning();
4341 Session::graph_reordered ()
4343 /* don't do this stuff if we are setting up connections
4344 from a set_state() call or creating new tracks. Ditto for deletion.
4347 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
4351 /* every track/bus asked for this to be handled but it was deferred because
4352 we were connecting. do it now.
4355 request_input_change_handling ();
4359 /* force all diskstreams to update their capture offset values to
4360 reflect any changes in latencies within the graph.
4363 boost::shared_ptr<RouteList> rl = routes.reader ();
4364 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4365 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4367 tr->set_capture_offset ();
4372 /** @return Number of frames that there is disk space available to write,
4375 boost::optional<framecnt_t>
4376 Session::available_capture_duration ()
4378 Glib::Threads::Mutex::Lock lm (space_lock);
4380 if (_total_free_4k_blocks_uncertain) {
4381 return boost::optional<framecnt_t> ();
4384 float sample_bytes_on_disk = 4.0; // keep gcc happy
4386 switch (config.get_native_file_data_format()) {
4388 sample_bytes_on_disk = 4.0;
4392 sample_bytes_on_disk = 3.0;
4396 sample_bytes_on_disk = 2.0;
4400 /* impossible, but keep some gcc versions happy */
4401 fatal << string_compose (_("programming error: %1"),
4402 X_("illegal native file data format"))
4404 abort(); /*NOTREACHED*/
4407 double scale = 4096.0 / sample_bytes_on_disk;
4409 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
4410 return max_framecnt;
4413 return (framecnt_t) floor (_total_free_4k_blocks * scale);
4417 Session::add_bundle (boost::shared_ptr<Bundle> bundle, bool emit_signal)
4420 RCUWriter<BundleList> writer (_bundles);
4421 boost::shared_ptr<BundleList> b = writer.get_copy ();
4422 b->push_back (bundle);
4426 BundleAddedOrRemoved (); /* EMIT SIGNAL */
4433 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
4435 bool removed = false;
4438 RCUWriter<BundleList> writer (_bundles);
4439 boost::shared_ptr<BundleList> b = writer.get_copy ();
4440 BundleList::iterator i = find (b->begin(), b->end(), bundle);
4442 if (i != b->end()) {
4449 BundleAddedOrRemoved (); /* EMIT SIGNAL */
4455 boost::shared_ptr<Bundle>
4456 Session::bundle_by_name (string name) const
4458 boost::shared_ptr<BundleList> b = _bundles.reader ();
4460 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
4461 if ((*i)->name() == name) {
4466 return boost::shared_ptr<Bundle> ();
4470 Session::tempo_map_changed (const PropertyChange&)
4474 playlists->update_after_tempo_map_change ();
4476 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
4482 Session::update_locations_after_tempo_map_change (const Locations::LocationList& loc)
4484 for (Locations::LocationList::const_iterator i = loc.begin(); i != loc.end(); ++i) {
4485 (*i)->recompute_frames_from_bbt ();
4489 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
4490 * the given count with the current block size.
4493 Session::ensure_buffers (ChanCount howmany)
4495 BufferManager::ensure_buffers (howmany, bounce_processing() ? bounce_chunk_size : 0);
4499 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
4501 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4502 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
4507 Session::next_insert_id ()
4509 /* this doesn't really loop forever. just think about it */
4512 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
4513 if (!insert_bitset[n]) {
4514 insert_bitset[n] = true;
4520 /* none available, so resize and try again */
4522 insert_bitset.resize (insert_bitset.size() + 16, false);
4527 Session::next_send_id ()
4529 /* this doesn't really loop forever. just think about it */
4532 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
4533 if (!send_bitset[n]) {
4534 send_bitset[n] = true;
4540 /* none available, so resize and try again */
4542 send_bitset.resize (send_bitset.size() + 16, false);
4547 Session::next_aux_send_id ()
4549 /* this doesn't really loop forever. just think about it */
4552 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
4553 if (!aux_send_bitset[n]) {
4554 aux_send_bitset[n] = true;
4560 /* none available, so resize and try again */
4562 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
4567 Session::next_return_id ()
4569 /* this doesn't really loop forever. just think about it */
4572 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
4573 if (!return_bitset[n]) {
4574 return_bitset[n] = true;
4580 /* none available, so resize and try again */
4582 return_bitset.resize (return_bitset.size() + 16, false);
4587 Session::mark_send_id (uint32_t id)
4589 if (id >= send_bitset.size()) {
4590 send_bitset.resize (id+16, false);
4592 if (send_bitset[id]) {
4593 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
4595 send_bitset[id] = true;
4599 Session::mark_aux_send_id (uint32_t id)
4601 if (id >= aux_send_bitset.size()) {
4602 aux_send_bitset.resize (id+16, false);
4604 if (aux_send_bitset[id]) {
4605 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
4607 aux_send_bitset[id] = true;
4611 Session::mark_return_id (uint32_t id)
4613 if (id >= return_bitset.size()) {
4614 return_bitset.resize (id+16, false);
4616 if (return_bitset[id]) {
4617 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
4619 return_bitset[id] = true;
4623 Session::mark_insert_id (uint32_t id)
4625 if (id >= insert_bitset.size()) {
4626 insert_bitset.resize (id+16, false);
4628 if (insert_bitset[id]) {
4629 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
4631 insert_bitset[id] = true;
4635 Session::unmark_send_id (uint32_t id)
4637 if (id < send_bitset.size()) {
4638 send_bitset[id] = false;
4643 Session::unmark_aux_send_id (uint32_t id)
4645 if (id < aux_send_bitset.size()) {
4646 aux_send_bitset[id] = false;
4651 Session::unmark_return_id (uint32_t id)
4653 if (id < return_bitset.size()) {
4654 return_bitset[id] = false;
4659 Session::unmark_insert_id (uint32_t id)
4661 if (id < insert_bitset.size()) {
4662 insert_bitset[id] = false;
4667 Session::reset_native_file_format ()
4669 boost::shared_ptr<RouteList> rl = routes.reader ();
4670 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4671 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4673 /* don't save state as we do this, there's no point
4676 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
4677 tr->reset_write_sources (false);
4678 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
4684 Session::route_name_unique (string n) const
4686 boost::shared_ptr<RouteList> r = routes.reader ();
4688 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4689 if ((*i)->name() == n) {
4698 Session::route_name_internal (string n) const
4700 if (auditioner && auditioner->name() == n) {
4704 if (_click_io && _click_io->name() == n) {
4712 Session::freeze_all (InterThreadInfo& itt)
4714 boost::shared_ptr<RouteList> r = routes.reader ();
4716 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4718 boost::shared_ptr<Track> t;
4720 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4721 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4731 boost::shared_ptr<Region>
4732 Session::write_one_track (Track& track, framepos_t start, framepos_t end,
4733 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4734 InterThreadInfo& itt,
4735 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
4736 bool for_export, bool for_freeze)
4738 boost::shared_ptr<Region> result;
4739 boost::shared_ptr<Playlist> playlist;
4740 boost::shared_ptr<Source> source;
4741 ChanCount diskstream_channels (track.n_channels());
4742 framepos_t position;
4743 framecnt_t this_chunk;
4745 framepos_t latency_skip;
4747 framepos_t len = end - start;
4748 bool need_block_size_reset = false;
4749 ChanCount const max_proc = track.max_processor_streams ();
4750 string legal_playlist_name;
4751 string possible_path;
4754 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4755 end, start) << endmsg;
4759 diskstream_channels = track.bounce_get_output_streams (diskstream_channels, endpoint,
4760 include_endpoint, for_export, for_freeze);
4762 if (diskstream_channels.n(track.data_type()) < 1) {
4763 error << _("Cannot write a range with no data.") << endmsg;
4767 // block all process callback handling
4769 block_processing ();
4772 // synchronize with AudioEngine::process_callback()
4773 // make sure processing is not currently running
4774 // and processing_blocked() is honored before
4775 // acquiring thread buffers
4776 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4779 _bounce_processing_active = true;
4781 /* call tree *MUST* hold route_lock */
4783 if ((playlist = track.playlist()) == 0) {
4787 legal_playlist_name = legalize_for_path (playlist->name());
4789 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n(track.data_type()); ++chan_n) {
4791 string base_name = string_compose ("%1-%2-bounce", playlist->name(), chan_n);
4792 string path = ((track.data_type() == DataType::AUDIO)
4793 ? new_audio_source_path (legal_playlist_name, diskstream_channels.n_audio(), chan_n, false, true)
4794 : new_midi_source_path (legal_playlist_name));
4801 source = SourceFactory::createWritable (track.data_type(), *this, path, false, frame_rate());
4804 catch (failed_constructor& err) {
4805 error << string_compose (_("cannot create new file \"%1\" for %2"), path, track.name()) << endmsg;
4809 srcs.push_back (source);
4812 /* tell redirects that care that we are about to use a much larger
4813 * blocksize. this will flush all plugins too, so that they are ready
4814 * to be used for this process.
4817 need_block_size_reset = true;
4818 track.set_block_size (bounce_chunk_size);
4819 _engine.main_thread()->get_buffers ();
4823 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
4825 /* create a set of reasonably-sized buffers */
4826 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4827 buffers.ensure_buffers(*t, max_proc.get(*t), bounce_chunk_size);
4829 buffers.set_count (max_proc);
4831 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4832 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4833 boost::shared_ptr<MidiSource> ms;
4835 afs->prepare_for_peakfile_writes ();
4836 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4837 Source::Lock lock(ms->mutex());
4838 ms->mark_streaming_write_started(lock);
4842 while (to_do && !itt.cancel) {
4844 this_chunk = min (to_do, bounce_chunk_size);
4846 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze)) {
4850 start += this_chunk;
4851 to_do -= this_chunk;
4852 itt.progress = (float) (1.0 - ((double) to_do / len));
4854 if (latency_skip >= bounce_chunk_size) {
4855 latency_skip -= bounce_chunk_size;
4859 const framecnt_t current_chunk = this_chunk - latency_skip;
4862 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4863 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4864 boost::shared_ptr<MidiSource> ms;
4867 if (afs->write (buffers.get_audio(n).data(latency_skip), current_chunk) != current_chunk) {
4870 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4871 Source::Lock lock(ms->mutex());
4873 const MidiBuffer& buf = buffers.get_midi(0);
4874 for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
4875 Evoral::Event<framepos_t> ev = *i;
4876 ev.set_time(ev.time() - position);
4877 ms->append_event_frames(lock, ev, ms->timeline_position());
4884 /* post-roll, pick up delayed processor output */
4885 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
4887 while (latency_skip && !itt.cancel) {
4888 this_chunk = min (latency_skip, bounce_chunk_size);
4889 latency_skip -= this_chunk;
4891 buffers.silence (this_chunk, 0);
4892 track.bounce_process (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze);
4895 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4896 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4899 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4911 xnow = localtime (&now);
4913 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4914 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4915 boost::shared_ptr<MidiSource> ms;
4918 afs->update_header (position, *xnow, now);
4919 afs->flush_header ();
4920 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4921 Source::Lock lock(ms->mutex());
4922 ms->mark_streaming_write_completed(lock);
4926 /* construct a region to represent the bounced material */
4930 plist.add (Properties::start, 0);
4931 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4932 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4934 result = RegionFactory::create (srcs, plist);
4940 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4941 (*src)->mark_for_remove ();
4942 (*src)->drop_references ();
4946 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4947 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4950 afs->done_with_peakfile_writes ();
4954 _bounce_processing_active = false;
4956 if (need_block_size_reset) {
4957 _engine.main_thread()->drop_buffers ();
4958 track.set_block_size (get_block_size());
4961 unblock_processing ();
4967 Session::gain_automation_buffer() const
4969 return ProcessThread::gain_automation_buffer ();
4973 Session::trim_automation_buffer() const
4975 return ProcessThread::trim_automation_buffer ();
4979 Session::send_gain_automation_buffer() const
4981 return ProcessThread::send_gain_automation_buffer ();
4985 Session::pan_automation_buffer() const
4987 return ProcessThread::pan_automation_buffer ();
4991 Session::get_silent_buffers (ChanCount count)
4993 return ProcessThread::get_silent_buffers (count);
4997 Session::get_scratch_buffers (ChanCount count, bool silence)
4999 return ProcessThread::get_scratch_buffers (count, silence);
5003 Session::get_route_buffers (ChanCount count, bool silence)
5005 return ProcessThread::get_route_buffers (count, silence);
5010 Session::get_mix_buffers (ChanCount count)
5012 return ProcessThread::get_mix_buffers (count);
5016 Session::ntracks () const
5019 boost::shared_ptr<RouteList> r = routes.reader ();
5021 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5022 if (boost::dynamic_pointer_cast<Track> (*i)) {
5031 Session::nbusses () const
5034 boost::shared_ptr<RouteList> r = routes.reader ();
5036 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5037 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
5046 Session::add_automation_list(AutomationList *al)
5048 automation_lists[al->id()] = al;
5051 /** @return true if there is at least one record-enabled track, otherwise false */
5053 Session::have_rec_enabled_track () const
5055 return g_atomic_int_get (const_cast<gint*>(&_have_rec_enabled_track)) == 1;
5059 Session::have_rec_disabled_track () const
5061 return g_atomic_int_get (const_cast<gint*>(&_have_rec_disabled_track)) == 1;
5064 /** Update the state of our rec-enabled tracks flag */
5066 Session::update_route_record_state ()
5068 boost::shared_ptr<RouteList> rl = routes.reader ();
5069 RouteList::iterator i = rl->begin();
5070 while (i != rl->end ()) {
5072 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5073 if (tr && tr->record_enabled ()) {
5080 int const old = g_atomic_int_get (&_have_rec_enabled_track);
5082 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
5084 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
5085 RecordStateChanged (); /* EMIT SIGNAL */
5090 while (i != rl->end ()) {
5092 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5093 if (tr && !tr->record_enabled ()) {
5100 g_atomic_int_set (&_have_rec_disabled_track, i != rl->end () ? 1 : 0);
5104 Session::listen_position_changed ()
5106 boost::shared_ptr<RouteList> r = routes.reader ();
5108 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5109 (*i)->listen_position_changed ();
5114 Session::solo_control_mode_changed ()
5116 /* cancel all solo or all listen when solo control mode changes */
5119 set_solo (get_routes(), false);
5120 } else if (listening()) {
5121 set_listen (get_routes(), false);
5125 /** Called when a property of one of our route groups changes */
5127 Session::route_group_property_changed (RouteGroup* rg)
5129 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
5132 /** Called when a route is added to one of our route groups */
5134 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
5136 RouteAddedToRouteGroup (rg, r);
5139 /** Called when a route is removed from one of our route groups */
5141 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
5143 update_route_record_state ();
5144 RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */
5147 boost::shared_ptr<RouteList>
5148 Session::get_tracks () const
5150 boost::shared_ptr<RouteList> rl = routes.reader ();
5151 boost::shared_ptr<RouteList> tl (new RouteList);
5153 for (RouteList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
5154 if (boost::dynamic_pointer_cast<Track> (*r)) {
5155 if (!(*r)->is_auditioner()) {
5163 boost::shared_ptr<RouteList>
5164 Session::get_routes_with_regions_at (framepos_t const p) const
5166 boost::shared_ptr<RouteList> r = routes.reader ();
5167 boost::shared_ptr<RouteList> rl (new RouteList);
5169 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5170 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5175 boost::shared_ptr<Playlist> pl = tr->playlist ();
5180 if (pl->has_region_at (p)) {
5189 Session::goto_end ()
5191 if (_session_range_location) {
5192 request_locate (_session_range_location->end(), false);
5194 request_locate (0, false);
5199 Session::goto_start ()
5201 if (_session_range_location) {
5202 request_locate (_session_range_location->start(), false);
5204 request_locate (0, false);
5209 Session::current_start_frame () const
5211 return _session_range_location ? _session_range_location->start() : 0;
5215 Session::current_end_frame () const
5217 return _session_range_location ? _session_range_location->end() : 0;
5221 Session::add_session_range_location (framepos_t start, framepos_t end)
5223 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
5224 _locations->add (_session_range_location);
5228 Session::step_edit_status_change (bool yn)
5234 send = (_step_editors == 0);
5239 send = (_step_editors == 1);
5242 if (_step_editors > 0) {
5248 StepEditStatusChange (val);
5254 Session::start_time_changed (framepos_t old)
5256 /* Update the auto loop range to match the session range
5257 (unless the auto loop range has been changed by the user)
5260 Location* s = _locations->session_range_location ();
5265 Location* l = _locations->auto_loop_location ();
5267 if (l && l->start() == old) {
5268 l->set_start (s->start(), true);
5273 Session::end_time_changed (framepos_t old)
5275 /* Update the auto loop range to match the session range
5276 (unless the auto loop range has been changed by the user)
5279 Location* s = _locations->session_range_location ();
5284 Location* l = _locations->auto_loop_location ();
5286 if (l && l->end() == old) {
5287 l->set_end (s->end(), true);
5291 std::vector<std::string>
5292 Session::source_search_path (DataType type) const
5296 if (session_dirs.size() == 1) {
5298 case DataType::AUDIO:
5299 sp.push_back (_session_dir->sound_path());
5301 case DataType::MIDI:
5302 sp.push_back (_session_dir->midi_path());
5306 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
5307 SessionDirectory sdir (i->path);
5309 case DataType::AUDIO:
5310 sp.push_back (sdir.sound_path());
5312 case DataType::MIDI:
5313 sp.push_back (sdir.midi_path());
5319 if (type == DataType::AUDIO) {
5320 const string sound_path_2X = _session_dir->sound_path_2X();
5321 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
5322 if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) {
5323 sp.push_back (sound_path_2X);
5328 // now check the explicit (possibly user-specified) search path
5331 case DataType::AUDIO:
5332 sp += Searchpath(config.get_audio_search_path ());
5334 case DataType::MIDI:
5335 sp += Searchpath(config.get_midi_search_path ());
5343 Session::ensure_search_path_includes (const string& path, DataType type)
5352 case DataType::AUDIO:
5353 sp += Searchpath(config.get_audio_search_path ());
5355 case DataType::MIDI:
5356 sp += Searchpath (config.get_midi_search_path ());
5360 for (vector<std::string>::iterator i = sp.begin(); i != sp.end(); ++i) {
5361 /* No need to add this new directory if it has the same inode as
5362 an existing one; checking inode rather than name prevents duplicated
5363 directories when we are using symlinks.
5365 On Windows, I think we could just do if (*i == path) here.
5367 if (PBD::equivalent_paths (*i, path)) {
5375 case DataType::AUDIO:
5376 config.set_audio_search_path (sp.to_string());
5378 case DataType::MIDI:
5379 config.set_midi_search_path (sp.to_string());
5385 Session::remove_dir_from_search_path (const string& dir, DataType type)
5390 case DataType::AUDIO:
5391 sp = Searchpath(config.get_audio_search_path ());
5393 case DataType::MIDI:
5394 sp = Searchpath (config.get_midi_search_path ());
5401 case DataType::AUDIO:
5402 config.set_audio_search_path (sp.to_string());
5404 case DataType::MIDI:
5405 config.set_midi_search_path (sp.to_string());
5411 boost::shared_ptr<Speakers>
5412 Session::get_speakers()
5418 Session::unknown_processors () const
5422 boost::shared_ptr<RouteList> r = routes.reader ();
5423 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5424 list<string> t = (*i)->unknown_processors ();
5425 copy (t.begin(), t.end(), back_inserter (p));
5435 Session::update_latency (bool playback)
5437 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
5439 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
5443 boost::shared_ptr<RouteList> r = routes.reader ();
5444 framecnt_t max_latency = 0;
5447 /* reverse the list so that we work backwards from the last route to run to the first */
5448 RouteList* rl = routes.reader().get();
5449 r.reset (new RouteList (*rl));
5450 reverse (r->begin(), r->end());
5453 /* compute actual latency values for the given direction and store them all in per-port
5454 structures. this will also publish the same values (to JACK) so that computation of latency
5455 for routes can consistently use public latency values.
5458 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5459 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
5462 /* because we latency compensate playback, our published playback latencies should
5463 be the same for all output ports - all material played back by ardour has
5464 the same latency, whether its caused by plugins or by latency compensation. since
5465 these may differ from the values computed above, reset all playback port latencies
5469 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
5471 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5472 (*i)->set_public_port_latencies (max_latency, playback);
5477 post_playback_latency ();
5481 post_capture_latency ();
5484 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
5488 Session::post_playback_latency ()
5490 set_worst_playback_latency ();
5492 boost::shared_ptr<RouteList> r = routes.reader ();
5494 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5495 if (!(*i)->is_auditioner() && ((*i)->active())) {
5496 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
5500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5501 (*i)->set_latency_compensation (_worst_track_latency);
5506 Session::post_capture_latency ()
5508 set_worst_capture_latency ();
5510 /* reflect any changes in capture latencies into capture offsets
5513 boost::shared_ptr<RouteList> rl = routes.reader();
5514 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5515 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5517 tr->set_capture_offset ();
5523 Session::initialize_latencies ()
5526 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
5527 update_latency (false);
5528 update_latency (true);
5531 set_worst_io_latencies ();
5535 Session::set_worst_io_latencies ()
5537 set_worst_playback_latency ();
5538 set_worst_capture_latency ();
5542 Session::set_worst_playback_latency ()
5544 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5548 _worst_output_latency = 0;
5550 if (!_engine.connected()) {
5554 boost::shared_ptr<RouteList> r = routes.reader ();
5556 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5557 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
5560 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
5564 Session::set_worst_capture_latency ()
5566 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5570 _worst_input_latency = 0;
5572 if (!_engine.connected()) {
5576 boost::shared_ptr<RouteList> r = routes.reader ();
5578 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5579 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
5582 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
5586 Session::update_latency_compensation (bool force_whole_graph)
5588 bool some_track_latency_changed = false;
5590 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5594 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
5596 _worst_track_latency = 0;
5598 boost::shared_ptr<RouteList> r = routes.reader ();
5600 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5601 if (!(*i)->is_auditioner() && ((*i)->active())) {
5603 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
5604 some_track_latency_changed = true;
5606 _worst_track_latency = max (tl, _worst_track_latency);
5610 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
5611 (some_track_latency_changed ? "yes" : "no")));
5613 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
5615 if (some_track_latency_changed || force_whole_graph) {
5616 _engine.update_latencies ();
5620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5621 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5625 tr->set_capture_offset ();
5630 Session::session_name_is_legal (const string& path)
5632 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
5634 for (int i = 0; illegal_chars[i]; ++i) {
5635 if (path.find (illegal_chars[i]) != string::npos) {
5636 return illegal_chars[i];
5644 Session::next_control_id () const
5648 /* the monitor bus remote ID is in a different
5649 * "namespace" than regular routes. its existence doesn't
5650 * affect normal (low) numbered routes.
5657 return nroutes() - subtract;
5661 Session::notify_remote_id_change ()
5663 if (deletion_in_progress()) {
5667 switch (Config->get_remote_model()) {
5669 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
5677 Session::sync_order_keys ()
5679 if (deletion_in_progress()) {
5683 /* tell everyone that something has happened to the sort keys
5684 and let them sync up with the change(s)
5685 this will give objects that manage the sort order keys the
5686 opportunity to keep them in sync if they wish to.
5689 DEBUG_TRACE (DEBUG::OrderKeys, "Sync Order Keys.\n");
5691 reassign_track_numbers();
5693 Route::SyncOrderKeys (); /* EMIT SIGNAL */
5695 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
5699 Session::operation_in_progress (GQuark op) const
5701 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
5704 boost::shared_ptr<Port>
5705 Session::ltc_input_port () const
5707 return _ltc_input->nth (0);
5710 boost::shared_ptr<Port>
5711 Session::ltc_output_port () const
5713 return _ltc_output->nth (0);
5717 Session::reconnect_ltc_input ()
5721 string src = Config->get_ltc_source_port();
5723 _ltc_input->disconnect (this);
5725 if (src != _("None") && !src.empty()) {
5726 _ltc_input->nth (0)->connect (src);
5732 Session::reconnect_ltc_output ()
5737 string src = Config->get_ltc_sink_port();
5739 _ltc_output->disconnect (this);
5741 if (src != _("None") && !src.empty()) {
5742 _ltc_output->nth (0)->connect (src);