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);
2495 RouteAddedOrRemoved (true); /* EMIT SIGNAL */
2498 catch (failed_constructor &err) {
2499 error << _("Session: could not create new audio track.") << endmsg;
2503 catch (AudioEngine::PortRegistrationFailure& pfe) {
2505 error << pfe.what() << endmsg;
2513 if (!new_routes.empty()) {
2514 StateProtector sp (this);
2515 if (Profile->get_trx()) {
2516 add_routes (new_routes, false, false, false);
2518 add_routes (new_routes, true, true, false);
2525 /** Caller must not hold process lock.
2526 * @param name_template string to use for the start of the name, or "" to use "Bus".
2529 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
2532 uint32_t bus_id = 0;
2536 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
2539 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
2540 error << "cannot find name for new audio bus" << endmsg;
2545 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
2551 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
2552 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
2555 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2557 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
2558 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2559 input_channels, output_channels)
2565 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
2566 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2567 input_channels, output_channels)
2574 route_group->add (bus);
2576 if (Config->get_remote_model() == UserOrdered) {
2577 bus->set_remote_control_id (next_control_id());
2580 bus->add_internal_return ();
2582 ret.push_back (bus);
2588 catch (failed_constructor &err) {
2589 error << _("Session: could not create new audio route.") << endmsg;
2593 catch (AudioEngine::PortRegistrationFailure& pfe) {
2594 error << pfe.what() << endmsg;
2604 StateProtector sp (this);
2605 if (Profile->get_trx()) {
2606 add_routes (ret, false, false, false);
2608 add_routes (ret, false, true, true); // autoconnect // outputs only
2617 Session::new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name_base)
2620 uint32_t control_id;
2622 uint32_t number = 0;
2623 const uint32_t being_added = how_many;
2625 if (!tree.read (template_path.c_str())) {
2629 XMLNode* node = tree.root();
2631 IO::disable_connecting ();
2633 control_id = next_control_id ();
2637 XMLNode node_copy (*node);
2639 /* Remove IDs of everything so that new ones are used */
2640 node_copy.remove_property_recursively (X_("id"));
2645 if (!name_base.empty()) {
2647 /* if we're adding more than one routes, force
2648 * all the names of the new routes to be
2649 * numbered, via the final parameter.
2652 if (!find_route_name (name_base.c_str(), ++number, name, sizeof(name), (being_added > 1))) {
2653 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2659 string const route_name = node_copy.property(X_("name"))->value ();
2661 /* generate a new name by adding a number to the end of the template name */
2662 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2663 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2664 abort(); /*NOTREACHED*/
2668 /* set this name in the XML description that we are about to use */
2669 Route::set_name_in_state (node_copy, name);
2671 /* trim bitslots from listen sends so that new ones are used */
2672 XMLNodeList children = node_copy.children ();
2673 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2674 if ((*i)->name() == X_("Processor")) {
2675 XMLProperty* role = (*i)->property (X_("role"));
2676 if (role && role->value() == X_("Listen")) {
2677 (*i)->remove_property (X_("bitslot"));
2682 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2685 error << _("Session: cannot create track/bus from template description") << endmsg;
2689 if (boost::dynamic_pointer_cast<Track>(route)) {
2690 /* force input/output change signals so that the new diskstream
2691 picks up the configuration of the route. During session
2692 loading this normally happens in a different way.
2695 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2697 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2698 change.after = route->input()->n_ports();
2699 route->input()->changed (change, this);
2700 change.after = route->output()->n_ports();
2701 route->output()->changed (change, this);
2704 route->set_remote_control_id (control_id);
2707 ret.push_back (route);
2710 catch (failed_constructor &err) {
2711 error << _("Session: could not create new route from template") << endmsg;
2715 catch (AudioEngine::PortRegistrationFailure& pfe) {
2716 error << pfe.what() << endmsg;
2725 StateProtector sp (this);
2726 if (Profile->get_trx()) {
2727 add_routes (ret, false, false, false);
2729 add_routes (ret, true, true, false);
2731 IO::enable_connecting ();
2738 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2741 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
2742 add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
2745 error << _("Adding new tracks/busses failed") << endmsg;
2750 update_latency (true);
2751 update_latency (false);
2756 save_state (_current_snapshot_name);
2759 reassign_track_numbers();
2761 update_route_record_state ();
2763 RouteAdded (new_routes); /* EMIT SIGNAL */
2767 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
2769 ChanCount existing_inputs;
2770 ChanCount existing_outputs;
2771 uint32_t order = next_control_id();
2773 if (_order_hint > -1) {
2774 order = _order_hint;
2778 count_existing_track_channels (existing_inputs, existing_outputs);
2781 RCUWriter<RouteList> writer (routes);
2782 boost::shared_ptr<RouteList> r = writer.get_copy ();
2783 r->insert (r->end(), new_routes.begin(), new_routes.end());
2785 /* if there is no control out and we're not in the middle of loading,
2786 resort the graph here. if there is a control out, we will resort
2787 toward the end of this method. if we are in the middle of loading,
2788 we will resort when done.
2791 if (!_monitor_out && IO::connecting_legal) {
2792 resort_routes_using (r);
2796 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2798 boost::weak_ptr<Route> wpr (*x);
2799 boost::shared_ptr<Route> r (*x);
2801 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2802 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2803 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2804 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2805 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2806 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2808 if (r->is_master()) {
2812 if (r->is_monitor()) {
2816 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2818 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2819 track_playlist_changed (boost::weak_ptr<Track> (tr));
2820 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_route_record_state, this));
2822 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2824 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2825 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2830 if (input_auto_connect || output_auto_connect) {
2831 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2834 /* order keys are a GUI responsibility but we need to set up
2835 reasonable defaults because they also affect the remote control
2836 ID in most situations.
2839 if (!r->has_order_key ()) {
2840 if (r->is_auditioner()) {
2841 /* use an arbitrarily high value */
2842 r->set_order_key (UINT_MAX);
2844 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
2845 r->set_order_key (order);
2853 if (_monitor_out && IO::connecting_legal) {
2854 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2856 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2857 if ((*x)->is_monitor()) {
2859 } else if ((*x)->is_master()) {
2862 (*x)->enable_monitor_send ();
2869 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2871 boost::shared_ptr<RouteList> r = routes.reader ();
2872 boost::shared_ptr<Send> s;
2874 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2875 if ((s = (*i)->internal_send_for (dest)) != 0) {
2876 s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO);
2882 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2884 boost::shared_ptr<RouteList> r = routes.reader ();
2885 boost::shared_ptr<Send> s;
2887 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2888 if ((s = (*i)->internal_send_for (dest)) != 0) {
2889 s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY);
2895 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2897 boost::shared_ptr<RouteList> r = routes.reader ();
2898 boost::shared_ptr<Send> s;
2900 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2901 if ((s = (*i)->internal_send_for (dest)) != 0) {
2902 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2907 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2909 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2911 boost::shared_ptr<RouteList> r = routes.reader ();
2912 boost::shared_ptr<RouteList> t (new RouteList);
2914 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2915 /* no MIDI sends because there are no MIDI busses yet */
2916 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2921 add_internal_sends (dest, p, t);
2925 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2927 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2928 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2933 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2935 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2939 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2941 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2945 if (!dest->internal_return()) {
2946 dest->add_internal_return ();
2949 sender->add_aux_send (dest, before);
2956 Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
2958 { // RCU Writer scope
2959 RCUWriter<RouteList> writer (routes);
2960 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2963 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
2965 if (*iter == _master_out) {
2969 (*iter)->set_solo (false, this);
2973 /* deleting the master out seems like a dumb
2974 idea, but its more of a UI policy issue
2978 if (*iter == _master_out) {
2979 _master_out = boost::shared_ptr<Route> ();
2982 if (*iter == _monitor_out) {
2983 _monitor_out.reset ();
2986 update_route_solo_state ();
2988 // We need to disconnect the route's inputs and outputs
2990 (*iter)->input()->disconnect (0);
2991 (*iter)->output()->disconnect (0);
2993 /* if the route had internal sends sending to it, remove them */
2994 if ((*iter)->internal_return()) {
2996 boost::shared_ptr<RouteList> r = routes.reader ();
2997 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2998 boost::shared_ptr<Send> s = (*i)->internal_send_for (*iter);
3000 (*i)->remove_processor (s);
3005 /* if the monitoring section had a pointer to this route, remove it */
3006 if (_monitor_out && !(*iter)->is_master() && !(*iter)->is_monitor()) {
3007 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3008 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
3009 (*iter)->remove_aux_or_listen (_monitor_out);
3012 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*iter);
3013 if (mt && mt->step_editing()) {
3014 if (_step_editors > 0) {
3019 RouteAddedOrRemoved (false); /* EMIT SIGNAL */
3022 /* writer goes out of scope, forces route list update */
3024 } // end of RCU Writer scope
3026 update_latency_compensation ();
3029 /* Re-sort routes to remove the graph's current references to the one that is
3030 * going away, then flush old references out of the graph.
3031 * Wave Tracks: reconnect routes
3034 if (ARDOUR::Profile->get_trx () ) {
3035 reconnect_existing_routes(true, false);
3040 if (_process_graph) {
3041 _process_graph->clear_other_chain ();
3044 /* get rid of it from the dead wood collection in the route list manager */
3045 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
3049 /* try to cause everyone to drop their references
3050 * and unregister ports from the backend
3052 PBD::Unwinder<bool> uw_flag (_route_deletion_in_progress, true);
3054 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3055 (*iter)->drop_references ();
3058 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
3060 /* save the new state of the world */
3062 if (save_state (_current_snapshot_name)) {
3063 save_history (_current_snapshot_name);
3066 reassign_track_numbers();
3067 update_route_record_state ();
3071 Session::remove_route (boost::shared_ptr<Route> route)
3073 boost::shared_ptr<RouteList> rl (new RouteList);
3074 rl->push_back (route);
3079 Session::route_mute_changed (void* /*src*/)
3085 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
3087 boost::shared_ptr<Route> route = wpr.lock();
3089 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
3093 if (route->listening_via_monitor ()) {
3095 if (Config->get_exclusive_solo()) {
3096 /* new listen: disable all other listen */
3097 boost::shared_ptr<RouteList> r = routes.reader ();
3098 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3099 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
3102 (*i)->set_listen (false, this);
3108 } else if (_listen_cnt > 0) {
3113 update_route_solo_state ();
3116 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
3118 boost::shared_ptr<Route> route = wpr.lock ();
3121 /* should not happen */
3122 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
3126 bool send_changed = false;
3128 if (route->solo_isolated()) {
3129 if (_solo_isolated_cnt == 0) {
3130 send_changed = true;
3132 _solo_isolated_cnt++;
3133 } else if (_solo_isolated_cnt > 0) {
3134 _solo_isolated_cnt--;
3135 if (_solo_isolated_cnt == 0) {
3136 send_changed = true;
3141 IsolatedChanged (); /* EMIT SIGNAL */
3146 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
3148 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
3150 if (!self_solo_change) {
3151 // session doesn't care about changes to soloed-by-others
3155 if (solo_update_disabled) {
3157 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
3161 boost::shared_ptr<Route> route = wpr.lock ();
3164 boost::shared_ptr<RouteList> r = routes.reader ();
3167 if (route->self_soloed()) {
3173 RouteGroup* rg = route->route_group ();
3174 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
3176 if (delta == 1 && Config->get_exclusive_solo()) {
3178 /* new solo: disable all other solos, but not the group if its solo-enabled */
3180 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3181 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
3182 (leave_group_alone && ((*i)->route_group() == rg))) {
3185 (*i)->set_solo (false, this);
3189 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
3191 solo_update_disabled = true;
3193 RouteList uninvolved;
3195 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
3197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3198 bool via_sends_only;
3199 bool in_signal_flow;
3201 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
3202 (leave_group_alone && ((*i)->route_group() == rg))) {
3206 in_signal_flow = false;
3208 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
3210 if ((*i)->feeds (route, &via_sends_only)) {
3211 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
3212 if (!via_sends_only) {
3213 if (!route->soloed_by_others_upstream()) {
3214 (*i)->mod_solo_by_others_downstream (delta);
3217 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
3219 in_signal_flow = true;
3221 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
3224 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
3226 if (route->feeds (*i, &via_sends_only)) {
3227 /* propagate solo upstream only if routing other than
3228 sends is involved, but do consider the other route
3229 (*i) to be part of the signal flow even if only
3232 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
3236 route->soloed_by_others_downstream(),
3237 route->soloed_by_others_upstream()));
3238 if (!via_sends_only) {
3239 if (!route->soloed_by_others_downstream()) {
3240 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
3241 (*i)->mod_solo_by_others_upstream (delta);
3243 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
3246 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
3248 in_signal_flow = true;
3250 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
3253 if (!in_signal_flow) {
3254 uninvolved.push_back (*i);
3258 solo_update_disabled = false;
3259 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
3261 update_route_solo_state (r);
3263 /* now notify that the mute state of the routes not involved in the signal
3264 pathway of the just-solo-changed route may have altered.
3267 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
3268 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
3269 (*i)->act_on_mute ();
3270 (*i)->mute_changed (this);
3273 SoloChanged (); /* EMIT SIGNAL */
3278 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
3280 /* now figure out if anything that matters is soloed (or is "listening")*/
3282 bool something_soloed = false;
3283 uint32_t listeners = 0;
3284 uint32_t isolated = 0;
3287 r = routes.reader();
3290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3291 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner() && (*i)->self_soloed()) {
3292 something_soloed = true;
3295 if (!(*i)->is_auditioner() && (*i)->listening_via_monitor()) {
3296 if (Config->get_solo_control_is_listen_control()) {
3299 (*i)->set_listen (false, this);
3303 if ((*i)->solo_isolated()) {
3308 if (something_soloed != _non_soloed_outs_muted) {
3309 _non_soloed_outs_muted = something_soloed;
3310 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
3313 _listen_cnt = listeners;
3315 if (isolated != _solo_isolated_cnt) {
3316 _solo_isolated_cnt = isolated;
3317 IsolatedChanged (); /* EMIT SIGNAL */
3320 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
3321 something_soloed, listeners, isolated));
3324 boost::shared_ptr<RouteList>
3325 Session::get_routes_with_internal_returns() const
3327 boost::shared_ptr<RouteList> r = routes.reader ();
3328 boost::shared_ptr<RouteList> rl (new RouteList);
3330 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3331 if ((*i)->internal_return ()) {
3339 Session::io_name_is_legal (const std::string& name)
3341 boost::shared_ptr<RouteList> r = routes.reader ();
3343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3344 if ((*i)->name() == name) {
3348 if ((*i)->has_io_processor_named (name)) {
3357 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
3360 vector<string> connections;
3362 /* if we are passed only a single route and we're not told to turn
3363 * others off, then just do the simple thing.
3366 if (flip_others == false && rl->size() == 1) {
3367 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
3369 mt->set_input_active (onoff);
3374 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
3376 PortSet& ps ((*rt)->input()->ports());
3378 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
3379 p->get_connections (connections);
3382 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
3383 routes_using_input_from (*s, rl2);
3386 /* scan all relevant routes to see if others are on or off */
3388 bool others_are_already_on = false;
3390 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
3392 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
3398 if ((*r) != (*rt)) {
3399 if (mt->input_active()) {
3400 others_are_already_on = true;
3403 /* this one needs changing */
3404 mt->set_input_active (onoff);
3410 /* globally reverse other routes */
3412 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
3413 if ((*r) != (*rt)) {
3414 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
3416 mt->set_input_active (!others_are_already_on);
3425 Session::routes_using_input_from (const string& str, RouteList& rl)
3427 boost::shared_ptr<RouteList> r = routes.reader();
3429 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3430 if ((*i)->input()->connected_to (str)) {
3436 boost::shared_ptr<Route>
3437 Session::route_by_name (string name)
3439 boost::shared_ptr<RouteList> r = routes.reader ();
3441 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3442 if ((*i)->name() == name) {
3447 return boost::shared_ptr<Route> ((Route*) 0);
3450 boost::shared_ptr<Route>
3451 Session::route_by_id (PBD::ID id)
3453 boost::shared_ptr<RouteList> r = routes.reader ();
3455 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3456 if ((*i)->id() == id) {
3461 return boost::shared_ptr<Route> ((Route*) 0);
3464 boost::shared_ptr<Track>
3465 Session::track_by_diskstream_id (PBD::ID id)
3467 boost::shared_ptr<RouteList> r = routes.reader ();
3469 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3470 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
3471 if (t && t->using_diskstream_id (id)) {
3476 return boost::shared_ptr<Track> ();
3479 boost::shared_ptr<Route>
3480 Session::route_by_remote_id (uint32_t id)
3482 boost::shared_ptr<RouteList> r = routes.reader ();
3484 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3485 if ((*i)->remote_control_id() == id) {
3490 return boost::shared_ptr<Route> ((Route*) 0);
3495 Session::reassign_track_numbers ()
3499 RouteList r (*(routes.reader ()));
3500 SignalOrderRouteSorter sorter;
3503 StateProtector sp (this);
3505 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
3506 if (boost::dynamic_pointer_cast<Track> (*i)) {
3507 (*i)->set_track_number(++tn);
3509 else if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
3510 (*i)->set_track_number(--bn);
3513 const uint32_t decimals = ceilf (log10f (tn + 1));
3514 const bool decimals_changed = _track_number_decimals != decimals;
3515 _track_number_decimals = decimals;
3517 if (decimals_changed && config.get_track_name_number ()) {
3518 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
3519 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
3521 t->resync_track_name();
3524 // trigger GUI re-layout
3525 config.ParameterChanged("track-name-number");
3530 Session::playlist_region_added (boost::weak_ptr<Region> w)
3532 boost::shared_ptr<Region> r = w.lock ();
3537 /* These are the operations that are currently in progress... */
3538 list<GQuark> curr = _current_trans_quarks;
3541 /* ...and these are the operations during which we want to update
3542 the session range location markers.
3545 ops.push_back (Operations::capture);
3546 ops.push_back (Operations::paste);
3547 ops.push_back (Operations::duplicate_region);
3548 ops.push_back (Operations::insert_file);
3549 ops.push_back (Operations::insert_region);
3550 ops.push_back (Operations::drag_region_brush);
3551 ops.push_back (Operations::region_drag);
3552 ops.push_back (Operations::selection_grab);
3553 ops.push_back (Operations::region_fill);
3554 ops.push_back (Operations::fill_selection);
3555 ops.push_back (Operations::create_region);
3556 ops.push_back (Operations::region_copy);
3557 ops.push_back (Operations::fixed_time_region_copy);
3560 /* See if any of the current operations match the ones that we want */
3562 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
3564 /* If so, update the session range markers */
3566 maybe_update_session_range (r->position (), r->last_frame ());
3570 /** Update the session range markers if a is before the current start or
3571 * b is after the current end.
3574 Session::maybe_update_session_range (framepos_t a, framepos_t b)
3576 if (_state_of_the_state & Loading) {
3580 if (_session_range_location == 0) {
3582 add_session_range_location (a, b);
3586 if (a < _session_range_location->start()) {
3587 _session_range_location->set_start (a);
3590 if (b > _session_range_location->end()) {
3591 _session_range_location->set_end (b);
3597 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
3599 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
3600 maybe_update_session_range (i->to, i->to + i->length);
3605 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
3607 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
3608 maybe_update_session_range (i->from, i->to);
3612 /* Region management */
3614 boost::shared_ptr<Region>
3615 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
3617 const RegionFactory::RegionMap& regions (RegionFactory::regions());
3618 RegionFactory::RegionMap::const_iterator i;
3619 boost::shared_ptr<Region> region;
3621 Glib::Threads::Mutex::Lock lm (region_lock);
3623 for (i = regions.begin(); i != regions.end(); ++i) {
3627 if (region->whole_file()) {
3629 if (child->source_equivalent (region)) {
3635 return boost::shared_ptr<Region> ();
3639 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
3641 set<boost::shared_ptr<Region> > relevant_regions;
3643 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
3644 RegionFactory::get_regions_using_source (*s, relevant_regions);
3647 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
3648 set<boost::shared_ptr<Region> >::iterator tmp;
3653 playlists->destroy_region (*r);
3654 RegionFactory::map_remove (*r);
3656 (*r)->drop_sources ();
3657 (*r)->drop_references ();
3659 relevant_regions.erase (r);
3664 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
3667 Glib::Threads::Mutex::Lock ls (source_lock);
3668 /* remove from the main source list */
3669 sources.erase ((*s)->id());
3672 (*s)->mark_for_remove ();
3673 (*s)->drop_references ();
3682 Session::remove_last_capture ()
3684 list<boost::shared_ptr<Source> > srcs;
3686 boost::shared_ptr<RouteList> rl = routes.reader ();
3687 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3688 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3693 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
3696 srcs.insert (srcs.end(), l.begin(), l.end());
3701 destroy_sources (srcs);
3703 save_state (_current_snapshot_name);
3708 /* Source Management */
3711 Session::add_source (boost::shared_ptr<Source> source)
3713 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3714 pair<SourceMap::iterator,bool> result;
3716 entry.first = source->id();
3717 entry.second = source;
3720 Glib::Threads::Mutex::Lock lm (source_lock);
3721 result = sources.insert (entry);
3724 if (result.second) {
3726 /* yay, new source */
3728 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3731 if (!fs->within_session()) {
3732 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3738 boost::shared_ptr<AudioFileSource> afs;
3740 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3741 if (Config->get_auto_analyse_audio()) {
3742 Analyser::queue_source_for_analysis (source, false);
3746 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3751 Session::remove_source (boost::weak_ptr<Source> src)
3753 if (_state_of_the_state & Deletion) {
3757 SourceMap::iterator i;
3758 boost::shared_ptr<Source> source = src.lock();
3765 Glib::Threads::Mutex::Lock lm (source_lock);
3767 if ((i = sources.find (source->id())) != sources.end()) {
3772 if (!(_state_of_the_state & StateOfTheState (InCleanup|Loading))) {
3774 /* save state so we don't end up with a session file
3775 referring to non-existent sources.
3778 save_state (_current_snapshot_name);
3782 boost::shared_ptr<Source>
3783 Session::source_by_id (const PBD::ID& id)
3785 Glib::Threads::Mutex::Lock lm (source_lock);
3786 SourceMap::iterator i;
3787 boost::shared_ptr<Source> source;
3789 if ((i = sources.find (id)) != sources.end()) {
3796 boost::shared_ptr<AudioFileSource>
3797 Session::audio_source_by_path_and_channel (const string& path, uint16_t chn) const
3799 /* Restricted to audio files because only audio sources have channel
3803 Glib::Threads::Mutex::Lock lm (source_lock);
3805 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3806 boost::shared_ptr<AudioFileSource> afs
3807 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3809 if (afs && afs->path() == path && chn == afs->channel()) {
3814 return boost::shared_ptr<AudioFileSource>();
3817 boost::shared_ptr<MidiSource>
3818 Session::midi_source_by_path (const std::string& path) const
3820 /* Restricted to MIDI files because audio sources require a channel
3821 for unique identification, in addition to a path.
3824 Glib::Threads::Mutex::Lock lm (source_lock);
3826 for (SourceMap::const_iterator s = sources.begin(); s != sources.end(); ++s) {
3827 boost::shared_ptr<MidiSource> ms
3828 = boost::dynamic_pointer_cast<MidiSource>(s->second);
3829 boost::shared_ptr<FileSource> fs
3830 = boost::dynamic_pointer_cast<FileSource>(s->second);
3832 if (ms && fs && fs->path() == path) {
3837 return boost::shared_ptr<MidiSource>();
3841 Session::count_sources_by_origin (const string& path)
3844 Glib::Threads::Mutex::Lock lm (source_lock);
3846 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3847 boost::shared_ptr<FileSource> fs
3848 = boost::dynamic_pointer_cast<FileSource>(i->second);
3850 if (fs && fs->origin() == path) {
3859 Session::peak_path (string base) const
3861 if (Glib::path_is_absolute (base)) {
3863 /* rip the session dir from the audiofile source */
3865 string session_path;
3866 string interchange_dir_string = string (interchange_dir_name) + G_DIR_SEPARATOR;
3867 bool in_another_session = true;
3869 if (base.find (interchange_dir_string) != string::npos) {
3871 session_path = Glib::path_get_dirname (base); /* now ends in audiofiles */
3872 session_path = Glib::path_get_dirname (session_path); /* now ends in session name */
3873 session_path = Glib::path_get_dirname (session_path); /* now ends in interchange */
3874 session_path = Glib::path_get_dirname (session_path); /* now has session path */
3876 /* see if it is within our session */
3878 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3879 if (i->path == session_path) {
3880 in_another_session = false;
3885 in_another_session = false;
3889 if (in_another_session) {
3890 SessionDirectory sd (session_path);
3891 return Glib::build_filename (sd.peak_path(), Glib::path_get_basename (base) + peakfile_suffix);
3895 base = Glib::path_get_basename (base);
3896 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3900 Session::new_audio_source_path_for_embedded (const std::string& path)
3904 * we know that the filename is already unique because it exists
3905 * out in the filesystem.
3907 * However, when we bring it into the session, we could get a
3910 * Eg. two embedded files:
3915 * When merged into session, these collide.
3917 * There will not be a conflict with in-memory sources
3918 * because when the source was created we already picked
3919 * a unique name for it.
3921 * This collision is not likely to be common, but we have to guard
3922 * against it. So, if there is a collision, take the md5 hash of the
3923 * the path, and use that as the filename instead.
3926 SessionDirectory sdir (get_best_session_directory_for_new_audio());
3927 string base = Glib::path_get_basename (path);
3928 string newpath = Glib::build_filename (sdir.sound_path(), base);
3930 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3934 md5.digestString (path.c_str());
3935 md5.writeToString ();
3936 base = md5.digestChars;
3938 string ext = get_suffix (path);
3945 newpath = Glib::build_filename (sdir.sound_path(), base);
3947 /* if this collides, we're screwed */
3949 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3950 error << string_compose (_("Merging embedded file %1: name collision AND md5 hash collision!"), path) << endmsg;
3959 /** Return true if there are no audio file sources that use @param name as
3960 * the filename component of their path.
3962 * Return false otherwise.
3964 * This method MUST ONLY be used to check in-session, mono files since it
3965 * hard-codes the channel of the audio file source we are looking for as zero.
3967 * If/when Ardour supports native files in non-mono formats, the logic here
3968 * will need to be revisited.
3971 Session::audio_source_name_is_unique (const string& name)
3973 std::vector<string> sdirs = source_search_path (DataType::AUDIO);
3974 vector<space_and_path>::iterator i;
3975 uint32_t existing = 0;
3977 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
3979 /* note that we search *without* the extension so that
3980 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3981 in the event that this new name is required for
3982 a file format change.
3985 const string spath = *i;
3987 if (matching_unsuffixed_filename_exists_in (spath, name)) {
3992 /* it is possible that we have the path already
3993 * assigned to a source that has not yet been written
3994 * (ie. the write source for a diskstream). we have to
3995 * check this in order to make sure that our candidate
3996 * path isn't used again, because that can lead to
3997 * two Sources point to the same file with different
3998 * notions of their removability.
4002 string possible_path = Glib::build_filename (spath, name);
4004 if (audio_source_by_path_and_channel (possible_path, 0)) {
4010 return (existing == 0);
4014 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)
4017 const string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
4021 sstr << setfill ('0') << setw (4) << cnt;
4022 sstr << legalized_base;
4024 sstr << legalized_base;
4026 if (take_required || related_exists) {
4038 } else if (nchan > 2) {
4043 /* XXX what? more than 26 channels! */
4054 /** Return a unique name based on \a base for a new internal audio source */
4056 Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required)
4059 string possible_name;
4060 const uint32_t limit = 9999; // arbitrary limit on number of files with the same basic name
4062 bool some_related_source_name_exists = false;
4064 legalized = legalize_for_path (base);
4066 // Find a "version" of the base name that doesn't exist in any of the possible directories.
4068 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
4070 possible_name = format_audio_source_name (legalized, nchan, chan, destructive, take_required, cnt, some_related_source_name_exists);
4072 if (audio_source_name_is_unique (possible_name)) {
4076 some_related_source_name_exists = true;
4079 error << string_compose(
4080 _("There are already %1 recordings for %2, which I consider too many."),
4081 limit, base) << endmsg;
4083 throw failed_constructor();
4087 /* We've established that the new name does not exist in any session
4088 * directory, so now find out which one we should use for this new
4092 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4094 std::string s = Glib::build_filename (sdir.sound_path(), possible_name);
4099 /** Return a unique name based on `base` for a new internal MIDI source */
4101 Session::new_midi_source_path (const string& base)
4104 char buf[PATH_MAX+1];
4105 const uint32_t limit = 10000;
4107 string possible_path;
4108 string possible_name;
4111 legalized = legalize_for_path (base);
4113 // Find a "version" of the file name that doesn't exist in any of the possible directories.
4114 std::vector<string> sdirs = source_search_path(DataType::MIDI);
4116 /* - the main session folder is the first in the vector.
4117 * - after checking all locations for file-name uniqueness,
4118 * we keep the one from the last iteration as new file name
4119 * - midi files are small and should just be kept in the main session-folder
4121 * -> reverse the array, check main session folder last and use that as location
4124 std::reverse(sdirs.begin(), sdirs.end());
4126 for (cnt = 1; cnt <= limit; ++cnt) {
4128 vector<space_and_path>::iterator i;
4129 uint32_t existing = 0;
4131 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4133 snprintf (buf, sizeof(buf), "%s-%u.mid", legalized.c_str(), cnt);
4134 possible_name = buf;
4136 possible_path = Glib::build_filename (*i, possible_name);
4138 if (Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
4142 if (midi_source_by_path (possible_path)) {
4147 if (existing == 0) {
4152 error << string_compose(
4153 _("There are already %1 recordings for %2, which I consider too many."),
4154 limit, base) << endmsg;
4160 /* No need to "find best location" for software/app-based RAID, because
4161 MIDI is so small that we always put it in the same place.
4164 return possible_path;
4168 /** Create a new within-session audio source */
4169 boost::shared_ptr<AudioFileSource>
4170 Session::create_audio_source_for_session (size_t n_chans, string const & base, uint32_t chan, bool destructive)
4172 const string path = new_audio_source_path (base, n_chans, chan, destructive, true);
4174 if (!path.empty()) {
4175 return boost::dynamic_pointer_cast<AudioFileSource> (
4176 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
4178 throw failed_constructor ();
4182 /** Create a new within-session MIDI source */
4183 boost::shared_ptr<MidiSource>
4184 Session::create_midi_source_for_session (string const & basic_name)
4186 const string path = new_midi_source_path (basic_name);
4188 if (!path.empty()) {
4189 return boost::dynamic_pointer_cast<SMFSource> (
4190 SourceFactory::createWritable (
4191 DataType::MIDI, *this, path, false, frame_rate()));
4193 throw failed_constructor ();
4197 /** Create a new within-session MIDI source */
4198 boost::shared_ptr<MidiSource>
4199 Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
4201 /* the caller passes in the track the source will be used in,
4202 so that we can keep the numbering sane.
4204 Rationale: a track with the name "Foo" that has had N
4205 captures carried out so far will ALREADY have a write source
4206 named "Foo-N+1.mid" waiting to be used for the next capture.
4208 If we call new_midi_source_name() we will get "Foo-N+2". But
4209 there is no region corresponding to "Foo-N+1", so when
4210 "Foo-N+2" appears in the track, the gap presents the user
4211 with odd behaviour - why did it skip past Foo-N+1?
4213 We could explain this to the user in some odd way, but
4214 instead we rename "Foo-N+1.mid" as "Foo-N+2.mid", and then
4217 If that attempted rename fails, we get "Foo-N+2.mid" anyway.
4220 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (track);
4222 std::string name = track->steal_write_source_name ();
4225 return boost::shared_ptr<MidiSource>();
4228 /* MIDI files are small, just put them in the first location of the
4229 session source search path.
4232 const string path = Glib::build_filename (source_search_path (DataType::MIDI).front(), name);
4234 return boost::dynamic_pointer_cast<SMFSource> (
4235 SourceFactory::createWritable (
4236 DataType::MIDI, *this, path, false, frame_rate()));
4241 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
4243 if (playlist->hidden()) {
4247 playlists->add (playlist);
4250 playlist->release();
4257 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
4259 if (_state_of_the_state & Deletion) {
4263 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
4269 playlists->remove (playlist);
4275 Session::set_audition (boost::shared_ptr<Region> r)
4277 pending_audition_region = r;
4278 add_post_transport_work (PostTransportAudition);
4279 _butler->schedule_transport_work ();
4283 Session::audition_playlist ()
4285 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
4286 ev->region.reset ();
4291 Session::non_realtime_set_audition ()
4293 assert (pending_audition_region);
4294 auditioner->audition_region (pending_audition_region);
4295 pending_audition_region.reset ();
4296 AuditionActive (true); /* EMIT SIGNAL */
4300 Session::audition_region (boost::shared_ptr<Region> r)
4302 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
4308 Session::cancel_audition ()
4313 if (auditioner->auditioning()) {
4314 auditioner->cancel_audition ();
4315 AuditionActive (false); /* EMIT SIGNAL */
4320 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
4322 if (a->is_monitor()) {
4325 if (b->is_monitor()) {
4328 return a->order_key () < b->order_key ();
4332 Session::is_auditioning () const
4334 /* can be called before we have an auditioner object */
4336 return auditioner->auditioning();
4343 Session::graph_reordered ()
4345 /* don't do this stuff if we are setting up connections
4346 from a set_state() call or creating new tracks. Ditto for deletion.
4349 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
4353 /* every track/bus asked for this to be handled but it was deferred because
4354 we were connecting. do it now.
4357 request_input_change_handling ();
4361 /* force all diskstreams to update their capture offset values to
4362 reflect any changes in latencies within the graph.
4365 boost::shared_ptr<RouteList> rl = routes.reader ();
4366 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4367 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4369 tr->set_capture_offset ();
4374 /** @return Number of frames that there is disk space available to write,
4377 boost::optional<framecnt_t>
4378 Session::available_capture_duration ()
4380 Glib::Threads::Mutex::Lock lm (space_lock);
4382 if (_total_free_4k_blocks_uncertain) {
4383 return boost::optional<framecnt_t> ();
4386 float sample_bytes_on_disk = 4.0; // keep gcc happy
4388 switch (config.get_native_file_data_format()) {
4390 sample_bytes_on_disk = 4.0;
4394 sample_bytes_on_disk = 3.0;
4398 sample_bytes_on_disk = 2.0;
4402 /* impossible, but keep some gcc versions happy */
4403 fatal << string_compose (_("programming error: %1"),
4404 X_("illegal native file data format"))
4406 abort(); /*NOTREACHED*/
4409 double scale = 4096.0 / sample_bytes_on_disk;
4411 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
4412 return max_framecnt;
4415 return (framecnt_t) floor (_total_free_4k_blocks * scale);
4419 Session::add_bundle (boost::shared_ptr<Bundle> bundle, bool emit_signal)
4422 RCUWriter<BundleList> writer (_bundles);
4423 boost::shared_ptr<BundleList> b = writer.get_copy ();
4424 b->push_back (bundle);
4428 BundleAddedOrRemoved (); /* EMIT SIGNAL */
4435 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
4437 bool removed = false;
4440 RCUWriter<BundleList> writer (_bundles);
4441 boost::shared_ptr<BundleList> b = writer.get_copy ();
4442 BundleList::iterator i = find (b->begin(), b->end(), bundle);
4444 if (i != b->end()) {
4451 BundleAddedOrRemoved (); /* EMIT SIGNAL */
4457 boost::shared_ptr<Bundle>
4458 Session::bundle_by_name (string name) const
4460 boost::shared_ptr<BundleList> b = _bundles.reader ();
4462 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
4463 if ((*i)->name() == name) {
4468 return boost::shared_ptr<Bundle> ();
4472 Session::tempo_map_changed (const PropertyChange&)
4476 playlists->update_after_tempo_map_change ();
4478 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
4484 Session::update_locations_after_tempo_map_change (const Locations::LocationList& loc)
4486 for (Locations::LocationList::const_iterator i = loc.begin(); i != loc.end(); ++i) {
4487 (*i)->recompute_frames_from_bbt ();
4491 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
4492 * the given count with the current block size.
4495 Session::ensure_buffers (ChanCount howmany)
4497 BufferManager::ensure_buffers (howmany, bounce_processing() ? bounce_chunk_size : 0);
4501 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
4503 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4504 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
4509 Session::next_insert_id ()
4511 /* this doesn't really loop forever. just think about it */
4514 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
4515 if (!insert_bitset[n]) {
4516 insert_bitset[n] = true;
4522 /* none available, so resize and try again */
4524 insert_bitset.resize (insert_bitset.size() + 16, false);
4529 Session::next_send_id ()
4531 /* this doesn't really loop forever. just think about it */
4534 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
4535 if (!send_bitset[n]) {
4536 send_bitset[n] = true;
4542 /* none available, so resize and try again */
4544 send_bitset.resize (send_bitset.size() + 16, false);
4549 Session::next_aux_send_id ()
4551 /* this doesn't really loop forever. just think about it */
4554 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
4555 if (!aux_send_bitset[n]) {
4556 aux_send_bitset[n] = true;
4562 /* none available, so resize and try again */
4564 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
4569 Session::next_return_id ()
4571 /* this doesn't really loop forever. just think about it */
4574 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
4575 if (!return_bitset[n]) {
4576 return_bitset[n] = true;
4582 /* none available, so resize and try again */
4584 return_bitset.resize (return_bitset.size() + 16, false);
4589 Session::mark_send_id (uint32_t id)
4591 if (id >= send_bitset.size()) {
4592 send_bitset.resize (id+16, false);
4594 if (send_bitset[id]) {
4595 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
4597 send_bitset[id] = true;
4601 Session::mark_aux_send_id (uint32_t id)
4603 if (id >= aux_send_bitset.size()) {
4604 aux_send_bitset.resize (id+16, false);
4606 if (aux_send_bitset[id]) {
4607 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
4609 aux_send_bitset[id] = true;
4613 Session::mark_return_id (uint32_t id)
4615 if (id >= return_bitset.size()) {
4616 return_bitset.resize (id+16, false);
4618 if (return_bitset[id]) {
4619 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
4621 return_bitset[id] = true;
4625 Session::mark_insert_id (uint32_t id)
4627 if (id >= insert_bitset.size()) {
4628 insert_bitset.resize (id+16, false);
4630 if (insert_bitset[id]) {
4631 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
4633 insert_bitset[id] = true;
4637 Session::unmark_send_id (uint32_t id)
4639 if (id < send_bitset.size()) {
4640 send_bitset[id] = false;
4645 Session::unmark_aux_send_id (uint32_t id)
4647 if (id < aux_send_bitset.size()) {
4648 aux_send_bitset[id] = false;
4653 Session::unmark_return_id (uint32_t id)
4655 if (id < return_bitset.size()) {
4656 return_bitset[id] = false;
4661 Session::unmark_insert_id (uint32_t id)
4663 if (id < insert_bitset.size()) {
4664 insert_bitset[id] = false;
4669 Session::reset_native_file_format ()
4671 boost::shared_ptr<RouteList> rl = routes.reader ();
4672 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4673 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4675 /* don't save state as we do this, there's no point
4678 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
4679 tr->reset_write_sources (false);
4680 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
4686 Session::route_name_unique (string n) const
4688 boost::shared_ptr<RouteList> r = routes.reader ();
4690 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4691 if ((*i)->name() == n) {
4700 Session::route_name_internal (string n) const
4702 if (auditioner && auditioner->name() == n) {
4706 if (_click_io && _click_io->name() == n) {
4714 Session::freeze_all (InterThreadInfo& itt)
4716 boost::shared_ptr<RouteList> r = routes.reader ();
4718 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4720 boost::shared_ptr<Track> t;
4722 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4723 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4733 boost::shared_ptr<Region>
4734 Session::write_one_track (Track& track, framepos_t start, framepos_t end,
4735 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4736 InterThreadInfo& itt,
4737 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
4738 bool for_export, bool for_freeze)
4740 boost::shared_ptr<Region> result;
4741 boost::shared_ptr<Playlist> playlist;
4742 boost::shared_ptr<Source> source;
4743 ChanCount diskstream_channels (track.n_channels());
4744 framepos_t position;
4745 framecnt_t this_chunk;
4747 framepos_t latency_skip;
4749 framepos_t len = end - start;
4750 bool need_block_size_reset = false;
4751 ChanCount const max_proc = track.max_processor_streams ();
4752 string legal_playlist_name;
4753 string possible_path;
4756 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4757 end, start) << endmsg;
4761 diskstream_channels = track.bounce_get_output_streams (diskstream_channels, endpoint,
4762 include_endpoint, for_export, for_freeze);
4764 if (diskstream_channels.n(track.data_type()) < 1) {
4765 error << _("Cannot write a range with no data.") << endmsg;
4769 // block all process callback handling
4771 block_processing ();
4774 // synchronize with AudioEngine::process_callback()
4775 // make sure processing is not currently running
4776 // and processing_blocked() is honored before
4777 // acquiring thread buffers
4778 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4781 _bounce_processing_active = true;
4783 /* call tree *MUST* hold route_lock */
4785 if ((playlist = track.playlist()) == 0) {
4789 legal_playlist_name = legalize_for_path (playlist->name());
4791 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n(track.data_type()); ++chan_n) {
4793 string base_name = string_compose ("%1-%2-bounce", playlist->name(), chan_n);
4794 string path = ((track.data_type() == DataType::AUDIO)
4795 ? new_audio_source_path (legal_playlist_name, diskstream_channels.n_audio(), chan_n, false, true)
4796 : new_midi_source_path (legal_playlist_name));
4803 source = SourceFactory::createWritable (track.data_type(), *this, path, false, frame_rate());
4806 catch (failed_constructor& err) {
4807 error << string_compose (_("cannot create new file \"%1\" for %2"), path, track.name()) << endmsg;
4811 srcs.push_back (source);
4814 /* tell redirects that care that we are about to use a much larger
4815 * blocksize. this will flush all plugins too, so that they are ready
4816 * to be used for this process.
4819 need_block_size_reset = true;
4820 track.set_block_size (bounce_chunk_size);
4821 _engine.main_thread()->get_buffers ();
4825 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
4827 /* create a set of reasonably-sized buffers */
4828 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4829 buffers.ensure_buffers(*t, max_proc.get(*t), bounce_chunk_size);
4831 buffers.set_count (max_proc);
4833 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4834 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4835 boost::shared_ptr<MidiSource> ms;
4837 afs->prepare_for_peakfile_writes ();
4838 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4839 Source::Lock lock(ms->mutex());
4840 ms->mark_streaming_write_started(lock);
4844 while (to_do && !itt.cancel) {
4846 this_chunk = min (to_do, bounce_chunk_size);
4848 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze)) {
4852 start += this_chunk;
4853 to_do -= this_chunk;
4854 itt.progress = (float) (1.0 - ((double) to_do / len));
4856 if (latency_skip >= bounce_chunk_size) {
4857 latency_skip -= bounce_chunk_size;
4861 const framecnt_t current_chunk = this_chunk - latency_skip;
4864 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4865 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4866 boost::shared_ptr<MidiSource> ms;
4869 if (afs->write (buffers.get_audio(n).data(latency_skip), current_chunk) != current_chunk) {
4872 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4873 Source::Lock lock(ms->mutex());
4875 const MidiBuffer& buf = buffers.get_midi(0);
4876 for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
4877 Evoral::Event<framepos_t> ev = *i;
4878 ev.set_time(ev.time() - position);
4879 ms->append_event_frames(lock, ev, ms->timeline_position());
4886 /* post-roll, pick up delayed processor output */
4887 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
4889 while (latency_skip && !itt.cancel) {
4890 this_chunk = min (latency_skip, bounce_chunk_size);
4891 latency_skip -= this_chunk;
4893 buffers.silence (this_chunk, 0);
4894 track.bounce_process (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze);
4897 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4898 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4901 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4913 xnow = localtime (&now);
4915 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4916 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4917 boost::shared_ptr<MidiSource> ms;
4920 afs->update_header (position, *xnow, now);
4921 afs->flush_header ();
4922 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
4923 Source::Lock lock(ms->mutex());
4924 ms->mark_streaming_write_completed(lock);
4928 /* construct a region to represent the bounced material */
4932 plist.add (Properties::start, 0);
4933 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4934 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4936 result = RegionFactory::create (srcs, plist);
4942 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4943 (*src)->mark_for_remove ();
4944 (*src)->drop_references ();
4948 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4949 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4952 afs->done_with_peakfile_writes ();
4956 _bounce_processing_active = false;
4958 if (need_block_size_reset) {
4959 _engine.main_thread()->drop_buffers ();
4960 track.set_block_size (get_block_size());
4963 unblock_processing ();
4969 Session::gain_automation_buffer() const
4971 return ProcessThread::gain_automation_buffer ();
4975 Session::trim_automation_buffer() const
4977 return ProcessThread::trim_automation_buffer ();
4981 Session::send_gain_automation_buffer() const
4983 return ProcessThread::send_gain_automation_buffer ();
4987 Session::pan_automation_buffer() const
4989 return ProcessThread::pan_automation_buffer ();
4993 Session::get_silent_buffers (ChanCount count)
4995 return ProcessThread::get_silent_buffers (count);
4999 Session::get_scratch_buffers (ChanCount count, bool silence)
5001 return ProcessThread::get_scratch_buffers (count, silence);
5005 Session::get_route_buffers (ChanCount count, bool silence)
5007 return ProcessThread::get_route_buffers (count, silence);
5012 Session::get_mix_buffers (ChanCount count)
5014 return ProcessThread::get_mix_buffers (count);
5018 Session::ntracks () const
5021 boost::shared_ptr<RouteList> r = routes.reader ();
5023 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5024 if (boost::dynamic_pointer_cast<Track> (*i)) {
5033 Session::nbusses () const
5036 boost::shared_ptr<RouteList> r = routes.reader ();
5038 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5039 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
5048 Session::add_automation_list(AutomationList *al)
5050 automation_lists[al->id()] = al;
5053 /** @return true if there is at least one record-enabled track, otherwise false */
5055 Session::have_rec_enabled_track () const
5057 return g_atomic_int_get (const_cast<gint*>(&_have_rec_enabled_track)) == 1;
5061 Session::have_rec_disabled_track () const
5063 return g_atomic_int_get (const_cast<gint*>(&_have_rec_disabled_track)) == 1;
5066 /** Update the state of our rec-enabled tracks flag */
5068 Session::update_route_record_state ()
5070 boost::shared_ptr<RouteList> rl = routes.reader ();
5071 RouteList::iterator i = rl->begin();
5072 while (i != rl->end ()) {
5074 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5075 if (tr && tr->record_enabled ()) {
5082 int const old = g_atomic_int_get (&_have_rec_enabled_track);
5084 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
5086 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
5087 RecordStateChanged (); /* EMIT SIGNAL */
5092 while (i != rl->end ()) {
5094 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5095 if (tr && !tr->record_enabled ()) {
5102 g_atomic_int_set (&_have_rec_disabled_track, i != rl->end () ? 1 : 0);
5106 Session::listen_position_changed ()
5108 boost::shared_ptr<RouteList> r = routes.reader ();
5110 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5111 (*i)->listen_position_changed ();
5116 Session::solo_control_mode_changed ()
5118 /* cancel all solo or all listen when solo control mode changes */
5121 set_solo (get_routes(), false);
5122 } else if (listening()) {
5123 set_listen (get_routes(), false);
5127 /** Called when a property of one of our route groups changes */
5129 Session::route_group_property_changed (RouteGroup* rg)
5131 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
5134 /** Called when a route is added to one of our route groups */
5136 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
5138 RouteAddedToRouteGroup (rg, r);
5141 /** Called when a route is removed from one of our route groups */
5143 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
5145 update_route_record_state ();
5146 RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */
5149 boost::shared_ptr<RouteList>
5150 Session::get_tracks () const
5152 boost::shared_ptr<RouteList> rl = routes.reader ();
5153 boost::shared_ptr<RouteList> tl (new RouteList);
5155 for (RouteList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
5156 if (boost::dynamic_pointer_cast<Track> (*r)) {
5157 if (!(*r)->is_auditioner()) {
5165 boost::shared_ptr<RouteList>
5166 Session::get_routes_with_regions_at (framepos_t const p) const
5168 boost::shared_ptr<RouteList> r = routes.reader ();
5169 boost::shared_ptr<RouteList> rl (new RouteList);
5171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5172 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5177 boost::shared_ptr<Playlist> pl = tr->playlist ();
5182 if (pl->has_region_at (p)) {
5191 Session::goto_end ()
5193 if (_session_range_location) {
5194 request_locate (_session_range_location->end(), false);
5196 request_locate (0, false);
5201 Session::goto_start ()
5203 if (_session_range_location) {
5204 request_locate (_session_range_location->start(), false);
5206 request_locate (0, false);
5211 Session::current_start_frame () const
5213 return _session_range_location ? _session_range_location->start() : 0;
5217 Session::current_end_frame () const
5219 return _session_range_location ? _session_range_location->end() : 0;
5223 Session::add_session_range_location (framepos_t start, framepos_t end)
5225 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
5226 _locations->add (_session_range_location);
5230 Session::step_edit_status_change (bool yn)
5236 send = (_step_editors == 0);
5241 send = (_step_editors == 1);
5244 if (_step_editors > 0) {
5250 StepEditStatusChange (val);
5256 Session::start_time_changed (framepos_t old)
5258 /* Update the auto loop range to match the session range
5259 (unless the auto loop range has been changed by the user)
5262 Location* s = _locations->session_range_location ();
5267 Location* l = _locations->auto_loop_location ();
5269 if (l && l->start() == old) {
5270 l->set_start (s->start(), true);
5275 Session::end_time_changed (framepos_t old)
5277 /* Update the auto loop range to match the session range
5278 (unless the auto loop range has been changed by the user)
5281 Location* s = _locations->session_range_location ();
5286 Location* l = _locations->auto_loop_location ();
5288 if (l && l->end() == old) {
5289 l->set_end (s->end(), true);
5293 std::vector<std::string>
5294 Session::source_search_path (DataType type) const
5298 if (session_dirs.size() == 1) {
5300 case DataType::AUDIO:
5301 sp.push_back (_session_dir->sound_path());
5303 case DataType::MIDI:
5304 sp.push_back (_session_dir->midi_path());
5308 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
5309 SessionDirectory sdir (i->path);
5311 case DataType::AUDIO:
5312 sp.push_back (sdir.sound_path());
5314 case DataType::MIDI:
5315 sp.push_back (sdir.midi_path());
5321 if (type == DataType::AUDIO) {
5322 const string sound_path_2X = _session_dir->sound_path_2X();
5323 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
5324 if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) {
5325 sp.push_back (sound_path_2X);
5330 // now check the explicit (possibly user-specified) search path
5333 case DataType::AUDIO:
5334 sp += Searchpath(config.get_audio_search_path ());
5336 case DataType::MIDI:
5337 sp += Searchpath(config.get_midi_search_path ());
5345 Session::ensure_search_path_includes (const string& path, DataType type)
5354 case DataType::AUDIO:
5355 sp += Searchpath(config.get_audio_search_path ());
5357 case DataType::MIDI:
5358 sp += Searchpath (config.get_midi_search_path ());
5362 for (vector<std::string>::iterator i = sp.begin(); i != sp.end(); ++i) {
5363 /* No need to add this new directory if it has the same inode as
5364 an existing one; checking inode rather than name prevents duplicated
5365 directories when we are using symlinks.
5367 On Windows, I think we could just do if (*i == path) here.
5369 if (PBD::equivalent_paths (*i, path)) {
5377 case DataType::AUDIO:
5378 config.set_audio_search_path (sp.to_string());
5380 case DataType::MIDI:
5381 config.set_midi_search_path (sp.to_string());
5387 Session::remove_dir_from_search_path (const string& dir, DataType type)
5392 case DataType::AUDIO:
5393 sp = Searchpath(config.get_audio_search_path ());
5395 case DataType::MIDI:
5396 sp = Searchpath (config.get_midi_search_path ());
5403 case DataType::AUDIO:
5404 config.set_audio_search_path (sp.to_string());
5406 case DataType::MIDI:
5407 config.set_midi_search_path (sp.to_string());
5413 boost::shared_ptr<Speakers>
5414 Session::get_speakers()
5420 Session::unknown_processors () const
5424 boost::shared_ptr<RouteList> r = routes.reader ();
5425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5426 list<string> t = (*i)->unknown_processors ();
5427 copy (t.begin(), t.end(), back_inserter (p));
5437 Session::update_latency (bool playback)
5439 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
5441 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
5445 boost::shared_ptr<RouteList> r = routes.reader ();
5446 framecnt_t max_latency = 0;
5449 /* reverse the list so that we work backwards from the last route to run to the first */
5450 RouteList* rl = routes.reader().get();
5451 r.reset (new RouteList (*rl));
5452 reverse (r->begin(), r->end());
5455 /* compute actual latency values for the given direction and store them all in per-port
5456 structures. this will also publish the same values (to JACK) so that computation of latency
5457 for routes can consistently use public latency values.
5460 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5461 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
5464 /* because we latency compensate playback, our published playback latencies should
5465 be the same for all output ports - all material played back by ardour has
5466 the same latency, whether its caused by plugins or by latency compensation. since
5467 these may differ from the values computed above, reset all playback port latencies
5471 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
5473 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5474 (*i)->set_public_port_latencies (max_latency, playback);
5479 post_playback_latency ();
5483 post_capture_latency ();
5486 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
5490 Session::post_playback_latency ()
5492 set_worst_playback_latency ();
5494 boost::shared_ptr<RouteList> r = routes.reader ();
5496 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5497 if (!(*i)->is_auditioner() && ((*i)->active())) {
5498 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
5502 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5503 (*i)->set_latency_compensation (_worst_track_latency);
5508 Session::post_capture_latency ()
5510 set_worst_capture_latency ();
5512 /* reflect any changes in capture latencies into capture offsets
5515 boost::shared_ptr<RouteList> rl = routes.reader();
5516 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5517 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5519 tr->set_capture_offset ();
5525 Session::initialize_latencies ()
5528 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
5529 update_latency (false);
5530 update_latency (true);
5533 set_worst_io_latencies ();
5537 Session::set_worst_io_latencies ()
5539 set_worst_playback_latency ();
5540 set_worst_capture_latency ();
5544 Session::set_worst_playback_latency ()
5546 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5550 _worst_output_latency = 0;
5552 if (!_engine.connected()) {
5556 boost::shared_ptr<RouteList> r = routes.reader ();
5558 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5559 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
5562 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
5566 Session::set_worst_capture_latency ()
5568 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5572 _worst_input_latency = 0;
5574 if (!_engine.connected()) {
5578 boost::shared_ptr<RouteList> r = routes.reader ();
5580 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5581 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
5584 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
5588 Session::update_latency_compensation (bool force_whole_graph)
5590 bool some_track_latency_changed = false;
5592 if (_state_of_the_state & (InitialConnecting|Deletion)) {
5596 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
5598 _worst_track_latency = 0;
5600 boost::shared_ptr<RouteList> r = routes.reader ();
5602 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5603 if (!(*i)->is_auditioner() && ((*i)->active())) {
5605 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
5606 some_track_latency_changed = true;
5608 _worst_track_latency = max (tl, _worst_track_latency);
5612 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
5613 (some_track_latency_changed ? "yes" : "no")));
5615 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
5617 if (some_track_latency_changed || force_whole_graph) {
5618 _engine.update_latencies ();
5622 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5623 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5627 tr->set_capture_offset ();
5632 Session::session_name_is_legal (const string& path)
5634 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
5636 for (int i = 0; illegal_chars[i]; ++i) {
5637 if (path.find (illegal_chars[i]) != string::npos) {
5638 return illegal_chars[i];
5646 Session::next_control_id () const
5650 /* the monitor bus remote ID is in a different
5651 * "namespace" than regular routes. its existence doesn't
5652 * affect normal (low) numbered routes.
5659 return nroutes() - subtract;
5663 Session::notify_remote_id_change ()
5665 if (deletion_in_progress()) {
5669 switch (Config->get_remote_model()) {
5671 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
5679 Session::sync_order_keys ()
5681 if (deletion_in_progress()) {
5685 /* tell everyone that something has happened to the sort keys
5686 and let them sync up with the change(s)
5687 this will give objects that manage the sort order keys the
5688 opportunity to keep them in sync if they wish to.
5691 DEBUG_TRACE (DEBUG::OrderKeys, "Sync Order Keys.\n");
5693 reassign_track_numbers();
5695 Route::SyncOrderKeys (); /* EMIT SIGNAL */
5697 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
5701 Session::operation_in_progress (GQuark op) const
5703 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
5706 boost::shared_ptr<Port>
5707 Session::ltc_input_port () const
5709 return _ltc_input->nth (0);
5712 boost::shared_ptr<Port>
5713 Session::ltc_output_port () const
5715 return _ltc_output->nth (0);
5719 Session::reconnect_ltc_input ()
5723 string src = Config->get_ltc_source_port();
5725 _ltc_input->disconnect (this);
5727 if (src != _("None") && !src.empty()) {
5728 _ltc_input->nth (0)->connect (src);
5734 Session::reconnect_ltc_output ()
5739 string src = Config->get_ltc_sink_port();
5741 _ltc_output->disconnect (this);
5743 if (src != _("None") && !src.empty()) {
5744 _ltc_output->nth (0)->connect (src);