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 /* disconnect from any and all signals that we are connected to */
239 _engine.remove_session ();
241 /* deregister all ports - there will be no process or any other
242 * callbacks from the engine any more.
245 Port::PortDrop (); /* EMIT SIGNAL */
251 /* clear history so that no references to objects are held any more */
255 /* clear state tree so that no references to objects are held any more */
259 /* reset dynamic state version back to default */
261 Stateful::loading_state_version = 0;
263 _butler->drop_references ();
267 delete midi_control_ui;
268 delete _all_route_group;
270 if (click_data != default_click) {
271 delete [] click_data;
274 if (click_emphasis_data != default_click_emphasis) {
275 delete [] click_emphasis_data;
280 /* clear out any pending dead wood from RCU managed objects */
285 AudioDiskstream::free_working_buffers();
287 /* tell everyone who is still standing that we're about to die */
290 /* tell everyone to drop references and delete objects as we go */
292 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
293 RegionFactory::delete_all_regions ();
295 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
297 /* reset these three references to special routes before we do the usual route delete thing */
300 _master_out.reset ();
301 _monitor_out.reset ();
304 RCUWriter<RouteList> writer (routes);
305 boost::shared_ptr<RouteList> r = writer.get_copy ();
307 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
308 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
309 (*i)->drop_references ();
313 /* writer goes out of scope and updates master */
317 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
318 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
319 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
320 i->second->drop_references ();
325 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
326 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
331 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
336 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
338 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
339 boost_debug_list_ptrs ();
344 Session::when_engine_running ()
346 string first_physical_output;
348 BootMessage (_("Set block size and sample rate"));
350 set_block_size (_engine.frames_per_cycle());
351 set_frame_rate (_engine.frame_rate());
353 BootMessage (_("Using configuration"));
355 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
356 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
358 Config->map_parameters (ff);
359 config.map_parameters (ft);
361 /* every time we reconnect, recompute worst case output latencies */
363 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
365 if (synced_to_jack()) {
366 _engine.transport_stop ();
369 if (config.get_jack_time_master()) {
370 _engine.transport_locate (_transport_frame);
378 _ltc_input.reset (new IO (*this, _("LTC In"), IO::Input));
379 _ltc_output.reset (new IO (*this, _("LTC Out"), IO::Output));
381 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-In")) != 0) {
382 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
385 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
386 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
388 reconnect_ltc_input ();
391 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-Out")) != 0) {
392 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
395 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
396 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
398 reconnect_ltc_output ();
401 /* fix up names of LTC ports because we don't want the normal
402 * IO style of NAME/TYPE-{in,out}N
405 _ltc_input->nth (0)->set_name (_("LTC-in"));
406 _ltc_output->nth (0)->set_name (_("LTC-out"));
408 _click_io.reset (new ClickIO (*this, "click"));
409 _click_gain.reset (new Amp (*this));
410 _click_gain->activate ();
412 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
414 /* existing state for Click */
417 if (Stateful::loading_state_version < 3000) {
418 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
420 const XMLNodeList& children (child->children());
421 XMLNodeList::const_iterator i = children.begin();
422 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
424 if (i != children.end()) {
425 c = _click_gain->set_state (**i, Stateful::loading_state_version);
431 _clicking = Config->get_clicking ();
435 error << _("could not setup Click I/O") << endmsg;
442 /* default state for Click: dual-mono to first 2 physical outputs */
445 _engine.get_physical_outputs (DataType::AUDIO, outs);
447 for (uint32_t physport = 0; physport < 2; ++physport) {
448 if (outs.size() > physport) {
449 if (_click_io->add_port (outs[physport], this)) {
450 // relax, even though its an error
455 if (_click_io->n_ports () > ChanCount::ZERO) {
456 _clicking = Config->get_clicking ();
461 catch (failed_constructor& err) {
462 error << _("cannot setup Click I/O") << endmsg;
465 BootMessage (_("Compute I/O Latencies"));
468 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
471 BootMessage (_("Set up standard connections"));
473 vector<string> inputs[DataType::num_types];
474 vector<string> outputs[DataType::num_types];
475 for (uint32_t i = 0; i < DataType::num_types; ++i) {
476 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
477 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
480 /* Create a set of Bundle objects that map
481 to the physical I/O currently available. We create both
482 mono and stereo bundles, so that the common cases of mono
483 and stereo tracks get bundles to put in their mixer strip
484 in / out menus. There may be a nicer way of achieving that;
485 it doesn't really scale that well to higher channel counts
488 /* mono output bundles */
490 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
492 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
494 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
495 c->add_channel (_("mono"), DataType::AUDIO);
496 c->set_port (0, outputs[DataType::AUDIO][np]);
501 /* stereo output bundles */
503 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
504 if (np + 1 < outputs[DataType::AUDIO].size()) {
506 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
507 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
508 c->add_channel (_("L"), DataType::AUDIO);
509 c->set_port (0, outputs[DataType::AUDIO][np]);
510 c->add_channel (_("R"), DataType::AUDIO);
511 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
517 /* mono input bundles */
519 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
521 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
523 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
524 c->add_channel (_("mono"), DataType::AUDIO);
525 c->set_port (0, inputs[DataType::AUDIO][np]);
530 /* stereo input bundles */
532 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
533 if (np + 1 < inputs[DataType::AUDIO].size()) {
535 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
537 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
538 c->add_channel (_("L"), DataType::AUDIO);
539 c->set_port (0, inputs[DataType::AUDIO][np]);
540 c->add_channel (_("R"), DataType::AUDIO);
541 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
547 /* MIDI input bundles */
549 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
550 string n = inputs[DataType::MIDI][np];
551 boost::erase_first (n, X_("alsa_pcm:"));
553 boost::shared_ptr<Bundle> c (new Bundle (n, false));
554 c->add_channel ("", DataType::MIDI);
555 c->set_port (0, inputs[DataType::MIDI][np]);
559 /* MIDI output bundles */
561 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
562 string n = outputs[DataType::MIDI][np];
563 boost::erase_first (n, X_("alsa_pcm:"));
565 boost::shared_ptr<Bundle> c (new Bundle (n, true));
566 c->add_channel ("", DataType::MIDI);
567 c->set_port (0, outputs[DataType::MIDI][np]);
571 BootMessage (_("Setup signal flow and plugins"));
573 /* Reset all panners */
575 Delivery::reset_panners ();
577 /* this will cause the CPM to instantiate any protocols that are in use
578 * (or mandatory), which will pass it this Session, and then call
579 * set_state() on each instantiated protocol to match stored state.
582 ControlProtocolManager::instance().set_session (this);
584 /* This must be done after the ControlProtocolManager set_session above,
585 as it will set states for ports which the ControlProtocolManager creates.
588 MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
590 /* And this must be done after the MIDI::Manager::set_port_states as
591 * it will try to make connections whose details are loaded by set_port_states.
596 /* Let control protocols know that we are now all connected, so they
597 * could start talking to surfaces if they want to.
600 ControlProtocolManager::instance().midi_connectivity_established ();
602 if (_is_new && !no_auto_connect()) {
603 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
604 auto_connect_master_bus ();
607 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
609 /* update latencies */
611 initialize_latencies ();
613 /* hook us up to the engine */
615 BootMessage (_("Connect to engine"));
616 _engine.set_session (this);
617 _engine.reset_timebase ();
621 Session::auto_connect_master_bus ()
623 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
627 /* if requested auto-connect the outputs to the first N physical ports.
630 uint32_t limit = _master_out->n_outputs().n_total();
631 vector<string> outputs[DataType::num_types];
633 for (uint32_t i = 0; i < DataType::num_types; ++i) {
634 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
637 for (uint32_t n = 0; n < limit; ++n) {
638 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
640 if (outputs[p->type()].size() > n) {
641 connect_to = outputs[p->type()][n];
644 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
645 if (_master_out->output()->connect (p, connect_to, this)) {
646 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
655 Session::remove_monitor_section ()
661 /* force reversion to Solo-In-Place */
662 Config->set_solo_control_is_listen_control (false);
665 /* Hold process lock while doing this so that we don't hear bits and
666 * pieces of audio as we work on each route.
669 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
671 /* Connect tracks to monitor section. Note that in an
672 existing session, the internal sends will already exist, but we want the
673 routes to notice that they connect to the control out specifically.
677 boost::shared_ptr<RouteList> r = routes.reader ();
678 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
680 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
682 if ((*x)->is_monitor()) {
684 } else if ((*x)->is_master()) {
687 (*x)->remove_aux_or_listen (_monitor_out);
692 remove_route (_monitor_out);
693 auto_connect_master_bus ();
697 Session::add_monitor_section ()
701 if (_monitor_out || !_master_out) {
705 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
711 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
712 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
715 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
716 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
717 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
721 add_routes (rl, false, false, false);
723 assert (_monitor_out);
725 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
726 are undefined, at best.
729 uint32_t limit = _monitor_out->n_inputs().n_audio();
733 /* connect the inputs to the master bus outputs. this
734 * represents a separate data feed from the internal sends from
735 * each route. as of jan 2011, it allows the monitor section to
736 * conditionally ignore either the internal sends or the normal
737 * input feed, but we should really find a better way to do
741 _master_out->output()->disconnect (this);
743 for (uint32_t n = 0; n < limit; ++n) {
744 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
745 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
748 string connect_to = o->name();
749 if (_monitor_out->input()->connect (p, connect_to, this)) {
750 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
758 /* if monitor section is not connected, connect it to physical outs
761 if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
763 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
765 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
768 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
770 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
771 Config->get_monitor_bus_preferred_bundle())
777 /* Monitor bus is audio only */
779 uint32_t mod = n_physical_outputs.get (DataType::AUDIO);
780 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
781 vector<string> outputs[DataType::num_types];
783 for (uint32_t i = 0; i < DataType::num_types; ++i) {
784 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
790 for (uint32_t n = 0; n < limit; ++n) {
792 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
794 if (outputs[DataType::AUDIO].size() > (n % mod)) {
795 connect_to = outputs[DataType::AUDIO][n % mod];
798 if (!connect_to.empty()) {
799 if (_monitor_out->output()->connect (p, connect_to, this)) {
800 error << string_compose (
801 _("cannot connect control output %1 to %2"),
812 /* Hold process lock while doing this so that we don't hear bits and
813 * pieces of audio as we work on each route.
816 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
818 /* Connect tracks to monitor section. Note that in an
819 existing session, the internal sends will already exist, but we want the
820 routes to notice that they connect to the control out specifically.
824 boost::shared_ptr<RouteList> rls = routes.reader ();
826 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
828 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
830 if ((*x)->is_monitor()) {
832 } else if ((*x)->is_master()) {
835 (*x)->enable_monitor_send ();
841 Session::hookup_io ()
843 /* stop graph reordering notifications from
844 causing resorts, etc.
847 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
851 /* we delay creating the auditioner till now because
852 it makes its own connections to ports.
856 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
858 throw failed_constructor ();
860 a->use_new_diskstream ();
864 catch (failed_constructor& err) {
865 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
869 /* load bundles, which we may have postponed earlier on */
870 if (_bundle_xml_node) {
871 load_bundles (*_bundle_xml_node);
872 delete _bundle_xml_node;
875 /* Tell all IO objects to connect themselves together */
877 IO::enable_connecting ();
878 MIDI::JackMIDIPort::MakeConnections ();
880 /* Anyone who cares about input state, wake up and do something */
882 IOConnectionsComplete (); /* EMIT SIGNAL */
884 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
886 /* now handle the whole enchilada as if it was one
892 /* update the full solo state, which can't be
893 correctly determined on a per-route basis, but
894 needs the global overview that only the session
898 update_route_solo_state ();
902 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
904 boost::shared_ptr<Track> track = wp.lock ();
909 boost::shared_ptr<Playlist> playlist;
911 if ((playlist = track->playlist()) != 0) {
912 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
913 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
914 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
919 Session::record_enabling_legal () const
921 /* this used to be in here, but survey says.... we don't need to restrict it */
922 // if (record_status() == Recording) {
926 if (Config->get_all_safe()) {
933 Session::set_track_monitor_input_status (bool yn)
935 boost::shared_ptr<RouteList> rl = routes.reader ();
936 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
937 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
938 if (tr && tr->record_enabled ()) {
939 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
940 tr->request_jack_monitors_input (yn);
946 Session::auto_punch_start_changed (Location* location)
948 replace_event (SessionEvent::PunchIn, location->start());
950 if (get_record_enabled() && config.get_punch_in()) {
951 /* capture start has been changed, so save new pending state */
952 save_state ("", true);
957 Session::auto_punch_end_changed (Location* location)
959 framepos_t when_to_stop = location->end();
960 // when_to_stop += _worst_output_latency + _worst_input_latency;
961 replace_event (SessionEvent::PunchOut, when_to_stop);
965 Session::auto_punch_changed (Location* location)
967 framepos_t when_to_stop = location->end();
969 replace_event (SessionEvent::PunchIn, location->start());
970 //when_to_stop += _worst_output_latency + _worst_input_latency;
971 replace_event (SessionEvent::PunchOut, when_to_stop);
974 /** @param loc A loop location.
975 * @param pos Filled in with the start time of the required fade-out (in session frames).
976 * @param length Filled in with the length of the required fade-out.
979 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
981 pos = max (loc->start(), loc->end() - 64);
982 length = loc->end() - pos;
986 Session::auto_loop_changed (Location* location)
988 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
991 auto_loop_declick_range (location, dcp, dcl);
992 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
994 if (transport_rolling() && play_loop) {
997 // if (_transport_frame > location->end()) {
999 if (_transport_frame < location->start() || _transport_frame > location->end()) {
1000 // relocate to beginning of loop
1001 clear_events (SessionEvent::LocateRoll);
1003 request_locate (location->start(), true);
1006 else if (Config->get_seamless_loop() && !loop_changing) {
1008 // schedule a locate-roll to refill the diskstreams at the
1009 // previous loop end
1010 loop_changing = true;
1012 if (location->end() > last_loopend) {
1013 clear_events (SessionEvent::LocateRoll);
1014 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1021 last_loopend = location->end();
1025 Session::set_auto_punch_location (Location* location)
1029 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1030 punch_connections.drop_connections();
1031 existing->set_auto_punch (false, this);
1032 remove_event (existing->start(), SessionEvent::PunchIn);
1033 clear_events (SessionEvent::PunchOut);
1034 auto_punch_location_changed (0);
1039 if (location == 0) {
1043 if (location->end() <= location->start()) {
1044 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1048 punch_connections.drop_connections ();
1050 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1051 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1052 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1054 location->set_auto_punch (true, this);
1056 auto_punch_changed (location);
1058 auto_punch_location_changed (location);
1062 Session::set_auto_loop_location (Location* location)
1066 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1067 loop_connections.drop_connections ();
1068 existing->set_auto_loop (false, this);
1069 remove_event (existing->end(), SessionEvent::AutoLoop);
1072 auto_loop_declick_range (existing, dcp, dcl);
1073 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1074 auto_loop_location_changed (0);
1079 if (location == 0) {
1083 if (location->end() <= location->start()) {
1084 error << _("Session: you can't use a mark for auto loop") << endmsg;
1088 last_loopend = location->end();
1090 loop_connections.drop_connections ();
1092 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1093 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1094 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1096 location->set_auto_loop (true, this);
1098 /* take care of our stuff first */
1100 auto_loop_changed (location);
1102 /* now tell everyone else */
1104 auto_loop_location_changed (location);
1108 Session::locations_added (Location *)
1114 Session::locations_changed ()
1116 _locations->apply (*this, &Session::handle_locations_changed);
1120 Session::handle_locations_changed (Locations::LocationList& locations)
1122 Locations::LocationList::iterator i;
1124 bool set_loop = false;
1125 bool set_punch = false;
1127 for (i = locations.begin(); i != locations.end(); ++i) {
1131 if (location->is_auto_punch()) {
1132 set_auto_punch_location (location);
1135 if (location->is_auto_loop()) {
1136 set_auto_loop_location (location);
1140 if (location->is_session_range()) {
1141 _session_range_location = location;
1146 set_auto_loop_location (0);
1149 set_auto_punch_location (0);
1156 Session::enable_record ()
1158 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1159 /* no recording at anything except normal speed */
1164 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1166 if (rs == Recording) {
1170 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1172 _last_record_location = _transport_frame;
1173 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1175 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1176 set_track_monitor_input_status (true);
1179 RecordStateChanged ();
1186 Session::disable_record (bool rt_context, bool force)
1190 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1192 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1193 g_atomic_int_set (&_record_status, Disabled);
1194 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1196 if (rs == Recording) {
1197 g_atomic_int_set (&_record_status, Enabled);
1201 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1202 set_track_monitor_input_status (false);
1205 RecordStateChanged (); /* emit signal */
1208 remove_pending_capture_state ();
1214 Session::step_back_from_record ()
1216 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1218 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1219 set_track_monitor_input_status (false);
1222 RecordStateChanged (); /* emit signal */
1227 Session::maybe_enable_record ()
1229 if (_step_editors > 0) {
1233 g_atomic_int_set (&_record_status, Enabled);
1235 /* This function is currently called from somewhere other than an RT thread.
1236 This save_state() call therefore doesn't impact anything. Doing it here
1237 means that we save pending state of which sources the next record will use,
1238 which gives us some chance of recovering from a crash during the record.
1241 save_state ("", true);
1243 if (_transport_speed) {
1244 if (!config.get_punch_in()) {
1248 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1249 RecordStateChanged (); /* EMIT SIGNAL */
1256 Session::audible_frame () const
1262 /* the first of these two possible settings for "offset"
1263 mean that the audible frame is stationary until
1264 audio emerges from the latency compensation
1267 the second means that the audible frame is stationary
1268 until audio would emerge from a physical port
1269 in the absence of any plugin latency compensation
1272 offset = worst_playback_latency ();
1274 if (offset > current_block_size) {
1275 offset -= current_block_size;
1277 /* XXX is this correct? if we have no external
1278 physical connections and everything is internal
1279 then surely this is zero? still, how
1280 likely is that anyway?
1282 offset = current_block_size;
1285 if (synced_to_jack()) {
1286 tf = _engine.transport_frame();
1288 tf = _transport_frame;
1293 if (!non_realtime_work_pending()) {
1297 /* Check to see if we have passed the first guaranteed
1298 audible frame past our last start position. if not,
1299 return that last start point because in terms
1300 of audible frames, we have not moved yet.
1302 `Start position' in this context means the time we last
1303 either started, located, or changed transport direction.
1306 if (_transport_speed > 0.0f) {
1308 if (!play_loop || !have_looped) {
1309 if (tf < _last_roll_or_reversal_location + offset) {
1310 return _last_roll_or_reversal_location;
1318 } else if (_transport_speed < 0.0f) {
1320 /* XXX wot? no backward looping? */
1322 if (tf > _last_roll_or_reversal_location - offset) {
1323 return _last_roll_or_reversal_location;
1335 Session::set_frame_rate (framecnt_t frames_per_second)
1337 /** \fn void Session::set_frame_size(framecnt_t)
1338 the AudioEngine object that calls this guarantees
1339 that it will not be called while we are also in
1340 ::process(). Its fine to do things that block
1344 _base_frame_rate = frames_per_second;
1350 // XXX we need some equivalent to this, somehow
1351 // SndFileSource::setup_standard_crossfades (frames_per_second);
1355 /* XXX need to reset/reinstantiate all LADSPA plugins */
1359 Session::set_block_size (pframes_t nframes)
1361 /* the AudioEngine guarantees
1362 that it will not be called while we are also in
1363 ::process(). It is therefore fine to do things that block
1368 current_block_size = nframes;
1372 boost::shared_ptr<RouteList> r = routes.reader ();
1374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1375 (*i)->set_block_size (nframes);
1378 boost::shared_ptr<RouteList> rl = routes.reader ();
1379 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1380 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1382 tr->set_block_size (nframes);
1386 set_worst_io_latencies ();
1392 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1394 boost::shared_ptr<Route> r2;
1396 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1397 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1401 /* make a copy of the existing list of routes that feed r1 */
1403 Route::FedBy existing (r1->fed_by());
1405 /* for each route that feeds r1, recurse, marking it as feeding
1409 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1410 if (!(r2 = i->r.lock ())) {
1411 /* (*i) went away, ignore it */
1415 /* r2 is a route that feeds r1 which somehow feeds base. mark
1416 base as being fed by r2
1419 rbase->add_fed_by (r2, i->sends_only);
1423 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1427 if (r1->feeds (r2) && r2->feeds (r1)) {
1431 /* now recurse, so that we can mark base as being fed by
1432 all routes that feed r2
1435 trace_terminal (r2, rbase);
1442 Session::resort_routes ()
1444 /* don't do anything here with signals emitted
1445 by Routes during initial setup or while we
1446 are being destroyed.
1449 if (_state_of_the_state & (InitialConnecting | Deletion)) {
1454 RCUWriter<RouteList> writer (routes);
1455 boost::shared_ptr<RouteList> r = writer.get_copy ();
1456 resort_routes_using (r);
1457 /* writer goes out of scope and forces update */
1461 boost::shared_ptr<RouteList> rl = routes.reader ();
1462 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1463 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1465 const Route::FedBy& fb ((*i)->fed_by());
1467 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1468 boost::shared_ptr<Route> sf = f->r.lock();
1470 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1478 /** This is called whenever we need to rebuild the graph of how we will process
1480 * @param r List of routes, in any order.
1484 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1486 /* We are going to build a directed graph of our routes;
1487 this is where the edges of that graph are put.
1492 /* Go through all routes doing two things:
1494 * 1. Collect the edges of the route graph. Each of these edges
1495 * is a pair of routes, one of which directly feeds the other
1496 * either by a JACK connection or by an internal send.
1498 * 2. Begin the process of making routes aware of which other
1499 * routes directly or indirectly feed them. This information
1500 * is used by the solo code.
1503 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1505 /* Clear out the route's list of direct or indirect feeds */
1506 (*i)->clear_fed_by ();
1508 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
1510 bool via_sends_only;
1512 /* See if this *j feeds *i according to the current state of the JACK
1513 connections and internal sends.
1515 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
1516 /* add the edge to the graph (part #1) */
1517 edges.add (*j, *i, via_sends_only);
1518 /* tell the route (for part #2) */
1519 (*i)->add_fed_by (*j, via_sends_only);
1524 /* Attempt a topological sort of the route graph */
1525 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
1527 if (sorted_routes) {
1528 /* We got a satisfactory topological sort, so there is no feedback;
1531 Note: the process graph rechain does not require a
1532 topologically-sorted list, but hey ho.
1534 if (_process_graph) {
1535 _process_graph->rechain (sorted_routes, edges);
1538 _current_route_graph = edges;
1540 /* Complete the building of the routes' lists of what directly
1541 or indirectly feeds them.
1543 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1544 trace_terminal (*i, *i);
1547 *r = *sorted_routes;
1550 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1551 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1552 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1553 (*i)->name(), (*i)->order_key (MixerSort)));
1557 SuccessfulGraphSort (); /* EMIT SIGNAL */
1560 /* The topological sort failed, so we have a problem. Tell everyone
1561 and stick to the old graph; this will continue to be processed, so
1562 until the feedback is fixed, what is played back will not quite
1563 reflect what is actually connected. Note also that we do not
1564 do trace_terminal here, as it would fail due to an endless recursion,
1565 so the solo code will think that everything is still connected
1569 FeedbackDetected (); /* EMIT SIGNAL */
1574 /** Find a route name starting with \a base, maybe followed by the
1575 * lowest \a id. \a id will always be added if \a definitely_add_number
1576 * is true on entry; otherwise it will only be added if required
1577 * to make the name unique.
1579 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1580 * The available route name with the lowest ID will be used, and \a id
1581 * will be set to the ID.
1583 * \return false if a route name could not be found, and \a track_name
1584 * and \a id do not reflect a free route name.
1587 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1589 if (!definitely_add_number && route_by_name (base) == 0) {
1590 /* juse use the base */
1591 snprintf (name, name_len, "%s", base.c_str());
1596 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1598 if (route_by_name (name) == 0) {
1604 } while (id < (UINT_MAX-1));
1609 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
1611 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
1613 in = ChanCount::ZERO;
1614 out = ChanCount::ZERO;
1616 boost::shared_ptr<RouteList> r = routes.reader ();
1618 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1619 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1620 if (tr && !tr->is_hidden()) {
1621 in += tr->n_inputs();
1622 out += tr->n_outputs();
1627 /** Caller must not hold process lock
1628 * @param name_template string to use for the start of the name, or "" to use "MIDI".
1629 * @param instrument plugin info for the instrument to insert pre-fader, if any
1631 list<boost::shared_ptr<MidiTrack> >
1632 Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
1633 TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1635 char track_name[32];
1636 uint32_t track_id = 0;
1638 RouteList new_routes;
1639 list<boost::shared_ptr<MidiTrack> > ret;
1641 cerr << "Adding MIDI track with in = " << input << " out = " << output << endl;
1643 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
1646 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1647 error << "cannot find name for new midi track" << endmsg;
1651 boost::shared_ptr<MidiTrack> track;
1654 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1656 if (track->init ()) {
1660 track->use_new_diskstream();
1662 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1663 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1666 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1667 if (track->input()->ensure_io (input, false, this)) {
1668 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
1672 if (track->output()->ensure_io (output, false, this)) {
1673 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
1678 track->non_realtime_input_change();
1681 route_group->add (track);
1684 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1686 if (Config->get_remote_model() == UserOrdered) {
1687 track->set_remote_control_id (next_control_id());
1690 new_routes.push_back (track);
1691 ret.push_back (track);
1694 catch (failed_constructor &err) {
1695 error << _("Session: could not create new midi track.") << endmsg;
1699 catch (AudioEngine::PortRegistrationFailure& pfe) {
1701 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;
1709 if (!new_routes.empty()) {
1710 add_routes (new_routes, true, true, true);
1713 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
1714 PluginPtr plugin = instrument->load (*this);
1715 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
1716 (*r)->add_processor (p, PreFader);
1726 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
1728 boost::shared_ptr<Route> midi_track (wmt.lock());
1734 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
1736 if (change.after.n_audio() <= change.before.n_audio()) {
1740 /* new audio ports: make sure the audio goes somewhere useful,
1741 unless the user has no-auto-connect selected.
1743 The existing ChanCounts don't matter for this call as they are only
1744 to do with matching input and output indices, and we are only changing
1750 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
1754 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1755 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1756 * @param output_start As \a input_start, but for outputs.
1759 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
1760 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
1762 if (!IO::connecting_legal) {
1766 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
1772 /* If both inputs and outputs are auto-connected to physical ports,
1773 use the max of input and output offsets to ensure auto-connected
1774 port numbers always match up (e.g. the first audio input and the
1775 first audio output of the route will have the same physical
1776 port number). Otherwise just use the lowest input or output
1780 DEBUG_TRACE (DEBUG::Graph,
1781 string_compose("Auto-connect: existing in = %1 out = %2\n",
1782 existing_inputs, existing_outputs));
1784 const bool in_out_physical =
1785 (Config->get_input_auto_connect() & AutoConnectPhysical)
1786 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1789 const ChanCount in_offset = in_out_physical
1790 ? ChanCount::max(existing_inputs, existing_outputs)
1793 const ChanCount out_offset = in_out_physical
1794 ? ChanCount::max(existing_inputs, existing_outputs)
1797 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1798 vector<string> physinputs;
1799 vector<string> physoutputs;
1801 _engine.get_physical_outputs (*t, physoutputs);
1802 _engine.get_physical_inputs (*t, physinputs);
1804 if (!physinputs.empty() && connect_inputs) {
1805 uint32_t nphysical_in = physinputs.size();
1807 DEBUG_TRACE (DEBUG::Graph,
1808 string_compose("There are %1 physical inputs of type %2\n",
1811 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1814 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1815 DEBUG_TRACE (DEBUG::Graph,
1816 string_compose("Get index %1 + %2 % %3 = %4\n",
1817 in_offset.get(*t), i, nphysical_in,
1818 (in_offset.get(*t) + i) % nphysical_in));
1819 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1822 DEBUG_TRACE (DEBUG::Graph,
1823 string_compose("Connect route %1 IN to %2\n",
1824 route->name(), port));
1826 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
1830 ChanCount one_added (*t, 1);
1831 existing_inputs += one_added;
1835 if (!physoutputs.empty()) {
1836 uint32_t nphysical_out = physoutputs.size();
1837 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1840 if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
1841 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1842 } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
1843 /* master bus is audio only */
1844 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1845 port = _master_out->input()->ports().port(*t,
1846 i % _master_out->input()->n_ports().get(*t))->name();
1850 DEBUG_TRACE (DEBUG::Graph,
1851 string_compose("Connect route %1 OUT to %2\n",
1852 route->name(), port));
1854 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
1858 ChanCount one_added (*t, 1);
1859 existing_outputs += one_added;
1865 /** Caller must not hold process lock
1866 * @param name_template string to use for the start of the name, or "" to use "Audio".
1868 list< boost::shared_ptr<AudioTrack> >
1869 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
1870 uint32_t how_many, string name_template)
1872 char track_name[32];
1873 uint32_t track_id = 0;
1875 RouteList new_routes;
1876 list<boost::shared_ptr<AudioTrack> > ret;
1878 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
1881 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1882 error << "cannot find name for new audio track" << endmsg;
1886 boost::shared_ptr<AudioTrack> track;
1889 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1891 if (track->init ()) {
1895 track->use_new_diskstream();
1897 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1898 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1901 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1903 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1904 error << string_compose (
1905 _("cannot configure %1 in/%2 out configuration for new audio track"),
1906 input_channels, output_channels)
1911 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1912 error << string_compose (
1913 _("cannot configure %1 in/%2 out configuration for new audio track"),
1914 input_channels, output_channels)
1921 route_group->add (track);
1924 track->non_realtime_input_change();
1926 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1927 if (Config->get_remote_model() == UserOrdered) {
1928 track->set_remote_control_id (next_control_id());
1931 new_routes.push_back (track);
1932 ret.push_back (track);
1935 catch (failed_constructor &err) {
1936 error << _("Session: could not create new audio track.") << endmsg;
1940 catch (AudioEngine::PortRegistrationFailure& pfe) {
1942 error << pfe.what() << endmsg;
1950 if (!new_routes.empty()) {
1951 add_routes (new_routes, true, true, true);
1957 /** Caller must not hold process lock.
1958 * @param name_template string to use for the start of the name, or "" to use "Bus".
1961 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1964 uint32_t bus_id = 0;
1968 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
1971 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1972 error << "cannot find name for new audio bus" << endmsg;
1977 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1983 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1984 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1987 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1989 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1990 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1991 input_channels, output_channels)
1997 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1998 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1999 input_channels, output_channels)
2006 route_group->add (bus);
2008 if (Config->get_remote_model() == UserOrdered) {
2009 bus->set_remote_control_id (next_control_id());
2012 bus->add_internal_return ();
2014 ret.push_back (bus);
2020 catch (failed_constructor &err) {
2021 error << _("Session: could not create new audio route.") << endmsg;
2025 catch (AudioEngine::PortRegistrationFailure& pfe) {
2026 error << pfe.what() << endmsg;
2036 add_routes (ret, false, true, true); // autoconnect outputs only
2044 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2047 uint32_t control_id;
2049 uint32_t number = 0;
2051 if (!tree.read (template_path.c_str())) {
2055 XMLNode* node = tree.root();
2057 IO::disable_connecting ();
2059 control_id = next_control_id ();
2063 XMLNode node_copy (*node);
2065 /* Remove IDs of everything so that new ones are used */
2066 node_copy.remove_property_recursively (X_("id"));
2069 string const route_name = node_copy.property(X_("name"))->value ();
2071 /* generate a new name by adding a number to the end of the template name */
2073 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2074 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2078 /* set this name in the XML description that we are about to use */
2079 Route::set_name_in_state (node_copy, name);
2081 /* trim bitslots from listen sends so that new ones are used */
2082 XMLNodeList children = node_copy.children ();
2083 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2084 if ((*i)->name() == X_("Processor")) {
2085 XMLProperty* role = (*i)->property (X_("role"));
2086 if (role && role->value() == X_("Listen")) {
2087 (*i)->remove_property (X_("bitslot"));
2092 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2095 error << _("Session: cannot create track/bus from template description") << endmsg;
2099 if (boost::dynamic_pointer_cast<Track>(route)) {
2100 /* force input/output change signals so that the new diskstream
2101 picks up the configuration of the route. During session
2102 loading this normally happens in a different way.
2105 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2107 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2108 change.after = route->input()->n_ports();
2109 route->input()->changed (change, this);
2110 change.after = route->output()->n_ports();
2111 route->output()->changed (change, this);
2114 route->set_remote_control_id (control_id);
2117 ret.push_back (route);
2120 catch (failed_constructor &err) {
2121 error << _("Session: could not create new route from template") << endmsg;
2125 catch (AudioEngine::PortRegistrationFailure& pfe) {
2126 error << pfe.what() << endmsg;
2135 add_routes (ret, true, true, true);
2136 IO::enable_connecting ();
2143 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2146 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
2147 add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
2150 error << _("Adding new tracks/busses failed") << endmsg;
2155 update_latency (true);
2156 update_latency (false);
2161 save_state (_current_snapshot_name);
2164 RouteAdded (new_routes); /* EMIT SIGNAL */
2168 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
2170 ChanCount existing_inputs;
2171 ChanCount existing_outputs;
2172 uint32_t order = next_control_id();
2174 count_existing_track_channels (existing_inputs, existing_outputs);
2177 RCUWriter<RouteList> writer (routes);
2178 boost::shared_ptr<RouteList> r = writer.get_copy ();
2179 r->insert (r->end(), new_routes.begin(), new_routes.end());
2181 /* if there is no control out and we're not in the middle of loading,
2182 resort the graph here. if there is a control out, we will resort
2183 toward the end of this method. if we are in the middle of loading,
2184 we will resort when done.
2187 if (!_monitor_out && IO::connecting_legal) {
2188 resort_routes_using (r);
2192 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2194 boost::weak_ptr<Route> wpr (*x);
2195 boost::shared_ptr<Route> r (*x);
2197 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2198 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2199 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2200 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2201 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2202 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2204 if (r->is_master()) {
2208 if (r->is_monitor()) {
2212 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2214 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2215 track_playlist_changed (boost::weak_ptr<Track> (tr));
2216 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2218 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2220 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2221 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2226 if (input_auto_connect || output_auto_connect) {
2227 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2230 /* order keys are a GUI responsibility but we need to set up
2231 reasonable defaults because they also affect the remote control
2232 ID in most situations.
2235 if (!r->has_order_key (EditorSort)) {
2236 if (r->is_hidden()) {
2237 /* use an arbitrarily high value */
2238 r->set_order_key (EditorSort, UINT_MAX);
2239 r->set_order_key (MixerSort, UINT_MAX);
2241 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
2242 r->set_order_key (EditorSort, order);
2243 r->set_order_key (MixerSort, order);
2251 if (_monitor_out && IO::connecting_legal) {
2252 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2254 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2255 if ((*x)->is_monitor()) {
2257 } else if ((*x)->is_master()) {
2260 (*x)->enable_monitor_send ();
2267 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2269 boost::shared_ptr<RouteList> r = routes.reader ();
2270 boost::shared_ptr<Send> s;
2272 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2273 if ((s = (*i)->internal_send_for (dest)) != 0) {
2274 s->amp()->gain_control()->set_value (0.0);
2280 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2282 boost::shared_ptr<RouteList> r = routes.reader ();
2283 boost::shared_ptr<Send> s;
2285 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2286 if ((s = (*i)->internal_send_for (dest)) != 0) {
2287 s->amp()->gain_control()->set_value (1.0);
2293 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2295 boost::shared_ptr<RouteList> r = routes.reader ();
2296 boost::shared_ptr<Send> s;
2298 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2299 if ((s = (*i)->internal_send_for (dest)) != 0) {
2300 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2305 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2307 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2309 boost::shared_ptr<RouteList> r = routes.reader ();
2310 boost::shared_ptr<RouteList> t (new RouteList);
2312 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2313 /* no MIDI sends because there are no MIDI busses yet */
2314 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2319 add_internal_sends (dest, p, t);
2323 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2325 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2326 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2331 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2333 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2337 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2339 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2343 if (!dest->internal_return()) {
2344 dest->add_internal_return ();
2347 sender->add_aux_send (dest, before);
2353 Session::remove_route (boost::shared_ptr<Route> route)
2355 if (route == _master_out) {
2359 route->set_solo (false, this);
2362 RCUWriter<RouteList> writer (routes);
2363 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2367 /* deleting the master out seems like a dumb
2368 idea, but its more of a UI policy issue
2372 if (route == _master_out) {
2373 _master_out = boost::shared_ptr<Route> ();
2376 if (route == _monitor_out) {
2377 _monitor_out.reset ();
2380 /* writer goes out of scope, forces route list update */
2383 update_route_solo_state ();
2385 // We need to disconnect the route's inputs and outputs
2387 route->input()->disconnect (0);
2388 route->output()->disconnect (0);
2390 /* if the route had internal sends sending to it, remove them */
2391 if (route->internal_return()) {
2393 boost::shared_ptr<RouteList> r = routes.reader ();
2394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2395 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2397 (*i)->remove_processor (s);
2402 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2403 if (mt && mt->step_editing()) {
2404 if (_step_editors > 0) {
2409 update_latency_compensation ();
2412 /* Re-sort routes to remove the graph's current references to the one that is
2413 * going away, then flush old references out of the graph.
2417 if (_process_graph) {
2418 _process_graph->clear_other_chain ();
2421 /* get rid of it from the dead wood collection in the route list manager */
2423 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2427 /* try to cause everyone to drop their references */
2429 route->drop_references ();
2431 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2433 /* save the new state of the world */
2435 if (save_state (_current_snapshot_name)) {
2436 save_history (_current_snapshot_name);
2441 Session::route_mute_changed (void* /*src*/)
2447 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2449 boost::shared_ptr<Route> route = wpr.lock();
2451 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2455 if (route->listening_via_monitor ()) {
2457 if (Config->get_exclusive_solo()) {
2458 /* new listen: disable all other listen */
2459 boost::shared_ptr<RouteList> r = routes.reader ();
2460 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2461 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2464 (*i)->set_listen (false, this);
2470 } else if (_listen_cnt > 0) {
2475 update_route_solo_state ();
2478 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2480 boost::shared_ptr<Route> route = wpr.lock ();
2483 /* should not happen */
2484 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2488 bool send_changed = false;
2490 if (route->solo_isolated()) {
2491 if (_solo_isolated_cnt == 0) {
2492 send_changed = true;
2494 _solo_isolated_cnt++;
2495 } else if (_solo_isolated_cnt > 0) {
2496 _solo_isolated_cnt--;
2497 if (_solo_isolated_cnt == 0) {
2498 send_changed = true;
2503 IsolatedChanged (); /* EMIT SIGNAL */
2508 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2510 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
2512 if (!self_solo_change) {
2513 // session doesn't care about changes to soloed-by-others
2517 if (solo_update_disabled) {
2519 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
2523 boost::shared_ptr<Route> route = wpr.lock ();
2526 boost::shared_ptr<RouteList> r = routes.reader ();
2529 if (route->self_soloed()) {
2535 RouteGroup* rg = route->route_group ();
2536 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
2538 if (delta == 1 && Config->get_exclusive_solo()) {
2540 /* new solo: disable all other solos, but not the group if its solo-enabled */
2542 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2543 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2544 (leave_group_alone && ((*i)->route_group() == rg))) {
2547 (*i)->set_solo (false, this);
2551 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
2553 solo_update_disabled = true;
2555 RouteList uninvolved;
2557 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
2559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2560 bool via_sends_only;
2561 bool in_signal_flow;
2563 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2564 (leave_group_alone && ((*i)->route_group() == rg))) {
2568 in_signal_flow = false;
2570 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
2572 if ((*i)->feeds (route, &via_sends_only)) {
2573 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
2574 if (!via_sends_only) {
2575 if (!route->soloed_by_others_upstream()) {
2576 (*i)->mod_solo_by_others_downstream (delta);
2579 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
2581 in_signal_flow = true;
2583 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
2586 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
2588 if (route->feeds (*i, &via_sends_only)) {
2589 /* propagate solo upstream only if routing other than
2590 sends is involved, but do consider the other route
2591 (*i) to be part of the signal flow even if only
2594 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
2598 route->soloed_by_others_downstream(),
2599 route->soloed_by_others_upstream()));
2600 if (!via_sends_only) {
2601 if (!route->soloed_by_others_downstream()) {
2602 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
2603 (*i)->mod_solo_by_others_upstream (delta);
2605 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
2608 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
2610 in_signal_flow = true;
2612 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
2615 if (!in_signal_flow) {
2616 uninvolved.push_back (*i);
2620 solo_update_disabled = false;
2621 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
2623 update_route_solo_state (r);
2625 /* now notify that the mute state of the routes not involved in the signal
2626 pathway of the just-solo-changed route may have altered.
2629 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2630 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
2631 (*i)->mute_changed (this);
2634 SoloChanged (); /* EMIT SIGNAL */
2639 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2641 /* now figure out if anything that matters is soloed (or is "listening")*/
2643 bool something_soloed = false;
2644 uint32_t listeners = 0;
2645 uint32_t isolated = 0;
2648 r = routes.reader();
2651 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2652 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2653 something_soloed = true;
2656 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2657 if (Config->get_solo_control_is_listen_control()) {
2660 (*i)->set_listen (false, this);
2664 if ((*i)->solo_isolated()) {
2669 if (something_soloed != _non_soloed_outs_muted) {
2670 _non_soloed_outs_muted = something_soloed;
2671 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2674 _listen_cnt = listeners;
2676 if (isolated != _solo_isolated_cnt) {
2677 _solo_isolated_cnt = isolated;
2678 IsolatedChanged (); /* EMIT SIGNAL */
2681 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
2682 something_soloed, listeners, isolated));
2685 boost::shared_ptr<RouteList>
2686 Session::get_routes_with_internal_returns() const
2688 boost::shared_ptr<RouteList> r = routes.reader ();
2689 boost::shared_ptr<RouteList> rl (new RouteList);
2691 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2692 if ((*i)->internal_return ()) {
2700 Session::io_name_is_legal (const std::string& name)
2702 boost::shared_ptr<RouteList> r = routes.reader ();
2704 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2705 if ((*i)->name() == name) {
2709 if ((*i)->has_io_processor_named (name)) {
2718 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
2721 vector<string> connections;
2723 /* if we are passed only a single route and we're not told to turn
2724 * others off, then just do the simple thing.
2727 if (flip_others == false && rl->size() == 1) {
2728 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
2730 mt->set_input_active (onoff);
2735 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
2737 PortSet& ps ((*rt)->input()->ports());
2739 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
2740 p->get_connections (connections);
2743 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
2744 routes_using_input_from (*s, rl2);
2747 /* scan all relevant routes to see if others are on or off */
2749 bool others_are_already_on = false;
2751 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2753 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2759 if ((*r) != (*rt)) {
2760 if (mt->input_active()) {
2761 others_are_already_on = true;
2764 /* this one needs changing */
2765 mt->set_input_active (onoff);
2771 /* globally reverse other routes */
2773 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2774 if ((*r) != (*rt)) {
2775 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2777 mt->set_input_active (!others_are_already_on);
2786 Session::routes_using_input_from (const string& str, RouteList& rl)
2788 boost::shared_ptr<RouteList> r = routes.reader();
2790 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2791 if ((*i)->input()->connected_to (str)) {
2797 boost::shared_ptr<Route>
2798 Session::route_by_name (string name)
2800 boost::shared_ptr<RouteList> r = routes.reader ();
2802 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2803 if ((*i)->name() == name) {
2808 return boost::shared_ptr<Route> ((Route*) 0);
2811 boost::shared_ptr<Route>
2812 Session::route_by_id (PBD::ID id)
2814 boost::shared_ptr<RouteList> r = routes.reader ();
2816 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2817 if ((*i)->id() == id) {
2822 return boost::shared_ptr<Route> ((Route*) 0);
2825 boost::shared_ptr<Track>
2826 Session::track_by_diskstream_id (PBD::ID id)
2828 boost::shared_ptr<RouteList> r = routes.reader ();
2830 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2831 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
2832 if (t && t->using_diskstream_id (id)) {
2837 return boost::shared_ptr<Track> ();
2840 boost::shared_ptr<Route>
2841 Session::route_by_remote_id (uint32_t id)
2843 boost::shared_ptr<RouteList> r = routes.reader ();
2845 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2846 if ((*i)->remote_control_id() == id) {
2851 return boost::shared_ptr<Route> ((Route*) 0);
2855 Session::playlist_region_added (boost::weak_ptr<Region> w)
2857 boost::shared_ptr<Region> r = w.lock ();
2862 /* These are the operations that are currently in progress... */
2863 list<GQuark> curr = _current_trans_quarks;
2866 /* ...and these are the operations during which we want to update
2867 the session range location markers.
2870 ops.push_back (Operations::capture);
2871 ops.push_back (Operations::paste);
2872 ops.push_back (Operations::duplicate_region);
2873 ops.push_back (Operations::insert_file);
2874 ops.push_back (Operations::insert_region);
2875 ops.push_back (Operations::drag_region_brush);
2876 ops.push_back (Operations::region_drag);
2877 ops.push_back (Operations::selection_grab);
2878 ops.push_back (Operations::region_fill);
2879 ops.push_back (Operations::fill_selection);
2880 ops.push_back (Operations::create_region);
2881 ops.push_back (Operations::region_copy);
2882 ops.push_back (Operations::fixed_time_region_copy);
2885 /* See if any of the current operations match the ones that we want */
2887 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2889 /* If so, update the session range markers */
2891 maybe_update_session_range (r->position (), r->last_frame ());
2895 /** Update the session range markers if a is before the current start or
2896 * b is after the current end.
2899 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2901 if (_state_of_the_state & Loading) {
2905 if (_session_range_location == 0) {
2907 add_session_range_location (a, b);
2911 if (a < _session_range_location->start()) {
2912 _session_range_location->set_start (a);
2915 if (b > _session_range_location->end()) {
2916 _session_range_location->set_end (b);
2922 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2924 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2925 maybe_update_session_range (i->to, i->to + i->length);
2930 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2932 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2933 maybe_update_session_range (i->from, i->to);
2937 /* Region management */
2939 boost::shared_ptr<Region>
2940 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2942 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2943 RegionFactory::RegionMap::const_iterator i;
2944 boost::shared_ptr<Region> region;
2946 Glib::Threads::Mutex::Lock lm (region_lock);
2948 for (i = regions.begin(); i != regions.end(); ++i) {
2952 if (region->whole_file()) {
2954 if (child->source_equivalent (region)) {
2960 return boost::shared_ptr<Region> ();
2964 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2966 set<boost::shared_ptr<Region> > relevant_regions;
2968 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2969 RegionFactory::get_regions_using_source (*s, relevant_regions);
2972 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2973 set<boost::shared_ptr<Region> >::iterator tmp;
2978 playlists->destroy_region (*r);
2979 RegionFactory::map_remove (*r);
2981 (*r)->drop_sources ();
2982 (*r)->drop_references ();
2984 relevant_regions.erase (r);
2989 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2992 Glib::Threads::Mutex::Lock ls (source_lock);
2993 /* remove from the main source list */
2994 sources.erase ((*s)->id());
2997 (*s)->mark_for_remove ();
2998 (*s)->drop_references ();
3007 Session::remove_last_capture ()
3009 list<boost::shared_ptr<Source> > srcs;
3011 boost::shared_ptr<RouteList> rl = routes.reader ();
3012 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3013 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3018 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
3021 srcs.insert (srcs.end(), l.begin(), l.end());
3026 destroy_sources (srcs);
3028 save_state (_current_snapshot_name);
3033 /* Source Management */
3036 Session::add_source (boost::shared_ptr<Source> source)
3038 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3039 pair<SourceMap::iterator,bool> result;
3041 entry.first = source->id();
3042 entry.second = source;
3045 Glib::Threads::Mutex::Lock lm (source_lock);
3046 result = sources.insert (entry);
3049 if (result.second) {
3051 /* yay, new source */
3053 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3056 if (!fs->within_session()) {
3057 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3063 boost::shared_ptr<AudioFileSource> afs;
3065 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3066 if (Config->get_auto_analyse_audio()) {
3067 Analyser::queue_source_for_analysis (source, false);
3071 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3076 Session::remove_source (boost::weak_ptr<Source> src)
3078 if (_state_of_the_state & Deletion) {
3082 SourceMap::iterator i;
3083 boost::shared_ptr<Source> source = src.lock();
3090 Glib::Threads::Mutex::Lock lm (source_lock);
3092 if ((i = sources.find (source->id())) != sources.end()) {
3097 if (!(_state_of_the_state & InCleanup)) {
3099 /* save state so we don't end up with a session file
3100 referring to non-existent sources.
3103 save_state (_current_snapshot_name);
3107 boost::shared_ptr<Source>
3108 Session::source_by_id (const PBD::ID& id)
3110 Glib::Threads::Mutex::Lock lm (source_lock);
3111 SourceMap::iterator i;
3112 boost::shared_ptr<Source> source;
3114 if ((i = sources.find (id)) != sources.end()) {
3121 boost::shared_ptr<Source>
3122 Session::source_by_path_and_channel (const string& path, uint16_t chn)
3124 Glib::Threads::Mutex::Lock lm (source_lock);
3126 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3127 boost::shared_ptr<AudioFileSource> afs
3128 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3130 if (afs && afs->path() == path && chn == afs->channel()) {
3134 return boost::shared_ptr<Source>();
3138 Session::count_sources_by_origin (const string& path)
3141 Glib::Threads::Mutex::Lock lm (source_lock);
3143 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3144 boost::shared_ptr<FileSource> fs
3145 = boost::dynamic_pointer_cast<FileSource>(i->second);
3147 if (fs && fs->origin() == path) {
3157 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3160 string old_basename = PBD::basename_nosuffix (oldname);
3161 string new_legalized = legalize_for_path (newname);
3163 /* note: we know (or assume) the old path is already valid */
3167 /* destructive file sources have a name of the form:
3169 /path/to/Tnnnn-NAME(%[LR])?.wav
3171 the task here is to replace NAME with the new name.
3176 string::size_type dash;
3178 dir = Glib::path_get_dirname (path);
3179 path = Glib::path_get_basename (path);
3181 /* '-' is not a legal character for the NAME part of the path */
3183 if ((dash = path.find_last_of ('-')) == string::npos) {
3187 prefix = path.substr (0, dash);
3191 path += new_legalized;
3192 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3193 path = Glib::build_filename (dir, path);
3197 /* non-destructive file sources have a name of the form:
3199 /path/to/NAME-nnnnn(%[LR])?.ext
3201 the task here is to replace NAME with the new name.
3206 string::size_type dash;
3207 string::size_type postfix;
3209 dir = Glib::path_get_dirname (path);
3210 path = Glib::path_get_basename (path);
3212 /* '-' is not a legal character for the NAME part of the path */
3214 if ((dash = path.find_last_of ('-')) == string::npos) {
3218 suffix = path.substr (dash+1);
3220 // Suffix is now everything after the dash. Now we need to eliminate
3221 // the nnnnn part, which is done by either finding a '%' or a '.'
3223 postfix = suffix.find_last_of ("%");
3224 if (postfix == string::npos) {
3225 postfix = suffix.find_last_of ('.');
3228 if (postfix != string::npos) {
3229 suffix = suffix.substr (postfix);
3231 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3235 const uint32_t limit = 10000;
3236 char buf[PATH_MAX+1];
3238 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3240 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
3242 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
3243 path = Glib::build_filename (dir, buf);
3251 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
3260 /** Return the full path (in some session directory) for a new within-session source.
3261 * \a name must be a session-unique name that does not contain slashes
3262 * (e.g. as returned by new_*_source_name)
3265 Session::new_source_path_from_name (DataType type, const string& name)
3267 assert(name.find("/") == string::npos);
3269 SessionDirectory sdir(get_best_session_directory_for_new_source());
3272 if (type == DataType::AUDIO) {
3273 p = sdir.sound_path();
3274 } else if (type == DataType::MIDI) {
3275 p = sdir.midi_path();
3277 error << "Unknown source type, unable to create file path" << endmsg;
3281 return Glib::build_filename (p, name);
3285 Session::peak_path (string base) const
3287 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3290 /** Return a unique name based on \a base for a new internal audio source */
3292 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3295 char buf[PATH_MAX+1];
3296 const uint32_t limit = 10000;
3298 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3301 legalized = legalize_for_path (base);
3303 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3304 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3306 vector<space_and_path>::iterator i;
3307 uint32_t existing = 0;
3309 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3314 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3315 cnt, legalized.c_str(), ext.c_str());
3316 } else if (nchan == 2) {
3318 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
3319 cnt, legalized.c_str(), ext.c_str());
3321 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
3322 cnt, legalized.c_str(), ext.c_str());
3324 } else if (nchan < 26) {
3325 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
3326 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
3328 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3329 cnt, legalized.c_str(), ext.c_str());
3335 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3336 } else if (nchan == 2) {
3338 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
3340 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
3342 } else if (nchan < 26) {
3343 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
3345 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3349 SessionDirectory sdir((*i).path);
3351 string spath = sdir.sound_path();
3353 /* note that we search *without* the extension so that
3354 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3355 in the event that this new name is required for
3356 a file format change.
3359 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
3365 if (existing == 0) {
3370 error << string_compose(
3371 _("There are already %1 recordings for %2, which I consider too many."),
3372 limit, base) << endmsg;
3374 throw failed_constructor();
3378 return Glib::path_get_basename (buf);
3381 /** Create a new within-session audio source */
3382 boost::shared_ptr<AudioFileSource>
3383 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3385 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3386 const string path = new_source_path_from_name(DataType::AUDIO, name);
3388 return boost::dynamic_pointer_cast<AudioFileSource> (
3389 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3392 /** Return a unique name based on \a base for a new internal MIDI source */
3394 Session::new_midi_source_name (const string& base)
3397 char buf[PATH_MAX+1];
3398 const uint32_t limit = 10000;
3402 legalized = legalize_for_path (base);
3404 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3405 for (cnt = 1; cnt <= limit; ++cnt) {
3407 vector<space_and_path>::iterator i;
3408 uint32_t existing = 0;
3410 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3412 SessionDirectory sdir((*i).path);
3414 std::string p = Glib::build_filename (sdir.midi_path(), legalized);
3416 snprintf (buf, sizeof(buf), "%s-%u.mid", p.c_str(), cnt);
3418 if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3423 if (existing == 0) {
3428 error << string_compose(
3429 _("There are already %1 recordings for %2, which I consider too many."),
3430 limit, base) << endmsg;
3432 throw failed_constructor();
3436 return Glib::path_get_basename(buf);
3440 /** Create a new within-session MIDI source */
3441 boost::shared_ptr<MidiSource>
3442 Session::create_midi_source_for_session (Track* track, string const & n)
3444 /* try to use the existing write source for the track, to keep numbering sane
3448 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3452 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3455 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3456 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3460 const string name = new_midi_source_name (n);
3461 const string path = new_source_path_from_name (DataType::MIDI, name);
3463 return boost::dynamic_pointer_cast<SMFSource> (
3464 SourceFactory::createWritable (
3465 DataType::MIDI, *this, path, string(), false, frame_rate()));
3470 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3472 if (playlist->hidden()) {
3476 playlists->add (playlist);
3479 playlist->release();
3486 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3488 if (_state_of_the_state & Deletion) {
3492 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3498 playlists->remove (playlist);
3504 Session::set_audition (boost::shared_ptr<Region> r)
3506 pending_audition_region = r;
3507 add_post_transport_work (PostTransportAudition);
3508 _butler->schedule_transport_work ();
3512 Session::audition_playlist ()
3514 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3515 ev->region.reset ();
3520 Session::non_realtime_set_audition ()
3522 assert (pending_audition_region);
3523 auditioner->audition_region (pending_audition_region);
3524 pending_audition_region.reset ();
3525 AuditionActive (true); /* EMIT SIGNAL */
3529 Session::audition_region (boost::shared_ptr<Region> r)
3531 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3537 Session::cancel_audition ()
3539 if (auditioner->auditioning()) {
3540 auditioner->cancel_audition ();
3541 AuditionActive (false); /* EMIT SIGNAL */
3546 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3548 if (a->is_monitor()) {
3551 if (b->is_monitor()) {
3554 return a->order_key (MixerSort) < b->order_key (MixerSort);
3558 Session::is_auditioning () const
3560 /* can be called before we have an auditioner object */
3562 return auditioner->auditioning();
3569 Session::graph_reordered ()
3571 /* don't do this stuff if we are setting up connections
3572 from a set_state() call or creating new tracks. Ditto for deletion.
3575 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
3579 /* every track/bus asked for this to be handled but it was deferred because
3580 we were connecting. do it now.
3583 request_input_change_handling ();
3587 /* force all diskstreams to update their capture offset values to
3588 reflect any changes in latencies within the graph.
3591 boost::shared_ptr<RouteList> rl = routes.reader ();
3592 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3593 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3595 tr->set_capture_offset ();
3600 /** @return Number of frames that there is disk space available to write,
3603 boost::optional<framecnt_t>
3604 Session::available_capture_duration ()
3606 Glib::Threads::Mutex::Lock lm (space_lock);
3608 if (_total_free_4k_blocks_uncertain) {
3609 return boost::optional<framecnt_t> ();
3612 float sample_bytes_on_disk = 4.0; // keep gcc happy
3614 switch (config.get_native_file_data_format()) {
3616 sample_bytes_on_disk = 4.0;
3620 sample_bytes_on_disk = 3.0;
3624 sample_bytes_on_disk = 2.0;
3628 /* impossible, but keep some gcc versions happy */
3629 fatal << string_compose (_("programming error: %1"),
3630 X_("illegal native file data format"))
3635 double scale = 4096.0 / sample_bytes_on_disk;
3637 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3638 return max_framecnt;
3641 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3645 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3648 RCUWriter<BundleList> writer (_bundles);
3649 boost::shared_ptr<BundleList> b = writer.get_copy ();
3650 b->push_back (bundle);
3653 BundleAdded (bundle); /* EMIT SIGNAL */
3659 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3661 bool removed = false;
3664 RCUWriter<BundleList> writer (_bundles);
3665 boost::shared_ptr<BundleList> b = writer.get_copy ();
3666 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3668 if (i != b->end()) {
3675 BundleRemoved (bundle); /* EMIT SIGNAL */
3681 boost::shared_ptr<Bundle>
3682 Session::bundle_by_name (string name) const
3684 boost::shared_ptr<BundleList> b = _bundles.reader ();
3686 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3687 if ((*i)->name() == name) {
3692 return boost::shared_ptr<Bundle> ();
3696 Session::tempo_map_changed (const PropertyChange&)
3700 playlists->update_after_tempo_map_change ();
3702 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3708 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3710 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3711 (*i)->recompute_frames_from_bbt ();
3715 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3716 * the given count with the current block size.
3719 Session::ensure_buffers (ChanCount howmany)
3721 BufferManager::ensure_buffers (howmany);
3725 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3727 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3728 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3733 Session::next_insert_id ()
3735 /* this doesn't really loop forever. just think about it */
3738 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3739 if (!insert_bitset[n]) {
3740 insert_bitset[n] = true;
3746 /* none available, so resize and try again */
3748 insert_bitset.resize (insert_bitset.size() + 16, false);
3753 Session::next_send_id ()
3755 /* this doesn't really loop forever. just think about it */
3758 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3759 if (!send_bitset[n]) {
3760 send_bitset[n] = true;
3766 /* none available, so resize and try again */
3768 send_bitset.resize (send_bitset.size() + 16, false);
3773 Session::next_aux_send_id ()
3775 /* this doesn't really loop forever. just think about it */
3778 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
3779 if (!aux_send_bitset[n]) {
3780 aux_send_bitset[n] = true;
3786 /* none available, so resize and try again */
3788 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
3793 Session::next_return_id ()
3795 /* this doesn't really loop forever. just think about it */
3798 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3799 if (!return_bitset[n]) {
3800 return_bitset[n] = true;
3806 /* none available, so resize and try again */
3808 return_bitset.resize (return_bitset.size() + 16, false);
3813 Session::mark_send_id (uint32_t id)
3815 if (id >= send_bitset.size()) {
3816 send_bitset.resize (id+16, false);
3818 if (send_bitset[id]) {
3819 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3821 send_bitset[id] = true;
3825 Session::mark_aux_send_id (uint32_t id)
3827 if (id >= aux_send_bitset.size()) {
3828 aux_send_bitset.resize (id+16, false);
3830 if (aux_send_bitset[id]) {
3831 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
3833 aux_send_bitset[id] = true;
3837 Session::mark_return_id (uint32_t id)
3839 if (id >= return_bitset.size()) {
3840 return_bitset.resize (id+16, false);
3842 if (return_bitset[id]) {
3843 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3845 return_bitset[id] = true;
3849 Session::mark_insert_id (uint32_t id)
3851 if (id >= insert_bitset.size()) {
3852 insert_bitset.resize (id+16, false);
3854 if (insert_bitset[id]) {
3855 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3857 insert_bitset[id] = true;
3861 Session::unmark_send_id (uint32_t id)
3863 if (id < send_bitset.size()) {
3864 send_bitset[id] = false;
3869 Session::unmark_aux_send_id (uint32_t id)
3871 if (id < aux_send_bitset.size()) {
3872 aux_send_bitset[id] = false;
3877 Session::unmark_return_id (uint32_t id)
3879 if (id < return_bitset.size()) {
3880 return_bitset[id] = false;
3885 Session::unmark_insert_id (uint32_t id)
3887 if (id < insert_bitset.size()) {
3888 insert_bitset[id] = false;
3893 Session::reset_native_file_format ()
3895 boost::shared_ptr<RouteList> rl = routes.reader ();
3896 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3897 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3899 /* don't save state as we do this, there's no point
3902 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3903 tr->reset_write_sources (false);
3904 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3910 Session::route_name_unique (string n) const
3912 boost::shared_ptr<RouteList> r = routes.reader ();
3914 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3915 if ((*i)->name() == n) {
3924 Session::route_name_internal (string n) const
3926 if (auditioner && auditioner->name() == n) {
3930 if (_click_io && _click_io->name() == n) {
3938 Session::freeze_all (InterThreadInfo& itt)
3940 boost::shared_ptr<RouteList> r = routes.reader ();
3942 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3944 boost::shared_ptr<Track> t;
3946 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3947 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3957 boost::shared_ptr<Region>
3958 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3959 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3960 InterThreadInfo& itt,
3961 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
3964 boost::shared_ptr<Region> result;
3965 boost::shared_ptr<Playlist> playlist;
3966 boost::shared_ptr<AudioFileSource> fsource;
3968 char buf[PATH_MAX+1];
3969 ChanCount diskstream_channels (track.n_channels());
3970 framepos_t position;
3971 framecnt_t this_chunk;
3974 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3975 const string sound_dir = sdir.sound_path();
3976 framepos_t len = end - start;
3977 bool need_block_size_reset = false;
3979 ChanCount const max_proc = track.max_processor_streams ();
3982 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3983 end, start) << endmsg;
3987 const framecnt_t chunk_size = (256 * 1024)/4;
3989 // block all process callback handling
3991 block_processing ();
3993 /* call tree *MUST* hold route_lock */
3995 if ((playlist = track.playlist()) == 0) {
3999 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
4001 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
4003 for (x = 0; x < 99999; ++x) {
4004 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());
4005 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
4011 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4016 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4017 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
4020 catch (failed_constructor& err) {
4021 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4025 srcs.push_back (fsource);
4028 /* tell redirects that care that we are about to use a much larger
4029 * blocksize. this will flush all plugins too, so that they are ready
4030 * to be used for this process.
4033 need_block_size_reset = true;
4034 track.set_block_size (chunk_size);
4039 /* create a set of reasonably-sized buffers */
4040 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
4041 buffers.set_count (max_proc);
4043 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4044 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4046 afs->prepare_for_peakfile_writes ();
4049 while (to_do && !itt.cancel) {
4051 this_chunk = min (to_do, chunk_size);
4053 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export)) {
4058 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4059 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4062 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4068 start += this_chunk;
4069 to_do -= this_chunk;
4071 itt.progress = (float) (1.0 - ((double) to_do / len));
4080 xnow = localtime (&now);
4082 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4083 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4086 afs->update_header (position, *xnow, now);
4087 afs->flush_header ();
4091 /* construct a region to represent the bounced material */
4095 plist.add (Properties::start, 0);
4096 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4097 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4099 result = RegionFactory::create (srcs, plist);
4105 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4106 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4109 afs->mark_for_remove ();
4112 (*src)->drop_references ();
4116 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4117 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4120 afs->done_with_peakfile_writes ();
4125 if (need_block_size_reset) {
4126 track.set_block_size (get_block_size());
4129 unblock_processing ();
4135 Session::gain_automation_buffer() const
4137 return ProcessThread::gain_automation_buffer ();
4141 Session::send_gain_automation_buffer() const
4143 return ProcessThread::send_gain_automation_buffer ();
4147 Session::pan_automation_buffer() const
4149 return ProcessThread::pan_automation_buffer ();
4153 Session::get_silent_buffers (ChanCount count)
4155 return ProcessThread::get_silent_buffers (count);
4159 Session::get_scratch_buffers (ChanCount count)
4161 return ProcessThread::get_scratch_buffers (count);
4165 Session::get_mix_buffers (ChanCount count)
4167 return ProcessThread::get_mix_buffers (count);
4171 Session::ntracks () const
4174 boost::shared_ptr<RouteList> r = routes.reader ();
4176 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4177 if (boost::dynamic_pointer_cast<Track> (*i)) {
4186 Session::nbusses () const
4189 boost::shared_ptr<RouteList> r = routes.reader ();
4191 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4192 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4201 Session::add_automation_list(AutomationList *al)
4203 automation_lists[al->id()] = al;
4206 /** @return true if there is at least one record-enabled track, otherwise false */
4208 Session::have_rec_enabled_track () const
4210 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
4213 /** Update the state of our rec-enabled tracks flag */
4215 Session::update_have_rec_enabled_track ()
4217 boost::shared_ptr<RouteList> rl = routes.reader ();
4218 RouteList::iterator i = rl->begin();
4219 while (i != rl->end ()) {
4221 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4222 if (tr && tr->record_enabled ()) {
4229 int const old = g_atomic_int_get (&_have_rec_enabled_track);
4231 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
4233 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
4234 RecordStateChanged (); /* EMIT SIGNAL */
4239 Session::listen_position_changed ()
4241 boost::shared_ptr<RouteList> r = routes.reader ();
4243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4244 (*i)->listen_position_changed ();
4249 Session::solo_control_mode_changed ()
4251 /* cancel all solo or all listen when solo control mode changes */
4254 set_solo (get_routes(), false);
4255 } else if (listening()) {
4256 set_listen (get_routes(), false);
4260 /** Called when a property of one of our route groups changes */
4262 Session::route_group_property_changed (RouteGroup* rg)
4264 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
4267 /** Called when a route is added to one of our route groups */
4269 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4271 RouteAddedToRouteGroup (rg, r);
4274 /** Called when a route is removed from one of our route groups */
4276 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4278 RouteRemovedFromRouteGroup (rg, r);
4281 boost::shared_ptr<RouteList>
4282 Session::get_routes_with_regions_at (framepos_t const p) const
4284 boost::shared_ptr<RouteList> r = routes.reader ();
4285 boost::shared_ptr<RouteList> rl (new RouteList);
4287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4288 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4293 boost::shared_ptr<Playlist> pl = tr->playlist ();
4298 if (pl->has_region_at (p)) {
4307 Session::goto_end ()
4309 if (_session_range_location) {
4310 request_locate (_session_range_location->end(), false);
4312 request_locate (0, false);
4317 Session::goto_start ()
4319 if (_session_range_location) {
4320 request_locate (_session_range_location->start(), false);
4322 request_locate (0, false);
4327 Session::current_start_frame () const
4329 return _session_range_location ? _session_range_location->start() : 0;
4333 Session::current_end_frame () const
4335 return _session_range_location ? _session_range_location->end() : 0;
4339 Session::add_session_range_location (framepos_t start, framepos_t end)
4341 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4342 _locations->add (_session_range_location);
4346 Session::step_edit_status_change (bool yn)
4352 send = (_step_editors == 0);
4357 send = (_step_editors == 1);
4360 if (_step_editors > 0) {
4366 StepEditStatusChange (val);
4372 Session::start_time_changed (framepos_t old)
4374 /* Update the auto loop range to match the session range
4375 (unless the auto loop range has been changed by the user)
4378 Location* s = _locations->session_range_location ();
4383 Location* l = _locations->auto_loop_location ();
4385 if (l && l->start() == old) {
4386 l->set_start (s->start(), true);
4391 Session::end_time_changed (framepos_t old)
4393 /* Update the auto loop range to match the session range
4394 (unless the auto loop range has been changed by the user)
4397 Location* s = _locations->session_range_location ();
4402 Location* l = _locations->auto_loop_location ();
4404 if (l && l->end() == old) {
4405 l->set_end (s->end(), true);
4410 Session::source_search_path (DataType type) const
4414 if (session_dirs.size() == 1) {
4416 case DataType::AUDIO:
4417 s.push_back (_session_dir->sound_path());
4419 case DataType::MIDI:
4420 s.push_back (_session_dir->midi_path());
4424 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4425 SessionDirectory sdir (i->path);
4427 case DataType::AUDIO:
4428 s.push_back (sdir.sound_path());
4430 case DataType::MIDI:
4431 s.push_back (sdir.midi_path());
4437 if (type == DataType::AUDIO) {
4438 const string sound_path_2X = _session_dir->sound_path_2X();
4439 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
4440 if (find (s.begin(), s.end(), sound_path_2X) == s.end()) {
4441 s.push_back (sound_path_2X);
4446 /* now check the explicit (possibly user-specified) search path
4449 vector<string> dirs;
4452 case DataType::AUDIO:
4453 split (config.get_audio_search_path (), dirs, ':');
4455 case DataType::MIDI:
4456 split (config.get_midi_search_path (), dirs, ':');
4460 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4461 if (find (s.begin(), s.end(), *i) == s.end()) {
4468 for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) {
4469 if (!search_path.empty()) {
4479 Session::ensure_search_path_includes (const string& path, DataType type)
4482 vector<string> dirs;
4489 case DataType::AUDIO:
4490 search_path = config.get_audio_search_path ();
4492 case DataType::MIDI:
4493 search_path = config.get_midi_search_path ();
4497 split (search_path, dirs, ':');
4499 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4500 /* No need to add this new directory if it has the same inode as
4501 an existing one; checking inode rather than name prevents duplicated
4502 directories when we are using symlinks.
4504 On Windows, I think we could just do if (*i == path) here.
4506 if (PBD::equivalent_paths (*i, path)) {
4511 if (!search_path.empty()) {
4515 search_path += path;
4518 case DataType::AUDIO:
4519 config.set_audio_search_path (search_path);
4521 case DataType::MIDI:
4522 config.set_midi_search_path (search_path);
4527 boost::shared_ptr<Speakers>
4528 Session::get_speakers()
4534 Session::unknown_processors () const
4538 boost::shared_ptr<RouteList> r = routes.reader ();
4539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4540 list<string> t = (*i)->unknown_processors ();
4541 copy (t.begin(), t.end(), back_inserter (p));
4551 Session::update_latency (bool playback)
4553 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4555 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
4559 boost::shared_ptr<RouteList> r = routes.reader ();
4560 framecnt_t max_latency = 0;
4563 /* reverse the list so that we work backwards from the last route to run to the first */
4564 RouteList* rl = routes.reader().get();
4565 r.reset (new RouteList (*rl));
4566 reverse (r->begin(), r->end());
4569 /* compute actual latency values for the given direction and store them all in per-port
4570 structures. this will also publish the same values (to JACK) so that computation of latency
4571 for routes can consistently use public latency values.
4574 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4575 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4578 /* because we latency compensate playback, our published playback latencies should
4579 be the same for all output ports - all material played back by ardour has
4580 the same latency, whether its caused by plugins or by latency compensation. since
4581 these may differ from the values computed above, reset all playback port latencies
4585 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4587 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4588 (*i)->set_public_port_latencies (max_latency, playback);
4593 post_playback_latency ();
4597 post_capture_latency ();
4600 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
4604 Session::post_playback_latency ()
4606 set_worst_playback_latency ();
4608 boost::shared_ptr<RouteList> r = routes.reader ();
4610 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4611 if (!(*i)->is_hidden() && ((*i)->active())) {
4612 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
4616 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4617 (*i)->set_latency_compensation (_worst_track_latency);
4622 Session::post_capture_latency ()
4624 set_worst_capture_latency ();
4626 /* reflect any changes in capture latencies into capture offsets
4629 boost::shared_ptr<RouteList> rl = routes.reader();
4630 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4631 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4633 tr->set_capture_offset ();
4639 Session::initialize_latencies ()
4642 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4643 update_latency (false);
4644 update_latency (true);
4647 set_worst_io_latencies ();
4651 Session::set_worst_io_latencies ()
4653 set_worst_playback_latency ();
4654 set_worst_capture_latency ();
4658 Session::set_worst_playback_latency ()
4660 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4664 _worst_output_latency = 0;
4666 if (!_engine.connected()) {
4670 boost::shared_ptr<RouteList> r = routes.reader ();
4672 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4673 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
4676 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
4680 Session::set_worst_capture_latency ()
4682 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4686 _worst_input_latency = 0;
4688 if (!_engine.connected()) {
4692 boost::shared_ptr<RouteList> r = routes.reader ();
4694 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4695 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
4698 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
4702 Session::update_latency_compensation (bool force_whole_graph)
4704 bool some_track_latency_changed = false;
4706 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4710 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
4712 _worst_track_latency = 0;
4714 boost::shared_ptr<RouteList> r = routes.reader ();
4716 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4717 if (!(*i)->is_hidden() && ((*i)->active())) {
4719 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
4720 some_track_latency_changed = true;
4722 _worst_track_latency = max (tl, _worst_track_latency);
4726 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
4727 (some_track_latency_changed ? "yes" : "no")));
4729 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
4731 if (some_track_latency_changed || force_whole_graph) {
4732 _engine.update_latencies ();
4736 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4737 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4741 tr->set_capture_offset ();
4746 Session::session_name_is_legal (const string& path)
4748 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
4750 for (int i = 0; illegal_chars[i]; ++i) {
4751 if (path.find (illegal_chars[i]) != string::npos) {
4752 return illegal_chars[i];
4760 Session::next_control_id () const
4764 /* the monitor bus remote ID is in a different
4765 * "namespace" than regular routes. its existence doesn't
4766 * affect normal (low) numbered routes.
4773 return nroutes() - subtract;
4777 Session::notify_remote_id_change ()
4779 if (deletion_in_progress()) {
4783 switch (Config->get_remote_model()) {
4786 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
4794 Session::sync_order_keys (RouteSortOrderKey sort_key_changed)
4796 if (deletion_in_progress()) {
4800 /* tell everyone that something has happened to the sort keys
4801 and let them sync up with the change(s)
4802 this will give objects that manage the sort order keys the
4803 opportunity to keep them in sync if they wish to.
4806 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("Sync Order Keys, based on %1\n", enum_2_string (sort_key_changed)));
4808 Route::SyncOrderKeys (sort_key_changed); /* EMIT SIGNAL */
4810 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
4814 Session::operation_in_progress (GQuark op) const
4816 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
4819 boost::shared_ptr<Port>
4820 Session::ltc_input_port () const
4822 return _ltc_input->nth (0);
4825 boost::shared_ptr<Port>
4826 Session::ltc_output_port () const
4828 return _ltc_output->nth (0);
4832 Session::reconnect_ltc_input ()
4836 string src = Config->get_ltc_source_port();
4838 _ltc_input->disconnect (this);
4840 if (src != _("None") && !src.empty()) {
4841 _ltc_input->nth (0)->connect (src);
4847 Session::reconnect_ltc_output ()
4852 string src = Config->get_ltc_sink_port();
4854 _ltc_output->disconnect (this);
4856 if (src != _("None") && !src.empty()) {
4857 _ltc_output->nth (0)->connect (src);