2 Copyright (C) 1999-2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/threads.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/error.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
48 #include "pbd/unwind.h"
50 #include "ardour/amp.h"
51 #include "ardour/analyser.h"
52 #include "ardour/audio_buffer.h"
53 #include "ardour/audio_diskstream.h"
54 #include "ardour/audio_port.h"
55 #include "ardour/audio_track.h"
56 #include "ardour/audioengine.h"
57 #include "ardour/audiofilesource.h"
58 #include "ardour/auditioner.h"
59 #include "ardour/buffer_manager.h"
60 #include "ardour/buffer_set.h"
61 #include "ardour/bundle.h"
62 #include "ardour/butler.h"
63 #include "ardour/click.h"
64 #include "ardour/control_protocol_manager.h"
65 #include "ardour/data_type.h"
66 #include "ardour/debug.h"
67 #include "ardour/filename_extensions.h"
68 #include "ardour/graph.h"
69 #include "ardour/midi_track.h"
70 #include "ardour/midi_ui.h"
71 #include "ardour/operations.h"
72 #include "ardour/playlist.h"
73 #include "ardour/plugin.h"
74 #include "ardour/plugin_insert.h"
75 #include "ardour/process_thread.h"
76 #include "ardour/rc_configuration.h"
77 #include "ardour/recent_sessions.h"
78 #include "ardour/region.h"
79 #include "ardour/region_factory.h"
80 #include "ardour/route_graph.h"
81 #include "ardour/route_group.h"
82 #include "ardour/send.h"
83 #include "ardour/session.h"
84 #include "ardour/session_directory.h"
85 #include "ardour/session_playlists.h"
86 #include "ardour/smf_source.h"
87 #include "ardour/source_factory.h"
88 #include "ardour/utils.h"
90 #include "midi++/port.h"
91 #include "midi++/jack_midi_port.h"
92 #include "midi++/mmc.h"
93 #include "midi++/manager.h"
104 using namespace ARDOUR;
107 bool Session::_disable_all_loaded_plugins = false;
109 PBD::Signal1<void,std::string> Session::Dialog;
110 PBD::Signal0<int> Session::AskAboutPendingState;
111 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
112 PBD::Signal0<void> Session::SendFeedback;
113 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
115 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
116 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
117 PBD::Signal2<void,std::string, std::string> Session::Exported;
118 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
119 PBD::Signal0<void> Session::Quit;
120 PBD::Signal0<void> Session::FeedbackDetected;
121 PBD::Signal0<void> Session::SuccessfulGraphSort;
123 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
124 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
126 /** @param snapshot_name Snapshot name, without .ardour suffix */
127 Session::Session (AudioEngine &eng,
128 const string& fullpath,
129 const string& snapshot_name,
130 BusProfile* bus_profile,
133 , _target_transport_speed (0.0)
134 , _requested_return_frame (-1)
135 , _session_dir (new SessionDirectory(fullpath))
137 , _state_of_the_state (Clean)
138 , _butler (new Butler (*this))
139 , _post_transport_work (0)
140 , _send_timecode_update (false)
141 , _all_route_group (new RouteGroup (*this, "all"))
142 , routes (new RouteList)
143 , _total_free_4k_blocks (0)
144 , _total_free_4k_blocks_uncertain (false)
145 , _bundles (new BundleList)
146 , _bundle_xml_node (0)
149 , click_emphasis_data (0)
151 , _have_rec_enabled_track (false)
152 , _suspend_timecode_transmission (0)
154 _locations = new Locations (*this);
159 if (how_many_dsp_threads () > 1) {
160 /* For now, only create the graph if we are using >1 DSP threads, as
161 it is a bit slower than the old code with 1 thread.
163 _process_graph.reset (new Graph (*this));
166 playlists.reset (new SessionPlaylists);
168 _all_route_group->set_active (true, this);
170 interpolation.add_channel_to (0, 0);
172 if (!eng.connected()) {
173 throw failed_constructor();
176 n_physical_outputs = _engine.n_physical_outputs ();
177 n_physical_inputs = _engine.n_physical_inputs ();
179 first_stage_init (fullpath, snapshot_name);
181 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
184 if (create (mix_template, bus_profile)) {
186 throw failed_constructor ();
190 if (second_stage_init ()) {
192 throw failed_constructor ();
195 store_recent_sessions(_name, _path);
197 bool was_dirty = dirty();
199 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
201 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
202 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
205 DirtyChanged (); /* EMIT SIGNAL */
208 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
209 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
225 vector<void*> debug_pointers;
227 /* if we got to here, leaving pending capture state around
231 remove_pending_capture_state ();
233 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
235 _engine.remove_session ();
237 /* deregister all ports - there will be no process or any other
238 * callbacks from the engine any more.
241 Port::PortDrop (); /* EMIT SIGNAL */
247 /* clear history so that no references to objects are held any more */
251 /* clear state tree so that no references to objects are held any more */
255 /* reset dynamic state version back to default */
257 Stateful::loading_state_version = 0;
259 _butler->drop_references ();
263 delete midi_control_ui;
264 delete _all_route_group;
266 if (click_data != default_click) {
267 delete [] click_data;
270 if (click_emphasis_data != default_click_emphasis) {
271 delete [] click_emphasis_data;
276 /* clear out any pending dead wood from RCU managed objects */
281 AudioDiskstream::free_working_buffers();
283 /* tell everyone who is still standing that we're about to die */
286 /* tell everyone to drop references and delete objects as we go */
288 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
289 RegionFactory::delete_all_regions ();
291 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
293 /* reset these three references to special routes before we do the usual route delete thing */
296 _master_out.reset ();
297 _monitor_out.reset ();
300 RCUWriter<RouteList> writer (routes);
301 boost::shared_ptr<RouteList> r = writer.get_copy ();
303 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
304 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
305 (*i)->drop_references ();
309 /* writer goes out of scope and updates master */
313 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
314 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
315 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
316 i->second->drop_references ();
321 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
322 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
327 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
332 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
334 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
335 boost_debug_list_ptrs ();
340 Session::when_engine_running ()
342 string first_physical_output;
344 BootMessage (_("Set block size and sample rate"));
346 set_block_size (_engine.frames_per_cycle());
347 set_frame_rate (_engine.frame_rate());
349 BootMessage (_("Using configuration"));
351 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
352 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
354 Config->map_parameters (ff);
355 config.map_parameters (ft);
357 /* every time we reconnect, recompute worst case output latencies */
359 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
361 if (synced_to_jack()) {
362 _engine.transport_stop ();
365 if (config.get_jack_time_master()) {
366 _engine.transport_locate (_transport_frame);
374 _ltc_input.reset (new IO (*this, _("LTC In"), IO::Input));
375 _ltc_output.reset (new IO (*this, _("LTC Out"), IO::Output));
377 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-In")) != 0) {
378 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
381 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
382 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
384 reconnect_ltc_input ();
387 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-Out")) != 0) {
388 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
391 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
392 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
394 reconnect_ltc_output ();
397 /* fix up names of LTC ports because we don't want the normal
398 * IO style of NAME/TYPE-{in,out}N
401 _ltc_input->nth (0)->set_name (_("LTC-in"));
402 _ltc_output->nth (0)->set_name (_("LTC-out"));
404 _click_io.reset (new ClickIO (*this, "click"));
405 _click_gain.reset (new Amp (*this));
406 _click_gain->activate ();
408 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
410 /* existing state for Click */
413 if (Stateful::loading_state_version < 3000) {
414 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
416 const XMLNodeList& children (child->children());
417 XMLNodeList::const_iterator i = children.begin();
418 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
420 if (i != children.end()) {
421 c = _click_gain->set_state (**i, Stateful::loading_state_version);
427 _clicking = Config->get_clicking ();
431 error << _("could not setup Click I/O") << endmsg;
438 /* default state for Click: dual-mono to first 2 physical outputs */
441 _engine.get_physical_outputs (DataType::AUDIO, outs);
443 for (uint32_t physport = 0; physport < 2; ++physport) {
444 if (outs.size() > physport) {
445 if (_click_io->add_port (outs[physport], this)) {
446 // relax, even though its an error
451 if (_click_io->n_ports () > ChanCount::ZERO) {
452 _clicking = Config->get_clicking ();
457 catch (failed_constructor& err) {
458 error << _("cannot setup Click I/O") << endmsg;
461 BootMessage (_("Compute I/O Latencies"));
464 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
467 BootMessage (_("Set up standard connections"));
469 vector<string> inputs[DataType::num_types];
470 vector<string> outputs[DataType::num_types];
471 for (uint32_t i = 0; i < DataType::num_types; ++i) {
472 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
473 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
476 /* Create a set of Bundle objects that map
477 to the physical I/O currently available. We create both
478 mono and stereo bundles, so that the common cases of mono
479 and stereo tracks get bundles to put in their mixer strip
480 in / out menus. There may be a nicer way of achieving that;
481 it doesn't really scale that well to higher channel counts
484 /* mono output bundles */
486 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
488 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
490 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
491 c->add_channel (_("mono"), DataType::AUDIO);
492 c->set_port (0, outputs[DataType::AUDIO][np]);
497 /* stereo output bundles */
499 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
500 if (np + 1 < outputs[DataType::AUDIO].size()) {
502 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
503 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
504 c->add_channel (_("L"), DataType::AUDIO);
505 c->set_port (0, outputs[DataType::AUDIO][np]);
506 c->add_channel (_("R"), DataType::AUDIO);
507 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
513 /* mono input bundles */
515 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
517 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
519 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
520 c->add_channel (_("mono"), DataType::AUDIO);
521 c->set_port (0, inputs[DataType::AUDIO][np]);
526 /* stereo input bundles */
528 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
529 if (np + 1 < inputs[DataType::AUDIO].size()) {
531 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
533 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
534 c->add_channel (_("L"), DataType::AUDIO);
535 c->set_port (0, inputs[DataType::AUDIO][np]);
536 c->add_channel (_("R"), DataType::AUDIO);
537 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
543 /* MIDI input bundles */
545 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
546 string n = inputs[DataType::MIDI][np];
547 boost::erase_first (n, X_("alsa_pcm:"));
549 boost::shared_ptr<Bundle> c (new Bundle (n, false));
550 c->add_channel ("", DataType::MIDI);
551 c->set_port (0, inputs[DataType::MIDI][np]);
555 /* MIDI output bundles */
557 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
558 string n = outputs[DataType::MIDI][np];
559 boost::erase_first (n, X_("alsa_pcm:"));
561 boost::shared_ptr<Bundle> c (new Bundle (n, true));
562 c->add_channel ("", DataType::MIDI);
563 c->set_port (0, outputs[DataType::MIDI][np]);
567 BootMessage (_("Setup signal flow and plugins"));
569 /* Reset all panners */
571 Delivery::reset_panners ();
573 /* this will cause the CPM to instantiate any protocols that are in use
574 * (or mandatory), which will pass it this Session, and then call
575 * set_state() on each instantiated protocol to match stored state.
578 ControlProtocolManager::instance().set_session (this);
580 /* This must be done after the ControlProtocolManager set_session above,
581 as it will set states for ports which the ControlProtocolManager creates.
584 MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
586 /* And this must be done after the MIDI::Manager::set_port_states as
587 * it will try to make connections whose details are loaded by set_port_states.
592 /* Let control protocols know that we are now all connected, so they
593 * could start talking to surfaces if they want to.
596 ControlProtocolManager::instance().midi_connectivity_established ();
598 if (_is_new && !no_auto_connect()) {
599 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
600 auto_connect_master_bus ();
603 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
605 /* update latencies */
607 initialize_latencies ();
609 /* hook us up to the engine */
611 BootMessage (_("Connect to engine"));
612 _engine.set_session (this);
613 _engine.reset_timebase ();
617 Session::auto_connect_master_bus ()
619 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
623 /* if requested auto-connect the outputs to the first N physical ports.
626 uint32_t limit = _master_out->n_outputs().n_total();
627 vector<string> outputs[DataType::num_types];
629 for (uint32_t i = 0; i < DataType::num_types; ++i) {
630 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
633 for (uint32_t n = 0; n < limit; ++n) {
634 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
636 if (outputs[p->type()].size() > n) {
637 connect_to = outputs[p->type()][n];
640 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
641 if (_master_out->output()->connect (p, connect_to, this)) {
642 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
651 Session::remove_monitor_section ()
657 /* force reversion to Solo-In-Place */
658 Config->set_solo_control_is_listen_control (false);
661 /* Hold process lock while doing this so that we don't hear bits and
662 * pieces of audio as we work on each route.
665 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
667 /* Connect tracks to monitor section. Note that in an
668 existing session, the internal sends will already exist, but we want the
669 routes to notice that they connect to the control out specifically.
673 boost::shared_ptr<RouteList> r = routes.reader ();
674 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
676 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
678 if ((*x)->is_monitor()) {
680 } else if ((*x)->is_master()) {
683 (*x)->remove_aux_or_listen (_monitor_out);
688 remove_route (_monitor_out);
689 auto_connect_master_bus ();
693 Session::add_monitor_section ()
697 if (_monitor_out || !_master_out) {
701 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
707 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
708 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
711 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
712 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
713 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
717 add_routes (rl, false, false, false);
719 assert (_monitor_out);
721 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
722 are undefined, at best.
725 uint32_t limit = _monitor_out->n_inputs().n_audio();
729 /* connect the inputs to the master bus outputs. this
730 * represents a separate data feed from the internal sends from
731 * each route. as of jan 2011, it allows the monitor section to
732 * conditionally ignore either the internal sends or the normal
733 * input feed, but we should really find a better way to do
737 _master_out->output()->disconnect (this);
739 for (uint32_t n = 0; n < limit; ++n) {
740 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
741 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
744 string connect_to = o->name();
745 if (_monitor_out->input()->connect (p, connect_to, this)) {
746 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
754 /* if monitor section is not connected, connect it to physical outs
757 if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
759 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
761 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
764 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
766 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
767 Config->get_monitor_bus_preferred_bundle())
773 /* Monitor bus is audio only */
775 uint32_t mod = n_physical_outputs.get (DataType::AUDIO);
776 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
777 vector<string> outputs[DataType::num_types];
779 for (uint32_t i = 0; i < DataType::num_types; ++i) {
780 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
786 for (uint32_t n = 0; n < limit; ++n) {
788 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
790 if (outputs[DataType::AUDIO].size() > (n % mod)) {
791 connect_to = outputs[DataType::AUDIO][n % mod];
794 if (!connect_to.empty()) {
795 if (_monitor_out->output()->connect (p, connect_to, this)) {
796 error << string_compose (
797 _("cannot connect control output %1 to %2"),
808 /* Hold process lock while doing this so that we don't hear bits and
809 * pieces of audio as we work on each route.
812 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
814 /* Connect tracks to monitor section. Note that in an
815 existing session, the internal sends will already exist, but we want the
816 routes to notice that they connect to the control out specifically.
820 boost::shared_ptr<RouteList> rls = routes.reader ();
822 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
824 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
826 if ((*x)->is_monitor()) {
828 } else if ((*x)->is_master()) {
831 (*x)->enable_monitor_send ();
837 Session::hookup_io ()
839 /* stop graph reordering notifications from
840 causing resorts, etc.
843 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
847 /* we delay creating the auditioner till now because
848 it makes its own connections to ports.
852 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
854 throw failed_constructor ();
856 a->use_new_diskstream ();
860 catch (failed_constructor& err) {
861 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
865 /* load bundles, which we may have postponed earlier on */
866 if (_bundle_xml_node) {
867 load_bundles (*_bundle_xml_node);
868 delete _bundle_xml_node;
871 /* Tell all IO objects to connect themselves together */
873 IO::enable_connecting ();
874 MIDI::JackMIDIPort::MakeConnections ();
876 /* Anyone who cares about input state, wake up and do something */
878 IOConnectionsComplete (); /* EMIT SIGNAL */
880 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
882 /* now handle the whole enchilada as if it was one
888 /* update the full solo state, which can't be
889 correctly determined on a per-route basis, but
890 needs the global overview that only the session
894 update_route_solo_state ();
898 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
900 boost::shared_ptr<Track> track = wp.lock ();
905 boost::shared_ptr<Playlist> playlist;
907 if ((playlist = track->playlist()) != 0) {
908 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
909 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
910 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
915 Session::record_enabling_legal () const
917 /* this used to be in here, but survey says.... we don't need to restrict it */
918 // if (record_status() == Recording) {
922 if (Config->get_all_safe()) {
929 Session::set_track_monitor_input_status (bool yn)
931 boost::shared_ptr<RouteList> rl = routes.reader ();
932 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
933 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
934 if (tr && tr->record_enabled ()) {
935 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
936 tr->request_jack_monitors_input (yn);
942 Session::auto_punch_start_changed (Location* location)
944 replace_event (SessionEvent::PunchIn, location->start());
946 if (get_record_enabled() && config.get_punch_in()) {
947 /* capture start has been changed, so save new pending state */
948 save_state ("", true);
953 Session::auto_punch_end_changed (Location* location)
955 framepos_t when_to_stop = location->end();
956 // when_to_stop += _worst_output_latency + _worst_input_latency;
957 replace_event (SessionEvent::PunchOut, when_to_stop);
961 Session::auto_punch_changed (Location* location)
963 framepos_t when_to_stop = location->end();
965 replace_event (SessionEvent::PunchIn, location->start());
966 //when_to_stop += _worst_output_latency + _worst_input_latency;
967 replace_event (SessionEvent::PunchOut, when_to_stop);
970 /** @param loc A loop location.
971 * @param pos Filled in with the start time of the required fade-out (in session frames).
972 * @param length Filled in with the length of the required fade-out.
975 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
977 pos = max (loc->start(), loc->end() - 64);
978 length = loc->end() - pos;
982 Session::auto_loop_changed (Location* location)
984 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
987 auto_loop_declick_range (location, dcp, dcl);
988 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
990 if (transport_rolling() && play_loop) {
993 // if (_transport_frame > location->end()) {
995 if (_transport_frame < location->start() || _transport_frame > location->end()) {
996 // relocate to beginning of loop
997 clear_events (SessionEvent::LocateRoll);
999 request_locate (location->start(), true);
1002 else if (Config->get_seamless_loop() && !loop_changing) {
1004 // schedule a locate-roll to refill the diskstreams at the
1005 // previous loop end
1006 loop_changing = true;
1008 if (location->end() > last_loopend) {
1009 clear_events (SessionEvent::LocateRoll);
1010 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1017 last_loopend = location->end();
1021 Session::set_auto_punch_location (Location* location)
1025 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1026 punch_connections.drop_connections();
1027 existing->set_auto_punch (false, this);
1028 remove_event (existing->start(), SessionEvent::PunchIn);
1029 clear_events (SessionEvent::PunchOut);
1030 auto_punch_location_changed (0);
1035 if (location == 0) {
1039 if (location->end() <= location->start()) {
1040 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1044 punch_connections.drop_connections ();
1046 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1047 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1048 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1050 location->set_auto_punch (true, this);
1052 auto_punch_changed (location);
1054 auto_punch_location_changed (location);
1058 Session::set_auto_loop_location (Location* location)
1062 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1063 loop_connections.drop_connections ();
1064 existing->set_auto_loop (false, this);
1065 remove_event (existing->end(), SessionEvent::AutoLoop);
1068 auto_loop_declick_range (existing, dcp, dcl);
1069 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1070 auto_loop_location_changed (0);
1075 if (location == 0) {
1079 if (location->end() <= location->start()) {
1080 error << _("Session: you can't use a mark for auto loop") << endmsg;
1084 last_loopend = location->end();
1086 loop_connections.drop_connections ();
1088 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1089 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1090 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1092 location->set_auto_loop (true, this);
1094 /* take care of our stuff first */
1096 auto_loop_changed (location);
1098 /* now tell everyone else */
1100 auto_loop_location_changed (location);
1104 Session::locations_added (Location *)
1110 Session::locations_changed ()
1112 _locations->apply (*this, &Session::handle_locations_changed);
1116 Session::handle_locations_changed (Locations::LocationList& locations)
1118 Locations::LocationList::iterator i;
1120 bool set_loop = false;
1121 bool set_punch = false;
1123 for (i = locations.begin(); i != locations.end(); ++i) {
1127 if (location->is_auto_punch()) {
1128 set_auto_punch_location (location);
1131 if (location->is_auto_loop()) {
1132 set_auto_loop_location (location);
1136 if (location->is_session_range()) {
1137 _session_range_location = location;
1142 set_auto_loop_location (0);
1145 set_auto_punch_location (0);
1152 Session::enable_record ()
1154 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1155 /* no recording at anything except normal speed */
1160 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1162 if (rs == Recording) {
1166 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1168 _last_record_location = _transport_frame;
1169 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1171 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1172 set_track_monitor_input_status (true);
1175 RecordStateChanged ();
1182 Session::disable_record (bool rt_context, bool force)
1186 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1188 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1189 g_atomic_int_set (&_record_status, Disabled);
1190 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1192 if (rs == Recording) {
1193 g_atomic_int_set (&_record_status, Enabled);
1197 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1198 set_track_monitor_input_status (false);
1201 RecordStateChanged (); /* emit signal */
1204 remove_pending_capture_state ();
1210 Session::step_back_from_record ()
1212 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1214 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1215 set_track_monitor_input_status (false);
1218 RecordStateChanged (); /* emit signal */
1223 Session::maybe_enable_record ()
1225 if (_step_editors > 0) {
1229 g_atomic_int_set (&_record_status, Enabled);
1231 /* This function is currently called from somewhere other than an RT thread.
1232 This save_state() call therefore doesn't impact anything. Doing it here
1233 means that we save pending state of which sources the next record will use,
1234 which gives us some chance of recovering from a crash during the record.
1237 save_state ("", true);
1239 if (_transport_speed) {
1240 if (!config.get_punch_in()) {
1244 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1245 RecordStateChanged (); /* EMIT SIGNAL */
1252 Session::audible_frame () const
1258 /* the first of these two possible settings for "offset"
1259 mean that the audible frame is stationary until
1260 audio emerges from the latency compensation
1263 the second means that the audible frame is stationary
1264 until audio would emerge from a physical port
1265 in the absence of any plugin latency compensation
1268 offset = worst_playback_latency ();
1270 if (offset > current_block_size) {
1271 offset -= current_block_size;
1273 /* XXX is this correct? if we have no external
1274 physical connections and everything is internal
1275 then surely this is zero? still, how
1276 likely is that anyway?
1278 offset = current_block_size;
1281 if (synced_to_jack()) {
1282 tf = _engine.transport_frame();
1284 tf = _transport_frame;
1289 if (!non_realtime_work_pending()) {
1293 /* Check to see if we have passed the first guaranteed
1294 audible frame past our last start position. if not,
1295 return that last start point because in terms
1296 of audible frames, we have not moved yet.
1298 `Start position' in this context means the time we last
1299 either started, located, or changed transport direction.
1302 if (_transport_speed > 0.0f) {
1304 if (!play_loop || !have_looped) {
1305 if (tf < _last_roll_or_reversal_location + offset) {
1306 return _last_roll_or_reversal_location;
1314 } else if (_transport_speed < 0.0f) {
1316 /* XXX wot? no backward looping? */
1318 if (tf > _last_roll_or_reversal_location - offset) {
1319 return _last_roll_or_reversal_location;
1331 Session::set_frame_rate (framecnt_t frames_per_second)
1333 /** \fn void Session::set_frame_size(framecnt_t)
1334 the AudioEngine object that calls this guarantees
1335 that it will not be called while we are also in
1336 ::process(). Its fine to do things that block
1340 _base_frame_rate = frames_per_second;
1344 Automatable::set_automation_interval (ceil ((double) frames_per_second * 0.001 * Config->get_automation_interval_msecs()));
1348 // XXX we need some equivalent to this, somehow
1349 // SndFileSource::setup_standard_crossfades (frames_per_second);
1353 /* XXX need to reset/reinstantiate all LADSPA plugins */
1357 Session::set_block_size (pframes_t nframes)
1359 /* the AudioEngine guarantees
1360 that it will not be called while we are also in
1361 ::process(). It is therefore fine to do things that block
1366 current_block_size = nframes;
1370 boost::shared_ptr<RouteList> r = routes.reader ();
1372 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1373 (*i)->set_block_size (nframes);
1376 boost::shared_ptr<RouteList> rl = routes.reader ();
1377 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1378 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1380 tr->set_block_size (nframes);
1384 set_worst_io_latencies ();
1390 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1392 boost::shared_ptr<Route> r2;
1394 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1395 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1399 /* make a copy of the existing list of routes that feed r1 */
1401 Route::FedBy existing (r1->fed_by());
1403 /* for each route that feeds r1, recurse, marking it as feeding
1407 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1408 if (!(r2 = i->r.lock ())) {
1409 /* (*i) went away, ignore it */
1413 /* r2 is a route that feeds r1 which somehow feeds base. mark
1414 base as being fed by r2
1417 rbase->add_fed_by (r2, i->sends_only);
1421 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1425 if (r1->feeds (r2) && r2->feeds (r1)) {
1429 /* now recurse, so that we can mark base as being fed by
1430 all routes that feed r2
1433 trace_terminal (r2, rbase);
1440 Session::resort_routes ()
1442 /* don't do anything here with signals emitted
1443 by Routes during initial setup or while we
1444 are being destroyed.
1447 if (_state_of_the_state & (InitialConnecting | Deletion)) {
1452 RCUWriter<RouteList> writer (routes);
1453 boost::shared_ptr<RouteList> r = writer.get_copy ();
1454 resort_routes_using (r);
1455 /* writer goes out of scope and forces update */
1459 boost::shared_ptr<RouteList> rl = routes.reader ();
1460 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1461 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1463 const Route::FedBy& fb ((*i)->fed_by());
1465 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1466 boost::shared_ptr<Route> sf = f->r.lock();
1468 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1476 /** This is called whenever we need to rebuild the graph of how we will process
1478 * @param r List of routes, in any order.
1482 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1484 /* We are going to build a directed graph of our routes;
1485 this is where the edges of that graph are put.
1490 /* Go through all routes doing two things:
1492 * 1. Collect the edges of the route graph. Each of these edges
1493 * is a pair of routes, one of which directly feeds the other
1494 * either by a JACK connection or by an internal send.
1496 * 2. Begin the process of making routes aware of which other
1497 * routes directly or indirectly feed them. This information
1498 * is used by the solo code.
1501 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1503 /* Clear out the route's list of direct or indirect feeds */
1504 (*i)->clear_fed_by ();
1506 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
1508 bool via_sends_only;
1510 /* See if this *j feeds *i according to the current state of the JACK
1511 connections and internal sends.
1513 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
1514 /* add the edge to the graph (part #1) */
1515 edges.add (*j, *i, via_sends_only);
1516 /* tell the route (for part #2) */
1517 (*i)->add_fed_by (*j, via_sends_only);
1522 /* Attempt a topological sort of the route graph */
1523 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
1525 if (sorted_routes) {
1526 /* We got a satisfactory topological sort, so there is no feedback;
1529 Note: the process graph rechain does not require a
1530 topologically-sorted list, but hey ho.
1532 if (_process_graph) {
1533 _process_graph->rechain (sorted_routes, edges);
1536 _current_route_graph = edges;
1538 /* Complete the building of the routes' lists of what directly
1539 or indirectly feeds them.
1541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1542 trace_terminal (*i, *i);
1545 *r = *sorted_routes;
1548 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1549 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1550 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1551 (*i)->name(), (*i)->order_key (MixerSort)));
1555 SuccessfulGraphSort (); /* EMIT SIGNAL */
1558 /* The topological sort failed, so we have a problem. Tell everyone
1559 and stick to the old graph; this will continue to be processed, so
1560 until the feedback is fixed, what is played back will not quite
1561 reflect what is actually connected. Note also that we do not
1562 do trace_terminal here, as it would fail due to an endless recursion,
1563 so the solo code will think that everything is still connected
1567 FeedbackDetected (); /* EMIT SIGNAL */
1572 /** Find a route name starting with \a base, maybe followed by the
1573 * lowest \a id. \a id will always be added if \a definitely_add_number
1574 * is true on entry; otherwise it will only be added if required
1575 * to make the name unique.
1577 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1578 * The available route name with the lowest ID will be used, and \a id
1579 * will be set to the ID.
1581 * \return false if a route name could not be found, and \a track_name
1582 * and \a id do not reflect a free route name.
1585 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1587 if (!definitely_add_number && route_by_name (base) == 0) {
1588 /* juse use the base */
1589 snprintf (name, name_len, "%s", base.c_str());
1594 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1596 if (route_by_name (name) == 0) {
1602 } while (id < (UINT_MAX-1));
1607 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
1609 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
1611 in = ChanCount::ZERO;
1612 out = ChanCount::ZERO;
1614 boost::shared_ptr<RouteList> r = routes.reader ();
1616 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1617 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1618 if (tr && !tr->is_hidden()) {
1619 in += tr->n_inputs();
1620 out += tr->n_outputs();
1625 /** Caller must not hold process lock
1626 * @param name_template string to use for the start of the name, or "" to use "MIDI".
1627 * @param instrument plugin info for the instrument to insert pre-fader, if any
1629 list<boost::shared_ptr<MidiTrack> >
1630 Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
1631 TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1633 char track_name[32];
1634 uint32_t track_id = 0;
1636 RouteList new_routes;
1637 list<boost::shared_ptr<MidiTrack> > ret;
1639 cerr << "Adding MIDI track with in = " << input << " out = " << output << endl;
1641 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
1644 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1645 error << "cannot find name for new midi track" << endmsg;
1649 boost::shared_ptr<MidiTrack> track;
1652 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1654 if (track->init ()) {
1658 track->use_new_diskstream();
1660 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1661 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1664 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1665 if (track->input()->ensure_io (input, false, this)) {
1666 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
1670 if (track->output()->ensure_io (output, false, this)) {
1671 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
1676 track->non_realtime_input_change();
1679 route_group->add (track);
1682 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1684 if (Config->get_remote_model() == UserOrdered) {
1685 track->set_remote_control_id (next_control_id());
1688 new_routes.push_back (track);
1689 ret.push_back (track);
1692 catch (failed_constructor &err) {
1693 error << _("Session: could not create new midi track.") << endmsg;
1697 catch (AudioEngine::PortRegistrationFailure& pfe) {
1699 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;
1707 if (!new_routes.empty()) {
1708 add_routes (new_routes, true, true, true);
1711 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
1712 PluginPtr plugin = instrument->load (*this);
1713 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
1714 (*r)->add_processor (p, PreFader);
1724 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
1726 boost::shared_ptr<Route> midi_track (wmt.lock());
1732 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
1734 if (change.after.n_audio() <= change.before.n_audio()) {
1738 /* new audio ports: make sure the audio goes somewhere useful,
1739 unless the user has no-auto-connect selected.
1741 The existing ChanCounts don't matter for this call as they are only
1742 to do with matching input and output indices, and we are only changing
1748 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
1752 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1753 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1754 * @param output_start As \a input_start, but for outputs.
1757 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
1758 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
1760 if (!IO::connecting_legal) {
1764 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
1770 /* If both inputs and outputs are auto-connected to physical ports,
1771 use the max of input and output offsets to ensure auto-connected
1772 port numbers always match up (e.g. the first audio input and the
1773 first audio output of the route will have the same physical
1774 port number). Otherwise just use the lowest input or output
1778 DEBUG_TRACE (DEBUG::Graph,
1779 string_compose("Auto-connect: existing in = %1 out = %2\n",
1780 existing_inputs, existing_outputs));
1782 const bool in_out_physical =
1783 (Config->get_input_auto_connect() & AutoConnectPhysical)
1784 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1787 const ChanCount in_offset = in_out_physical
1788 ? ChanCount::max(existing_inputs, existing_outputs)
1791 const ChanCount out_offset = in_out_physical
1792 ? ChanCount::max(existing_inputs, existing_outputs)
1795 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1796 vector<string> physinputs;
1797 vector<string> physoutputs;
1799 _engine.get_physical_outputs (*t, physoutputs);
1800 _engine.get_physical_inputs (*t, physinputs);
1802 if (!physinputs.empty() && connect_inputs) {
1803 uint32_t nphysical_in = physinputs.size();
1805 DEBUG_TRACE (DEBUG::Graph,
1806 string_compose("There are %1 physical inputs of type %2\n",
1809 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1812 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1813 DEBUG_TRACE (DEBUG::Graph,
1814 string_compose("Get index %1 + %2 % %3 = %4\n",
1815 in_offset.get(*t), i, nphysical_in,
1816 (in_offset.get(*t) + i) % nphysical_in));
1817 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1820 DEBUG_TRACE (DEBUG::Graph,
1821 string_compose("Connect route %1 IN to %2\n",
1822 route->name(), port));
1824 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
1828 ChanCount one_added (*t, 1);
1829 existing_inputs += one_added;
1833 if (!physoutputs.empty()) {
1834 uint32_t nphysical_out = physoutputs.size();
1835 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1838 if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
1839 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1840 } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
1841 /* master bus is audio only */
1842 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1843 port = _master_out->input()->ports().port(*t,
1844 i % _master_out->input()->n_ports().get(*t))->name();
1848 DEBUG_TRACE (DEBUG::Graph,
1849 string_compose("Connect route %1 OUT to %2\n",
1850 route->name(), port));
1852 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
1856 ChanCount one_added (*t, 1);
1857 existing_outputs += one_added;
1863 /** Caller must not hold process lock
1864 * @param name_template string to use for the start of the name, or "" to use "Audio".
1866 list< boost::shared_ptr<AudioTrack> >
1867 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
1868 uint32_t how_many, string name_template)
1870 char track_name[32];
1871 uint32_t track_id = 0;
1873 RouteList new_routes;
1874 list<boost::shared_ptr<AudioTrack> > ret;
1876 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
1879 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1880 error << "cannot find name for new audio track" << endmsg;
1884 boost::shared_ptr<AudioTrack> track;
1887 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1889 if (track->init ()) {
1893 track->use_new_diskstream();
1895 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1896 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1899 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1901 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1902 error << string_compose (
1903 _("cannot configure %1 in/%2 out configuration for new audio track"),
1904 input_channels, output_channels)
1909 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1910 error << string_compose (
1911 _("cannot configure %1 in/%2 out configuration for new audio track"),
1912 input_channels, output_channels)
1919 route_group->add (track);
1922 track->non_realtime_input_change();
1924 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1925 if (Config->get_remote_model() == UserOrdered) {
1926 track->set_remote_control_id (next_control_id());
1929 new_routes.push_back (track);
1930 ret.push_back (track);
1933 catch (failed_constructor &err) {
1934 error << _("Session: could not create new audio track.") << endmsg;
1938 catch (AudioEngine::PortRegistrationFailure& pfe) {
1940 error << pfe.what() << endmsg;
1948 if (!new_routes.empty()) {
1949 add_routes (new_routes, true, true, true);
1955 /** Caller must not hold process lock.
1956 * @param name_template string to use for the start of the name, or "" to use "Bus".
1959 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1962 uint32_t bus_id = 0;
1966 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
1969 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1970 error << "cannot find name for new audio bus" << endmsg;
1975 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1981 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1982 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1985 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1987 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1988 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1989 input_channels, output_channels)
1995 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1996 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1997 input_channels, output_channels)
2004 route_group->add (bus);
2006 if (Config->get_remote_model() == UserOrdered) {
2007 bus->set_remote_control_id (next_control_id());
2010 bus->add_internal_return ();
2012 ret.push_back (bus);
2016 catch (failed_constructor &err) {
2017 error << _("Session: could not create new audio route.") << endmsg;
2021 catch (AudioEngine::PortRegistrationFailure& pfe) {
2022 error << pfe.what() << endmsg;
2032 add_routes (ret, false, true, true); // autoconnect outputs only
2040 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2043 uint32_t control_id;
2045 uint32_t number = 0;
2047 if (!tree.read (template_path.c_str())) {
2051 XMLNode* node = tree.root();
2053 IO::disable_connecting ();
2055 control_id = next_control_id ();
2059 XMLNode node_copy (*node);
2061 /* Remove IDs of everything so that new ones are used */
2062 node_copy.remove_property_recursively (X_("id"));
2065 string const route_name = node_copy.property(X_("name"))->value ();
2067 /* generate a new name by adding a number to the end of the template name */
2069 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2070 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2074 /* set this name in the XML description that we are about to use */
2075 Route::set_name_in_state (node_copy, name);
2077 /* trim bitslots from listen sends so that new ones are used */
2078 XMLNodeList children = node_copy.children ();
2079 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2080 if ((*i)->name() == X_("Processor")) {
2081 XMLProperty* role = (*i)->property (X_("role"));
2082 if (role && role->value() == X_("Listen")) {
2083 (*i)->remove_property (X_("bitslot"));
2088 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2091 error << _("Session: cannot create track/bus from template description") << endmsg;
2095 if (boost::dynamic_pointer_cast<Track>(route)) {
2096 /* force input/output change signals so that the new diskstream
2097 picks up the configuration of the route. During session
2098 loading this normally happens in a different way.
2101 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2103 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2104 change.after = route->input()->n_ports();
2105 route->input()->changed (change, this);
2106 change.after = route->output()->n_ports();
2107 route->output()->changed (change, this);
2110 route->set_remote_control_id (control_id);
2113 ret.push_back (route);
2116 catch (failed_constructor &err) {
2117 error << _("Session: could not create new route from template") << endmsg;
2121 catch (AudioEngine::PortRegistrationFailure& pfe) {
2122 error << pfe.what() << endmsg;
2131 add_routes (ret, true, true, true);
2132 IO::enable_connecting ();
2139 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2141 ChanCount existing_inputs;
2142 ChanCount existing_outputs;
2143 uint32_t order = next_control_id();
2145 count_existing_track_channels (existing_inputs, existing_outputs);
2148 RCUWriter<RouteList> writer (routes);
2149 boost::shared_ptr<RouteList> r = writer.get_copy ();
2150 r->insert (r->end(), new_routes.begin(), new_routes.end());
2152 /* if there is no control out and we're not in the middle of loading,
2153 resort the graph here. if there is a control out, we will resort
2154 toward the end of this method. if we are in the middle of loading,
2155 we will resort when done.
2158 if (!_monitor_out && IO::connecting_legal) {
2159 resort_routes_using (r);
2163 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2165 boost::weak_ptr<Route> wpr (*x);
2166 boost::shared_ptr<Route> r (*x);
2168 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2169 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2170 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2171 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2172 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2173 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2175 if (r->is_master()) {
2179 if (r->is_monitor()) {
2183 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2185 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2186 track_playlist_changed (boost::weak_ptr<Track> (tr));
2187 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2189 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2191 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2192 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2196 if (input_auto_connect || output_auto_connect) {
2197 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2200 /* order keys are a GUI responsibility but we need to set up
2201 reasonable defaults because they also affect the remote control
2202 ID in most situations.
2205 if (!r->has_order_key (EditorSort)) {
2206 if (r->is_hidden()) {
2207 /* use an arbitrarily high value */
2208 r->set_order_key (EditorSort, UINT_MAX);
2209 r->set_order_key (MixerSort, UINT_MAX);
2211 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
2212 r->set_order_key (EditorSort, order);
2213 r->set_order_key (MixerSort, order);
2219 if (_monitor_out && IO::connecting_legal) {
2222 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2224 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2225 if ((*x)->is_monitor()) {
2227 } else if ((*x)->is_master()) {
2230 (*x)->enable_monitor_send ();
2241 save_state (_current_snapshot_name);
2244 RouteAdded (new_routes); /* EMIT SIGNAL */
2248 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2250 boost::shared_ptr<RouteList> r = routes.reader ();
2251 boost::shared_ptr<Send> s;
2253 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2254 if ((s = (*i)->internal_send_for (dest)) != 0) {
2255 s->amp()->gain_control()->set_value (0.0);
2261 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2263 boost::shared_ptr<RouteList> r = routes.reader ();
2264 boost::shared_ptr<Send> s;
2266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267 if ((s = (*i)->internal_send_for (dest)) != 0) {
2268 s->amp()->gain_control()->set_value (1.0);
2274 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2276 boost::shared_ptr<RouteList> r = routes.reader ();
2277 boost::shared_ptr<Send> s;
2279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2280 if ((s = (*i)->internal_send_for (dest)) != 0) {
2281 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2286 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2288 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2290 boost::shared_ptr<RouteList> r = routes.reader ();
2291 boost::shared_ptr<RouteList> t (new RouteList);
2293 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2294 /* no MIDI sends because there are no MIDI busses yet */
2295 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2300 add_internal_sends (dest, p, t);
2304 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2306 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2307 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2312 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2314 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2318 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2320 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2324 if (!dest->internal_return()) {
2325 dest->add_internal_return ();
2328 sender->add_aux_send (dest, before);
2334 Session::remove_route (boost::shared_ptr<Route> route)
2336 if (route == _master_out) {
2340 route->set_solo (false, this);
2343 RCUWriter<RouteList> writer (routes);
2344 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2348 /* deleting the master out seems like a dumb
2349 idea, but its more of a UI policy issue
2353 if (route == _master_out) {
2354 _master_out = boost::shared_ptr<Route> ();
2357 if (route == _monitor_out) {
2358 _monitor_out.reset ();
2361 /* writer goes out of scope, forces route list update */
2364 update_route_solo_state ();
2366 // We need to disconnect the route's inputs and outputs
2368 route->input()->disconnect (0);
2369 route->output()->disconnect (0);
2371 /* if the route had internal sends sending to it, remove them */
2372 if (route->internal_return()) {
2374 boost::shared_ptr<RouteList> r = routes.reader ();
2375 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2376 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2378 (*i)->remove_processor (s);
2383 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2384 if (mt && mt->step_editing()) {
2385 if (_step_editors > 0) {
2390 update_latency_compensation ();
2393 /* Re-sort routes to remove the graph's current references to the one that is
2394 * going away, then flush old references out of the graph.
2398 if (_process_graph) {
2399 _process_graph->clear_other_chain ();
2402 /* get rid of it from the dead wood collection in the route list manager */
2404 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2408 /* try to cause everyone to drop their references */
2410 route->drop_references ();
2412 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2414 /* save the new state of the world */
2416 if (save_state (_current_snapshot_name)) {
2417 save_history (_current_snapshot_name);
2422 Session::route_mute_changed (void* /*src*/)
2428 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2430 boost::shared_ptr<Route> route = wpr.lock();
2432 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2436 if (route->listening_via_monitor ()) {
2438 if (Config->get_exclusive_solo()) {
2439 /* new listen: disable all other listen */
2440 boost::shared_ptr<RouteList> r = routes.reader ();
2441 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2442 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2445 (*i)->set_listen (false, this);
2451 } else if (_listen_cnt > 0) {
2456 update_route_solo_state ();
2459 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2461 boost::shared_ptr<Route> route = wpr.lock ();
2464 /* should not happen */
2465 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2469 bool send_changed = false;
2471 if (route->solo_isolated()) {
2472 if (_solo_isolated_cnt == 0) {
2473 send_changed = true;
2475 _solo_isolated_cnt++;
2476 } else if (_solo_isolated_cnt > 0) {
2477 _solo_isolated_cnt--;
2478 if (_solo_isolated_cnt == 0) {
2479 send_changed = true;
2484 IsolatedChanged (); /* EMIT SIGNAL */
2489 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2491 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
2493 if (!self_solo_change) {
2494 // session doesn't care about changes to soloed-by-others
2498 if (solo_update_disabled) {
2500 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
2504 boost::shared_ptr<Route> route = wpr.lock ();
2507 boost::shared_ptr<RouteList> r = routes.reader ();
2510 if (route->self_soloed()) {
2516 RouteGroup* rg = route->route_group ();
2517 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
2519 if (delta == 1 && Config->get_exclusive_solo()) {
2521 /* new solo: disable all other solos, but not the group if its solo-enabled */
2523 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2524 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2525 (leave_group_alone && ((*i)->route_group() == rg))) {
2528 (*i)->set_solo (false, this);
2532 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
2534 solo_update_disabled = true;
2536 RouteList uninvolved;
2538 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
2540 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2541 bool via_sends_only;
2542 bool in_signal_flow;
2544 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2545 (leave_group_alone && ((*i)->route_group() == rg))) {
2549 in_signal_flow = false;
2551 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
2553 if ((*i)->feeds (route, &via_sends_only)) {
2554 if (!via_sends_only) {
2555 if (!route->soloed_by_others_upstream()) {
2556 (*i)->mod_solo_by_others_downstream (delta);
2559 in_signal_flow = true;
2561 DEBUG_TRACE (DEBUG::Solo, "\tno feed from\n");
2564 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
2566 if (route->feeds (*i, &via_sends_only)) {
2567 /* propagate solo upstream only if routing other than
2568 sends is involved, but do consider the other route
2569 (*i) to be part of the signal flow even if only
2572 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
2576 route->soloed_by_others_downstream(),
2577 route->soloed_by_others_upstream()));
2578 if (!via_sends_only) {
2579 if (!route->soloed_by_others_downstream()) {
2580 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
2581 (*i)->mod_solo_by_others_upstream (delta);
2584 in_signal_flow = true;
2586 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
2589 if (!in_signal_flow) {
2590 uninvolved.push_back (*i);
2594 solo_update_disabled = false;
2595 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
2597 update_route_solo_state (r);
2599 /* now notify that the mute state of the routes not involved in the signal
2600 pathway of the just-solo-changed route may have altered.
2603 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2604 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1\n", (*i)->name()));
2605 (*i)->mute_changed (this);
2608 SoloChanged (); /* EMIT SIGNAL */
2613 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2615 /* now figure out if anything that matters is soloed (or is "listening")*/
2617 bool something_soloed = false;
2618 uint32_t listeners = 0;
2619 uint32_t isolated = 0;
2622 r = routes.reader();
2625 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2626 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2627 something_soloed = true;
2630 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2631 if (Config->get_solo_control_is_listen_control()) {
2634 (*i)->set_listen (false, this);
2638 if ((*i)->solo_isolated()) {
2643 if (something_soloed != _non_soloed_outs_muted) {
2644 _non_soloed_outs_muted = something_soloed;
2645 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2648 _listen_cnt = listeners;
2650 if (isolated != _solo_isolated_cnt) {
2651 _solo_isolated_cnt = isolated;
2652 IsolatedChanged (); /* EMIT SIGNAL */
2656 boost::shared_ptr<RouteList>
2657 Session::get_routes_with_internal_returns() const
2659 boost::shared_ptr<RouteList> r = routes.reader ();
2660 boost::shared_ptr<RouteList> rl (new RouteList);
2662 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2663 if ((*i)->internal_return ()) {
2671 Session::io_name_is_legal (const std::string& name)
2673 boost::shared_ptr<RouteList> r = routes.reader ();
2675 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2676 if ((*i)->name() == name) {
2680 if ((*i)->has_io_processor_named (name)) {
2689 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
2692 vector<string> connections;
2694 /* if we are passed only a single route and we're not told to turn
2695 * others off, then just do the simple thing.
2698 if (flip_others == false && rl->size() == 1) {
2699 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
2701 mt->set_input_active (onoff);
2706 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
2708 PortSet& ps ((*rt)->input()->ports());
2710 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
2711 p->get_connections (connections);
2714 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
2715 routes_using_input_from (*s, rl2);
2718 /* scan all relevant routes to see if others are on or off */
2720 bool others_are_already_on = false;
2722 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2724 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2730 if ((*r) != (*rt)) {
2731 if (mt->input_active()) {
2732 others_are_already_on = true;
2735 /* this one needs changing */
2736 mt->set_input_active (onoff);
2742 /* globally reverse other routes */
2744 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2745 if ((*r) != (*rt)) {
2746 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2748 mt->set_input_active (!others_are_already_on);
2757 Session::routes_using_input_from (const string& str, RouteList& rl)
2759 boost::shared_ptr<RouteList> r = routes.reader();
2761 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2762 if ((*i)->input()->connected_to (str)) {
2768 boost::shared_ptr<Route>
2769 Session::route_by_name (string name)
2771 boost::shared_ptr<RouteList> r = routes.reader ();
2773 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2774 if ((*i)->name() == name) {
2779 return boost::shared_ptr<Route> ((Route*) 0);
2782 boost::shared_ptr<Route>
2783 Session::route_by_id (PBD::ID id)
2785 boost::shared_ptr<RouteList> r = routes.reader ();
2787 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2788 if ((*i)->id() == id) {
2793 return boost::shared_ptr<Route> ((Route*) 0);
2796 boost::shared_ptr<Track>
2797 Session::track_by_diskstream_id (PBD::ID id)
2799 boost::shared_ptr<RouteList> r = routes.reader ();
2801 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2802 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
2803 if (t && t->using_diskstream_id (id)) {
2808 return boost::shared_ptr<Track> ();
2811 boost::shared_ptr<Route>
2812 Session::route_by_remote_id (uint32_t id)
2814 boost::shared_ptr<RouteList> r = routes.reader ();
2816 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2817 if ((*i)->remote_control_id() == id) {
2822 return boost::shared_ptr<Route> ((Route*) 0);
2826 Session::playlist_region_added (boost::weak_ptr<Region> w)
2828 boost::shared_ptr<Region> r = w.lock ();
2833 /* These are the operations that are currently in progress... */
2834 list<GQuark> curr = _current_trans_quarks;
2837 /* ...and these are the operations during which we want to update
2838 the session range location markers.
2841 ops.push_back (Operations::capture);
2842 ops.push_back (Operations::paste);
2843 ops.push_back (Operations::duplicate_region);
2844 ops.push_back (Operations::insert_file);
2845 ops.push_back (Operations::insert_region);
2846 ops.push_back (Operations::drag_region_brush);
2847 ops.push_back (Operations::region_drag);
2848 ops.push_back (Operations::selection_grab);
2849 ops.push_back (Operations::region_fill);
2850 ops.push_back (Operations::fill_selection);
2851 ops.push_back (Operations::create_region);
2852 ops.push_back (Operations::region_copy);
2853 ops.push_back (Operations::fixed_time_region_copy);
2856 /* See if any of the current operations match the ones that we want */
2858 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2860 /* If so, update the session range markers */
2862 maybe_update_session_range (r->position (), r->last_frame ());
2866 /** Update the session range markers if a is before the current start or
2867 * b is after the current end.
2870 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2872 if (_state_of_the_state & Loading) {
2876 if (_session_range_location == 0) {
2878 add_session_range_location (a, b);
2882 if (a < _session_range_location->start()) {
2883 _session_range_location->set_start (a);
2886 if (b > _session_range_location->end()) {
2887 _session_range_location->set_end (b);
2893 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2895 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2896 maybe_update_session_range (i->to, i->to + i->length);
2901 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2903 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2904 maybe_update_session_range (i->from, i->to);
2908 /* Region management */
2910 boost::shared_ptr<Region>
2911 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2913 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2914 RegionFactory::RegionMap::const_iterator i;
2915 boost::shared_ptr<Region> region;
2917 Glib::Threads::Mutex::Lock lm (region_lock);
2919 for (i = regions.begin(); i != regions.end(); ++i) {
2923 if (region->whole_file()) {
2925 if (child->source_equivalent (region)) {
2931 return boost::shared_ptr<Region> ();
2935 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2937 set<boost::shared_ptr<Region> > relevant_regions;
2939 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2940 RegionFactory::get_regions_using_source (*s, relevant_regions);
2943 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2944 set<boost::shared_ptr<Region> >::iterator tmp;
2949 playlists->destroy_region (*r);
2950 RegionFactory::map_remove (*r);
2952 (*r)->drop_sources ();
2953 (*r)->drop_references ();
2955 relevant_regions.erase (r);
2960 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2963 Glib::Threads::Mutex::Lock ls (source_lock);
2964 /* remove from the main source list */
2965 sources.erase ((*s)->id());
2968 (*s)->mark_for_remove ();
2969 (*s)->drop_references ();
2978 Session::remove_last_capture ()
2980 list<boost::shared_ptr<Source> > srcs;
2982 boost::shared_ptr<RouteList> rl = routes.reader ();
2983 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2984 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2989 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2992 srcs.insert (srcs.end(), l.begin(), l.end());
2997 destroy_sources (srcs);
2999 save_state (_current_snapshot_name);
3004 /* Source Management */
3007 Session::add_source (boost::shared_ptr<Source> source)
3009 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3010 pair<SourceMap::iterator,bool> result;
3012 entry.first = source->id();
3013 entry.second = source;
3016 Glib::Threads::Mutex::Lock lm (source_lock);
3017 result = sources.insert (entry);
3020 if (result.second) {
3022 /* yay, new source */
3024 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3027 if (!fs->within_session()) {
3028 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3034 boost::shared_ptr<AudioFileSource> afs;
3036 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3037 if (Config->get_auto_analyse_audio()) {
3038 Analyser::queue_source_for_analysis (source, false);
3042 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3047 Session::remove_source (boost::weak_ptr<Source> src)
3049 if (_state_of_the_state & Deletion) {
3053 SourceMap::iterator i;
3054 boost::shared_ptr<Source> source = src.lock();
3061 Glib::Threads::Mutex::Lock lm (source_lock);
3063 if ((i = sources.find (source->id())) != sources.end()) {
3068 if (!(_state_of_the_state & InCleanup)) {
3070 /* save state so we don't end up with a session file
3071 referring to non-existent sources.
3074 save_state (_current_snapshot_name);
3078 boost::shared_ptr<Source>
3079 Session::source_by_id (const PBD::ID& id)
3081 Glib::Threads::Mutex::Lock lm (source_lock);
3082 SourceMap::iterator i;
3083 boost::shared_ptr<Source> source;
3085 if ((i = sources.find (id)) != sources.end()) {
3092 boost::shared_ptr<Source>
3093 Session::source_by_path_and_channel (const string& path, uint16_t chn)
3095 Glib::Threads::Mutex::Lock lm (source_lock);
3097 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3098 boost::shared_ptr<AudioFileSource> afs
3099 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3101 if (afs && afs->path() == path && chn == afs->channel()) {
3105 return boost::shared_ptr<Source>();
3109 Session::count_sources_by_origin (const string& path)
3112 Glib::Threads::Mutex::Lock lm (source_lock);
3114 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3115 boost::shared_ptr<FileSource> fs
3116 = boost::dynamic_pointer_cast<FileSource>(i->second);
3118 if (fs && fs->origin() == path) {
3128 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3131 string old_basename = PBD::basename_nosuffix (oldname);
3132 string new_legalized = legalize_for_path (newname);
3134 /* note: we know (or assume) the old path is already valid */
3138 /* destructive file sources have a name of the form:
3140 /path/to/Tnnnn-NAME(%[LR])?.wav
3142 the task here is to replace NAME with the new name.
3147 string::size_type dash;
3149 dir = Glib::path_get_dirname (path);
3150 path = Glib::path_get_basename (path);
3152 /* '-' is not a legal character for the NAME part of the path */
3154 if ((dash = path.find_last_of ('-')) == string::npos) {
3158 prefix = path.substr (0, dash);
3162 path += new_legalized;
3163 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3164 path = Glib::build_filename (dir, path);
3168 /* non-destructive file sources have a name of the form:
3170 /path/to/NAME-nnnnn(%[LR])?.ext
3172 the task here is to replace NAME with the new name.
3177 string::size_type dash;
3178 string::size_type postfix;
3180 dir = Glib::path_get_dirname (path);
3181 path = Glib::path_get_basename (path);
3183 /* '-' is not a legal character for the NAME part of the path */
3185 if ((dash = path.find_last_of ('-')) == string::npos) {
3189 suffix = path.substr (dash+1);
3191 // Suffix is now everything after the dash. Now we need to eliminate
3192 // the nnnnn part, which is done by either finding a '%' or a '.'
3194 postfix = suffix.find_last_of ("%");
3195 if (postfix == string::npos) {
3196 postfix = suffix.find_last_of ('.');
3199 if (postfix != string::npos) {
3200 suffix = suffix.substr (postfix);
3202 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3206 const uint32_t limit = 10000;
3207 char buf[PATH_MAX+1];
3209 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3211 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
3213 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
3214 path = Glib::build_filename (dir, buf);
3222 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
3231 /** Return the full path (in some session directory) for a new within-session source.
3232 * \a name must be a session-unique name that does not contain slashes
3233 * (e.g. as returned by new_*_source_name)
3236 Session::new_source_path_from_name (DataType type, const string& name)
3238 assert(name.find("/") == string::npos);
3240 SessionDirectory sdir(get_best_session_directory_for_new_source());
3243 if (type == DataType::AUDIO) {
3244 p = sdir.sound_path();
3245 } else if (type == DataType::MIDI) {
3246 p = sdir.midi_path();
3248 error << "Unknown source type, unable to create file path" << endmsg;
3252 return Glib::build_filename (p, name);
3256 Session::peak_path (string base) const
3258 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3261 /** Return a unique name based on \a base for a new internal audio source */
3263 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3266 char buf[PATH_MAX+1];
3267 const uint32_t limit = 10000;
3269 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3272 legalized = legalize_for_path (base);
3274 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3275 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3277 vector<space_and_path>::iterator i;
3278 uint32_t existing = 0;
3280 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3285 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3286 cnt, legalized.c_str(), ext.c_str());
3287 } else if (nchan == 2) {
3289 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
3290 cnt, legalized.c_str(), ext.c_str());
3292 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
3293 cnt, legalized.c_str(), ext.c_str());
3295 } else if (nchan < 26) {
3296 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
3297 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
3299 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3300 cnt, legalized.c_str(), ext.c_str());
3306 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3307 } else if (nchan == 2) {
3309 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
3311 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
3313 } else if (nchan < 26) {
3314 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
3316 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3320 SessionDirectory sdir((*i).path);
3322 string spath = sdir.sound_path();
3324 /* note that we search *without* the extension so that
3325 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3326 in the event that this new name is required for
3327 a file format change.
3330 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
3336 if (existing == 0) {
3341 error << string_compose(
3342 _("There are already %1 recordings for %2, which I consider too many."),
3343 limit, base) << endmsg;
3345 throw failed_constructor();
3349 return Glib::path_get_basename (buf);
3352 /** Create a new within-session audio source */
3353 boost::shared_ptr<AudioFileSource>
3354 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3356 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3357 const string path = new_source_path_from_name(DataType::AUDIO, name);
3359 return boost::dynamic_pointer_cast<AudioFileSource> (
3360 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3363 /** Return a unique name based on \a base for a new internal MIDI source */
3365 Session::new_midi_source_name (const string& base)
3368 char buf[PATH_MAX+1];
3369 const uint32_t limit = 10000;
3373 legalized = legalize_for_path (base);
3375 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3376 for (cnt = 1; cnt <= limit; ++cnt) {
3378 vector<space_and_path>::iterator i;
3379 uint32_t existing = 0;
3381 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3383 SessionDirectory sdir((*i).path);
3385 std::string p = Glib::build_filename (sdir.midi_path(), legalized);
3387 snprintf (buf, sizeof(buf), "%s-%u.mid", p.c_str(), cnt);
3389 if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3394 if (existing == 0) {
3399 error << string_compose(
3400 _("There are already %1 recordings for %2, which I consider too many."),
3401 limit, base) << endmsg;
3403 throw failed_constructor();
3407 return Glib::path_get_basename(buf);
3411 /** Create a new within-session MIDI source */
3412 boost::shared_ptr<MidiSource>
3413 Session::create_midi_source_for_session (Track* track, string const & n)
3415 /* try to use the existing write source for the track, to keep numbering sane
3419 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3423 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3426 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3427 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3431 const string name = new_midi_source_name (n);
3432 const string path = new_source_path_from_name (DataType::MIDI, name);
3434 return boost::dynamic_pointer_cast<SMFSource> (
3435 SourceFactory::createWritable (
3436 DataType::MIDI, *this, path, string(), false, frame_rate()));
3441 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3443 if (playlist->hidden()) {
3447 playlists->add (playlist);
3450 playlist->release();
3457 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3459 if (_state_of_the_state & Deletion) {
3463 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3469 playlists->remove (playlist);
3475 Session::set_audition (boost::shared_ptr<Region> r)
3477 pending_audition_region = r;
3478 add_post_transport_work (PostTransportAudition);
3479 _butler->schedule_transport_work ();
3483 Session::audition_playlist ()
3485 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3486 ev->region.reset ();
3491 Session::non_realtime_set_audition ()
3493 assert (pending_audition_region);
3494 auditioner->audition_region (pending_audition_region);
3495 pending_audition_region.reset ();
3496 AuditionActive (true); /* EMIT SIGNAL */
3500 Session::audition_region (boost::shared_ptr<Region> r)
3502 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3508 Session::cancel_audition ()
3510 if (auditioner->auditioning()) {
3511 auditioner->cancel_audition ();
3512 AuditionActive (false); /* EMIT SIGNAL */
3517 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3519 if (a->is_monitor()) {
3522 if (b->is_monitor()) {
3525 return a->order_key (MixerSort) < b->order_key (MixerSort);
3529 Session::is_auditioning () const
3531 /* can be called before we have an auditioner object */
3533 return auditioner->auditioning();
3540 Session::graph_reordered ()
3542 /* don't do this stuff if we are setting up connections
3543 from a set_state() call or creating new tracks. Ditto for deletion.
3546 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3550 /* every track/bus asked for this to be handled but it was deferred because
3551 we were connecting. do it now.
3554 request_input_change_handling ();
3558 /* force all diskstreams to update their capture offset values to
3559 reflect any changes in latencies within the graph.
3562 boost::shared_ptr<RouteList> rl = routes.reader ();
3563 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3564 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3566 tr->set_capture_offset ();
3571 /** @return Number of frames that there is disk space available to write,
3574 boost::optional<framecnt_t>
3575 Session::available_capture_duration ()
3577 Glib::Threads::Mutex::Lock lm (space_lock);
3579 if (_total_free_4k_blocks_uncertain) {
3580 return boost::optional<framecnt_t> ();
3583 float sample_bytes_on_disk = 4.0; // keep gcc happy
3585 switch (config.get_native_file_data_format()) {
3587 sample_bytes_on_disk = 4.0;
3591 sample_bytes_on_disk = 3.0;
3595 sample_bytes_on_disk = 2.0;
3599 /* impossible, but keep some gcc versions happy */
3600 fatal << string_compose (_("programming error: %1"),
3601 X_("illegal native file data format"))
3606 double scale = 4096.0 / sample_bytes_on_disk;
3608 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3609 return max_framecnt;
3612 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3616 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3619 RCUWriter<BundleList> writer (_bundles);
3620 boost::shared_ptr<BundleList> b = writer.get_copy ();
3621 b->push_back (bundle);
3624 BundleAdded (bundle); /* EMIT SIGNAL */
3630 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3632 bool removed = false;
3635 RCUWriter<BundleList> writer (_bundles);
3636 boost::shared_ptr<BundleList> b = writer.get_copy ();
3637 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3639 if (i != b->end()) {
3646 BundleRemoved (bundle); /* EMIT SIGNAL */
3652 boost::shared_ptr<Bundle>
3653 Session::bundle_by_name (string name) const
3655 boost::shared_ptr<BundleList> b = _bundles.reader ();
3657 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3658 if ((*i)->name() == name) {
3663 return boost::shared_ptr<Bundle> ();
3667 Session::tempo_map_changed (const PropertyChange&)
3671 playlists->update_after_tempo_map_change ();
3673 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3679 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3681 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3682 (*i)->recompute_frames_from_bbt ();
3686 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3687 * the given count with the current block size.
3690 Session::ensure_buffers (ChanCount howmany)
3692 BufferManager::ensure_buffers (howmany);
3696 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3698 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3699 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3704 Session::next_insert_id ()
3706 /* this doesn't really loop forever. just think about it */
3709 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3710 if (!insert_bitset[n]) {
3711 insert_bitset[n] = true;
3717 /* none available, so resize and try again */
3719 insert_bitset.resize (insert_bitset.size() + 16, false);
3724 Session::next_send_id ()
3726 /* this doesn't really loop forever. just think about it */
3729 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3730 if (!send_bitset[n]) {
3731 send_bitset[n] = true;
3737 /* none available, so resize and try again */
3739 send_bitset.resize (send_bitset.size() + 16, false);
3744 Session::next_aux_send_id ()
3746 /* this doesn't really loop forever. just think about it */
3749 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
3750 if (!aux_send_bitset[n]) {
3751 aux_send_bitset[n] = true;
3757 /* none available, so resize and try again */
3759 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
3764 Session::next_return_id ()
3766 /* this doesn't really loop forever. just think about it */
3769 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3770 if (!return_bitset[n]) {
3771 return_bitset[n] = true;
3777 /* none available, so resize and try again */
3779 return_bitset.resize (return_bitset.size() + 16, false);
3784 Session::mark_send_id (uint32_t id)
3786 if (id >= send_bitset.size()) {
3787 send_bitset.resize (id+16, false);
3789 if (send_bitset[id]) {
3790 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3792 send_bitset[id] = true;
3796 Session::mark_aux_send_id (uint32_t id)
3798 if (id >= aux_send_bitset.size()) {
3799 aux_send_bitset.resize (id+16, false);
3801 if (aux_send_bitset[id]) {
3802 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
3804 aux_send_bitset[id] = true;
3808 Session::mark_return_id (uint32_t id)
3810 if (id >= return_bitset.size()) {
3811 return_bitset.resize (id+16, false);
3813 if (return_bitset[id]) {
3814 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3816 return_bitset[id] = true;
3820 Session::mark_insert_id (uint32_t id)
3822 if (id >= insert_bitset.size()) {
3823 insert_bitset.resize (id+16, false);
3825 if (insert_bitset[id]) {
3826 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3828 insert_bitset[id] = true;
3832 Session::unmark_send_id (uint32_t id)
3834 if (id < send_bitset.size()) {
3835 send_bitset[id] = false;
3840 Session::unmark_aux_send_id (uint32_t id)
3842 if (id < aux_send_bitset.size()) {
3843 aux_send_bitset[id] = false;
3848 Session::unmark_return_id (uint32_t id)
3850 if (id < return_bitset.size()) {
3851 return_bitset[id] = false;
3856 Session::unmark_insert_id (uint32_t id)
3858 if (id < insert_bitset.size()) {
3859 insert_bitset[id] = false;
3864 Session::reset_native_file_format ()
3866 boost::shared_ptr<RouteList> rl = routes.reader ();
3867 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3868 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3870 /* don't save state as we do this, there's no point
3873 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3874 tr->reset_write_sources (false);
3875 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3881 Session::route_name_unique (string n) const
3883 boost::shared_ptr<RouteList> r = routes.reader ();
3885 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3886 if ((*i)->name() == n) {
3895 Session::route_name_internal (string n) const
3897 if (auditioner && auditioner->name() == n) {
3901 if (_click_io && _click_io->name() == n) {
3909 Session::freeze_all (InterThreadInfo& itt)
3911 boost::shared_ptr<RouteList> r = routes.reader ();
3913 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3915 boost::shared_ptr<Track> t;
3917 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3918 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3928 boost::shared_ptr<Region>
3929 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3930 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3931 InterThreadInfo& itt,
3932 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
3935 boost::shared_ptr<Region> result;
3936 boost::shared_ptr<Playlist> playlist;
3937 boost::shared_ptr<AudioFileSource> fsource;
3939 char buf[PATH_MAX+1];
3940 ChanCount diskstream_channels (track.n_channels());
3941 framepos_t position;
3942 framecnt_t this_chunk;
3945 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3946 const string sound_dir = sdir.sound_path();
3947 framepos_t len = end - start;
3948 bool need_block_size_reset = false;
3950 ChanCount const max_proc = track.max_processor_streams ();
3953 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3954 end, start) << endmsg;
3958 const framecnt_t chunk_size = (256 * 1024)/4;
3960 // block all process callback handling
3962 block_processing ();
3964 /* call tree *MUST* hold route_lock */
3966 if ((playlist = track.playlist()) == 0) {
3970 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3972 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3974 for (x = 0; x < 99999; ++x) {
3975 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());
3976 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3982 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3987 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3988 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3991 catch (failed_constructor& err) {
3992 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3996 srcs.push_back (fsource);
3999 /* tell redirects that care that we are about to use a much larger
4000 * blocksize. this will flush all plugins too, so that they are ready
4001 * to be used for this process.
4004 need_block_size_reset = true;
4005 track.set_block_size (chunk_size);
4010 /* create a set of reasonably-sized buffers */
4011 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
4012 buffers.set_count (max_proc);
4014 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4015 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4017 afs->prepare_for_peakfile_writes ();
4020 while (to_do && !itt.cancel) {
4022 this_chunk = min (to_do, chunk_size);
4024 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export)) {
4029 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4030 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4033 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4039 start += this_chunk;
4040 to_do -= this_chunk;
4042 itt.progress = (float) (1.0 - ((double) to_do / len));
4051 xnow = localtime (&now);
4053 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4054 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4057 afs->update_header (position, *xnow, now);
4058 afs->flush_header ();
4062 /* construct a region to represent the bounced material */
4066 plist.add (Properties::start, 0);
4067 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4068 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4070 result = RegionFactory::create (srcs, plist);
4076 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4077 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4080 afs->mark_for_remove ();
4083 (*src)->drop_references ();
4087 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4088 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4091 afs->done_with_peakfile_writes ();
4096 if (need_block_size_reset) {
4097 track.set_block_size (get_block_size());
4100 unblock_processing ();
4106 Session::gain_automation_buffer() const
4108 return ProcessThread::gain_automation_buffer ();
4112 Session::send_gain_automation_buffer() const
4114 return ProcessThread::send_gain_automation_buffer ();
4118 Session::pan_automation_buffer() const
4120 return ProcessThread::pan_automation_buffer ();
4124 Session::get_silent_buffers (ChanCount count)
4126 return ProcessThread::get_silent_buffers (count);
4130 Session::get_scratch_buffers (ChanCount count)
4132 return ProcessThread::get_scratch_buffers (count);
4136 Session::get_mix_buffers (ChanCount count)
4138 return ProcessThread::get_mix_buffers (count);
4142 Session::ntracks () const
4145 boost::shared_ptr<RouteList> r = routes.reader ();
4147 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4148 if (boost::dynamic_pointer_cast<Track> (*i)) {
4157 Session::nbusses () const
4160 boost::shared_ptr<RouteList> r = routes.reader ();
4162 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4163 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4172 Session::add_automation_list(AutomationList *al)
4174 automation_lists[al->id()] = al;
4177 /** @return true if there is at least one record-enabled track, otherwise false */
4179 Session::have_rec_enabled_track () const
4181 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
4184 /** Update the state of our rec-enabled tracks flag */
4186 Session::update_have_rec_enabled_track ()
4188 boost::shared_ptr<RouteList> rl = routes.reader ();
4189 RouteList::iterator i = rl->begin();
4190 while (i != rl->end ()) {
4192 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4193 if (tr && tr->record_enabled ()) {
4200 int const old = g_atomic_int_get (&_have_rec_enabled_track);
4202 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
4204 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
4205 RecordStateChanged (); /* EMIT SIGNAL */
4210 Session::listen_position_changed ()
4212 boost::shared_ptr<RouteList> r = routes.reader ();
4214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4215 (*i)->listen_position_changed ();
4220 Session::solo_control_mode_changed ()
4222 /* cancel all solo or all listen when solo control mode changes */
4225 set_solo (get_routes(), false);
4226 } else if (listening()) {
4227 set_listen (get_routes(), false);
4231 /** Called when a property of one of our route groups changes */
4233 Session::route_group_property_changed (RouteGroup* rg)
4235 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
4238 /** Called when a route is added to one of our route groups */
4240 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4242 RouteAddedToRouteGroup (rg, r);
4245 /** Called when a route is removed from one of our route groups */
4247 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4249 RouteRemovedFromRouteGroup (rg, r);
4252 boost::shared_ptr<RouteList>
4253 Session::get_routes_with_regions_at (framepos_t const p) const
4255 boost::shared_ptr<RouteList> r = routes.reader ();
4256 boost::shared_ptr<RouteList> rl (new RouteList);
4258 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4259 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4264 boost::shared_ptr<Playlist> pl = tr->playlist ();
4269 if (pl->has_region_at (p)) {
4278 Session::goto_end ()
4280 if (_session_range_location) {
4281 request_locate (_session_range_location->end(), false);
4283 request_locate (0, false);
4288 Session::goto_start ()
4290 if (_session_range_location) {
4291 request_locate (_session_range_location->start(), false);
4293 request_locate (0, false);
4298 Session::current_start_frame () const
4300 return _session_range_location ? _session_range_location->start() : 0;
4304 Session::current_end_frame () const
4306 return _session_range_location ? _session_range_location->end() : 0;
4310 Session::add_session_range_location (framepos_t start, framepos_t end)
4312 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4313 _locations->add (_session_range_location);
4317 Session::step_edit_status_change (bool yn)
4323 send = (_step_editors == 0);
4328 send = (_step_editors == 1);
4331 if (_step_editors > 0) {
4337 StepEditStatusChange (val);
4343 Session::start_time_changed (framepos_t old)
4345 /* Update the auto loop range to match the session range
4346 (unless the auto loop range has been changed by the user)
4349 Location* s = _locations->session_range_location ();
4354 Location* l = _locations->auto_loop_location ();
4356 if (l && l->start() == old) {
4357 l->set_start (s->start(), true);
4362 Session::end_time_changed (framepos_t old)
4364 /* Update the auto loop range to match the session range
4365 (unless the auto loop range has been changed by the user)
4368 Location* s = _locations->session_range_location ();
4373 Location* l = _locations->auto_loop_location ();
4375 if (l && l->end() == old) {
4376 l->set_end (s->end(), true);
4381 Session::source_search_path (DataType type) const
4385 if (session_dirs.size() == 1) {
4387 case DataType::AUDIO:
4388 s.push_back (_session_dir->sound_path());
4390 case DataType::MIDI:
4391 s.push_back (_session_dir->midi_path());
4395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4396 SessionDirectory sdir (i->path);
4398 case DataType::AUDIO:
4399 s.push_back (sdir.sound_path());
4401 case DataType::MIDI:
4402 s.push_back (sdir.midi_path());
4408 if (type == DataType::AUDIO) {
4409 const string sound_path_2X = _session_dir->sound_path_2X();
4410 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
4411 if (find (s.begin(), s.end(), sound_path_2X) == s.end()) {
4412 s.push_back (sound_path_2X);
4417 /* now check the explicit (possibly user-specified) search path
4420 vector<string> dirs;
4423 case DataType::AUDIO:
4424 split (config.get_audio_search_path (), dirs, ':');
4426 case DataType::MIDI:
4427 split (config.get_midi_search_path (), dirs, ':');
4431 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4432 if (find (s.begin(), s.end(), *i) == s.end()) {
4439 for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) {
4440 if (!search_path.empty()) {
4450 Session::ensure_search_path_includes (const string& path, DataType type)
4453 vector<string> dirs;
4460 case DataType::AUDIO:
4461 search_path = config.get_audio_search_path ();
4463 case DataType::MIDI:
4464 search_path = config.get_midi_search_path ();
4468 split (search_path, dirs, ':');
4470 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4471 /* No need to add this new directory if it has the same inode as
4472 an existing one; checking inode rather than name prevents duplicated
4473 directories when we are using symlinks.
4475 On Windows, I think we could just do if (*i == path) here.
4477 if (PBD::equivalent_paths (*i, path)) {
4482 if (!search_path.empty()) {
4486 search_path += path;
4489 case DataType::AUDIO:
4490 config.set_audio_search_path (search_path);
4492 case DataType::MIDI:
4493 config.set_midi_search_path (search_path);
4498 boost::shared_ptr<Speakers>
4499 Session::get_speakers()
4505 Session::unknown_processors () const
4509 boost::shared_ptr<RouteList> r = routes.reader ();
4510 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4511 list<string> t = (*i)->unknown_processors ();
4512 copy (t.begin(), t.end(), back_inserter (p));
4522 Session::update_latency (bool playback)
4524 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4526 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4530 boost::shared_ptr<RouteList> r = routes.reader ();
4531 framecnt_t max_latency = 0;
4534 /* reverse the list so that we work backwards from the last route to run to the first */
4535 RouteList* rl = routes.reader().get();
4536 r.reset (new RouteList (*rl));
4537 reverse (r->begin(), r->end());
4540 /* compute actual latency values for the given direction and store them all in per-port
4541 structures. this will also publish the same values (to JACK) so that computation of latency
4542 for routes can consistently use public latency values.
4545 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4546 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4549 /* because we latency compensate playback, our published playback latencies should
4550 be the same for all output ports - all material played back by ardour has
4551 the same latency, whether its caused by plugins or by latency compensation. since
4552 these may differ from the values computed above, reset all playback port latencies
4556 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4558 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4559 (*i)->set_public_port_latencies (max_latency, playback);
4564 post_playback_latency ();
4568 post_capture_latency ();
4571 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
4575 Session::post_playback_latency ()
4577 set_worst_playback_latency ();
4579 boost::shared_ptr<RouteList> r = routes.reader ();
4581 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4582 if (!(*i)->is_hidden() && ((*i)->active())) {
4583 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
4587 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4588 (*i)->set_latency_compensation (_worst_track_latency);
4593 Session::post_capture_latency ()
4595 set_worst_capture_latency ();
4597 /* reflect any changes in capture latencies into capture offsets
4600 boost::shared_ptr<RouteList> rl = routes.reader();
4601 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4602 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4604 tr->set_capture_offset ();
4610 Session::initialize_latencies ()
4613 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4614 update_latency (false);
4615 update_latency (true);
4618 set_worst_io_latencies ();
4622 Session::set_worst_io_latencies ()
4624 set_worst_playback_latency ();
4625 set_worst_capture_latency ();
4629 Session::set_worst_playback_latency ()
4631 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4635 _worst_output_latency = 0;
4637 if (!_engine.connected()) {
4641 boost::shared_ptr<RouteList> r = routes.reader ();
4643 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4644 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
4647 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
4651 Session::set_worst_capture_latency ()
4653 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4657 _worst_input_latency = 0;
4659 if (!_engine.connected()) {
4663 boost::shared_ptr<RouteList> r = routes.reader ();
4665 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4666 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
4669 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
4673 Session::update_latency_compensation (bool force_whole_graph)
4675 bool some_track_latency_changed = false;
4677 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4681 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
4683 _worst_track_latency = 0;
4685 boost::shared_ptr<RouteList> r = routes.reader ();
4687 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4688 if (!(*i)->is_hidden() && ((*i)->active())) {
4690 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
4691 some_track_latency_changed = true;
4693 _worst_track_latency = max (tl, _worst_track_latency);
4697 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
4698 (some_track_latency_changed ? "yes" : "no")));
4700 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
4702 if (some_track_latency_changed || force_whole_graph) {
4703 _engine.update_latencies ();
4707 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4708 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4712 tr->set_capture_offset ();
4717 Session::session_name_is_legal (const string& path)
4719 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
4721 for (int i = 0; illegal_chars[i]; ++i) {
4722 if (path.find (illegal_chars[i]) != string::npos) {
4723 return illegal_chars[i];
4731 Session::next_control_id () const
4735 /* the monitor bus remote ID is in a different
4736 * "namespace" than regular routes. its existence doesn't
4737 * affect normal (low) numbered routes.
4744 return nroutes() - subtract;
4748 Session::notify_remote_id_change ()
4750 if (deletion_in_progress()) {
4754 switch (Config->get_remote_model()) {
4757 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
4765 Session::sync_order_keys (RouteSortOrderKey sort_key_changed)
4767 if (deletion_in_progress()) {
4771 /* tell everyone that something has happened to the sort keys
4772 and let them sync up with the change(s)
4773 this will give objects that manage the sort order keys the
4774 opportunity to keep them in sync if they wish to.
4777 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("Sync Order Keys, based on %1\n", enum_2_string (sort_key_changed)));
4779 Route::SyncOrderKeys (sort_key_changed); /* EMIT SIGNAL */
4781 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
4785 Session::operation_in_progress (GQuark op) const
4787 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
4790 boost::shared_ptr<Port>
4791 Session::ltc_input_port () const
4793 return _ltc_input->nth (0);
4796 boost::shared_ptr<Port>
4797 Session::ltc_output_port () const
4799 return _ltc_output->nth (0);
4803 Session::reconnect_ltc_input ()
4807 string src = Config->get_ltc_source_port();
4809 _ltc_input->disconnect (this);
4811 if (src != _("None") && !src.empty()) {
4812 _ltc_input->nth (0)->connect (src);
4818 Session::reconnect_ltc_output ()
4823 string src = Config->get_ltc_sink_port();
4825 _ltc_output->disconnect (this);
4827 if (src != _("None") && !src.empty()) {
4828 _ltc_output->nth (0)->connect (src);