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/error.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
48 #include "pbd/unwind.h"
50 #include "ardour/amp.h"
51 #include "ardour/analyser.h"
52 #include "ardour/audio_buffer.h"
53 #include "ardour/audio_diskstream.h"
54 #include "ardour/audio_port.h"
55 #include "ardour/audio_track.h"
56 #include "ardour/audioengine.h"
57 #include "ardour/audiofilesource.h"
58 #include "ardour/auditioner.h"
59 #include "ardour/buffer_manager.h"
60 #include "ardour/buffer_set.h"
61 #include "ardour/bundle.h"
62 #include "ardour/butler.h"
63 #include "ardour/click.h"
64 #include "ardour/control_protocol_manager.h"
65 #include "ardour/data_type.h"
66 #include "ardour/debug.h"
67 #include "ardour/filename_extensions.h"
68 #include "ardour/graph.h"
69 #include "ardour/midi_track.h"
70 #include "ardour/midi_ui.h"
71 #include "ardour/operations.h"
72 #include "ardour/playlist.h"
73 #include "ardour/plugin.h"
74 #include "ardour/plugin_insert.h"
75 #include "ardour/process_thread.h"
76 #include "ardour/rc_configuration.h"
77 #include "ardour/recent_sessions.h"
78 #include "ardour/region.h"
79 #include "ardour/region_factory.h"
80 #include "ardour/route_graph.h"
81 #include "ardour/route_group.h"
82 #include "ardour/send.h"
83 #include "ardour/session.h"
84 #include "ardour/session_directory.h"
85 #include "ardour/session_playlists.h"
86 #include "ardour/smf_source.h"
87 #include "ardour/source_factory.h"
88 #include "ardour/utils.h"
90 #include "midi++/port.h"
91 #include "midi++/jack_midi_port.h"
92 #include "midi++/mmc.h"
93 #include "midi++/manager.h"
104 using namespace ARDOUR;
107 bool Session::_disable_all_loaded_plugins = false;
109 PBD::Signal1<void,std::string> Session::Dialog;
110 PBD::Signal0<int> Session::AskAboutPendingState;
111 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
112 PBD::Signal0<void> Session::SendFeedback;
113 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
115 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
116 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
117 PBD::Signal2<void,std::string, std::string> Session::Exported;
118 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
119 PBD::Signal0<void> Session::Quit;
120 PBD::Signal0<void> Session::FeedbackDetected;
121 PBD::Signal0<void> Session::SuccessfulGraphSort;
123 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
124 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
126 /** @param snapshot_name Snapshot name, without .ardour suffix */
127 Session::Session (AudioEngine &eng,
128 const string& fullpath,
129 const string& snapshot_name,
130 BusProfile* bus_profile,
133 , _target_transport_speed (0.0)
134 , _requested_return_frame (-1)
135 , _session_dir (new SessionDirectory(fullpath))
137 , _state_of_the_state (Clean)
138 , _butler (new Butler (*this))
139 , _post_transport_work (0)
140 , _send_timecode_update (false)
141 , _all_route_group (new RouteGroup (*this, "all"))
142 , routes (new RouteList)
143 , _total_free_4k_blocks (0)
144 , _total_free_4k_blocks_uncertain (false)
145 , _bundles (new BundleList)
146 , _bundle_xml_node (0)
149 , click_emphasis_data (0)
151 , _have_rec_enabled_track (false)
152 , _suspend_timecode_transmission (0)
154 _locations = new Locations (*this);
157 if (how_many_dsp_threads () > 1) {
158 /* For now, only create the graph if we are using >1 DSP threads, as
159 it is a bit slower than the old code with 1 thread.
161 _process_graph.reset (new Graph (*this));
164 playlists.reset (new SessionPlaylists);
166 _all_route_group->set_active (true, this);
168 interpolation.add_channel_to (0, 0);
170 if (!eng.connected()) {
171 throw failed_constructor();
174 n_physical_outputs = _engine.n_physical_outputs ();
175 n_physical_inputs = _engine.n_physical_inputs ();
177 first_stage_init (fullpath, snapshot_name);
179 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
182 if (create (mix_template, bus_profile)) {
184 throw failed_constructor ();
188 if (second_stage_init ()) {
190 throw failed_constructor ();
193 store_recent_sessions(_name, _path);
195 bool was_dirty = dirty();
197 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
199 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
200 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
203 DirtyChanged (); /* EMIT SIGNAL */
206 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
207 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
223 vector<void*> debug_pointers;
225 /* if we got to here, leaving pending capture state around
229 remove_pending_capture_state ();
231 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
233 /* disconnect from any and all signals that we are connected to */
237 _engine.remove_session ();
239 /* deregister all ports - there will be no process or any other
240 * callbacks from the engine any more.
243 Port::PortDrop (); /* EMIT SIGNAL */
247 /* clear history so that no references to objects are held any more */
251 /* clear state tree so that no references to objects are held any more */
255 /* reset dynamic state version back to default */
257 Stateful::loading_state_version = 0;
259 _butler->drop_references ();
263 delete midi_control_ui;
264 delete _all_route_group;
266 if (click_data != default_click) {
267 delete [] click_data;
270 if (click_emphasis_data != default_click_emphasis) {
271 delete [] click_emphasis_data;
276 /* clear out any pending dead wood from RCU managed objects */
281 AudioDiskstream::free_working_buffers();
283 /* tell everyone who is still standing that we're about to die */
286 /* tell everyone to drop references and delete objects as we go */
288 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
289 RegionFactory::delete_all_regions ();
291 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
293 /* reset these three references to special routes before we do the usual route delete thing */
296 _master_out.reset ();
297 _monitor_out.reset ();
300 RCUWriter<RouteList> writer (routes);
301 boost::shared_ptr<RouteList> r = writer.get_copy ();
303 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
304 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
305 (*i)->drop_references ();
309 /* writer goes out of scope and updates master */
313 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
314 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
315 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
316 i->second->drop_references ();
321 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
322 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
327 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
332 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
334 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
335 boost_debug_list_ptrs ();
340 Session::when_engine_running ()
342 string first_physical_output;
344 BootMessage (_("Set block size and sample rate"));
346 set_block_size (_engine.frames_per_cycle());
347 set_frame_rate (_engine.frame_rate());
349 BootMessage (_("Using configuration"));
351 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
352 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
354 Config->map_parameters (ff);
355 config.map_parameters (ft);
357 /* every time we reconnect, recompute worst case output latencies */
359 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
361 if (synced_to_jack()) {
362 _engine.transport_stop ();
365 if (config.get_jack_time_master()) {
366 _engine.transport_locate (_transport_frame);
374 _ltc_input.reset (new IO (*this, _("LTC In"), IO::Input));
375 _ltc_output.reset (new IO (*this, _("LTC Out"), IO::Output));
377 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-In")) != 0) {
378 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
381 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
382 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
384 reconnect_ltc_input ();
387 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-Out")) != 0) {
388 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
391 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
392 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
394 reconnect_ltc_output ();
397 /* fix up names of LTC ports because we don't want the normal
398 * IO style of NAME/TYPE-{in,out}N
401 _ltc_input->nth (0)->set_name (_("LTC-in"));
402 _ltc_output->nth (0)->set_name (_("LTC-out"));
404 _click_io.reset (new ClickIO (*this, "click"));
405 _click_gain.reset (new Amp (*this));
406 _click_gain->activate ();
408 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
410 /* existing state for Click */
413 if (Stateful::loading_state_version < 3000) {
414 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
416 const XMLNodeList& children (child->children());
417 XMLNodeList::const_iterator i = children.begin();
418 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
420 if (i != children.end()) {
421 c = _click_gain->set_state (**i, Stateful::loading_state_version);
427 _clicking = Config->get_clicking ();
431 error << _("could not setup Click I/O") << endmsg;
438 /* default state for Click: dual-mono to first 2 physical outputs */
441 _engine.get_physical_outputs (DataType::AUDIO, outs);
443 for (uint32_t physport = 0; physport < 2; ++physport) {
444 if (outs.size() > physport) {
445 if (_click_io->add_port (outs[physport], this)) {
446 // relax, even though its an error
451 if (_click_io->n_ports () > ChanCount::ZERO) {
452 _clicking = Config->get_clicking ();
457 catch (failed_constructor& err) {
458 error << _("cannot setup Click I/O") << endmsg;
461 BootMessage (_("Compute I/O Latencies"));
464 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
467 BootMessage (_("Set up standard connections"));
469 vector<string> inputs[DataType::num_types];
470 vector<string> outputs[DataType::num_types];
471 for (uint32_t i = 0; i < DataType::num_types; ++i) {
472 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
473 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
476 /* Create a set of Bundle objects that map
477 to the physical I/O currently available. We create both
478 mono and stereo bundles, so that the common cases of mono
479 and stereo tracks get bundles to put in their mixer strip
480 in / out menus. There may be a nicer way of achieving that;
481 it doesn't really scale that well to higher channel counts
484 /* mono output bundles */
486 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
488 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
490 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
491 c->add_channel (_("mono"), DataType::AUDIO);
492 c->set_port (0, outputs[DataType::AUDIO][np]);
497 /* stereo output bundles */
499 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
500 if (np + 1 < outputs[DataType::AUDIO].size()) {
502 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
503 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
504 c->add_channel (_("L"), DataType::AUDIO);
505 c->set_port (0, outputs[DataType::AUDIO][np]);
506 c->add_channel (_("R"), DataType::AUDIO);
507 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
513 /* mono input bundles */
515 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
517 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
519 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
520 c->add_channel (_("mono"), DataType::AUDIO);
521 c->set_port (0, inputs[DataType::AUDIO][np]);
526 /* stereo input bundles */
528 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
529 if (np + 1 < inputs[DataType::AUDIO].size()) {
531 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
533 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
534 c->add_channel (_("L"), DataType::AUDIO);
535 c->set_port (0, inputs[DataType::AUDIO][np]);
536 c->add_channel (_("R"), DataType::AUDIO);
537 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
543 /* MIDI input bundles */
545 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
546 string n = inputs[DataType::MIDI][np];
547 boost::erase_first (n, X_("alsa_pcm:"));
549 boost::shared_ptr<Bundle> c (new Bundle (n, false));
550 c->add_channel ("", DataType::MIDI);
551 c->set_port (0, inputs[DataType::MIDI][np]);
555 /* MIDI output bundles */
557 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
558 string n = outputs[DataType::MIDI][np];
559 boost::erase_first (n, X_("alsa_pcm:"));
561 boost::shared_ptr<Bundle> c (new Bundle (n, true));
562 c->add_channel ("", DataType::MIDI);
563 c->set_port (0, outputs[DataType::MIDI][np]);
567 BootMessage (_("Setup signal flow and plugins"));
569 /* Reset all panners */
571 Delivery::reset_panners ();
573 /* this will cause the CPM to instantiate any protocols that are in use
574 * (or mandatory), which will pass it this Session, and then call
575 * set_state() on each instantiated protocol to match stored state.
578 ControlProtocolManager::instance().set_session (this);
580 /* This must be done after the ControlProtocolManager set_session above,
581 as it will set states for ports which the ControlProtocolManager creates.
584 MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
586 /* And this must be done after the MIDI::Manager::set_port_states as
587 * it will try to make connections whose details are loaded by set_port_states.
592 /* Let control protocols know that we are now all connected, so they
593 * could start talking to surfaces if they want to.
596 ControlProtocolManager::instance().midi_connectivity_established ();
598 if (_is_new && !no_auto_connect()) {
599 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
600 auto_connect_master_bus ();
603 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
605 /* update latencies */
607 initialize_latencies ();
609 /* hook us up to the engine */
611 BootMessage (_("Connect to engine"));
612 _engine.set_session (this);
613 _engine.reset_timebase ();
617 Session::auto_connect_master_bus ()
619 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
623 /* if requested auto-connect the outputs to the first N physical ports.
626 uint32_t limit = _master_out->n_outputs().n_total();
627 vector<string> outputs[DataType::num_types];
629 for (uint32_t i = 0; i < DataType::num_types; ++i) {
630 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
633 for (uint32_t n = 0; n < limit; ++n) {
634 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
636 if (outputs[p->type()].size() > n) {
637 connect_to = outputs[p->type()][n];
640 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
641 if (_master_out->output()->connect (p, connect_to, this)) {
642 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
651 Session::remove_monitor_section ()
657 /* force reversion to Solo-In-Place */
658 Config->set_solo_control_is_listen_control (false);
661 /* Hold process lock while doing this so that we don't hear bits and
662 * pieces of audio as we work on each route.
665 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
667 /* Connect tracks to monitor section. Note that in an
668 existing session, the internal sends will already exist, but we want the
669 routes to notice that they connect to the control out specifically.
673 boost::shared_ptr<RouteList> r = routes.reader ();
674 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
676 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
678 if ((*x)->is_monitor()) {
680 } else if ((*x)->is_master()) {
683 (*x)->remove_aux_or_listen (_monitor_out);
688 remove_route (_monitor_out);
689 auto_connect_master_bus ();
693 Session::add_monitor_section ()
697 if (_monitor_out || !_master_out) {
701 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
707 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
708 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
711 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
712 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
713 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
717 add_routes (rl, false, false, false);
719 assert (_monitor_out);
721 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
722 are undefined, at best.
725 uint32_t limit = _monitor_out->n_inputs().n_audio();
729 /* connect the inputs to the master bus outputs. this
730 * represents a separate data feed from the internal sends from
731 * each route. as of jan 2011, it allows the monitor section to
732 * conditionally ignore either the internal sends or the normal
733 * input feed, but we should really find a better way to do
737 _master_out->output()->disconnect (this);
739 for (uint32_t n = 0; n < limit; ++n) {
740 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
741 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
744 string connect_to = o->name();
745 if (_monitor_out->input()->connect (p, connect_to, this)) {
746 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
754 /* if monitor section is not connected, connect it to physical outs
757 if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
759 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
761 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
764 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
766 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
767 Config->get_monitor_bus_preferred_bundle())
773 /* Monitor bus is audio only */
775 uint32_t mod = n_physical_outputs.get (DataType::AUDIO);
776 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
777 vector<string> outputs[DataType::num_types];
779 for (uint32_t i = 0; i < DataType::num_types; ++i) {
780 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
786 for (uint32_t n = 0; n < limit; ++n) {
788 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
790 if (outputs[DataType::AUDIO].size() > (n % mod)) {
791 connect_to = outputs[DataType::AUDIO][n % mod];
794 if (!connect_to.empty()) {
795 if (_monitor_out->output()->connect (p, connect_to, this)) {
796 error << string_compose (
797 _("cannot connect control output %1 to %2"),
808 /* Hold process lock while doing this so that we don't hear bits and
809 * pieces of audio as we work on each route.
812 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
814 /* Connect tracks to monitor section. Note that in an
815 existing session, the internal sends will already exist, but we want the
816 routes to notice that they connect to the control out specifically.
820 boost::shared_ptr<RouteList> rls = routes.reader ();
822 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
824 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
826 if ((*x)->is_monitor()) {
828 } else if ((*x)->is_master()) {
831 (*x)->enable_monitor_send ();
837 Session::hookup_io ()
839 /* stop graph reordering notifications from
840 causing resorts, etc.
843 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
847 /* we delay creating the auditioner till now because
848 it makes its own connections to ports.
852 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
854 throw failed_constructor ();
856 a->use_new_diskstream ();
860 catch (failed_constructor& err) {
861 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
865 /* load bundles, which we may have postponed earlier on */
866 if (_bundle_xml_node) {
867 load_bundles (*_bundle_xml_node);
868 delete _bundle_xml_node;
871 /* Tell all IO objects to connect themselves together */
873 IO::enable_connecting ();
874 MIDI::JackMIDIPort::MakeConnections ();
876 /* Anyone who cares about input state, wake up and do something */
878 IOConnectionsComplete (); /* EMIT SIGNAL */
880 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
882 /* now handle the whole enchilada as if it was one
888 /* update the full solo state, which can't be
889 correctly determined on a per-route basis, but
890 needs the global overview that only the session
894 update_route_solo_state ();
898 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
900 boost::shared_ptr<Track> track = wp.lock ();
905 boost::shared_ptr<Playlist> playlist;
907 if ((playlist = track->playlist()) != 0) {
908 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
909 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
910 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
915 Session::record_enabling_legal () const
917 /* this used to be in here, but survey says.... we don't need to restrict it */
918 // if (record_status() == Recording) {
922 if (Config->get_all_safe()) {
929 Session::set_track_monitor_input_status (bool yn)
931 boost::shared_ptr<RouteList> rl = routes.reader ();
932 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
933 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
934 if (tr && tr->record_enabled ()) {
935 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
936 tr->request_jack_monitors_input (yn);
942 Session::auto_punch_start_changed (Location* location)
944 replace_event (SessionEvent::PunchIn, location->start());
946 if (get_record_enabled() && config.get_punch_in()) {
947 /* capture start has been changed, so save new pending state */
948 save_state ("", true);
953 Session::auto_punch_end_changed (Location* location)
955 framepos_t when_to_stop = location->end();
956 // when_to_stop += _worst_output_latency + _worst_input_latency;
957 replace_event (SessionEvent::PunchOut, when_to_stop);
961 Session::auto_punch_changed (Location* location)
963 framepos_t when_to_stop = location->end();
965 replace_event (SessionEvent::PunchIn, location->start());
966 //when_to_stop += _worst_output_latency + _worst_input_latency;
967 replace_event (SessionEvent::PunchOut, when_to_stop);
970 /** @param loc A loop location.
971 * @param pos Filled in with the start time of the required fade-out (in session frames).
972 * @param length Filled in with the length of the required fade-out.
975 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
977 pos = max (loc->start(), loc->end() - 64);
978 length = loc->end() - pos;
982 Session::auto_loop_changed (Location* location)
984 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
987 auto_loop_declick_range (location, dcp, dcl);
988 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
990 if (transport_rolling() && play_loop) {
993 // if (_transport_frame > location->end()) {
995 if (_transport_frame < location->start() || _transport_frame > location->end()) {
996 // relocate to beginning of loop
997 clear_events (SessionEvent::LocateRoll);
999 request_locate (location->start(), true);
1002 else if (Config->get_seamless_loop() && !loop_changing) {
1004 // schedule a locate-roll to refill the diskstreams at the
1005 // previous loop end
1006 loop_changing = true;
1008 if (location->end() > last_loopend) {
1009 clear_events (SessionEvent::LocateRoll);
1010 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1017 last_loopend = location->end();
1021 Session::set_auto_punch_location (Location* location)
1025 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1026 punch_connections.drop_connections();
1027 existing->set_auto_punch (false, this);
1028 remove_event (existing->start(), SessionEvent::PunchIn);
1029 clear_events (SessionEvent::PunchOut);
1030 auto_punch_location_changed (0);
1035 if (location == 0) {
1039 if (location->end() <= location->start()) {
1040 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1044 punch_connections.drop_connections ();
1046 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1047 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1048 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1050 location->set_auto_punch (true, this);
1052 auto_punch_changed (location);
1054 auto_punch_location_changed (location);
1058 Session::set_auto_loop_location (Location* location)
1062 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1063 loop_connections.drop_connections ();
1064 existing->set_auto_loop (false, this);
1065 remove_event (existing->end(), SessionEvent::AutoLoop);
1068 auto_loop_declick_range (existing, dcp, dcl);
1069 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1070 auto_loop_location_changed (0);
1075 if (location == 0) {
1079 if (location->end() <= location->start()) {
1080 error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
1084 last_loopend = location->end();
1086 loop_connections.drop_connections ();
1088 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1089 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1090 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1092 location->set_auto_loop (true, this);
1094 /* take care of our stuff first */
1096 auto_loop_changed (location);
1098 /* now tell everyone else */
1100 auto_loop_location_changed (location);
1104 Session::locations_added (Location *)
1110 Session::locations_changed ()
1112 _locations->apply (*this, &Session::handle_locations_changed);
1116 Session::handle_locations_changed (Locations::LocationList& locations)
1118 Locations::LocationList::iterator i;
1120 bool set_loop = false;
1121 bool set_punch = false;
1123 for (i = locations.begin(); i != locations.end(); ++i) {
1127 if (location->is_auto_punch()) {
1128 set_auto_punch_location (location);
1131 if (location->is_auto_loop()) {
1132 set_auto_loop_location (location);
1136 if (location->is_session_range()) {
1137 _session_range_location = location;
1142 set_auto_loop_location (0);
1145 set_auto_punch_location (0);
1152 Session::enable_record ()
1154 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1155 /* no recording at anything except normal speed */
1160 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1162 if (rs == Recording) {
1166 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1168 _last_record_location = _transport_frame;
1169 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1171 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1172 set_track_monitor_input_status (true);
1175 RecordStateChanged ();
1182 Session::disable_record (bool rt_context, bool force)
1186 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1188 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1189 g_atomic_int_set (&_record_status, Disabled);
1190 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1192 if (rs == Recording) {
1193 g_atomic_int_set (&_record_status, Enabled);
1197 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1198 set_track_monitor_input_status (false);
1201 RecordStateChanged (); /* emit signal */
1204 remove_pending_capture_state ();
1210 Session::step_back_from_record ()
1212 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1214 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1215 set_track_monitor_input_status (false);
1218 RecordStateChanged (); /* emit signal */
1223 Session::maybe_enable_record ()
1225 if (_step_editors > 0) {
1229 g_atomic_int_set (&_record_status, Enabled);
1231 /* This function is currently called from somewhere other than an RT thread.
1232 This save_state() call therefore doesn't impact anything. Doing it here
1233 means that we save pending state of which sources the next record will use,
1234 which gives us some chance of recovering from a crash during the record.
1237 save_state ("", true);
1239 if (_transport_speed) {
1240 if (!config.get_punch_in()) {
1244 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1245 RecordStateChanged (); /* EMIT SIGNAL */
1252 Session::audible_frame () const
1258 /* the first of these two possible settings for "offset"
1259 mean that the audible frame is stationary until
1260 audio emerges from the latency compensation
1263 the second means that the audible frame is stationary
1264 until audio would emerge from a physical port
1265 in the absence of any plugin latency compensation
1268 offset = worst_playback_latency ();
1270 if (offset > current_block_size) {
1271 offset -= current_block_size;
1273 /* XXX is this correct? if we have no external
1274 physical connections and everything is internal
1275 then surely this is zero? still, how
1276 likely is that anyway?
1278 offset = current_block_size;
1281 if (synced_to_jack()) {
1282 tf = _engine.transport_frame();
1284 tf = _transport_frame;
1289 if (!non_realtime_work_pending()) {
1293 /* Check to see if we have passed the first guaranteed
1294 audible frame past our last start position. if not,
1295 return that last start point because in terms
1296 of audible frames, we have not moved yet.
1298 `Start position' in this context means the time we last
1299 either started, located, or changed transport direction.
1302 if (_transport_speed > 0.0f) {
1304 if (!play_loop || !have_looped) {
1305 if (tf < _last_roll_or_reversal_location + offset) {
1306 return _last_roll_or_reversal_location;
1314 } else if (_transport_speed < 0.0f) {
1316 /* XXX wot? no backward looping? */
1318 if (tf > _last_roll_or_reversal_location - offset) {
1319 return _last_roll_or_reversal_location;
1331 Session::set_frame_rate (framecnt_t frames_per_second)
1333 /** \fn void Session::set_frame_size(framecnt_t)
1334 the AudioEngine object that calls this guarantees
1335 that it will not be called while we are also in
1336 ::process(). Its fine to do things that block
1340 _base_frame_rate = frames_per_second;
1346 // XXX we need some equivalent to this, somehow
1347 // SndFileSource::setup_standard_crossfades (frames_per_second);
1351 /* XXX need to reset/reinstantiate all LADSPA plugins */
1355 Session::set_block_size (pframes_t nframes)
1357 /* the AudioEngine guarantees
1358 that it will not be called while we are also in
1359 ::process(). It is therefore fine to do things that block
1364 current_block_size = nframes;
1368 boost::shared_ptr<RouteList> r = routes.reader ();
1370 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1371 (*i)->set_block_size (nframes);
1374 boost::shared_ptr<RouteList> rl = routes.reader ();
1375 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1376 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1378 tr->set_block_size (nframes);
1382 set_worst_io_latencies ();
1388 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1390 boost::shared_ptr<Route> r2;
1392 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1393 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1397 /* make a copy of the existing list of routes that feed r1 */
1399 Route::FedBy existing (r1->fed_by());
1401 /* for each route that feeds r1, recurse, marking it as feeding
1405 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1406 if (!(r2 = i->r.lock ())) {
1407 /* (*i) went away, ignore it */
1411 /* r2 is a route that feeds r1 which somehow feeds base. mark
1412 base as being fed by r2
1415 rbase->add_fed_by (r2, i->sends_only);
1419 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1423 if (r1->feeds (r2) && r2->feeds (r1)) {
1427 /* now recurse, so that we can mark base as being fed by
1428 all routes that feed r2
1431 trace_terminal (r2, rbase);
1438 Session::resort_routes ()
1440 /* don't do anything here with signals emitted
1441 by Routes during initial setup or while we
1442 are being destroyed.
1445 if (_state_of_the_state & (InitialConnecting | Deletion)) {
1450 RCUWriter<RouteList> writer (routes);
1451 boost::shared_ptr<RouteList> r = writer.get_copy ();
1452 resort_routes_using (r);
1453 /* writer goes out of scope and forces update */
1457 boost::shared_ptr<RouteList> rl = routes.reader ();
1458 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1459 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1461 const Route::FedBy& fb ((*i)->fed_by());
1463 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1464 boost::shared_ptr<Route> sf = f->r.lock();
1466 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1474 /** This is called whenever we need to rebuild the graph of how we will process
1476 * @param r List of routes, in any order.
1480 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1482 /* We are going to build a directed graph of our routes;
1483 this is where the edges of that graph are put.
1488 /* Go through all routes doing two things:
1490 * 1. Collect the edges of the route graph. Each of these edges
1491 * is a pair of routes, one of which directly feeds the other
1492 * either by a JACK connection or by an internal send.
1494 * 2. Begin the process of making routes aware of which other
1495 * routes directly or indirectly feed them. This information
1496 * is used by the solo code.
1499 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501 /* Clear out the route's list of direct or indirect feeds */
1502 (*i)->clear_fed_by ();
1504 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
1506 bool via_sends_only;
1508 /* See if this *j feeds *i according to the current state of the JACK
1509 connections and internal sends.
1511 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
1512 /* add the edge to the graph (part #1) */
1513 edges.add (*j, *i, via_sends_only);
1514 /* tell the route (for part #2) */
1515 (*i)->add_fed_by (*j, via_sends_only);
1520 /* Attempt a topological sort of the route graph */
1521 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
1523 if (sorted_routes) {
1524 /* We got a satisfactory topological sort, so there is no feedback;
1527 Note: the process graph rechain does not require a
1528 topologically-sorted list, but hey ho.
1530 if (_process_graph) {
1531 _process_graph->rechain (sorted_routes, edges);
1534 _current_route_graph = edges;
1536 /* Complete the building of the routes' lists of what directly
1537 or indirectly feeds them.
1539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1540 trace_terminal (*i, *i);
1543 *r = *sorted_routes;
1546 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1547 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1548 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1549 (*i)->name(), (*i)->order_key (MixerSort)));
1553 SuccessfulGraphSort (); /* EMIT SIGNAL */
1556 /* The topological sort failed, so we have a problem. Tell everyone
1557 and stick to the old graph; this will continue to be processed, so
1558 until the feedback is fixed, what is played back will not quite
1559 reflect what is actually connected. Note also that we do not
1560 do trace_terminal here, as it would fail due to an endless recursion,
1561 so the solo code will think that everything is still connected
1565 FeedbackDetected (); /* EMIT SIGNAL */
1570 /** Find a route name starting with \a base, maybe followed by the
1571 * lowest \a id. \a id will always be added if \a definitely_add_number
1572 * is true on entry; otherwise it will only be added if required
1573 * to make the name unique.
1575 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1576 * The available route name with the lowest ID will be used, and \a id
1577 * will be set to the ID.
1579 * \return false if a route name could not be found, and \a track_name
1580 * and \a id do not reflect a free route name.
1583 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1585 if (!definitely_add_number && route_by_name (base) == 0) {
1586 /* juse use the base */
1587 snprintf (name, name_len, "%s", base.c_str());
1592 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1594 if (route_by_name (name) == 0) {
1600 } while (id < (UINT_MAX-1));
1605 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
1607 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
1609 in = ChanCount::ZERO;
1610 out = ChanCount::ZERO;
1612 boost::shared_ptr<RouteList> r = routes.reader ();
1614 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1615 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1616 if (tr && !tr->is_hidden()) {
1617 in += tr->n_inputs();
1618 out += tr->n_outputs();
1623 /** Caller must not hold process lock
1624 * @param name_template string to use for the start of the name, or "" to use "MIDI".
1625 * @param instrument plugin info for the instrument to insert pre-fader, if any
1627 list<boost::shared_ptr<MidiTrack> >
1628 Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
1629 TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1631 char track_name[32];
1632 uint32_t track_id = 0;
1634 RouteList new_routes;
1635 list<boost::shared_ptr<MidiTrack> > ret;
1637 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
1640 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1641 error << "cannot find name for new midi track" << endmsg;
1645 boost::shared_ptr<MidiTrack> track;
1648 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1650 if (track->init ()) {
1654 track->use_new_diskstream();
1656 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1657 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1660 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1661 if (track->input()->ensure_io (input, false, this)) {
1662 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
1666 if (track->output()->ensure_io (output, false, this)) {
1667 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
1672 track->non_realtime_input_change();
1675 route_group->add (track);
1678 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1680 if (Config->get_remote_model() == UserOrdered) {
1681 track->set_remote_control_id (next_control_id());
1684 new_routes.push_back (track);
1685 ret.push_back (track);
1688 catch (failed_constructor &err) {
1689 error << _("Session: could not create new midi track.") << endmsg;
1693 catch (AudioEngine::PortRegistrationFailure& pfe) {
1695 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;
1703 if (!new_routes.empty()) {
1704 add_routes (new_routes, true, true, true);
1707 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
1708 PluginPtr plugin = instrument->load (*this);
1709 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
1710 (*r)->add_processor (p, PreFader);
1720 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
1722 boost::shared_ptr<Route> midi_track (wmt.lock());
1728 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
1730 if (change.after.n_audio() <= change.before.n_audio()) {
1734 /* new audio ports: make sure the audio goes somewhere useful,
1735 unless the user has no-auto-connect selected.
1737 The existing ChanCounts don't matter for this call as they are only
1738 to do with matching input and output indices, and we are only changing
1744 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
1748 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1749 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1750 * @param output_start As \a input_start, but for outputs.
1753 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
1754 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
1756 if (!IO::connecting_legal) {
1760 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
1766 /* If both inputs and outputs are auto-connected to physical ports,
1767 use the max of input and output offsets to ensure auto-connected
1768 port numbers always match up (e.g. the first audio input and the
1769 first audio output of the route will have the same physical
1770 port number). Otherwise just use the lowest input or output
1774 DEBUG_TRACE (DEBUG::Graph,
1775 string_compose("Auto-connect: existing in = %1 out = %2\n",
1776 existing_inputs, existing_outputs));
1778 const bool in_out_physical =
1779 (Config->get_input_auto_connect() & AutoConnectPhysical)
1780 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1783 const ChanCount in_offset = in_out_physical
1784 ? ChanCount::max(existing_inputs, existing_outputs)
1787 const ChanCount out_offset = in_out_physical
1788 ? ChanCount::max(existing_inputs, existing_outputs)
1791 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1792 vector<string> physinputs;
1793 vector<string> physoutputs;
1795 _engine.get_physical_outputs (*t, physoutputs);
1796 _engine.get_physical_inputs (*t, physinputs);
1798 if (!physinputs.empty() && connect_inputs) {
1799 uint32_t nphysical_in = physinputs.size();
1801 DEBUG_TRACE (DEBUG::Graph,
1802 string_compose("There are %1 physical inputs of type %2\n",
1805 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1808 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1809 DEBUG_TRACE (DEBUG::Graph,
1810 string_compose("Get index %1 + %2 % %3 = %4\n",
1811 in_offset.get(*t), i, nphysical_in,
1812 (in_offset.get(*t) + i) % nphysical_in));
1813 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1816 DEBUG_TRACE (DEBUG::Graph,
1817 string_compose("Connect route %1 IN to %2\n",
1818 route->name(), port));
1820 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
1824 ChanCount one_added (*t, 1);
1825 existing_inputs += one_added;
1829 if (!physoutputs.empty()) {
1830 uint32_t nphysical_out = physoutputs.size();
1831 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1834 if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
1835 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1836 } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
1837 /* master bus is audio only */
1838 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1839 port = _master_out->input()->ports().port(*t,
1840 i % _master_out->input()->n_ports().get(*t))->name();
1844 DEBUG_TRACE (DEBUG::Graph,
1845 string_compose("Connect route %1 OUT to %2\n",
1846 route->name(), port));
1848 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
1852 ChanCount one_added (*t, 1);
1853 existing_outputs += one_added;
1859 /** Caller must not hold process lock
1860 * @param name_template string to use for the start of the name, or "" to use "Audio".
1862 list< boost::shared_ptr<AudioTrack> >
1863 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
1864 uint32_t how_many, string name_template)
1866 char track_name[32];
1867 uint32_t track_id = 0;
1869 RouteList new_routes;
1870 list<boost::shared_ptr<AudioTrack> > ret;
1872 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
1875 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1876 error << "cannot find name for new audio track" << endmsg;
1880 boost::shared_ptr<AudioTrack> track;
1883 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1885 if (track->init ()) {
1889 track->use_new_diskstream();
1891 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1892 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1895 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1897 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1898 error << string_compose (
1899 _("cannot configure %1 in/%2 out configuration for new audio track"),
1900 input_channels, output_channels)
1905 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1906 error << string_compose (
1907 _("cannot configure %1 in/%2 out configuration for new audio track"),
1908 input_channels, output_channels)
1915 route_group->add (track);
1918 track->non_realtime_input_change();
1920 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1921 if (Config->get_remote_model() == UserOrdered) {
1922 track->set_remote_control_id (next_control_id());
1925 new_routes.push_back (track);
1926 ret.push_back (track);
1929 catch (failed_constructor &err) {
1930 error << _("Session: could not create new audio track.") << endmsg;
1934 catch (AudioEngine::PortRegistrationFailure& pfe) {
1936 error << pfe.what() << endmsg;
1944 if (!new_routes.empty()) {
1945 add_routes (new_routes, true, true, true);
1951 /** Caller must not hold process lock.
1952 * @param name_template string to use for the start of the name, or "" to use "Bus".
1955 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1958 uint32_t bus_id = 0;
1962 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
1965 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1966 error << "cannot find name for new audio bus" << endmsg;
1971 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1977 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1978 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1981 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1983 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1984 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1985 input_channels, output_channels)
1991 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1992 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1993 input_channels, output_channels)
2000 route_group->add (bus);
2002 if (Config->get_remote_model() == UserOrdered) {
2003 bus->set_remote_control_id (next_control_id());
2006 bus->add_internal_return ();
2008 ret.push_back (bus);
2014 catch (failed_constructor &err) {
2015 error << _("Session: could not create new audio route.") << endmsg;
2019 catch (AudioEngine::PortRegistrationFailure& pfe) {
2020 error << pfe.what() << endmsg;
2030 add_routes (ret, false, true, true); // autoconnect outputs only
2038 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2041 uint32_t control_id;
2043 uint32_t number = 0;
2045 if (!tree.read (template_path.c_str())) {
2049 XMLNode* node = tree.root();
2051 IO::disable_connecting ();
2053 control_id = next_control_id ();
2057 XMLNode node_copy (*node);
2059 /* Remove IDs of everything so that new ones are used */
2060 node_copy.remove_property_recursively (X_("id"));
2063 string const route_name = node_copy.property(X_("name"))->value ();
2065 /* generate a new name by adding a number to the end of the template name */
2067 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2068 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2072 /* set this name in the XML description that we are about to use */
2073 Route::set_name_in_state (node_copy, name);
2075 /* trim bitslots from listen sends so that new ones are used */
2076 XMLNodeList children = node_copy.children ();
2077 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2078 if ((*i)->name() == X_("Processor")) {
2079 XMLProperty* role = (*i)->property (X_("role"));
2080 if (role && role->value() == X_("Listen")) {
2081 (*i)->remove_property (X_("bitslot"));
2086 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2089 error << _("Session: cannot create track/bus from template description") << endmsg;
2093 if (boost::dynamic_pointer_cast<Track>(route)) {
2094 /* force input/output change signals so that the new diskstream
2095 picks up the configuration of the route. During session
2096 loading this normally happens in a different way.
2099 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2101 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2102 change.after = route->input()->n_ports();
2103 route->input()->changed (change, this);
2104 change.after = route->output()->n_ports();
2105 route->output()->changed (change, this);
2108 route->set_remote_control_id (control_id);
2111 ret.push_back (route);
2114 catch (failed_constructor &err) {
2115 error << _("Session: could not create new route from template") << endmsg;
2119 catch (AudioEngine::PortRegistrationFailure& pfe) {
2120 error << pfe.what() << endmsg;
2129 add_routes (ret, true, true, true);
2130 IO::enable_connecting ();
2137 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2140 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
2141 add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
2144 error << _("Adding new tracks/busses failed") << endmsg;
2149 update_latency (true);
2150 update_latency (false);
2155 save_state (_current_snapshot_name);
2158 RouteAdded (new_routes); /* EMIT SIGNAL */
2162 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
2164 ChanCount existing_inputs;
2165 ChanCount existing_outputs;
2166 uint32_t order = next_control_id();
2168 count_existing_track_channels (existing_inputs, existing_outputs);
2171 RCUWriter<RouteList> writer (routes);
2172 boost::shared_ptr<RouteList> r = writer.get_copy ();
2173 r->insert (r->end(), new_routes.begin(), new_routes.end());
2175 /* if there is no control out and we're not in the middle of loading,
2176 resort the graph here. if there is a control out, we will resort
2177 toward the end of this method. if we are in the middle of loading,
2178 we will resort when done.
2181 if (!_monitor_out && IO::connecting_legal) {
2182 resort_routes_using (r);
2186 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2188 boost::weak_ptr<Route> wpr (*x);
2189 boost::shared_ptr<Route> r (*x);
2191 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2192 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2193 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2194 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2195 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2196 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2198 if (r->is_master()) {
2202 if (r->is_monitor()) {
2206 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2208 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2209 track_playlist_changed (boost::weak_ptr<Track> (tr));
2210 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2212 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2214 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2215 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2220 if (input_auto_connect || output_auto_connect) {
2221 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2224 /* order keys are a GUI responsibility but we need to set up
2225 reasonable defaults because they also affect the remote control
2226 ID in most situations.
2229 if (!r->has_order_key (EditorSort)) {
2230 if (r->is_hidden()) {
2231 /* use an arbitrarily high value */
2232 r->set_order_key (EditorSort, UINT_MAX);
2233 r->set_order_key (MixerSort, UINT_MAX);
2235 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
2236 r->set_order_key (EditorSort, order);
2237 r->set_order_key (MixerSort, order);
2245 if (_monitor_out && IO::connecting_legal) {
2246 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2248 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2249 if ((*x)->is_monitor()) {
2251 } else if ((*x)->is_master()) {
2254 (*x)->enable_monitor_send ();
2261 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2263 boost::shared_ptr<RouteList> r = routes.reader ();
2264 boost::shared_ptr<Send> s;
2266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267 if ((s = (*i)->internal_send_for (dest)) != 0) {
2268 s->amp()->gain_control()->set_value (0.0);
2274 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2276 boost::shared_ptr<RouteList> r = routes.reader ();
2277 boost::shared_ptr<Send> s;
2279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2280 if ((s = (*i)->internal_send_for (dest)) != 0) {
2281 s->amp()->gain_control()->set_value (1.0);
2287 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2289 boost::shared_ptr<RouteList> r = routes.reader ();
2290 boost::shared_ptr<Send> s;
2292 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2293 if ((s = (*i)->internal_send_for (dest)) != 0) {
2294 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2299 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2301 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2303 boost::shared_ptr<RouteList> r = routes.reader ();
2304 boost::shared_ptr<RouteList> t (new RouteList);
2306 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2307 /* no MIDI sends because there are no MIDI busses yet */
2308 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2313 add_internal_sends (dest, p, t);
2317 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2319 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2320 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2325 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2327 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2331 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2333 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2337 if (!dest->internal_return()) {
2338 dest->add_internal_return ();
2341 sender->add_aux_send (dest, before);
2347 Session::remove_route (boost::shared_ptr<Route> route)
2349 if (route == _master_out) {
2353 route->set_solo (false, this);
2356 RCUWriter<RouteList> writer (routes);
2357 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2361 /* deleting the master out seems like a dumb
2362 idea, but its more of a UI policy issue
2366 if (route == _master_out) {
2367 _master_out = boost::shared_ptr<Route> ();
2370 if (route == _monitor_out) {
2371 _monitor_out.reset ();
2374 /* writer goes out of scope, forces route list update */
2377 update_route_solo_state ();
2379 // We need to disconnect the route's inputs and outputs
2381 route->input()->disconnect (0);
2382 route->output()->disconnect (0);
2384 /* if the route had internal sends sending to it, remove them */
2385 if (route->internal_return()) {
2387 boost::shared_ptr<RouteList> r = routes.reader ();
2388 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2389 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2391 (*i)->remove_processor (s);
2396 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2397 if (mt && mt->step_editing()) {
2398 if (_step_editors > 0) {
2403 update_latency_compensation ();
2406 /* Re-sort routes to remove the graph's current references to the one that is
2407 * going away, then flush old references out of the graph.
2411 if (_process_graph) {
2412 _process_graph->clear_other_chain ();
2415 /* get rid of it from the dead wood collection in the route list manager */
2417 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2421 /* try to cause everyone to drop their references */
2423 route->drop_references ();
2425 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2427 /* save the new state of the world */
2429 if (save_state (_current_snapshot_name)) {
2430 save_history (_current_snapshot_name);
2435 Session::route_mute_changed (void* /*src*/)
2441 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2443 boost::shared_ptr<Route> route = wpr.lock();
2445 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2449 if (route->listening_via_monitor ()) {
2451 if (Config->get_exclusive_solo()) {
2452 /* new listen: disable all other listen */
2453 boost::shared_ptr<RouteList> r = routes.reader ();
2454 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2455 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2458 (*i)->set_listen (false, this);
2464 } else if (_listen_cnt > 0) {
2469 update_route_solo_state ();
2472 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2474 boost::shared_ptr<Route> route = wpr.lock ();
2477 /* should not happen */
2478 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2482 bool send_changed = false;
2484 if (route->solo_isolated()) {
2485 if (_solo_isolated_cnt == 0) {
2486 send_changed = true;
2488 _solo_isolated_cnt++;
2489 } else if (_solo_isolated_cnt > 0) {
2490 _solo_isolated_cnt--;
2491 if (_solo_isolated_cnt == 0) {
2492 send_changed = true;
2497 IsolatedChanged (); /* EMIT SIGNAL */
2502 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2504 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
2506 if (!self_solo_change) {
2507 // session doesn't care about changes to soloed-by-others
2511 if (solo_update_disabled) {
2513 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
2517 boost::shared_ptr<Route> route = wpr.lock ();
2520 boost::shared_ptr<RouteList> r = routes.reader ();
2523 if (route->self_soloed()) {
2529 RouteGroup* rg = route->route_group ();
2530 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
2532 if (delta == 1 && Config->get_exclusive_solo()) {
2534 /* new solo: disable all other solos, but not the group if its solo-enabled */
2536 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2537 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2538 (leave_group_alone && ((*i)->route_group() == rg))) {
2541 (*i)->set_solo (false, this);
2545 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
2547 solo_update_disabled = true;
2549 RouteList uninvolved;
2551 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
2553 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2554 bool via_sends_only;
2555 bool in_signal_flow;
2557 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2558 (leave_group_alone && ((*i)->route_group() == rg))) {
2562 in_signal_flow = false;
2564 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
2566 if ((*i)->feeds (route, &via_sends_only)) {
2567 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
2568 if (!via_sends_only) {
2569 if (!route->soloed_by_others_upstream()) {
2570 (*i)->mod_solo_by_others_downstream (delta);
2573 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
2575 in_signal_flow = true;
2577 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
2580 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
2582 if (route->feeds (*i, &via_sends_only)) {
2583 /* propagate solo upstream only if routing other than
2584 sends is involved, but do consider the other route
2585 (*i) to be part of the signal flow even if only
2588 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
2592 route->soloed_by_others_downstream(),
2593 route->soloed_by_others_upstream()));
2594 if (!via_sends_only) {
2595 if (!route->soloed_by_others_downstream()) {
2596 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
2597 (*i)->mod_solo_by_others_upstream (delta);
2599 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
2602 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
2604 in_signal_flow = true;
2606 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
2609 if (!in_signal_flow) {
2610 uninvolved.push_back (*i);
2614 solo_update_disabled = false;
2615 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
2617 update_route_solo_state (r);
2619 /* now notify that the mute state of the routes not involved in the signal
2620 pathway of the just-solo-changed route may have altered.
2623 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2624 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
2625 (*i)->mute_changed (this);
2628 SoloChanged (); /* EMIT SIGNAL */
2633 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2635 /* now figure out if anything that matters is soloed (or is "listening")*/
2637 bool something_soloed = false;
2638 uint32_t listeners = 0;
2639 uint32_t isolated = 0;
2642 r = routes.reader();
2645 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2646 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2647 something_soloed = true;
2650 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2651 if (Config->get_solo_control_is_listen_control()) {
2654 (*i)->set_listen (false, this);
2658 if ((*i)->solo_isolated()) {
2663 if (something_soloed != _non_soloed_outs_muted) {
2664 _non_soloed_outs_muted = something_soloed;
2665 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2668 _listen_cnt = listeners;
2670 if (isolated != _solo_isolated_cnt) {
2671 _solo_isolated_cnt = isolated;
2672 IsolatedChanged (); /* EMIT SIGNAL */
2675 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
2676 something_soloed, listeners, isolated));
2679 boost::shared_ptr<RouteList>
2680 Session::get_routes_with_internal_returns() const
2682 boost::shared_ptr<RouteList> r = routes.reader ();
2683 boost::shared_ptr<RouteList> rl (new RouteList);
2685 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2686 if ((*i)->internal_return ()) {
2694 Session::io_name_is_legal (const std::string& name)
2696 boost::shared_ptr<RouteList> r = routes.reader ();
2698 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2699 if ((*i)->name() == name) {
2703 if ((*i)->has_io_processor_named (name)) {
2712 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
2715 vector<string> connections;
2717 /* if we are passed only a single route and we're not told to turn
2718 * others off, then just do the simple thing.
2721 if (flip_others == false && rl->size() == 1) {
2722 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
2724 mt->set_input_active (onoff);
2729 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
2731 PortSet& ps ((*rt)->input()->ports());
2733 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
2734 p->get_connections (connections);
2737 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
2738 routes_using_input_from (*s, rl2);
2741 /* scan all relevant routes to see if others are on or off */
2743 bool others_are_already_on = false;
2745 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2747 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2753 if ((*r) != (*rt)) {
2754 if (mt->input_active()) {
2755 others_are_already_on = true;
2758 /* this one needs changing */
2759 mt->set_input_active (onoff);
2765 /* globally reverse other routes */
2767 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2768 if ((*r) != (*rt)) {
2769 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2771 mt->set_input_active (!others_are_already_on);
2780 Session::routes_using_input_from (const string& str, RouteList& rl)
2782 boost::shared_ptr<RouteList> r = routes.reader();
2784 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2785 if ((*i)->input()->connected_to (str)) {
2791 boost::shared_ptr<Route>
2792 Session::route_by_name (string name)
2794 boost::shared_ptr<RouteList> r = routes.reader ();
2796 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2797 if ((*i)->name() == name) {
2802 return boost::shared_ptr<Route> ((Route*) 0);
2805 boost::shared_ptr<Route>
2806 Session::route_by_id (PBD::ID id)
2808 boost::shared_ptr<RouteList> r = routes.reader ();
2810 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2811 if ((*i)->id() == id) {
2816 return boost::shared_ptr<Route> ((Route*) 0);
2819 boost::shared_ptr<Track>
2820 Session::track_by_diskstream_id (PBD::ID id)
2822 boost::shared_ptr<RouteList> r = routes.reader ();
2824 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2825 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
2826 if (t && t->using_diskstream_id (id)) {
2831 return boost::shared_ptr<Track> ();
2834 boost::shared_ptr<Route>
2835 Session::route_by_remote_id (uint32_t id)
2837 boost::shared_ptr<RouteList> r = routes.reader ();
2839 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2840 if ((*i)->remote_control_id() == id) {
2845 return boost::shared_ptr<Route> ((Route*) 0);
2849 Session::playlist_region_added (boost::weak_ptr<Region> w)
2851 boost::shared_ptr<Region> r = w.lock ();
2856 /* These are the operations that are currently in progress... */
2857 list<GQuark> curr = _current_trans_quarks;
2860 /* ...and these are the operations during which we want to update
2861 the session range location markers.
2864 ops.push_back (Operations::capture);
2865 ops.push_back (Operations::paste);
2866 ops.push_back (Operations::duplicate_region);
2867 ops.push_back (Operations::insert_file);
2868 ops.push_back (Operations::insert_region);
2869 ops.push_back (Operations::drag_region_brush);
2870 ops.push_back (Operations::region_drag);
2871 ops.push_back (Operations::selection_grab);
2872 ops.push_back (Operations::region_fill);
2873 ops.push_back (Operations::fill_selection);
2874 ops.push_back (Operations::create_region);
2875 ops.push_back (Operations::region_copy);
2876 ops.push_back (Operations::fixed_time_region_copy);
2879 /* See if any of the current operations match the ones that we want */
2881 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2883 /* If so, update the session range markers */
2885 maybe_update_session_range (r->position (), r->last_frame ());
2889 /** Update the session range markers if a is before the current start or
2890 * b is after the current end.
2893 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2895 if (_state_of_the_state & Loading) {
2899 if (_session_range_location == 0) {
2901 add_session_range_location (a, b);
2905 if (a < _session_range_location->start()) {
2906 _session_range_location->set_start (a);
2909 if (b > _session_range_location->end()) {
2910 _session_range_location->set_end (b);
2916 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2918 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2919 maybe_update_session_range (i->to, i->to + i->length);
2924 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2926 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2927 maybe_update_session_range (i->from, i->to);
2931 /* Region management */
2933 boost::shared_ptr<Region>
2934 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2936 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2937 RegionFactory::RegionMap::const_iterator i;
2938 boost::shared_ptr<Region> region;
2940 Glib::Threads::Mutex::Lock lm (region_lock);
2942 for (i = regions.begin(); i != regions.end(); ++i) {
2946 if (region->whole_file()) {
2948 if (child->source_equivalent (region)) {
2954 return boost::shared_ptr<Region> ();
2958 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2960 set<boost::shared_ptr<Region> > relevant_regions;
2962 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2963 RegionFactory::get_regions_using_source (*s, relevant_regions);
2966 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2967 set<boost::shared_ptr<Region> >::iterator tmp;
2972 playlists->destroy_region (*r);
2973 RegionFactory::map_remove (*r);
2975 (*r)->drop_sources ();
2976 (*r)->drop_references ();
2978 relevant_regions.erase (r);
2983 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2986 Glib::Threads::Mutex::Lock ls (source_lock);
2987 /* remove from the main source list */
2988 sources.erase ((*s)->id());
2991 (*s)->mark_for_remove ();
2992 (*s)->drop_references ();
3001 Session::remove_last_capture ()
3003 list<boost::shared_ptr<Source> > srcs;
3005 boost::shared_ptr<RouteList> rl = routes.reader ();
3006 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3007 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3012 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
3015 srcs.insert (srcs.end(), l.begin(), l.end());
3020 destroy_sources (srcs);
3022 save_state (_current_snapshot_name);
3027 /* Source Management */
3030 Session::add_source (boost::shared_ptr<Source> source)
3032 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3033 pair<SourceMap::iterator,bool> result;
3035 entry.first = source->id();
3036 entry.second = source;
3039 Glib::Threads::Mutex::Lock lm (source_lock);
3040 result = sources.insert (entry);
3043 if (result.second) {
3045 /* yay, new source */
3047 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3050 if (!fs->within_session()) {
3051 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3057 boost::shared_ptr<AudioFileSource> afs;
3059 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3060 if (Config->get_auto_analyse_audio()) {
3061 Analyser::queue_source_for_analysis (source, false);
3065 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3070 Session::remove_source (boost::weak_ptr<Source> src)
3072 if (_state_of_the_state & Deletion) {
3076 SourceMap::iterator i;
3077 boost::shared_ptr<Source> source = src.lock();
3084 Glib::Threads::Mutex::Lock lm (source_lock);
3086 if ((i = sources.find (source->id())) != sources.end()) {
3091 if (!(_state_of_the_state & InCleanup)) {
3093 /* save state so we don't end up with a session file
3094 referring to non-existent sources.
3097 save_state (_current_snapshot_name);
3101 boost::shared_ptr<Source>
3102 Session::source_by_id (const PBD::ID& id)
3104 Glib::Threads::Mutex::Lock lm (source_lock);
3105 SourceMap::iterator i;
3106 boost::shared_ptr<Source> source;
3108 if ((i = sources.find (id)) != sources.end()) {
3115 boost::shared_ptr<Source>
3116 Session::source_by_path_and_channel (const string& path, uint16_t chn)
3118 Glib::Threads::Mutex::Lock lm (source_lock);
3120 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3121 boost::shared_ptr<AudioFileSource> afs
3122 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3124 if (afs && afs->path() == path && chn == afs->channel()) {
3128 return boost::shared_ptr<Source>();
3132 Session::count_sources_by_origin (const string& path)
3135 Glib::Threads::Mutex::Lock lm (source_lock);
3137 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3138 boost::shared_ptr<FileSource> fs
3139 = boost::dynamic_pointer_cast<FileSource>(i->second);
3141 if (fs && fs->origin() == path) {
3151 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3154 string old_basename = PBD::basename_nosuffix (oldname);
3155 string new_legalized = legalize_for_path (newname);
3157 /* note: we know (or assume) the old path is already valid */
3161 /* destructive file sources have a name of the form:
3163 /path/to/Tnnnn-NAME(%[LR])?.wav
3165 the task here is to replace NAME with the new name.
3170 string::size_type dash;
3172 dir = Glib::path_get_dirname (path);
3173 path = Glib::path_get_basename (path);
3175 /* '-' is not a legal character for the NAME part of the path */
3177 if ((dash = path.find_last_of ('-')) == string::npos) {
3181 prefix = path.substr (0, dash);
3185 path += new_legalized;
3186 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3187 path = Glib::build_filename (dir, path);
3191 /* non-destructive file sources have a name of the form:
3193 /path/to/NAME-nnnnn(%[LR])?.ext
3195 the task here is to replace NAME with the new name.
3200 string::size_type dash;
3201 string::size_type postfix;
3203 dir = Glib::path_get_dirname (path);
3204 path = Glib::path_get_basename (path);
3206 /* '-' is not a legal character for the NAME part of the path */
3208 if ((dash = path.find_last_of ('-')) == string::npos) {
3212 suffix = path.substr (dash+1);
3214 // Suffix is now everything after the dash. Now we need to eliminate
3215 // the nnnnn part, which is done by either finding a '%' or a '.'
3217 postfix = suffix.find_last_of ("%");
3218 if (postfix == string::npos) {
3219 postfix = suffix.find_last_of ('.');
3222 if (postfix != string::npos) {
3223 suffix = suffix.substr (postfix);
3225 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3229 const uint32_t limit = 10000;
3230 char buf[PATH_MAX+1];
3232 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3234 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
3236 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
3237 path = Glib::build_filename (dir, buf);
3245 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
3254 /** Return the full path (in some session directory) for a new within-session source.
3255 * \a name must be a session-unique name that does not contain slashes
3256 * (e.g. as returned by new_*_source_name)
3259 Session::new_source_path_from_name (DataType type, const string& name)
3261 assert(name.find("/") == string::npos);
3263 SessionDirectory sdir(get_best_session_directory_for_new_source());
3266 if (type == DataType::AUDIO) {
3267 p = sdir.sound_path();
3268 } else if (type == DataType::MIDI) {
3269 p = sdir.midi_path();
3271 error << "Unknown source type, unable to create file path" << endmsg;
3275 return Glib::build_filename (p, name);
3279 Session::peak_path (string base) const
3281 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3284 /** Return a unique name based on \a base for a new internal audio source */
3286 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3289 char buf[PATH_MAX+1];
3290 const uint32_t limit = 10000;
3292 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3295 legalized = legalize_for_path (base);
3297 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3298 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3300 vector<space_and_path>::iterator i;
3301 uint32_t existing = 0;
3303 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3308 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3309 cnt, legalized.c_str(), ext.c_str());
3310 } else if (nchan == 2) {
3312 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
3313 cnt, legalized.c_str(), ext.c_str());
3315 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
3316 cnt, legalized.c_str(), ext.c_str());
3318 } else if (nchan < 26) {
3319 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
3320 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
3322 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3323 cnt, legalized.c_str(), ext.c_str());
3329 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3330 } else if (nchan == 2) {
3332 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
3334 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
3336 } else if (nchan < 26) {
3337 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
3339 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3343 SessionDirectory sdir((*i).path);
3345 string spath = sdir.sound_path();
3347 /* note that we search *without* the extension so that
3348 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3349 in the event that this new name is required for
3350 a file format change.
3353 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
3359 if (existing == 0) {
3364 error << string_compose(
3365 _("There are already %1 recordings for %2, which I consider too many."),
3366 limit, base) << endmsg;
3368 throw failed_constructor();
3372 return Glib::path_get_basename (buf);
3375 /** Create a new within-session audio source */
3376 boost::shared_ptr<AudioFileSource>
3377 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3379 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3380 const string path = new_source_path_from_name(DataType::AUDIO, name);
3382 return boost::dynamic_pointer_cast<AudioFileSource> (
3383 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3386 /** Return a unique name based on \a base for a new internal MIDI source */
3388 Session::new_midi_source_name (const string& base)
3391 char buf[PATH_MAX+1];
3392 const uint32_t limit = 10000;
3396 legalized = legalize_for_path (base);
3398 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3399 for (cnt = 1; cnt <= limit; ++cnt) {
3401 vector<space_and_path>::iterator i;
3402 uint32_t existing = 0;
3404 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3406 SessionDirectory sdir((*i).path);
3408 std::string p = Glib::build_filename (sdir.midi_path(), legalized);
3410 snprintf (buf, sizeof(buf), "%s-%u.mid", p.c_str(), cnt);
3412 if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3417 if (existing == 0) {
3422 error << string_compose(
3423 _("There are already %1 recordings for %2, which I consider too many."),
3424 limit, base) << endmsg;
3426 throw failed_constructor();
3430 return Glib::path_get_basename(buf);
3434 /** Create a new within-session MIDI source */
3435 boost::shared_ptr<MidiSource>
3436 Session::create_midi_source_for_session (Track* track, string const & n)
3438 /* try to use the existing write source for the track, to keep numbering sane
3442 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3446 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3449 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3450 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3454 const string name = new_midi_source_name (n);
3455 const string path = new_source_path_from_name (DataType::MIDI, name);
3457 return boost::dynamic_pointer_cast<SMFSource> (
3458 SourceFactory::createWritable (
3459 DataType::MIDI, *this, path, string(), false, frame_rate()));
3464 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3466 if (playlist->hidden()) {
3470 playlists->add (playlist);
3473 playlist->release();
3480 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3482 if (_state_of_the_state & Deletion) {
3486 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3492 playlists->remove (playlist);
3498 Session::set_audition (boost::shared_ptr<Region> r)
3500 pending_audition_region = r;
3501 add_post_transport_work (PostTransportAudition);
3502 _butler->schedule_transport_work ();
3506 Session::audition_playlist ()
3508 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3509 ev->region.reset ();
3514 Session::non_realtime_set_audition ()
3516 assert (pending_audition_region);
3517 auditioner->audition_region (pending_audition_region);
3518 pending_audition_region.reset ();
3519 AuditionActive (true); /* EMIT SIGNAL */
3523 Session::audition_region (boost::shared_ptr<Region> r)
3525 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3531 Session::cancel_audition ()
3533 if (auditioner->auditioning()) {
3534 auditioner->cancel_audition ();
3535 AuditionActive (false); /* EMIT SIGNAL */
3540 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3542 if (a->is_monitor()) {
3545 if (b->is_monitor()) {
3548 return a->order_key (MixerSort) < b->order_key (MixerSort);
3552 Session::is_auditioning () const
3554 /* can be called before we have an auditioner object */
3556 return auditioner->auditioning();
3563 Session::graph_reordered ()
3565 /* don't do this stuff if we are setting up connections
3566 from a set_state() call or creating new tracks. Ditto for deletion.
3569 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
3573 /* every track/bus asked for this to be handled but it was deferred because
3574 we were connecting. do it now.
3577 request_input_change_handling ();
3581 /* force all diskstreams to update their capture offset values to
3582 reflect any changes in latencies within the graph.
3585 boost::shared_ptr<RouteList> rl = routes.reader ();
3586 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3587 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3589 tr->set_capture_offset ();
3594 /** @return Number of frames that there is disk space available to write,
3597 boost::optional<framecnt_t>
3598 Session::available_capture_duration ()
3600 Glib::Threads::Mutex::Lock lm (space_lock);
3602 if (_total_free_4k_blocks_uncertain) {
3603 return boost::optional<framecnt_t> ();
3606 float sample_bytes_on_disk = 4.0; // keep gcc happy
3608 switch (config.get_native_file_data_format()) {
3610 sample_bytes_on_disk = 4.0;
3614 sample_bytes_on_disk = 3.0;
3618 sample_bytes_on_disk = 2.0;
3622 /* impossible, but keep some gcc versions happy */
3623 fatal << string_compose (_("programming error: %1"),
3624 X_("illegal native file data format"))
3629 double scale = 4096.0 / sample_bytes_on_disk;
3631 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3632 return max_framecnt;
3635 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3639 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3642 RCUWriter<BundleList> writer (_bundles);
3643 boost::shared_ptr<BundleList> b = writer.get_copy ();
3644 b->push_back (bundle);
3647 BundleAdded (bundle); /* EMIT SIGNAL */
3653 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3655 bool removed = false;
3658 RCUWriter<BundleList> writer (_bundles);
3659 boost::shared_ptr<BundleList> b = writer.get_copy ();
3660 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3662 if (i != b->end()) {
3669 BundleRemoved (bundle); /* EMIT SIGNAL */
3675 boost::shared_ptr<Bundle>
3676 Session::bundle_by_name (string name) const
3678 boost::shared_ptr<BundleList> b = _bundles.reader ();
3680 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3681 if ((*i)->name() == name) {
3686 return boost::shared_ptr<Bundle> ();
3690 Session::tempo_map_changed (const PropertyChange&)
3694 playlists->update_after_tempo_map_change ();
3696 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3702 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3704 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3705 (*i)->recompute_frames_from_bbt ();
3709 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3710 * the given count with the current block size.
3713 Session::ensure_buffers (ChanCount howmany)
3715 BufferManager::ensure_buffers (howmany);
3719 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3721 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3722 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3727 Session::next_insert_id ()
3729 /* this doesn't really loop forever. just think about it */
3732 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3733 if (!insert_bitset[n]) {
3734 insert_bitset[n] = true;
3740 /* none available, so resize and try again */
3742 insert_bitset.resize (insert_bitset.size() + 16, false);
3747 Session::next_send_id ()
3749 /* this doesn't really loop forever. just think about it */
3752 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3753 if (!send_bitset[n]) {
3754 send_bitset[n] = true;
3760 /* none available, so resize and try again */
3762 send_bitset.resize (send_bitset.size() + 16, false);
3767 Session::next_aux_send_id ()
3769 /* this doesn't really loop forever. just think about it */
3772 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
3773 if (!aux_send_bitset[n]) {
3774 aux_send_bitset[n] = true;
3780 /* none available, so resize and try again */
3782 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
3787 Session::next_return_id ()
3789 /* this doesn't really loop forever. just think about it */
3792 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3793 if (!return_bitset[n]) {
3794 return_bitset[n] = true;
3800 /* none available, so resize and try again */
3802 return_bitset.resize (return_bitset.size() + 16, false);
3807 Session::mark_send_id (uint32_t id)
3809 if (id >= send_bitset.size()) {
3810 send_bitset.resize (id+16, false);
3812 if (send_bitset[id]) {
3813 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3815 send_bitset[id] = true;
3819 Session::mark_aux_send_id (uint32_t id)
3821 if (id >= aux_send_bitset.size()) {
3822 aux_send_bitset.resize (id+16, false);
3824 if (aux_send_bitset[id]) {
3825 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
3827 aux_send_bitset[id] = true;
3831 Session::mark_return_id (uint32_t id)
3833 if (id >= return_bitset.size()) {
3834 return_bitset.resize (id+16, false);
3836 if (return_bitset[id]) {
3837 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3839 return_bitset[id] = true;
3843 Session::mark_insert_id (uint32_t id)
3845 if (id >= insert_bitset.size()) {
3846 insert_bitset.resize (id+16, false);
3848 if (insert_bitset[id]) {
3849 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3851 insert_bitset[id] = true;
3855 Session::unmark_send_id (uint32_t id)
3857 if (id < send_bitset.size()) {
3858 send_bitset[id] = false;
3863 Session::unmark_aux_send_id (uint32_t id)
3865 if (id < aux_send_bitset.size()) {
3866 aux_send_bitset[id] = false;
3871 Session::unmark_return_id (uint32_t id)
3873 if (id < return_bitset.size()) {
3874 return_bitset[id] = false;
3879 Session::unmark_insert_id (uint32_t id)
3881 if (id < insert_bitset.size()) {
3882 insert_bitset[id] = false;
3887 Session::reset_native_file_format ()
3889 boost::shared_ptr<RouteList> rl = routes.reader ();
3890 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3891 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3893 /* don't save state as we do this, there's no point
3896 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3897 tr->reset_write_sources (false);
3898 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3904 Session::route_name_unique (string n) const
3906 boost::shared_ptr<RouteList> r = routes.reader ();
3908 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3909 if ((*i)->name() == n) {
3918 Session::route_name_internal (string n) const
3920 if (auditioner && auditioner->name() == n) {
3924 if (_click_io && _click_io->name() == n) {
3932 Session::freeze_all (InterThreadInfo& itt)
3934 boost::shared_ptr<RouteList> r = routes.reader ();
3936 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3938 boost::shared_ptr<Track> t;
3940 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3941 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3951 boost::shared_ptr<Region>
3952 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3953 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3954 InterThreadInfo& itt,
3955 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
3958 boost::shared_ptr<Region> result;
3959 boost::shared_ptr<Playlist> playlist;
3960 boost::shared_ptr<AudioFileSource> fsource;
3962 char buf[PATH_MAX+1];
3963 ChanCount diskstream_channels (track.n_channels());
3964 framepos_t position;
3965 framecnt_t this_chunk;
3968 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3969 const string sound_dir = sdir.sound_path();
3970 framepos_t len = end - start;
3971 bool need_block_size_reset = false;
3973 ChanCount const max_proc = track.max_processor_streams ();
3976 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3977 end, start) << endmsg;
3981 const framecnt_t chunk_size = (256 * 1024)/4;
3983 // block all process callback handling
3985 block_processing ();
3987 /* call tree *MUST* hold route_lock */
3989 if ((playlist = track.playlist()) == 0) {
3993 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3995 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3997 for (x = 0; x < 99999; ++x) {
3998 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 "%s", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1, ext.c_str());
3999 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
4005 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4010 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4011 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
4014 catch (failed_constructor& err) {
4015 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4019 srcs.push_back (fsource);
4022 /* tell redirects that care that we are about to use a much larger
4023 * blocksize. this will flush all plugins too, so that they are ready
4024 * to be used for this process.
4027 need_block_size_reset = true;
4028 track.set_block_size (chunk_size);
4033 /* create a set of reasonably-sized buffers */
4034 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
4035 buffers.set_count (max_proc);
4037 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4038 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4040 afs->prepare_for_peakfile_writes ();
4043 while (to_do && !itt.cancel) {
4045 this_chunk = min (to_do, chunk_size);
4047 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export)) {
4052 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4053 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4056 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4062 start += this_chunk;
4063 to_do -= this_chunk;
4065 itt.progress = (float) (1.0 - ((double) to_do / len));
4074 xnow = localtime (&now);
4076 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4077 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4080 afs->update_header (position, *xnow, now);
4081 afs->flush_header ();
4085 /* construct a region to represent the bounced material */
4089 plist.add (Properties::start, 0);
4090 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4091 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4093 result = RegionFactory::create (srcs, plist);
4099 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4100 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4103 afs->mark_for_remove ();
4106 (*src)->drop_references ();
4110 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4111 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4114 afs->done_with_peakfile_writes ();
4119 if (need_block_size_reset) {
4120 track.set_block_size (get_block_size());
4123 unblock_processing ();
4129 Session::gain_automation_buffer() const
4131 return ProcessThread::gain_automation_buffer ();
4135 Session::send_gain_automation_buffer() const
4137 return ProcessThread::send_gain_automation_buffer ();
4141 Session::pan_automation_buffer() const
4143 return ProcessThread::pan_automation_buffer ();
4147 Session::get_silent_buffers (ChanCount count)
4149 return ProcessThread::get_silent_buffers (count);
4153 Session::get_scratch_buffers (ChanCount count)
4155 return ProcessThread::get_scratch_buffers (count);
4159 Session::get_mix_buffers (ChanCount count)
4161 return ProcessThread::get_mix_buffers (count);
4165 Session::ntracks () const
4168 boost::shared_ptr<RouteList> r = routes.reader ();
4170 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4171 if (boost::dynamic_pointer_cast<Track> (*i)) {
4180 Session::nbusses () const
4183 boost::shared_ptr<RouteList> r = routes.reader ();
4185 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4186 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4195 Session::add_automation_list(AutomationList *al)
4197 automation_lists[al->id()] = al;
4200 /** @return true if there is at least one record-enabled track, otherwise false */
4202 Session::have_rec_enabled_track () const
4204 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
4207 /** Update the state of our rec-enabled tracks flag */
4209 Session::update_have_rec_enabled_track ()
4211 boost::shared_ptr<RouteList> rl = routes.reader ();
4212 RouteList::iterator i = rl->begin();
4213 while (i != rl->end ()) {
4215 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4216 if (tr && tr->record_enabled ()) {
4223 int const old = g_atomic_int_get (&_have_rec_enabled_track);
4225 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
4227 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
4228 RecordStateChanged (); /* EMIT SIGNAL */
4233 Session::listen_position_changed ()
4235 boost::shared_ptr<RouteList> r = routes.reader ();
4237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4238 (*i)->listen_position_changed ();
4243 Session::solo_control_mode_changed ()
4245 /* cancel all solo or all listen when solo control mode changes */
4248 set_solo (get_routes(), false);
4249 } else if (listening()) {
4250 set_listen (get_routes(), false);
4254 /** Called when a property of one of our route groups changes */
4256 Session::route_group_property_changed (RouteGroup* rg)
4258 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
4261 /** Called when a route is added to one of our route groups */
4263 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4265 RouteAddedToRouteGroup (rg, r);
4268 /** Called when a route is removed from one of our route groups */
4270 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4272 RouteRemovedFromRouteGroup (rg, r);
4275 boost::shared_ptr<RouteList>
4276 Session::get_routes_with_regions_at (framepos_t const p) const
4278 boost::shared_ptr<RouteList> r = routes.reader ();
4279 boost::shared_ptr<RouteList> rl (new RouteList);
4281 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4282 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4287 boost::shared_ptr<Playlist> pl = tr->playlist ();
4292 if (pl->has_region_at (p)) {
4301 Session::goto_end ()
4303 if (_session_range_location) {
4304 request_locate (_session_range_location->end(), false);
4306 request_locate (0, false);
4311 Session::goto_start ()
4313 if (_session_range_location) {
4314 request_locate (_session_range_location->start(), false);
4316 request_locate (0, false);
4321 Session::current_start_frame () const
4323 return _session_range_location ? _session_range_location->start() : 0;
4327 Session::current_end_frame () const
4329 return _session_range_location ? _session_range_location->end() : 0;
4333 Session::add_session_range_location (framepos_t start, framepos_t end)
4335 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4336 _locations->add (_session_range_location);
4340 Session::step_edit_status_change (bool yn)
4346 send = (_step_editors == 0);
4351 send = (_step_editors == 1);
4354 if (_step_editors > 0) {
4360 StepEditStatusChange (val);
4366 Session::start_time_changed (framepos_t old)
4368 /* Update the auto loop range to match the session range
4369 (unless the auto loop range has been changed by the user)
4372 Location* s = _locations->session_range_location ();
4377 Location* l = _locations->auto_loop_location ();
4379 if (l && l->start() == old) {
4380 l->set_start (s->start(), true);
4385 Session::end_time_changed (framepos_t old)
4387 /* Update the auto loop range to match the session range
4388 (unless the auto loop range has been changed by the user)
4391 Location* s = _locations->session_range_location ();
4396 Location* l = _locations->auto_loop_location ();
4398 if (l && l->end() == old) {
4399 l->set_end (s->end(), true);
4404 Session::source_search_path (DataType type) const
4408 if (session_dirs.size() == 1) {
4410 case DataType::AUDIO:
4411 s.push_back (_session_dir->sound_path());
4413 case DataType::MIDI:
4414 s.push_back (_session_dir->midi_path());
4418 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4419 SessionDirectory sdir (i->path);
4421 case DataType::AUDIO:
4422 s.push_back (sdir.sound_path());
4424 case DataType::MIDI:
4425 s.push_back (sdir.midi_path());
4431 if (type == DataType::AUDIO) {
4432 const string sound_path_2X = _session_dir->sound_path_2X();
4433 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
4434 if (find (s.begin(), s.end(), sound_path_2X) == s.end()) {
4435 s.push_back (sound_path_2X);
4440 /* now check the explicit (possibly user-specified) search path
4443 vector<string> dirs;
4446 case DataType::AUDIO:
4447 split (config.get_audio_search_path (), dirs, ':');
4449 case DataType::MIDI:
4450 split (config.get_midi_search_path (), dirs, ':');
4454 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4455 if (find (s.begin(), s.end(), *i) == s.end()) {
4462 for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) {
4463 if (!search_path.empty()) {
4473 Session::ensure_search_path_includes (const string& path, DataType type)
4476 vector<string> dirs;
4483 case DataType::AUDIO:
4484 search_path = config.get_audio_search_path ();
4486 case DataType::MIDI:
4487 search_path = config.get_midi_search_path ();
4491 split (search_path, dirs, ':');
4493 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4494 /* No need to add this new directory if it has the same inode as
4495 an existing one; checking inode rather than name prevents duplicated
4496 directories when we are using symlinks.
4498 On Windows, I think we could just do if (*i == path) here.
4500 if (PBD::equivalent_paths (*i, path)) {
4505 if (!search_path.empty()) {
4509 search_path += path;
4512 case DataType::AUDIO:
4513 config.set_audio_search_path (search_path);
4515 case DataType::MIDI:
4516 config.set_midi_search_path (search_path);
4521 boost::shared_ptr<Speakers>
4522 Session::get_speakers()
4528 Session::unknown_processors () const
4532 boost::shared_ptr<RouteList> r = routes.reader ();
4533 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4534 list<string> t = (*i)->unknown_processors ();
4535 copy (t.begin(), t.end(), back_inserter (p));
4545 Session::update_latency (bool playback)
4547 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4549 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
4553 boost::shared_ptr<RouteList> r = routes.reader ();
4554 framecnt_t max_latency = 0;
4557 /* reverse the list so that we work backwards from the last route to run to the first */
4558 RouteList* rl = routes.reader().get();
4559 r.reset (new RouteList (*rl));
4560 reverse (r->begin(), r->end());
4563 /* compute actual latency values for the given direction and store them all in per-port
4564 structures. this will also publish the same values (to JACK) so that computation of latency
4565 for routes can consistently use public latency values.
4568 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4569 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4572 /* because we latency compensate playback, our published playback latencies should
4573 be the same for all output ports - all material played back by ardour has
4574 the same latency, whether its caused by plugins or by latency compensation. since
4575 these may differ from the values computed above, reset all playback port latencies
4579 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4581 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4582 (*i)->set_public_port_latencies (max_latency, playback);
4587 post_playback_latency ();
4591 post_capture_latency ();
4594 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
4598 Session::post_playback_latency ()
4600 set_worst_playback_latency ();
4602 boost::shared_ptr<RouteList> r = routes.reader ();
4604 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4605 if (!(*i)->is_hidden() && ((*i)->active())) {
4606 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
4610 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4611 (*i)->set_latency_compensation (_worst_track_latency);
4616 Session::post_capture_latency ()
4618 set_worst_capture_latency ();
4620 /* reflect any changes in capture latencies into capture offsets
4623 boost::shared_ptr<RouteList> rl = routes.reader();
4624 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4625 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4627 tr->set_capture_offset ();
4633 Session::initialize_latencies ()
4636 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4637 update_latency (false);
4638 update_latency (true);
4641 set_worst_io_latencies ();
4645 Session::set_worst_io_latencies ()
4647 set_worst_playback_latency ();
4648 set_worst_capture_latency ();
4652 Session::set_worst_playback_latency ()
4654 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4658 _worst_output_latency = 0;
4660 if (!_engine.connected()) {
4664 boost::shared_ptr<RouteList> r = routes.reader ();
4666 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4667 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
4670 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
4674 Session::set_worst_capture_latency ()
4676 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4680 _worst_input_latency = 0;
4682 if (!_engine.connected()) {
4686 boost::shared_ptr<RouteList> r = routes.reader ();
4688 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4689 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
4692 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
4696 Session::update_latency_compensation (bool force_whole_graph)
4698 bool some_track_latency_changed = false;
4700 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4704 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
4706 _worst_track_latency = 0;
4708 boost::shared_ptr<RouteList> r = routes.reader ();
4710 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4711 if (!(*i)->is_hidden() && ((*i)->active())) {
4713 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
4714 some_track_latency_changed = true;
4716 _worst_track_latency = max (tl, _worst_track_latency);
4720 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
4721 (some_track_latency_changed ? "yes" : "no")));
4723 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
4725 if (some_track_latency_changed || force_whole_graph) {
4726 _engine.update_latencies ();
4730 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4731 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4735 tr->set_capture_offset ();
4740 Session::session_name_is_legal (const string& path)
4742 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
4744 for (int i = 0; illegal_chars[i]; ++i) {
4745 if (path.find (illegal_chars[i]) != string::npos) {
4746 return illegal_chars[i];
4754 Session::next_control_id () const
4758 /* the monitor bus remote ID is in a different
4759 * "namespace" than regular routes. its existence doesn't
4760 * affect normal (low) numbered routes.
4767 return nroutes() - subtract;
4771 Session::notify_remote_id_change ()
4773 if (deletion_in_progress()) {
4777 switch (Config->get_remote_model()) {
4780 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
4788 Session::sync_order_keys (RouteSortOrderKey sort_key_changed)
4790 if (deletion_in_progress()) {
4794 /* tell everyone that something has happened to the sort keys
4795 and let them sync up with the change(s)
4796 this will give objects that manage the sort order keys the
4797 opportunity to keep them in sync if they wish to.
4800 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("Sync Order Keys, based on %1\n", enum_2_string (sort_key_changed)));
4802 Route::SyncOrderKeys (sort_key_changed); /* EMIT SIGNAL */
4804 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
4808 Session::operation_in_progress (GQuark op) const
4810 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
4813 boost::shared_ptr<Port>
4814 Session::ltc_input_port () const
4816 return _ltc_input->nth (0);
4819 boost::shared_ptr<Port>
4820 Session::ltc_output_port () const
4822 return _ltc_output->nth (0);
4826 Session::reconnect_ltc_input ()
4830 string src = Config->get_ltc_source_port();
4832 _ltc_input->disconnect (this);
4834 if (src != _("None") && !src.empty()) {
4835 _ltc_input->nth (0)->connect (src);
4841 Session::reconnect_ltc_output ()
4846 string src = Config->get_ltc_sink_port();
4848 _ltc_output->disconnect (this);
4850 if (src != _("None") && !src.empty()) {
4851 _ltc_output->nth (0)->connect (src);