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);
159 if (how_many_dsp_threads () > 1) {
160 /* For now, only create the graph if we are using >1 DSP threads, as
161 it is a bit slower than the old code with 1 thread.
163 _process_graph.reset (new Graph (*this));
166 playlists.reset (new SessionPlaylists);
168 _all_route_group->set_active (true, this);
170 interpolation.add_channel_to (0, 0);
172 if (!eng.connected()) {
173 throw failed_constructor();
176 n_physical_outputs = _engine.n_physical_outputs ();
177 n_physical_inputs = _engine.n_physical_inputs ();
179 first_stage_init (fullpath, snapshot_name);
181 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
184 if (create (mix_template, bus_profile)) {
186 throw failed_constructor ();
190 if (second_stage_init ()) {
192 throw failed_constructor ();
195 store_recent_sessions(_name, _path);
197 bool was_dirty = dirty();
199 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
201 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
202 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
205 DirtyChanged (); /* EMIT SIGNAL */
208 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
209 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
225 vector<void*> debug_pointers;
227 /* if we got to here, leaving pending capture state around
231 remove_pending_capture_state ();
233 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
235 _engine.remove_session ();
237 /* deregister all ports - there will be no process or any other
238 * callbacks from the engine any more.
241 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 << _("Session: you can't use a mark for auto loop") << 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 cerr << "Adding MIDI track with in = " << input << " out = " << output << endl;
1639 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
1642 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1643 error << "cannot find name for new midi track" << endmsg;
1647 boost::shared_ptr<MidiTrack> track;
1650 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1652 if (track->init ()) {
1656 track->use_new_diskstream();
1658 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1659 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1662 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1663 if (track->input()->ensure_io (input, false, this)) {
1664 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
1668 if (track->output()->ensure_io (output, false, this)) {
1669 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
1674 track->non_realtime_input_change();
1677 route_group->add (track);
1680 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1682 if (Config->get_remote_model() == UserOrdered) {
1683 track->set_remote_control_id (next_control_id());
1686 new_routes.push_back (track);
1687 ret.push_back (track);
1690 catch (failed_constructor &err) {
1691 error << _("Session: could not create new midi track.") << endmsg;
1695 catch (AudioEngine::PortRegistrationFailure& pfe) {
1697 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
1705 if (!new_routes.empty()) {
1706 add_routes (new_routes, true, true, true);
1709 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
1710 PluginPtr plugin = instrument->load (*this);
1711 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
1712 (*r)->add_processor (p, PreFader);
1722 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
1724 boost::shared_ptr<Route> midi_track (wmt.lock());
1730 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
1732 if (change.after.n_audio() <= change.before.n_audio()) {
1736 /* new audio ports: make sure the audio goes somewhere useful,
1737 unless the user has no-auto-connect selected.
1739 The existing ChanCounts don't matter for this call as they are only
1740 to do with matching input and output indices, and we are only changing
1746 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
1750 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1751 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1752 * @param output_start As \a input_start, but for outputs.
1755 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
1756 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
1758 if (!IO::connecting_legal) {
1762 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
1768 /* If both inputs and outputs are auto-connected to physical ports,
1769 use the max of input and output offsets to ensure auto-connected
1770 port numbers always match up (e.g. the first audio input and the
1771 first audio output of the route will have the same physical
1772 port number). Otherwise just use the lowest input or output
1776 DEBUG_TRACE (DEBUG::Graph,
1777 string_compose("Auto-connect: existing in = %1 out = %2\n",
1778 existing_inputs, existing_outputs));
1780 const bool in_out_physical =
1781 (Config->get_input_auto_connect() & AutoConnectPhysical)
1782 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1785 const ChanCount in_offset = in_out_physical
1786 ? ChanCount::max(existing_inputs, existing_outputs)
1789 const ChanCount out_offset = in_out_physical
1790 ? ChanCount::max(existing_inputs, existing_outputs)
1793 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1794 vector<string> physinputs;
1795 vector<string> physoutputs;
1797 _engine.get_physical_outputs (*t, physoutputs);
1798 _engine.get_physical_inputs (*t, physinputs);
1800 if (!physinputs.empty() && connect_inputs) {
1801 uint32_t nphysical_in = physinputs.size();
1803 DEBUG_TRACE (DEBUG::Graph,
1804 string_compose("There are %1 physical inputs of type %2\n",
1807 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1810 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1811 DEBUG_TRACE (DEBUG::Graph,
1812 string_compose("Get index %1 + %2 % %3 = %4\n",
1813 in_offset.get(*t), i, nphysical_in,
1814 (in_offset.get(*t) + i) % nphysical_in));
1815 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1818 DEBUG_TRACE (DEBUG::Graph,
1819 string_compose("Connect route %1 IN to %2\n",
1820 route->name(), port));
1822 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
1826 ChanCount one_added (*t, 1);
1827 existing_inputs += one_added;
1831 if (!physoutputs.empty()) {
1832 uint32_t nphysical_out = physoutputs.size();
1833 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1836 if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
1837 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1838 } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
1839 /* master bus is audio only */
1840 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1841 port = _master_out->input()->ports().port(*t,
1842 i % _master_out->input()->n_ports().get(*t))->name();
1846 DEBUG_TRACE (DEBUG::Graph,
1847 string_compose("Connect route %1 OUT to %2\n",
1848 route->name(), port));
1850 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
1854 ChanCount one_added (*t, 1);
1855 existing_outputs += one_added;
1861 /** Caller must not hold process lock
1862 * @param name_template string to use for the start of the name, or "" to use "Audio".
1864 list< boost::shared_ptr<AudioTrack> >
1865 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
1866 uint32_t how_many, string name_template)
1868 char track_name[32];
1869 uint32_t track_id = 0;
1871 RouteList new_routes;
1872 list<boost::shared_ptr<AudioTrack> > ret;
1874 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
1877 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1878 error << "cannot find name for new audio track" << endmsg;
1882 boost::shared_ptr<AudioTrack> track;
1885 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1887 if (track->init ()) {
1891 track->use_new_diskstream();
1893 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1894 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1897 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1899 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1900 error << string_compose (
1901 _("cannot configure %1 in/%2 out configuration for new audio track"),
1902 input_channels, output_channels)
1907 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1908 error << string_compose (
1909 _("cannot configure %1 in/%2 out configuration for new audio track"),
1910 input_channels, output_channels)
1917 route_group->add (track);
1920 track->non_realtime_input_change();
1922 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1923 if (Config->get_remote_model() == UserOrdered) {
1924 track->set_remote_control_id (next_control_id());
1927 new_routes.push_back (track);
1928 ret.push_back (track);
1931 catch (failed_constructor &err) {
1932 error << _("Session: could not create new audio track.") << endmsg;
1936 catch (AudioEngine::PortRegistrationFailure& pfe) {
1938 error << pfe.what() << endmsg;
1946 if (!new_routes.empty()) {
1947 add_routes (new_routes, true, true, true);
1953 /** Caller must not hold process lock.
1954 * @param name_template string to use for the start of the name, or "" to use "Bus".
1957 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1960 uint32_t bus_id = 0;
1964 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
1967 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1968 error << "cannot find name for new audio bus" << endmsg;
1973 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1979 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1980 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1983 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1985 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1986 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1987 input_channels, output_channels)
1993 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1994 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1995 input_channels, output_channels)
2002 route_group->add (bus);
2004 if (Config->get_remote_model() == UserOrdered) {
2005 bus->set_remote_control_id (next_control_id());
2008 bus->add_internal_return ();
2010 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);
2243 if (_monitor_out && IO::connecting_legal) {
2244 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2246 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2247 if ((*x)->is_monitor()) {
2249 } else if ((*x)->is_master()) {
2252 (*x)->enable_monitor_send ();
2259 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2261 boost::shared_ptr<RouteList> r = routes.reader ();
2262 boost::shared_ptr<Send> s;
2264 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2265 if ((s = (*i)->internal_send_for (dest)) != 0) {
2266 s->amp()->gain_control()->set_value (0.0);
2272 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2274 boost::shared_ptr<RouteList> r = routes.reader ();
2275 boost::shared_ptr<Send> s;
2277 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2278 if ((s = (*i)->internal_send_for (dest)) != 0) {
2279 s->amp()->gain_control()->set_value (1.0);
2285 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2287 boost::shared_ptr<RouteList> r = routes.reader ();
2288 boost::shared_ptr<Send> s;
2290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2291 if ((s = (*i)->internal_send_for (dest)) != 0) {
2292 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2297 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2299 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2301 boost::shared_ptr<RouteList> r = routes.reader ();
2302 boost::shared_ptr<RouteList> t (new RouteList);
2304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2305 /* no MIDI sends because there are no MIDI busses yet */
2306 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2311 add_internal_sends (dest, p, t);
2315 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2317 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2318 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2323 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2325 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2329 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2331 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2335 if (!dest->internal_return()) {
2336 dest->add_internal_return ();
2339 sender->add_aux_send (dest, before);
2345 Session::remove_route (boost::shared_ptr<Route> route)
2347 if (route == _master_out) {
2351 route->set_solo (false, this);
2354 RCUWriter<RouteList> writer (routes);
2355 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2359 /* deleting the master out seems like a dumb
2360 idea, but its more of a UI policy issue
2364 if (route == _master_out) {
2365 _master_out = boost::shared_ptr<Route> ();
2368 if (route == _monitor_out) {
2369 _monitor_out.reset ();
2372 /* writer goes out of scope, forces route list update */
2375 update_route_solo_state ();
2377 // We need to disconnect the route's inputs and outputs
2379 route->input()->disconnect (0);
2380 route->output()->disconnect (0);
2382 /* if the route had internal sends sending to it, remove them */
2383 if (route->internal_return()) {
2385 boost::shared_ptr<RouteList> r = routes.reader ();
2386 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2387 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2389 (*i)->remove_processor (s);
2394 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2395 if (mt && mt->step_editing()) {
2396 if (_step_editors > 0) {
2401 update_latency_compensation ();
2404 /* Re-sort routes to remove the graph's current references to the one that is
2405 * going away, then flush old references out of the graph.
2409 if (_process_graph) {
2410 _process_graph->clear_other_chain ();
2413 /* get rid of it from the dead wood collection in the route list manager */
2415 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2419 /* try to cause everyone to drop their references */
2421 route->drop_references ();
2423 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2425 /* save the new state of the world */
2427 if (save_state (_current_snapshot_name)) {
2428 save_history (_current_snapshot_name);
2433 Session::route_mute_changed (void* /*src*/)
2439 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2441 boost::shared_ptr<Route> route = wpr.lock();
2443 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2447 if (route->listening_via_monitor ()) {
2449 if (Config->get_exclusive_solo()) {
2450 /* new listen: disable all other listen */
2451 boost::shared_ptr<RouteList> r = routes.reader ();
2452 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2453 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2456 (*i)->set_listen (false, this);
2462 } else if (_listen_cnt > 0) {
2467 update_route_solo_state ();
2470 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2472 boost::shared_ptr<Route> route = wpr.lock ();
2475 /* should not happen */
2476 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2480 bool send_changed = false;
2482 if (route->solo_isolated()) {
2483 if (_solo_isolated_cnt == 0) {
2484 send_changed = true;
2486 _solo_isolated_cnt++;
2487 } else if (_solo_isolated_cnt > 0) {
2488 _solo_isolated_cnt--;
2489 if (_solo_isolated_cnt == 0) {
2490 send_changed = true;
2495 IsolatedChanged (); /* EMIT SIGNAL */
2500 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2502 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
2504 if (!self_solo_change) {
2505 // session doesn't care about changes to soloed-by-others
2509 if (solo_update_disabled) {
2511 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
2515 boost::shared_ptr<Route> route = wpr.lock ();
2518 boost::shared_ptr<RouteList> r = routes.reader ();
2521 if (route->self_soloed()) {
2527 RouteGroup* rg = route->route_group ();
2528 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
2530 if (delta == 1 && Config->get_exclusive_solo()) {
2532 /* new solo: disable all other solos, but not the group if its solo-enabled */
2534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2535 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2536 (leave_group_alone && ((*i)->route_group() == rg))) {
2539 (*i)->set_solo (false, this);
2543 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
2545 solo_update_disabled = true;
2547 RouteList uninvolved;
2549 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
2551 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2552 bool via_sends_only;
2553 bool in_signal_flow;
2555 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2556 (leave_group_alone && ((*i)->route_group() == rg))) {
2560 in_signal_flow = false;
2562 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
2564 if ((*i)->feeds (route, &via_sends_only)) {
2565 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
2566 if (!via_sends_only) {
2567 if (!route->soloed_by_others_upstream()) {
2568 (*i)->mod_solo_by_others_downstream (delta);
2571 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
2573 in_signal_flow = true;
2575 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
2578 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
2580 if (route->feeds (*i, &via_sends_only)) {
2581 /* propagate solo upstream only if routing other than
2582 sends is involved, but do consider the other route
2583 (*i) to be part of the signal flow even if only
2586 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
2590 route->soloed_by_others_downstream(),
2591 route->soloed_by_others_upstream()));
2592 if (!via_sends_only) {
2593 if (!route->soloed_by_others_downstream()) {
2594 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
2595 (*i)->mod_solo_by_others_upstream (delta);
2597 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
2600 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
2602 in_signal_flow = true;
2604 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
2607 if (!in_signal_flow) {
2608 uninvolved.push_back (*i);
2612 solo_update_disabled = false;
2613 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
2615 update_route_solo_state (r);
2617 /* now notify that the mute state of the routes not involved in the signal
2618 pathway of the just-solo-changed route may have altered.
2621 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2622 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
2623 (*i)->mute_changed (this);
2626 SoloChanged (); /* EMIT SIGNAL */
2631 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2633 /* now figure out if anything that matters is soloed (or is "listening")*/
2635 bool something_soloed = false;
2636 uint32_t listeners = 0;
2637 uint32_t isolated = 0;
2640 r = routes.reader();
2643 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2644 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2645 something_soloed = true;
2648 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2649 if (Config->get_solo_control_is_listen_control()) {
2652 (*i)->set_listen (false, this);
2656 if ((*i)->solo_isolated()) {
2661 if (something_soloed != _non_soloed_outs_muted) {
2662 _non_soloed_outs_muted = something_soloed;
2663 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2666 _listen_cnt = listeners;
2668 if (isolated != _solo_isolated_cnt) {
2669 _solo_isolated_cnt = isolated;
2670 IsolatedChanged (); /* EMIT SIGNAL */
2673 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
2674 something_soloed, listeners, isolated));
2677 boost::shared_ptr<RouteList>
2678 Session::get_routes_with_internal_returns() const
2680 boost::shared_ptr<RouteList> r = routes.reader ();
2681 boost::shared_ptr<RouteList> rl (new RouteList);
2683 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2684 if ((*i)->internal_return ()) {
2692 Session::io_name_is_legal (const std::string& name)
2694 boost::shared_ptr<RouteList> r = routes.reader ();
2696 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2697 if ((*i)->name() == name) {
2701 if ((*i)->has_io_processor_named (name)) {
2710 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
2713 vector<string> connections;
2715 /* if we are passed only a single route and we're not told to turn
2716 * others off, then just do the simple thing.
2719 if (flip_others == false && rl->size() == 1) {
2720 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
2722 mt->set_input_active (onoff);
2727 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
2729 PortSet& ps ((*rt)->input()->ports());
2731 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
2732 p->get_connections (connections);
2735 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
2736 routes_using_input_from (*s, rl2);
2739 /* scan all relevant routes to see if others are on or off */
2741 bool others_are_already_on = false;
2743 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2745 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2751 if ((*r) != (*rt)) {
2752 if (mt->input_active()) {
2753 others_are_already_on = true;
2756 /* this one needs changing */
2757 mt->set_input_active (onoff);
2763 /* globally reverse other routes */
2765 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2766 if ((*r) != (*rt)) {
2767 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2769 mt->set_input_active (!others_are_already_on);
2778 Session::routes_using_input_from (const string& str, RouteList& rl)
2780 boost::shared_ptr<RouteList> r = routes.reader();
2782 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2783 if ((*i)->input()->connected_to (str)) {
2789 boost::shared_ptr<Route>
2790 Session::route_by_name (string name)
2792 boost::shared_ptr<RouteList> r = routes.reader ();
2794 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2795 if ((*i)->name() == name) {
2800 return boost::shared_ptr<Route> ((Route*) 0);
2803 boost::shared_ptr<Route>
2804 Session::route_by_id (PBD::ID id)
2806 boost::shared_ptr<RouteList> r = routes.reader ();
2808 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2809 if ((*i)->id() == id) {
2814 return boost::shared_ptr<Route> ((Route*) 0);
2817 boost::shared_ptr<Track>
2818 Session::track_by_diskstream_id (PBD::ID id)
2820 boost::shared_ptr<RouteList> r = routes.reader ();
2822 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2823 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
2824 if (t && t->using_diskstream_id (id)) {
2829 return boost::shared_ptr<Track> ();
2832 boost::shared_ptr<Route>
2833 Session::route_by_remote_id (uint32_t id)
2835 boost::shared_ptr<RouteList> r = routes.reader ();
2837 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2838 if ((*i)->remote_control_id() == id) {
2843 return boost::shared_ptr<Route> ((Route*) 0);
2847 Session::playlist_region_added (boost::weak_ptr<Region> w)
2849 boost::shared_ptr<Region> r = w.lock ();
2854 /* These are the operations that are currently in progress... */
2855 list<GQuark> curr = _current_trans_quarks;
2858 /* ...and these are the operations during which we want to update
2859 the session range location markers.
2862 ops.push_back (Operations::capture);
2863 ops.push_back (Operations::paste);
2864 ops.push_back (Operations::duplicate_region);
2865 ops.push_back (Operations::insert_file);
2866 ops.push_back (Operations::insert_region);
2867 ops.push_back (Operations::drag_region_brush);
2868 ops.push_back (Operations::region_drag);
2869 ops.push_back (Operations::selection_grab);
2870 ops.push_back (Operations::region_fill);
2871 ops.push_back (Operations::fill_selection);
2872 ops.push_back (Operations::create_region);
2873 ops.push_back (Operations::region_copy);
2874 ops.push_back (Operations::fixed_time_region_copy);
2877 /* See if any of the current operations match the ones that we want */
2879 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2881 /* If so, update the session range markers */
2883 maybe_update_session_range (r->position (), r->last_frame ());
2887 /** Update the session range markers if a is before the current start or
2888 * b is after the current end.
2891 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2893 if (_state_of_the_state & Loading) {
2897 if (_session_range_location == 0) {
2899 add_session_range_location (a, b);
2903 if (a < _session_range_location->start()) {
2904 _session_range_location->set_start (a);
2907 if (b > _session_range_location->end()) {
2908 _session_range_location->set_end (b);
2914 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2916 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2917 maybe_update_session_range (i->to, i->to + i->length);
2922 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2924 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2925 maybe_update_session_range (i->from, i->to);
2929 /* Region management */
2931 boost::shared_ptr<Region>
2932 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2934 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2935 RegionFactory::RegionMap::const_iterator i;
2936 boost::shared_ptr<Region> region;
2938 Glib::Threads::Mutex::Lock lm (region_lock);
2940 for (i = regions.begin(); i != regions.end(); ++i) {
2944 if (region->whole_file()) {
2946 if (child->source_equivalent (region)) {
2952 return boost::shared_ptr<Region> ();
2956 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2958 set<boost::shared_ptr<Region> > relevant_regions;
2960 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2961 RegionFactory::get_regions_using_source (*s, relevant_regions);
2964 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2965 set<boost::shared_ptr<Region> >::iterator tmp;
2970 playlists->destroy_region (*r);
2971 RegionFactory::map_remove (*r);
2973 (*r)->drop_sources ();
2974 (*r)->drop_references ();
2976 relevant_regions.erase (r);
2981 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2984 Glib::Threads::Mutex::Lock ls (source_lock);
2985 /* remove from the main source list */
2986 sources.erase ((*s)->id());
2989 (*s)->mark_for_remove ();
2990 (*s)->drop_references ();
2999 Session::remove_last_capture ()
3001 list<boost::shared_ptr<Source> > srcs;
3003 boost::shared_ptr<RouteList> rl = routes.reader ();
3004 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3005 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3010 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
3013 srcs.insert (srcs.end(), l.begin(), l.end());
3018 destroy_sources (srcs);
3020 save_state (_current_snapshot_name);
3025 /* Source Management */
3028 Session::add_source (boost::shared_ptr<Source> source)
3030 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3031 pair<SourceMap::iterator,bool> result;
3033 entry.first = source->id();
3034 entry.second = source;
3037 Glib::Threads::Mutex::Lock lm (source_lock);
3038 result = sources.insert (entry);
3041 if (result.second) {
3043 /* yay, new source */
3045 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3048 if (!fs->within_session()) {
3049 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3055 boost::shared_ptr<AudioFileSource> afs;
3057 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3058 if (Config->get_auto_analyse_audio()) {
3059 Analyser::queue_source_for_analysis (source, false);
3063 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3068 Session::remove_source (boost::weak_ptr<Source> src)
3070 if (_state_of_the_state & Deletion) {
3074 SourceMap::iterator i;
3075 boost::shared_ptr<Source> source = src.lock();
3082 Glib::Threads::Mutex::Lock lm (source_lock);
3084 if ((i = sources.find (source->id())) != sources.end()) {
3089 if (!(_state_of_the_state & InCleanup)) {
3091 /* save state so we don't end up with a session file
3092 referring to non-existent sources.
3095 save_state (_current_snapshot_name);
3099 boost::shared_ptr<Source>
3100 Session::source_by_id (const PBD::ID& id)
3102 Glib::Threads::Mutex::Lock lm (source_lock);
3103 SourceMap::iterator i;
3104 boost::shared_ptr<Source> source;
3106 if ((i = sources.find (id)) != sources.end()) {
3113 boost::shared_ptr<Source>
3114 Session::source_by_path_and_channel (const string& path, uint16_t chn)
3116 Glib::Threads::Mutex::Lock lm (source_lock);
3118 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3119 boost::shared_ptr<AudioFileSource> afs
3120 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3122 if (afs && afs->path() == path && chn == afs->channel()) {
3126 return boost::shared_ptr<Source>();
3130 Session::count_sources_by_origin (const string& path)
3133 Glib::Threads::Mutex::Lock lm (source_lock);
3135 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3136 boost::shared_ptr<FileSource> fs
3137 = boost::dynamic_pointer_cast<FileSource>(i->second);
3139 if (fs && fs->origin() == path) {
3149 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3152 string old_basename = PBD::basename_nosuffix (oldname);
3153 string new_legalized = legalize_for_path (newname);
3155 /* note: we know (or assume) the old path is already valid */
3159 /* destructive file sources have a name of the form:
3161 /path/to/Tnnnn-NAME(%[LR])?.wav
3163 the task here is to replace NAME with the new name.
3168 string::size_type dash;
3170 dir = Glib::path_get_dirname (path);
3171 path = Glib::path_get_basename (path);
3173 /* '-' is not a legal character for the NAME part of the path */
3175 if ((dash = path.find_last_of ('-')) == string::npos) {
3179 prefix = path.substr (0, dash);
3183 path += new_legalized;
3184 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3185 path = Glib::build_filename (dir, path);
3189 /* non-destructive file sources have a name of the form:
3191 /path/to/NAME-nnnnn(%[LR])?.ext
3193 the task here is to replace NAME with the new name.
3198 string::size_type dash;
3199 string::size_type postfix;
3201 dir = Glib::path_get_dirname (path);
3202 path = Glib::path_get_basename (path);
3204 /* '-' is not a legal character for the NAME part of the path */
3206 if ((dash = path.find_last_of ('-')) == string::npos) {
3210 suffix = path.substr (dash+1);
3212 // Suffix is now everything after the dash. Now we need to eliminate
3213 // the nnnnn part, which is done by either finding a '%' or a '.'
3215 postfix = suffix.find_last_of ("%");
3216 if (postfix == string::npos) {
3217 postfix = suffix.find_last_of ('.');
3220 if (postfix != string::npos) {
3221 suffix = suffix.substr (postfix);
3223 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3227 const uint32_t limit = 10000;
3228 char buf[PATH_MAX+1];
3230 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3232 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
3234 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
3235 path = Glib::build_filename (dir, buf);
3243 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
3252 /** Return the full path (in some session directory) for a new within-session source.
3253 * \a name must be a session-unique name that does not contain slashes
3254 * (e.g. as returned by new_*_source_name)
3257 Session::new_source_path_from_name (DataType type, const string& name)
3259 assert(name.find("/") == string::npos);
3261 SessionDirectory sdir(get_best_session_directory_for_new_source());
3264 if (type == DataType::AUDIO) {
3265 p = sdir.sound_path();
3266 } else if (type == DataType::MIDI) {
3267 p = sdir.midi_path();
3269 error << "Unknown source type, unable to create file path" << endmsg;
3273 return Glib::build_filename (p, name);
3277 Session::peak_path (string base) const
3279 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3282 /** Return a unique name based on \a base for a new internal audio source */
3284 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3287 char buf[PATH_MAX+1];
3288 const uint32_t limit = 10000;
3290 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3293 legalized = legalize_for_path (base);
3295 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3296 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3298 vector<space_and_path>::iterator i;
3299 uint32_t existing = 0;
3301 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3306 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3307 cnt, legalized.c_str(), ext.c_str());
3308 } else if (nchan == 2) {
3310 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
3311 cnt, legalized.c_str(), ext.c_str());
3313 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
3314 cnt, legalized.c_str(), ext.c_str());
3316 } else if (nchan < 26) {
3317 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
3318 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
3320 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3321 cnt, legalized.c_str(), ext.c_str());
3327 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3328 } else if (nchan == 2) {
3330 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
3332 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
3334 } else if (nchan < 26) {
3335 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
3337 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3341 SessionDirectory sdir((*i).path);
3343 string spath = sdir.sound_path();
3345 /* note that we search *without* the extension so that
3346 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3347 in the event that this new name is required for
3348 a file format change.
3351 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
3357 if (existing == 0) {
3362 error << string_compose(
3363 _("There are already %1 recordings for %2, which I consider too many."),
3364 limit, base) << endmsg;
3366 throw failed_constructor();
3370 return Glib::path_get_basename (buf);
3373 /** Create a new within-session audio source */
3374 boost::shared_ptr<AudioFileSource>
3375 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3377 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3378 const string path = new_source_path_from_name(DataType::AUDIO, name);
3380 return boost::dynamic_pointer_cast<AudioFileSource> (
3381 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3384 /** Return a unique name based on \a base for a new internal MIDI source */
3386 Session::new_midi_source_name (const string& base)
3389 char buf[PATH_MAX+1];
3390 const uint32_t limit = 10000;
3394 legalized = legalize_for_path (base);
3396 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3397 for (cnt = 1; cnt <= limit; ++cnt) {
3399 vector<space_and_path>::iterator i;
3400 uint32_t existing = 0;
3402 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3404 SessionDirectory sdir((*i).path);
3406 std::string p = Glib::build_filename (sdir.midi_path(), legalized);
3408 snprintf (buf, sizeof(buf), "%s-%u.mid", p.c_str(), cnt);
3410 if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3415 if (existing == 0) {
3420 error << string_compose(
3421 _("There are already %1 recordings for %2, which I consider too many."),
3422 limit, base) << endmsg;
3424 throw failed_constructor();
3428 return Glib::path_get_basename(buf);
3432 /** Create a new within-session MIDI source */
3433 boost::shared_ptr<MidiSource>
3434 Session::create_midi_source_for_session (Track* track, string const & n)
3436 /* try to use the existing write source for the track, to keep numbering sane
3440 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3444 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3447 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3448 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3452 const string name = new_midi_source_name (n);
3453 const string path = new_source_path_from_name (DataType::MIDI, name);
3455 return boost::dynamic_pointer_cast<SMFSource> (
3456 SourceFactory::createWritable (
3457 DataType::MIDI, *this, path, string(), false, frame_rate()));
3462 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3464 if (playlist->hidden()) {
3468 playlists->add (playlist);
3471 playlist->release();
3478 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3480 if (_state_of_the_state & Deletion) {
3484 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3490 playlists->remove (playlist);
3496 Session::set_audition (boost::shared_ptr<Region> r)
3498 pending_audition_region = r;
3499 add_post_transport_work (PostTransportAudition);
3500 _butler->schedule_transport_work ();
3504 Session::audition_playlist ()
3506 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3507 ev->region.reset ();
3512 Session::non_realtime_set_audition ()
3514 assert (pending_audition_region);
3515 auditioner->audition_region (pending_audition_region);
3516 pending_audition_region.reset ();
3517 AuditionActive (true); /* EMIT SIGNAL */
3521 Session::audition_region (boost::shared_ptr<Region> r)
3523 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3529 Session::cancel_audition ()
3531 if (auditioner->auditioning()) {
3532 auditioner->cancel_audition ();
3533 AuditionActive (false); /* EMIT SIGNAL */
3538 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3540 if (a->is_monitor()) {
3543 if (b->is_monitor()) {
3546 return a->order_key (MixerSort) < b->order_key (MixerSort);
3550 Session::is_auditioning () const
3552 /* can be called before we have an auditioner object */
3554 return auditioner->auditioning();
3561 Session::graph_reordered ()
3563 /* don't do this stuff if we are setting up connections
3564 from a set_state() call or creating new tracks. Ditto for deletion.
3567 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
3571 /* every track/bus asked for this to be handled but it was deferred because
3572 we were connecting. do it now.
3575 request_input_change_handling ();
3579 /* force all diskstreams to update their capture offset values to
3580 reflect any changes in latencies within the graph.
3583 boost::shared_ptr<RouteList> rl = routes.reader ();
3584 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3585 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3587 tr->set_capture_offset ();
3592 /** @return Number of frames that there is disk space available to write,
3595 boost::optional<framecnt_t>
3596 Session::available_capture_duration ()
3598 Glib::Threads::Mutex::Lock lm (space_lock);
3600 if (_total_free_4k_blocks_uncertain) {
3601 return boost::optional<framecnt_t> ();
3604 float sample_bytes_on_disk = 4.0; // keep gcc happy
3606 switch (config.get_native_file_data_format()) {
3608 sample_bytes_on_disk = 4.0;
3612 sample_bytes_on_disk = 3.0;
3616 sample_bytes_on_disk = 2.0;
3620 /* impossible, but keep some gcc versions happy */
3621 fatal << string_compose (_("programming error: %1"),
3622 X_("illegal native file data format"))
3627 double scale = 4096.0 / sample_bytes_on_disk;
3629 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3630 return max_framecnt;
3633 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3637 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3640 RCUWriter<BundleList> writer (_bundles);
3641 boost::shared_ptr<BundleList> b = writer.get_copy ();
3642 b->push_back (bundle);
3645 BundleAdded (bundle); /* EMIT SIGNAL */
3651 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3653 bool removed = false;
3656 RCUWriter<BundleList> writer (_bundles);
3657 boost::shared_ptr<BundleList> b = writer.get_copy ();
3658 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3660 if (i != b->end()) {
3667 BundleRemoved (bundle); /* EMIT SIGNAL */
3673 boost::shared_ptr<Bundle>
3674 Session::bundle_by_name (string name) const
3676 boost::shared_ptr<BundleList> b = _bundles.reader ();
3678 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3679 if ((*i)->name() == name) {
3684 return boost::shared_ptr<Bundle> ();
3688 Session::tempo_map_changed (const PropertyChange&)
3692 playlists->update_after_tempo_map_change ();
3694 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3700 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3702 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3703 (*i)->recompute_frames_from_bbt ();
3707 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3708 * the given count with the current block size.
3711 Session::ensure_buffers (ChanCount howmany)
3713 BufferManager::ensure_buffers (howmany);
3717 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3719 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3720 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3725 Session::next_insert_id ()
3727 /* this doesn't really loop forever. just think about it */
3730 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3731 if (!insert_bitset[n]) {
3732 insert_bitset[n] = true;
3738 /* none available, so resize and try again */
3740 insert_bitset.resize (insert_bitset.size() + 16, false);
3745 Session::next_send_id ()
3747 /* this doesn't really loop forever. just think about it */
3750 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3751 if (!send_bitset[n]) {
3752 send_bitset[n] = true;
3758 /* none available, so resize and try again */
3760 send_bitset.resize (send_bitset.size() + 16, false);
3765 Session::next_aux_send_id ()
3767 /* this doesn't really loop forever. just think about it */
3770 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
3771 if (!aux_send_bitset[n]) {
3772 aux_send_bitset[n] = true;
3778 /* none available, so resize and try again */
3780 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
3785 Session::next_return_id ()
3787 /* this doesn't really loop forever. just think about it */
3790 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3791 if (!return_bitset[n]) {
3792 return_bitset[n] = true;
3798 /* none available, so resize and try again */
3800 return_bitset.resize (return_bitset.size() + 16, false);
3805 Session::mark_send_id (uint32_t id)
3807 if (id >= send_bitset.size()) {
3808 send_bitset.resize (id+16, false);
3810 if (send_bitset[id]) {
3811 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3813 send_bitset[id] = true;
3817 Session::mark_aux_send_id (uint32_t id)
3819 if (id >= aux_send_bitset.size()) {
3820 aux_send_bitset.resize (id+16, false);
3822 if (aux_send_bitset[id]) {
3823 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
3825 aux_send_bitset[id] = true;
3829 Session::mark_return_id (uint32_t id)
3831 if (id >= return_bitset.size()) {
3832 return_bitset.resize (id+16, false);
3834 if (return_bitset[id]) {
3835 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3837 return_bitset[id] = true;
3841 Session::mark_insert_id (uint32_t id)
3843 if (id >= insert_bitset.size()) {
3844 insert_bitset.resize (id+16, false);
3846 if (insert_bitset[id]) {
3847 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3849 insert_bitset[id] = true;
3853 Session::unmark_send_id (uint32_t id)
3855 if (id < send_bitset.size()) {
3856 send_bitset[id] = false;
3861 Session::unmark_aux_send_id (uint32_t id)
3863 if (id < aux_send_bitset.size()) {
3864 aux_send_bitset[id] = false;
3869 Session::unmark_return_id (uint32_t id)
3871 if (id < return_bitset.size()) {
3872 return_bitset[id] = false;
3877 Session::unmark_insert_id (uint32_t id)
3879 if (id < insert_bitset.size()) {
3880 insert_bitset[id] = false;
3885 Session::reset_native_file_format ()
3887 boost::shared_ptr<RouteList> rl = routes.reader ();
3888 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3889 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3891 /* don't save state as we do this, there's no point
3894 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3895 tr->reset_write_sources (false);
3896 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3902 Session::route_name_unique (string n) const
3904 boost::shared_ptr<RouteList> r = routes.reader ();
3906 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3907 if ((*i)->name() == n) {
3916 Session::route_name_internal (string n) const
3918 if (auditioner && auditioner->name() == n) {
3922 if (_click_io && _click_io->name() == n) {
3930 Session::freeze_all (InterThreadInfo& itt)
3932 boost::shared_ptr<RouteList> r = routes.reader ();
3934 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3936 boost::shared_ptr<Track> t;
3938 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3939 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3949 boost::shared_ptr<Region>
3950 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3951 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3952 InterThreadInfo& itt,
3953 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
3956 boost::shared_ptr<Region> result;
3957 boost::shared_ptr<Playlist> playlist;
3958 boost::shared_ptr<AudioFileSource> fsource;
3960 char buf[PATH_MAX+1];
3961 ChanCount diskstream_channels (track.n_channels());
3962 framepos_t position;
3963 framecnt_t this_chunk;
3966 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3967 const string sound_dir = sdir.sound_path();
3968 framepos_t len = end - start;
3969 bool need_block_size_reset = false;
3971 ChanCount const max_proc = track.max_processor_streams ();
3974 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3975 end, start) << endmsg;
3979 const framecnt_t chunk_size = (256 * 1024)/4;
3981 // block all process callback handling
3983 block_processing ();
3985 /* call tree *MUST* hold route_lock */
3987 if ((playlist = track.playlist()) == 0) {
3991 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3993 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3995 for (x = 0; x < 99999; ++x) {
3996 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());
3997 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
4003 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4008 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4009 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
4012 catch (failed_constructor& err) {
4013 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4017 srcs.push_back (fsource);
4020 /* tell redirects that care that we are about to use a much larger
4021 * blocksize. this will flush all plugins too, so that they are ready
4022 * to be used for this process.
4025 need_block_size_reset = true;
4026 track.set_block_size (chunk_size);
4031 /* create a set of reasonably-sized buffers */
4032 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
4033 buffers.set_count (max_proc);
4035 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4036 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4038 afs->prepare_for_peakfile_writes ();
4041 while (to_do && !itt.cancel) {
4043 this_chunk = min (to_do, chunk_size);
4045 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export)) {
4050 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4051 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4054 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4060 start += this_chunk;
4061 to_do -= this_chunk;
4063 itt.progress = (float) (1.0 - ((double) to_do / len));
4072 xnow = localtime (&now);
4074 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4075 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4078 afs->update_header (position, *xnow, now);
4079 afs->flush_header ();
4083 /* construct a region to represent the bounced material */
4087 plist.add (Properties::start, 0);
4088 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4089 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4091 result = RegionFactory::create (srcs, plist);
4097 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4098 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4101 afs->mark_for_remove ();
4104 (*src)->drop_references ();
4108 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4109 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4112 afs->done_with_peakfile_writes ();
4117 if (need_block_size_reset) {
4118 track.set_block_size (get_block_size());
4121 unblock_processing ();
4127 Session::gain_automation_buffer() const
4129 return ProcessThread::gain_automation_buffer ();
4133 Session::send_gain_automation_buffer() const
4135 return ProcessThread::send_gain_automation_buffer ();
4139 Session::pan_automation_buffer() const
4141 return ProcessThread::pan_automation_buffer ();
4145 Session::get_silent_buffers (ChanCount count)
4147 return ProcessThread::get_silent_buffers (count);
4151 Session::get_scratch_buffers (ChanCount count)
4153 return ProcessThread::get_scratch_buffers (count);
4157 Session::get_mix_buffers (ChanCount count)
4159 return ProcessThread::get_mix_buffers (count);
4163 Session::ntracks () const
4166 boost::shared_ptr<RouteList> r = routes.reader ();
4168 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4169 if (boost::dynamic_pointer_cast<Track> (*i)) {
4178 Session::nbusses () const
4181 boost::shared_ptr<RouteList> r = routes.reader ();
4183 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4184 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4193 Session::add_automation_list(AutomationList *al)
4195 automation_lists[al->id()] = al;
4198 /** @return true if there is at least one record-enabled track, otherwise false */
4200 Session::have_rec_enabled_track () const
4202 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
4205 /** Update the state of our rec-enabled tracks flag */
4207 Session::update_have_rec_enabled_track ()
4209 boost::shared_ptr<RouteList> rl = routes.reader ();
4210 RouteList::iterator i = rl->begin();
4211 while (i != rl->end ()) {
4213 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4214 if (tr && tr->record_enabled ()) {
4221 int const old = g_atomic_int_get (&_have_rec_enabled_track);
4223 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
4225 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
4226 RecordStateChanged (); /* EMIT SIGNAL */
4231 Session::listen_position_changed ()
4233 boost::shared_ptr<RouteList> r = routes.reader ();
4235 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4236 (*i)->listen_position_changed ();
4241 Session::solo_control_mode_changed ()
4243 /* cancel all solo or all listen when solo control mode changes */
4246 set_solo (get_routes(), false);
4247 } else if (listening()) {
4248 set_listen (get_routes(), false);
4252 /** Called when a property of one of our route groups changes */
4254 Session::route_group_property_changed (RouteGroup* rg)
4256 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
4259 /** Called when a route is added to one of our route groups */
4261 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4263 RouteAddedToRouteGroup (rg, r);
4266 /** Called when a route is removed from one of our route groups */
4268 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4270 RouteRemovedFromRouteGroup (rg, r);
4273 boost::shared_ptr<RouteList>
4274 Session::get_routes_with_regions_at (framepos_t const p) const
4276 boost::shared_ptr<RouteList> r = routes.reader ();
4277 boost::shared_ptr<RouteList> rl (new RouteList);
4279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4280 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4285 boost::shared_ptr<Playlist> pl = tr->playlist ();
4290 if (pl->has_region_at (p)) {
4299 Session::goto_end ()
4301 if (_session_range_location) {
4302 request_locate (_session_range_location->end(), false);
4304 request_locate (0, false);
4309 Session::goto_start ()
4311 if (_session_range_location) {
4312 request_locate (_session_range_location->start(), false);
4314 request_locate (0, false);
4319 Session::current_start_frame () const
4321 return _session_range_location ? _session_range_location->start() : 0;
4325 Session::current_end_frame () const
4327 return _session_range_location ? _session_range_location->end() : 0;
4331 Session::add_session_range_location (framepos_t start, framepos_t end)
4333 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4334 _locations->add (_session_range_location);
4338 Session::step_edit_status_change (bool yn)
4344 send = (_step_editors == 0);
4349 send = (_step_editors == 1);
4352 if (_step_editors > 0) {
4358 StepEditStatusChange (val);
4364 Session::start_time_changed (framepos_t old)
4366 /* Update the auto loop range to match the session range
4367 (unless the auto loop range has been changed by the user)
4370 Location* s = _locations->session_range_location ();
4375 Location* l = _locations->auto_loop_location ();
4377 if (l && l->start() == old) {
4378 l->set_start (s->start(), true);
4383 Session::end_time_changed (framepos_t old)
4385 /* Update the auto loop range to match the session range
4386 (unless the auto loop range has been changed by the user)
4389 Location* s = _locations->session_range_location ();
4394 Location* l = _locations->auto_loop_location ();
4396 if (l && l->end() == old) {
4397 l->set_end (s->end(), true);
4402 Session::source_search_path (DataType type) const
4406 if (session_dirs.size() == 1) {
4408 case DataType::AUDIO:
4409 s.push_back (_session_dir->sound_path());
4411 case DataType::MIDI:
4412 s.push_back (_session_dir->midi_path());
4416 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4417 SessionDirectory sdir (i->path);
4419 case DataType::AUDIO:
4420 s.push_back (sdir.sound_path());
4422 case DataType::MIDI:
4423 s.push_back (sdir.midi_path());
4429 if (type == DataType::AUDIO) {
4430 const string sound_path_2X = _session_dir->sound_path_2X();
4431 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
4432 if (find (s.begin(), s.end(), sound_path_2X) == s.end()) {
4433 s.push_back (sound_path_2X);
4438 /* now check the explicit (possibly user-specified) search path
4441 vector<string> dirs;
4444 case DataType::AUDIO:
4445 split (config.get_audio_search_path (), dirs, ':');
4447 case DataType::MIDI:
4448 split (config.get_midi_search_path (), dirs, ':');
4452 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4453 if (find (s.begin(), s.end(), *i) == s.end()) {
4460 for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) {
4461 if (!search_path.empty()) {
4471 Session::ensure_search_path_includes (const string& path, DataType type)
4474 vector<string> dirs;
4481 case DataType::AUDIO:
4482 search_path = config.get_audio_search_path ();
4484 case DataType::MIDI:
4485 search_path = config.get_midi_search_path ();
4489 split (search_path, dirs, ':');
4491 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4492 /* No need to add this new directory if it has the same inode as
4493 an existing one; checking inode rather than name prevents duplicated
4494 directories when we are using symlinks.
4496 On Windows, I think we could just do if (*i == path) here.
4498 if (PBD::equivalent_paths (*i, path)) {
4503 if (!search_path.empty()) {
4507 search_path += path;
4510 case DataType::AUDIO:
4511 config.set_audio_search_path (search_path);
4513 case DataType::MIDI:
4514 config.set_midi_search_path (search_path);
4519 boost::shared_ptr<Speakers>
4520 Session::get_speakers()
4526 Session::unknown_processors () const
4530 boost::shared_ptr<RouteList> r = routes.reader ();
4531 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4532 list<string> t = (*i)->unknown_processors ();
4533 copy (t.begin(), t.end(), back_inserter (p));
4543 Session::update_latency (bool playback)
4545 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4547 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
4551 boost::shared_ptr<RouteList> r = routes.reader ();
4552 framecnt_t max_latency = 0;
4555 /* reverse the list so that we work backwards from the last route to run to the first */
4556 RouteList* rl = routes.reader().get();
4557 r.reset (new RouteList (*rl));
4558 reverse (r->begin(), r->end());
4561 /* compute actual latency values for the given direction and store them all in per-port
4562 structures. this will also publish the same values (to JACK) so that computation of latency
4563 for routes can consistently use public latency values.
4566 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4567 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4570 /* because we latency compensate playback, our published playback latencies should
4571 be the same for all output ports - all material played back by ardour has
4572 the same latency, whether its caused by plugins or by latency compensation. since
4573 these may differ from the values computed above, reset all playback port latencies
4577 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4579 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4580 (*i)->set_public_port_latencies (max_latency, playback);
4585 post_playback_latency ();
4589 post_capture_latency ();
4592 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
4596 Session::post_playback_latency ()
4598 set_worst_playback_latency ();
4600 boost::shared_ptr<RouteList> r = routes.reader ();
4602 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4603 if (!(*i)->is_hidden() && ((*i)->active())) {
4604 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
4608 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4609 (*i)->set_latency_compensation (_worst_track_latency);
4614 Session::post_capture_latency ()
4616 set_worst_capture_latency ();
4618 /* reflect any changes in capture latencies into capture offsets
4621 boost::shared_ptr<RouteList> rl = routes.reader();
4622 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4623 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4625 tr->set_capture_offset ();
4631 Session::initialize_latencies ()
4634 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4635 update_latency (false);
4636 update_latency (true);
4639 set_worst_io_latencies ();
4643 Session::set_worst_io_latencies ()
4645 set_worst_playback_latency ();
4646 set_worst_capture_latency ();
4650 Session::set_worst_playback_latency ()
4652 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4656 _worst_output_latency = 0;
4658 if (!_engine.connected()) {
4662 boost::shared_ptr<RouteList> r = routes.reader ();
4664 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4665 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
4668 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
4672 Session::set_worst_capture_latency ()
4674 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4678 _worst_input_latency = 0;
4680 if (!_engine.connected()) {
4684 boost::shared_ptr<RouteList> r = routes.reader ();
4686 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4687 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
4690 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
4694 Session::update_latency_compensation (bool force_whole_graph)
4696 bool some_track_latency_changed = false;
4698 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4702 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
4704 _worst_track_latency = 0;
4706 boost::shared_ptr<RouteList> r = routes.reader ();
4708 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4709 if (!(*i)->is_hidden() && ((*i)->active())) {
4711 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
4712 some_track_latency_changed = true;
4714 _worst_track_latency = max (tl, _worst_track_latency);
4718 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
4719 (some_track_latency_changed ? "yes" : "no")));
4721 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
4723 if (some_track_latency_changed || force_whole_graph) {
4724 _engine.update_latencies ();
4728 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4729 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4733 tr->set_capture_offset ();
4738 Session::session_name_is_legal (const string& path)
4740 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
4742 for (int i = 0; illegal_chars[i]; ++i) {
4743 if (path.find (illegal_chars[i]) != string::npos) {
4744 return illegal_chars[i];
4752 Session::next_control_id () const
4756 /* the monitor bus remote ID is in a different
4757 * "namespace" than regular routes. its existence doesn't
4758 * affect normal (low) numbered routes.
4765 return nroutes() - subtract;
4769 Session::notify_remote_id_change ()
4771 if (deletion_in_progress()) {
4775 switch (Config->get_remote_model()) {
4778 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
4786 Session::sync_order_keys (RouteSortOrderKey sort_key_changed)
4788 if (deletion_in_progress()) {
4792 /* tell everyone that something has happened to the sort keys
4793 and let them sync up with the change(s)
4794 this will give objects that manage the sort order keys the
4795 opportunity to keep them in sync if they wish to.
4798 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("Sync Order Keys, based on %1\n", enum_2_string (sort_key_changed)));
4800 Route::SyncOrderKeys (sort_key_changed); /* EMIT SIGNAL */
4802 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
4806 Session::operation_in_progress (GQuark op) const
4808 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
4811 boost::shared_ptr<Port>
4812 Session::ltc_input_port () const
4814 return _ltc_input->nth (0);
4817 boost::shared_ptr<Port>
4818 Session::ltc_output_port () const
4820 return _ltc_output->nth (0);
4824 Session::reconnect_ltc_input ()
4828 string src = Config->get_ltc_source_port();
4830 _ltc_input->disconnect (this);
4832 if (src != _("None") && !src.empty()) {
4833 _ltc_input->nth (0)->connect (src);
4839 Session::reconnect_ltc_output ()
4844 string src = Config->get_ltc_sink_port();
4846 _ltc_output->disconnect (this);
4848 if (src != _("None") && !src.empty()) {
4849 _ltc_output->nth (0)->connect (src);