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;
122 PBD::Signal2<void,std::string,std::string> Session::VersionMismatch;
124 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
125 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
127 /** @param snapshot_name Snapshot name, without .ardour suffix */
128 Session::Session (AudioEngine &eng,
129 const string& fullpath,
130 const string& snapshot_name,
131 BusProfile* bus_profile,
134 , _target_transport_speed (0.0)
135 , _requested_return_frame (-1)
136 , _session_dir (new SessionDirectory(fullpath))
138 , _state_of_the_state (Clean)
139 , _butler (new Butler (*this))
140 , _post_transport_work (0)
141 , _send_timecode_update (false)
142 , _all_route_group (new RouteGroup (*this, "all"))
143 , routes (new RouteList)
144 , _total_free_4k_blocks (0)
145 , _total_free_4k_blocks_uncertain (false)
146 , _bundles (new BundleList)
147 , _bundle_xml_node (0)
150 , click_emphasis_data (0)
152 , _have_rec_enabled_track (false)
153 , _suspend_timecode_transmission (0)
155 _locations = new Locations (*this);
158 if (how_many_dsp_threads () > 1) {
159 /* For now, only create the graph if we are using >1 DSP threads, as
160 it is a bit slower than the old code with 1 thread.
162 _process_graph.reset (new Graph (*this));
165 playlists.reset (new SessionPlaylists);
167 _all_route_group->set_active (true, this);
169 interpolation.add_channel_to (0, 0);
171 if (!eng.connected()) {
172 throw failed_constructor();
175 n_physical_outputs = _engine.n_physical_outputs ();
176 n_physical_inputs = _engine.n_physical_inputs ();
178 first_stage_init (fullpath, snapshot_name);
180 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
183 if (create (mix_template, bus_profile)) {
185 throw failed_constructor ();
189 if (second_stage_init ()) {
191 throw failed_constructor ();
194 store_recent_sessions(_name, _path);
196 bool was_dirty = dirty();
198 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
200 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
201 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
204 DirtyChanged (); /* EMIT SIGNAL */
207 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
208 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
224 vector<void*> debug_pointers;
226 /* if we got to here, leaving pending capture state around
230 remove_pending_capture_state ();
232 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
234 /* disconnect from any and all signals that we are connected to */
238 _engine.remove_session ();
240 /* deregister all ports - there will be no process or any other
241 * callbacks from the engine any more.
244 Port::PortDrop (); /* EMIT SIGNAL */
248 /* clear history so that no references to objects are held any more */
252 /* clear state tree so that no references to objects are held any more */
256 /* reset dynamic state version back to default */
258 Stateful::loading_state_version = 0;
260 _butler->drop_references ();
264 delete midi_control_ui;
265 delete _all_route_group;
267 if (click_data != default_click) {
268 delete [] click_data;
271 if (click_emphasis_data != default_click_emphasis) {
272 delete [] click_emphasis_data;
277 /* clear out any pending dead wood from RCU managed objects */
282 AudioDiskstream::free_working_buffers();
284 /* tell everyone who is still standing that we're about to die */
287 /* tell everyone to drop references and delete objects as we go */
289 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
290 RegionFactory::delete_all_regions ();
292 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
294 /* reset these three references to special routes before we do the usual route delete thing */
297 _master_out.reset ();
298 _monitor_out.reset ();
301 RCUWriter<RouteList> writer (routes);
302 boost::shared_ptr<RouteList> r = writer.get_copy ();
304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
305 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
306 (*i)->drop_references ();
310 /* writer goes out of scope and updates master */
314 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
315 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
316 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
317 i->second->drop_references ();
322 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
323 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
328 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
333 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
335 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
336 boost_debug_list_ptrs ();
341 Session::when_engine_running ()
343 string first_physical_output;
345 BootMessage (_("Set block size and sample rate"));
347 set_block_size (_engine.frames_per_cycle());
348 set_frame_rate (_engine.frame_rate());
350 BootMessage (_("Using configuration"));
352 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
353 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
355 Config->map_parameters (ff);
356 config.map_parameters (ft);
358 /* every time we reconnect, recompute worst case output latencies */
360 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
362 if (synced_to_jack()) {
363 _engine.transport_stop ();
366 if (config.get_jack_time_master()) {
367 _engine.transport_locate (_transport_frame);
375 _ltc_input.reset (new IO (*this, _("LTC In"), IO::Input));
376 _ltc_output.reset (new IO (*this, _("LTC Out"), IO::Output));
378 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-In")) != 0) {
379 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
382 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
383 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
385 reconnect_ltc_input ();
388 if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-Out")) != 0) {
389 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
392 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
393 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
395 reconnect_ltc_output ();
398 /* fix up names of LTC ports because we don't want the normal
399 * IO style of NAME/TYPE-{in,out}N
402 _ltc_input->nth (0)->set_name (_("LTC-in"));
403 _ltc_output->nth (0)->set_name (_("LTC-out"));
405 _click_io.reset (new ClickIO (*this, "click"));
406 _click_gain.reset (new Amp (*this));
407 _click_gain->activate ();
409 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
411 /* existing state for Click */
414 if (Stateful::loading_state_version < 3000) {
415 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
417 const XMLNodeList& children (child->children());
418 XMLNodeList::const_iterator i = children.begin();
419 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
421 if (i != children.end()) {
422 c = _click_gain->set_state (**i, Stateful::loading_state_version);
428 _clicking = Config->get_clicking ();
432 error << _("could not setup Click I/O") << endmsg;
439 /* default state for Click: dual-mono to first 2 physical outputs */
442 _engine.get_physical_outputs (DataType::AUDIO, outs);
444 for (uint32_t physport = 0; physport < 2; ++physport) {
445 if (outs.size() > physport) {
446 if (_click_io->add_port (outs[physport], this)) {
447 // relax, even though its an error
452 if (_click_io->n_ports () > ChanCount::ZERO) {
453 _clicking = Config->get_clicking ();
458 catch (failed_constructor& err) {
459 error << _("cannot setup Click I/O") << endmsg;
462 BootMessage (_("Compute I/O Latencies"));
465 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
468 BootMessage (_("Set up standard connections"));
470 vector<string> inputs[DataType::num_types];
471 vector<string> outputs[DataType::num_types];
472 for (uint32_t i = 0; i < DataType::num_types; ++i) {
473 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
474 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
477 /* Create a set of Bundle objects that map
478 to the physical I/O currently available. We create both
479 mono and stereo bundles, so that the common cases of mono
480 and stereo tracks get bundles to put in their mixer strip
481 in / out menus. There may be a nicer way of achieving that;
482 it doesn't really scale that well to higher channel counts
485 /* mono output bundles */
487 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
489 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
491 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
492 c->add_channel (_("mono"), DataType::AUDIO);
493 c->set_port (0, outputs[DataType::AUDIO][np]);
498 /* stereo output bundles */
500 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
501 if (np + 1 < outputs[DataType::AUDIO].size()) {
503 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
504 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
505 c->add_channel (_("L"), DataType::AUDIO);
506 c->set_port (0, outputs[DataType::AUDIO][np]);
507 c->add_channel (_("R"), DataType::AUDIO);
508 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
514 /* mono input bundles */
516 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
518 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
520 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
521 c->add_channel (_("mono"), DataType::AUDIO);
522 c->set_port (0, inputs[DataType::AUDIO][np]);
527 /* stereo input bundles */
529 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
530 if (np + 1 < inputs[DataType::AUDIO].size()) {
532 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
534 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
535 c->add_channel (_("L"), DataType::AUDIO);
536 c->set_port (0, inputs[DataType::AUDIO][np]);
537 c->add_channel (_("R"), DataType::AUDIO);
538 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
544 /* MIDI input bundles */
546 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
547 string n = inputs[DataType::MIDI][np];
548 boost::erase_first (n, X_("alsa_pcm:"));
550 boost::shared_ptr<Bundle> c (new Bundle (n, false));
551 c->add_channel ("", DataType::MIDI);
552 c->set_port (0, inputs[DataType::MIDI][np]);
556 /* MIDI output bundles */
558 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
559 string n = outputs[DataType::MIDI][np];
560 boost::erase_first (n, X_("alsa_pcm:"));
562 boost::shared_ptr<Bundle> c (new Bundle (n, true));
563 c->add_channel ("", DataType::MIDI);
564 c->set_port (0, outputs[DataType::MIDI][np]);
568 BootMessage (_("Setup signal flow and plugins"));
570 /* Reset all panners */
572 Delivery::reset_panners ();
574 /* this will cause the CPM to instantiate any protocols that are in use
575 * (or mandatory), which will pass it this Session, and then call
576 * set_state() on each instantiated protocol to match stored state.
579 ControlProtocolManager::instance().set_session (this);
581 /* This must be done after the ControlProtocolManager set_session above,
582 as it will set states for ports which the ControlProtocolManager creates.
585 MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
587 /* And this must be done after the MIDI::Manager::set_port_states as
588 * it will try to make connections whose details are loaded by set_port_states.
593 /* Let control protocols know that we are now all connected, so they
594 * could start talking to surfaces if they want to.
597 ControlProtocolManager::instance().midi_connectivity_established ();
599 if (_is_new && !no_auto_connect()) {
600 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
601 auto_connect_master_bus ();
604 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
606 /* update latencies */
608 initialize_latencies ();
610 /* hook us up to the engine */
612 BootMessage (_("Connect to engine"));
613 _engine.set_session (this);
614 _engine.reset_timebase ();
618 Session::auto_connect_master_bus ()
620 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
624 /* if requested auto-connect the outputs to the first N physical ports.
627 uint32_t limit = _master_out->n_outputs().n_total();
628 vector<string> outputs[DataType::num_types];
630 for (uint32_t i = 0; i < DataType::num_types; ++i) {
631 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
634 for (uint32_t n = 0; n < limit; ++n) {
635 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
637 if (outputs[p->type()].size() > n) {
638 connect_to = outputs[p->type()][n];
641 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
642 if (_master_out->output()->connect (p, connect_to, this)) {
643 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
652 Session::remove_monitor_section ()
658 /* force reversion to Solo-In-Place */
659 Config->set_solo_control_is_listen_control (false);
662 /* Hold process lock while doing this so that we don't hear bits and
663 * pieces of audio as we work on each route.
666 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
668 /* Connect tracks to monitor section. Note that in an
669 existing session, the internal sends will already exist, but we want the
670 routes to notice that they connect to the control out specifically.
674 boost::shared_ptr<RouteList> r = routes.reader ();
675 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
677 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
679 if ((*x)->is_monitor()) {
681 } else if ((*x)->is_master()) {
684 (*x)->remove_aux_or_listen (_monitor_out);
689 remove_route (_monitor_out);
690 auto_connect_master_bus ();
694 Session::add_monitor_section ()
698 if (_monitor_out || !_master_out) {
702 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
708 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
709 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
712 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
713 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
714 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
718 add_routes (rl, false, false, false);
720 assert (_monitor_out);
722 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
723 are undefined, at best.
726 uint32_t limit = _monitor_out->n_inputs().n_audio();
730 /* connect the inputs to the master bus outputs. this
731 * represents a separate data feed from the internal sends from
732 * each route. as of jan 2011, it allows the monitor section to
733 * conditionally ignore either the internal sends or the normal
734 * input feed, but we should really find a better way to do
738 _master_out->output()->disconnect (this);
740 for (uint32_t n = 0; n < limit; ++n) {
741 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
742 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
745 string connect_to = o->name();
746 if (_monitor_out->input()->connect (p, connect_to, this)) {
747 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
755 /* if monitor section is not connected, connect it to physical outs
758 if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
760 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
762 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
765 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
767 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
768 Config->get_monitor_bus_preferred_bundle())
774 /* Monitor bus is audio only */
776 uint32_t mod = n_physical_outputs.get (DataType::AUDIO);
777 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
778 vector<string> outputs[DataType::num_types];
780 for (uint32_t i = 0; i < DataType::num_types; ++i) {
781 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
787 for (uint32_t n = 0; n < limit; ++n) {
789 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
791 if (outputs[DataType::AUDIO].size() > (n % mod)) {
792 connect_to = outputs[DataType::AUDIO][n % mod];
795 if (!connect_to.empty()) {
796 if (_monitor_out->output()->connect (p, connect_to, this)) {
797 error << string_compose (
798 _("cannot connect control output %1 to %2"),
809 /* Hold process lock while doing this so that we don't hear bits and
810 * pieces of audio as we work on each route.
813 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
815 /* Connect tracks to monitor section. Note that in an
816 existing session, the internal sends will already exist, but we want the
817 routes to notice that they connect to the control out specifically.
821 boost::shared_ptr<RouteList> rls = routes.reader ();
823 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
825 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
827 if ((*x)->is_monitor()) {
829 } else if ((*x)->is_master()) {
832 (*x)->enable_monitor_send ();
838 Session::hookup_io ()
840 /* stop graph reordering notifications from
841 causing resorts, etc.
844 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
848 /* we delay creating the auditioner till now because
849 it makes its own connections to ports.
853 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
855 throw failed_constructor ();
857 a->use_new_diskstream ();
861 catch (failed_constructor& err) {
862 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
866 /* load bundles, which we may have postponed earlier on */
867 if (_bundle_xml_node) {
868 load_bundles (*_bundle_xml_node);
869 delete _bundle_xml_node;
872 /* Tell all IO objects to connect themselves together */
874 IO::enable_connecting ();
875 MIDI::JackMIDIPort::MakeConnections ();
877 /* Anyone who cares about input state, wake up and do something */
879 IOConnectionsComplete (); /* EMIT SIGNAL */
881 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
883 /* now handle the whole enchilada as if it was one
889 /* update the full solo state, which can't be
890 correctly determined on a per-route basis, but
891 needs the global overview that only the session
895 update_route_solo_state ();
899 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
901 boost::shared_ptr<Track> track = wp.lock ();
906 boost::shared_ptr<Playlist> playlist;
908 if ((playlist = track->playlist()) != 0) {
909 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
910 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
911 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
916 Session::record_enabling_legal () const
918 /* this used to be in here, but survey says.... we don't need to restrict it */
919 // if (record_status() == Recording) {
923 if (Config->get_all_safe()) {
930 Session::set_track_monitor_input_status (bool yn)
932 boost::shared_ptr<RouteList> rl = routes.reader ();
933 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
934 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
935 if (tr && tr->record_enabled ()) {
936 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
937 tr->request_jack_monitors_input (yn);
943 Session::auto_punch_start_changed (Location* location)
945 replace_event (SessionEvent::PunchIn, location->start());
947 if (get_record_enabled() && config.get_punch_in()) {
948 /* capture start has been changed, so save new pending state */
949 save_state ("", true);
954 Session::auto_punch_end_changed (Location* location)
956 framepos_t when_to_stop = location->end();
957 // when_to_stop += _worst_output_latency + _worst_input_latency;
958 replace_event (SessionEvent::PunchOut, when_to_stop);
962 Session::auto_punch_changed (Location* location)
964 framepos_t when_to_stop = location->end();
966 replace_event (SessionEvent::PunchIn, location->start());
967 //when_to_stop += _worst_output_latency + _worst_input_latency;
968 replace_event (SessionEvent::PunchOut, when_to_stop);
971 /** @param loc A loop location.
972 * @param pos Filled in with the start time of the required fade-out (in session frames).
973 * @param length Filled in with the length of the required fade-out.
976 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
978 pos = max (loc->start(), loc->end() - 64);
979 length = loc->end() - pos;
983 Session::auto_loop_changed (Location* location)
985 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
988 auto_loop_declick_range (location, dcp, dcl);
989 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
991 if (transport_rolling() && play_loop) {
994 // if (_transport_frame > location->end()) {
996 if (_transport_frame < location->start() || _transport_frame > location->end()) {
997 // relocate to beginning of loop
998 clear_events (SessionEvent::LocateRoll);
1000 request_locate (location->start(), true);
1003 else if (Config->get_seamless_loop() && !loop_changing) {
1005 // schedule a locate-roll to refill the diskstreams at the
1006 // previous loop end
1007 loop_changing = true;
1009 if (location->end() > last_loopend) {
1010 clear_events (SessionEvent::LocateRoll);
1011 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1018 last_loopend = location->end();
1022 Session::set_auto_punch_location (Location* location)
1026 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1027 punch_connections.drop_connections();
1028 existing->set_auto_punch (false, this);
1029 remove_event (existing->start(), SessionEvent::PunchIn);
1030 clear_events (SessionEvent::PunchOut);
1031 auto_punch_location_changed (0);
1036 if (location == 0) {
1040 if (location->end() <= location->start()) {
1041 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1045 punch_connections.drop_connections ();
1047 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1048 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1049 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1051 location->set_auto_punch (true, this);
1053 auto_punch_changed (location);
1055 auto_punch_location_changed (location);
1059 Session::set_auto_loop_location (Location* location)
1063 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1064 loop_connections.drop_connections ();
1065 existing->set_auto_loop (false, this);
1066 remove_event (existing->end(), SessionEvent::AutoLoop);
1069 auto_loop_declick_range (existing, dcp, dcl);
1070 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1071 auto_loop_location_changed (0);
1076 if (location == 0) {
1080 if (location->end() <= location->start()) {
1081 error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
1085 last_loopend = location->end();
1087 loop_connections.drop_connections ();
1089 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1090 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1091 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1093 location->set_auto_loop (true, this);
1095 /* take care of our stuff first */
1097 auto_loop_changed (location);
1099 /* now tell everyone else */
1101 auto_loop_location_changed (location);
1105 Session::locations_added (Location *)
1111 Session::locations_changed ()
1113 _locations->apply (*this, &Session::handle_locations_changed);
1117 Session::handle_locations_changed (Locations::LocationList& locations)
1119 Locations::LocationList::iterator i;
1121 bool set_loop = false;
1122 bool set_punch = false;
1124 for (i = locations.begin(); i != locations.end(); ++i) {
1128 if (location->is_auto_punch()) {
1129 set_auto_punch_location (location);
1132 if (location->is_auto_loop()) {
1133 set_auto_loop_location (location);
1137 if (location->is_session_range()) {
1138 _session_range_location = location;
1143 set_auto_loop_location (0);
1146 set_auto_punch_location (0);
1153 Session::enable_record ()
1155 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1156 /* no recording at anything except normal speed */
1161 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1163 if (rs == Recording) {
1167 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1169 _last_record_location = _transport_frame;
1170 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1172 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1173 set_track_monitor_input_status (true);
1176 RecordStateChanged ();
1183 Session::disable_record (bool rt_context, bool force)
1187 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1189 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1190 g_atomic_int_set (&_record_status, Disabled);
1191 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1193 if (rs == Recording) {
1194 g_atomic_int_set (&_record_status, Enabled);
1198 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1199 set_track_monitor_input_status (false);
1202 RecordStateChanged (); /* emit signal */
1205 remove_pending_capture_state ();
1211 Session::step_back_from_record ()
1213 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1215 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1216 set_track_monitor_input_status (false);
1219 RecordStateChanged (); /* emit signal */
1224 Session::maybe_enable_record ()
1226 if (_step_editors > 0) {
1230 g_atomic_int_set (&_record_status, Enabled);
1232 /* This function is currently called from somewhere other than an RT thread.
1233 This save_state() call therefore doesn't impact anything. Doing it here
1234 means that we save pending state of which sources the next record will use,
1235 which gives us some chance of recovering from a crash during the record.
1238 save_state ("", true);
1240 if (_transport_speed) {
1241 if (!config.get_punch_in()) {
1245 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1246 RecordStateChanged (); /* EMIT SIGNAL */
1253 Session::audible_frame () const
1259 /* the first of these two possible settings for "offset"
1260 mean that the audible frame is stationary until
1261 audio emerges from the latency compensation
1264 the second means that the audible frame is stationary
1265 until audio would emerge from a physical port
1266 in the absence of any plugin latency compensation
1269 offset = worst_playback_latency ();
1271 if (offset > current_block_size) {
1272 offset -= current_block_size;
1274 /* XXX is this correct? if we have no external
1275 physical connections and everything is internal
1276 then surely this is zero? still, how
1277 likely is that anyway?
1279 offset = current_block_size;
1282 if (synced_to_jack()) {
1283 tf = _engine.transport_frame();
1285 tf = _transport_frame;
1290 if (!non_realtime_work_pending()) {
1294 /* Check to see if we have passed the first guaranteed
1295 audible frame past our last start position. if not,
1296 return that last start point because in terms
1297 of audible frames, we have not moved yet.
1299 `Start position' in this context means the time we last
1300 either started, located, or changed transport direction.
1303 if (_transport_speed > 0.0f) {
1305 if (!play_loop || !have_looped) {
1306 if (tf < _last_roll_or_reversal_location + offset) {
1307 return _last_roll_or_reversal_location;
1315 } else if (_transport_speed < 0.0f) {
1317 /* XXX wot? no backward looping? */
1319 if (tf > _last_roll_or_reversal_location - offset) {
1320 return _last_roll_or_reversal_location;
1332 Session::set_frame_rate (framecnt_t frames_per_second)
1334 /** \fn void Session::set_frame_size(framecnt_t)
1335 the AudioEngine object that calls this guarantees
1336 that it will not be called while we are also in
1337 ::process(). Its fine to do things that block
1341 _base_frame_rate = frames_per_second;
1347 // XXX we need some equivalent to this, somehow
1348 // SndFileSource::setup_standard_crossfades (frames_per_second);
1352 /* XXX need to reset/reinstantiate all LADSPA plugins */
1356 Session::set_block_size (pframes_t nframes)
1358 /* the AudioEngine guarantees
1359 that it will not be called while we are also in
1360 ::process(). It is therefore fine to do things that block
1365 current_block_size = nframes;
1369 boost::shared_ptr<RouteList> r = routes.reader ();
1371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1372 (*i)->set_block_size (nframes);
1375 boost::shared_ptr<RouteList> rl = routes.reader ();
1376 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1377 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1379 tr->set_block_size (nframes);
1383 set_worst_io_latencies ();
1389 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1391 boost::shared_ptr<Route> r2;
1393 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1394 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1398 /* make a copy of the existing list of routes that feed r1 */
1400 Route::FedBy existing (r1->fed_by());
1402 /* for each route that feeds r1, recurse, marking it as feeding
1406 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1407 if (!(r2 = i->r.lock ())) {
1408 /* (*i) went away, ignore it */
1412 /* r2 is a route that feeds r1 which somehow feeds base. mark
1413 base as being fed by r2
1416 rbase->add_fed_by (r2, i->sends_only);
1420 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1424 if (r1->feeds (r2) && r2->feeds (r1)) {
1428 /* now recurse, so that we can mark base as being fed by
1429 all routes that feed r2
1432 trace_terminal (r2, rbase);
1439 Session::resort_routes ()
1441 /* don't do anything here with signals emitted
1442 by Routes during initial setup or while we
1443 are being destroyed.
1446 if (_state_of_the_state & (InitialConnecting | Deletion)) {
1451 RCUWriter<RouteList> writer (routes);
1452 boost::shared_ptr<RouteList> r = writer.get_copy ();
1453 resort_routes_using (r);
1454 /* writer goes out of scope and forces update */
1458 boost::shared_ptr<RouteList> rl = routes.reader ();
1459 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1460 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1462 const Route::FedBy& fb ((*i)->fed_by());
1464 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1465 boost::shared_ptr<Route> sf = f->r.lock();
1467 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1475 /** This is called whenever we need to rebuild the graph of how we will process
1477 * @param r List of routes, in any order.
1481 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1483 /* We are going to build a directed graph of our routes;
1484 this is where the edges of that graph are put.
1489 /* Go through all routes doing two things:
1491 * 1. Collect the edges of the route graph. Each of these edges
1492 * is a pair of routes, one of which directly feeds the other
1493 * either by a JACK connection or by an internal send.
1495 * 2. Begin the process of making routes aware of which other
1496 * routes directly or indirectly feed them. This information
1497 * is used by the solo code.
1500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1502 /* Clear out the route's list of direct or indirect feeds */
1503 (*i)->clear_fed_by ();
1505 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
1507 bool via_sends_only;
1509 /* See if this *j feeds *i according to the current state of the JACK
1510 connections and internal sends.
1512 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
1513 /* add the edge to the graph (part #1) */
1514 edges.add (*j, *i, via_sends_only);
1515 /* tell the route (for part #2) */
1516 (*i)->add_fed_by (*j, via_sends_only);
1521 /* Attempt a topological sort of the route graph */
1522 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
1524 if (sorted_routes) {
1525 /* We got a satisfactory topological sort, so there is no feedback;
1528 Note: the process graph rechain does not require a
1529 topologically-sorted list, but hey ho.
1531 if (_process_graph) {
1532 _process_graph->rechain (sorted_routes, edges);
1535 _current_route_graph = edges;
1537 /* Complete the building of the routes' lists of what directly
1538 or indirectly feeds them.
1540 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1541 trace_terminal (*i, *i);
1544 *r = *sorted_routes;
1547 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1548 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1549 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1550 (*i)->name(), (*i)->order_key (MixerSort)));
1554 SuccessfulGraphSort (); /* EMIT SIGNAL */
1557 /* The topological sort failed, so we have a problem. Tell everyone
1558 and stick to the old graph; this will continue to be processed, so
1559 until the feedback is fixed, what is played back will not quite
1560 reflect what is actually connected. Note also that we do not
1561 do trace_terminal here, as it would fail due to an endless recursion,
1562 so the solo code will think that everything is still connected
1566 FeedbackDetected (); /* EMIT SIGNAL */
1571 /** Find a route name starting with \a base, maybe followed by the
1572 * lowest \a id. \a id will always be added if \a definitely_add_number
1573 * is true on entry; otherwise it will only be added if required
1574 * to make the name unique.
1576 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1577 * The available route name with the lowest ID will be used, and \a id
1578 * will be set to the ID.
1580 * \return false if a route name could not be found, and \a track_name
1581 * and \a id do not reflect a free route name.
1584 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1586 if (!definitely_add_number && route_by_name (base) == 0) {
1587 /* juse use the base */
1588 snprintf (name, name_len, "%s", base.c_str());
1593 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1595 if (route_by_name (name) == 0) {
1601 } while (id < (UINT_MAX-1));
1606 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
1608 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
1610 in = ChanCount::ZERO;
1611 out = ChanCount::ZERO;
1613 boost::shared_ptr<RouteList> r = routes.reader ();
1615 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1616 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1617 if (tr && !tr->is_hidden()) {
1618 in += tr->n_inputs();
1619 out += tr->n_outputs();
1624 /** Caller must not hold process lock
1625 * @param name_template string to use for the start of the name, or "" to use "MIDI".
1626 * @param instrument plugin info for the instrument to insert pre-fader, if any
1628 list<boost::shared_ptr<MidiTrack> >
1629 Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
1630 TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1632 char track_name[32];
1633 uint32_t track_id = 0;
1635 RouteList new_routes;
1636 list<boost::shared_ptr<MidiTrack> > ret;
1638 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
1641 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1642 error << "cannot find name for new midi track" << endmsg;
1646 boost::shared_ptr<MidiTrack> track;
1649 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1651 if (track->init ()) {
1655 track->use_new_diskstream();
1657 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1658 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1661 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1662 if (track->input()->ensure_io (input, false, this)) {
1663 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
1667 if (track->output()->ensure_io (output, false, this)) {
1668 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
1673 track->non_realtime_input_change();
1676 route_group->add (track);
1679 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1681 if (Config->get_remote_model() == UserOrdered) {
1682 track->set_remote_control_id (next_control_id());
1685 new_routes.push_back (track);
1686 ret.push_back (track);
1689 catch (failed_constructor &err) {
1690 error << _("Session: could not create new midi track.") << endmsg;
1694 catch (AudioEngine::PortRegistrationFailure& pfe) {
1696 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with more ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
1704 if (!new_routes.empty()) {
1705 add_routes (new_routes, true, true, true);
1708 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
1709 PluginPtr plugin = instrument->load (*this);
1710 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
1711 (*r)->add_processor (p, PreFader);
1721 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
1723 boost::shared_ptr<Route> midi_track (wmt.lock());
1729 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
1731 if (change.after.n_audio() <= change.before.n_audio()) {
1735 /* new audio ports: make sure the audio goes somewhere useful,
1736 unless the user has no-auto-connect selected.
1738 The existing ChanCounts don't matter for this call as they are only
1739 to do with matching input and output indices, and we are only changing
1745 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
1749 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1750 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1751 * @param output_start As \a input_start, but for outputs.
1754 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
1755 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
1757 if (!IO::connecting_legal) {
1761 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
1767 /* If both inputs and outputs are auto-connected to physical ports,
1768 use the max of input and output offsets to ensure auto-connected
1769 port numbers always match up (e.g. the first audio input and the
1770 first audio output of the route will have the same physical
1771 port number). Otherwise just use the lowest input or output
1775 DEBUG_TRACE (DEBUG::Graph,
1776 string_compose("Auto-connect: existing in = %1 out = %2\n",
1777 existing_inputs, existing_outputs));
1779 const bool in_out_physical =
1780 (Config->get_input_auto_connect() & AutoConnectPhysical)
1781 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1784 const ChanCount in_offset = in_out_physical
1785 ? ChanCount::max(existing_inputs, existing_outputs)
1788 const ChanCount out_offset = in_out_physical
1789 ? ChanCount::max(existing_inputs, existing_outputs)
1792 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1793 vector<string> physinputs;
1794 vector<string> physoutputs;
1796 _engine.get_physical_outputs (*t, physoutputs);
1797 _engine.get_physical_inputs (*t, physinputs);
1799 if (!physinputs.empty() && connect_inputs) {
1800 uint32_t nphysical_in = physinputs.size();
1802 DEBUG_TRACE (DEBUG::Graph,
1803 string_compose("There are %1 physical inputs of type %2\n",
1806 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1809 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1810 DEBUG_TRACE (DEBUG::Graph,
1811 string_compose("Get index %1 + %2 % %3 = %4\n",
1812 in_offset.get(*t), i, nphysical_in,
1813 (in_offset.get(*t) + i) % nphysical_in));
1814 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1817 DEBUG_TRACE (DEBUG::Graph,
1818 string_compose("Connect route %1 IN to %2\n",
1819 route->name(), port));
1821 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
1825 ChanCount one_added (*t, 1);
1826 existing_inputs += one_added;
1830 if (!physoutputs.empty()) {
1831 uint32_t nphysical_out = physoutputs.size();
1832 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1835 if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
1836 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1837 } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
1838 /* master bus is audio only */
1839 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1840 port = _master_out->input()->ports().port(*t,
1841 i % _master_out->input()->n_ports().get(*t))->name();
1845 DEBUG_TRACE (DEBUG::Graph,
1846 string_compose("Connect route %1 OUT to %2\n",
1847 route->name(), port));
1849 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
1853 ChanCount one_added (*t, 1);
1854 existing_outputs += one_added;
1860 /** Caller must not hold process lock
1861 * @param name_template string to use for the start of the name, or "" to use "Audio".
1863 list< boost::shared_ptr<AudioTrack> >
1864 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
1865 uint32_t how_many, string name_template)
1867 char track_name[32];
1868 uint32_t track_id = 0;
1870 RouteList new_routes;
1871 list<boost::shared_ptr<AudioTrack> > ret;
1873 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
1876 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1877 error << "cannot find name for new audio track" << endmsg;
1881 boost::shared_ptr<AudioTrack> track;
1884 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1886 if (track->init ()) {
1890 track->use_new_diskstream();
1892 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1893 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1896 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1898 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1899 error << string_compose (
1900 _("cannot configure %1 in/%2 out configuration for new audio track"),
1901 input_channels, output_channels)
1906 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1907 error << string_compose (
1908 _("cannot configure %1 in/%2 out configuration for new audio track"),
1909 input_channels, output_channels)
1916 route_group->add (track);
1919 track->non_realtime_input_change();
1921 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1922 if (Config->get_remote_model() == UserOrdered) {
1923 track->set_remote_control_id (next_control_id());
1926 new_routes.push_back (track);
1927 ret.push_back (track);
1930 catch (failed_constructor &err) {
1931 error << _("Session: could not create new audio track.") << endmsg;
1935 catch (AudioEngine::PortRegistrationFailure& pfe) {
1937 error << pfe.what() << endmsg;
1945 if (!new_routes.empty()) {
1946 add_routes (new_routes, true, true, true);
1952 /** Caller must not hold process lock.
1953 * @param name_template string to use for the start of the name, or "" to use "Bus".
1956 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1959 uint32_t bus_id = 0;
1963 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
1966 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1967 error << "cannot find name for new audio bus" << endmsg;
1972 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1978 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1979 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1982 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1984 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1985 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1986 input_channels, output_channels)
1992 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1993 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1994 input_channels, output_channels)
2001 route_group->add (bus);
2003 if (Config->get_remote_model() == UserOrdered) {
2004 bus->set_remote_control_id (next_control_id());
2007 bus->add_internal_return ();
2009 ret.push_back (bus);
2015 catch (failed_constructor &err) {
2016 error << _("Session: could not create new audio route.") << endmsg;
2020 catch (AudioEngine::PortRegistrationFailure& pfe) {
2021 error << pfe.what() << endmsg;
2031 add_routes (ret, false, true, true); // autoconnect outputs only
2039 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2042 uint32_t control_id;
2044 uint32_t number = 0;
2046 if (!tree.read (template_path.c_str())) {
2050 XMLNode* node = tree.root();
2052 IO::disable_connecting ();
2054 control_id = next_control_id ();
2058 XMLNode node_copy (*node);
2060 /* Remove IDs of everything so that new ones are used */
2061 node_copy.remove_property_recursively (X_("id"));
2064 string const route_name = node_copy.property(X_("name"))->value ();
2066 /* generate a new name by adding a number to the end of the template name */
2068 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2069 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2073 /* set this name in the XML description that we are about to use */
2074 Route::set_name_in_state (node_copy, name);
2076 /* trim bitslots from listen sends so that new ones are used */
2077 XMLNodeList children = node_copy.children ();
2078 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2079 if ((*i)->name() == X_("Processor")) {
2080 XMLProperty* role = (*i)->property (X_("role"));
2081 if (role && role->value() == X_("Listen")) {
2082 (*i)->remove_property (X_("bitslot"));
2087 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2090 error << _("Session: cannot create track/bus from template description") << endmsg;
2094 if (boost::dynamic_pointer_cast<Track>(route)) {
2095 /* force input/output change signals so that the new diskstream
2096 picks up the configuration of the route. During session
2097 loading this normally happens in a different way.
2100 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2102 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2103 change.after = route->input()->n_ports();
2104 route->input()->changed (change, this);
2105 change.after = route->output()->n_ports();
2106 route->output()->changed (change, this);
2109 route->set_remote_control_id (control_id);
2112 ret.push_back (route);
2115 catch (failed_constructor &err) {
2116 error << _("Session: could not create new route from template") << endmsg;
2120 catch (AudioEngine::PortRegistrationFailure& pfe) {
2121 error << pfe.what() << endmsg;
2130 add_routes (ret, true, true, true);
2131 IO::enable_connecting ();
2138 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2141 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
2142 add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
2145 error << _("Adding new tracks/busses failed") << endmsg;
2150 update_latency (true);
2151 update_latency (false);
2156 save_state (_current_snapshot_name);
2159 RouteAdded (new_routes); /* EMIT SIGNAL */
2163 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
2165 ChanCount existing_inputs;
2166 ChanCount existing_outputs;
2167 uint32_t order = next_control_id();
2169 count_existing_track_channels (existing_inputs, existing_outputs);
2172 RCUWriter<RouteList> writer (routes);
2173 boost::shared_ptr<RouteList> r = writer.get_copy ();
2174 r->insert (r->end(), new_routes.begin(), new_routes.end());
2176 /* if there is no control out and we're not in the middle of loading,
2177 resort the graph here. if there is a control out, we will resort
2178 toward the end of this method. if we are in the middle of loading,
2179 we will resort when done.
2182 if (!_monitor_out && IO::connecting_legal) {
2183 resort_routes_using (r);
2187 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2189 boost::weak_ptr<Route> wpr (*x);
2190 boost::shared_ptr<Route> r (*x);
2192 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2193 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2194 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2195 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2196 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2197 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2199 if (r->is_master()) {
2203 if (r->is_monitor()) {
2207 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2209 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2210 track_playlist_changed (boost::weak_ptr<Track> (tr));
2211 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2213 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2215 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2216 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2221 if (input_auto_connect || output_auto_connect) {
2222 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2225 /* order keys are a GUI responsibility but we need to set up
2226 reasonable defaults because they also affect the remote control
2227 ID in most situations.
2230 if (!r->has_order_key (EditorSort)) {
2231 if (r->is_hidden()) {
2232 /* use an arbitrarily high value */
2233 r->set_order_key (EditorSort, UINT_MAX);
2234 r->set_order_key (MixerSort, UINT_MAX);
2236 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
2237 r->set_order_key (EditorSort, order);
2238 r->set_order_key (MixerSort, order);
2246 if (_monitor_out && IO::connecting_legal) {
2247 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
2249 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2250 if ((*x)->is_monitor()) {
2252 } else if ((*x)->is_master()) {
2255 (*x)->enable_monitor_send ();
2262 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2264 boost::shared_ptr<RouteList> r = routes.reader ();
2265 boost::shared_ptr<Send> s;
2267 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2268 if ((s = (*i)->internal_send_for (dest)) != 0) {
2269 s->amp()->gain_control()->set_value (0.0);
2275 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2277 boost::shared_ptr<RouteList> r = routes.reader ();
2278 boost::shared_ptr<Send> s;
2280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 if ((s = (*i)->internal_send_for (dest)) != 0) {
2282 s->amp()->gain_control()->set_value (1.0);
2288 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2290 boost::shared_ptr<RouteList> r = routes.reader ();
2291 boost::shared_ptr<Send> s;
2293 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2294 if ((s = (*i)->internal_send_for (dest)) != 0) {
2295 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2300 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2302 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2304 boost::shared_ptr<RouteList> r = routes.reader ();
2305 boost::shared_ptr<RouteList> t (new RouteList);
2307 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2308 /* no MIDI sends because there are no MIDI busses yet */
2309 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2314 add_internal_sends (dest, p, t);
2318 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2320 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2321 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2326 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2328 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2332 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2334 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2338 if (!dest->internal_return()) {
2339 dest->add_internal_return ();
2342 sender->add_aux_send (dest, before);
2348 Session::remove_route (boost::shared_ptr<Route> route)
2350 if (route == _master_out) {
2354 route->set_solo (false, this);
2357 RCUWriter<RouteList> writer (routes);
2358 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2362 /* deleting the master out seems like a dumb
2363 idea, but its more of a UI policy issue
2367 if (route == _master_out) {
2368 _master_out = boost::shared_ptr<Route> ();
2371 if (route == _monitor_out) {
2372 _monitor_out.reset ();
2375 /* writer goes out of scope, forces route list update */
2378 update_route_solo_state ();
2380 // We need to disconnect the route's inputs and outputs
2382 route->input()->disconnect (0);
2383 route->output()->disconnect (0);
2385 /* if the route had internal sends sending to it, remove them */
2386 if (route->internal_return()) {
2388 boost::shared_ptr<RouteList> r = routes.reader ();
2389 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2390 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2392 (*i)->remove_processor (s);
2397 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2398 if (mt && mt->step_editing()) {
2399 if (_step_editors > 0) {
2404 update_latency_compensation ();
2407 /* Re-sort routes to remove the graph's current references to the one that is
2408 * going away, then flush old references out of the graph.
2412 if (_process_graph) {
2413 _process_graph->clear_other_chain ();
2416 /* get rid of it from the dead wood collection in the route list manager */
2418 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2422 /* try to cause everyone to drop their references */
2424 route->drop_references ();
2426 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2428 /* save the new state of the world */
2430 if (save_state (_current_snapshot_name)) {
2431 save_history (_current_snapshot_name);
2436 Session::route_mute_changed (void* /*src*/)
2442 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2444 boost::shared_ptr<Route> route = wpr.lock();
2446 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2450 if (route->listening_via_monitor ()) {
2452 if (Config->get_exclusive_solo()) {
2453 /* new listen: disable all other listen */
2454 boost::shared_ptr<RouteList> r = routes.reader ();
2455 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2456 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2459 (*i)->set_listen (false, this);
2465 } else if (_listen_cnt > 0) {
2470 update_route_solo_state ();
2473 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2475 boost::shared_ptr<Route> route = wpr.lock ();
2478 /* should not happen */
2479 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2483 bool send_changed = false;
2485 if (route->solo_isolated()) {
2486 if (_solo_isolated_cnt == 0) {
2487 send_changed = true;
2489 _solo_isolated_cnt++;
2490 } else if (_solo_isolated_cnt > 0) {
2491 _solo_isolated_cnt--;
2492 if (_solo_isolated_cnt == 0) {
2493 send_changed = true;
2498 IsolatedChanged (); /* EMIT SIGNAL */
2503 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2505 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
2507 if (!self_solo_change) {
2508 // session doesn't care about changes to soloed-by-others
2512 if (solo_update_disabled) {
2514 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
2518 boost::shared_ptr<Route> route = wpr.lock ();
2521 boost::shared_ptr<RouteList> r = routes.reader ();
2524 if (route->self_soloed()) {
2530 RouteGroup* rg = route->route_group ();
2531 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
2533 if (delta == 1 && Config->get_exclusive_solo()) {
2535 /* new solo: disable all other solos, but not the group if its solo-enabled */
2537 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2538 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2539 (leave_group_alone && ((*i)->route_group() == rg))) {
2542 (*i)->set_solo (false, this);
2546 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
2548 solo_update_disabled = true;
2550 RouteList uninvolved;
2552 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
2554 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2555 bool via_sends_only;
2556 bool in_signal_flow;
2558 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2559 (leave_group_alone && ((*i)->route_group() == rg))) {
2563 in_signal_flow = false;
2565 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
2567 if ((*i)->feeds (route, &via_sends_only)) {
2568 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
2569 if (!via_sends_only) {
2570 if (!route->soloed_by_others_upstream()) {
2571 (*i)->mod_solo_by_others_downstream (delta);
2574 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
2576 in_signal_flow = true;
2578 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
2581 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
2583 if (route->feeds (*i, &via_sends_only)) {
2584 /* propagate solo upstream only if routing other than
2585 sends is involved, but do consider the other route
2586 (*i) to be part of the signal flow even if only
2589 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
2593 route->soloed_by_others_downstream(),
2594 route->soloed_by_others_upstream()));
2595 if (!via_sends_only) {
2596 if (!route->soloed_by_others_downstream()) {
2597 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
2598 (*i)->mod_solo_by_others_upstream (delta);
2600 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
2603 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
2605 in_signal_flow = true;
2607 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
2610 if (!in_signal_flow) {
2611 uninvolved.push_back (*i);
2615 solo_update_disabled = false;
2616 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
2618 update_route_solo_state (r);
2620 /* now notify that the mute state of the routes not involved in the signal
2621 pathway of the just-solo-changed route may have altered.
2624 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2625 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
2626 (*i)->mute_changed (this);
2629 SoloChanged (); /* EMIT SIGNAL */
2634 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2636 /* now figure out if anything that matters is soloed (or is "listening")*/
2638 bool something_soloed = false;
2639 uint32_t listeners = 0;
2640 uint32_t isolated = 0;
2643 r = routes.reader();
2646 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2647 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2648 something_soloed = true;
2651 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2652 if (Config->get_solo_control_is_listen_control()) {
2655 (*i)->set_listen (false, this);
2659 if ((*i)->solo_isolated()) {
2664 if (something_soloed != _non_soloed_outs_muted) {
2665 _non_soloed_outs_muted = something_soloed;
2666 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2669 _listen_cnt = listeners;
2671 if (isolated != _solo_isolated_cnt) {
2672 _solo_isolated_cnt = isolated;
2673 IsolatedChanged (); /* EMIT SIGNAL */
2676 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
2677 something_soloed, listeners, isolated));
2680 boost::shared_ptr<RouteList>
2681 Session::get_routes_with_internal_returns() const
2683 boost::shared_ptr<RouteList> r = routes.reader ();
2684 boost::shared_ptr<RouteList> rl (new RouteList);
2686 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2687 if ((*i)->internal_return ()) {
2695 Session::io_name_is_legal (const std::string& name)
2697 boost::shared_ptr<RouteList> r = routes.reader ();
2699 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2700 if ((*i)->name() == name) {
2704 if ((*i)->has_io_processor_named (name)) {
2713 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
2716 vector<string> connections;
2718 /* if we are passed only a single route and we're not told to turn
2719 * others off, then just do the simple thing.
2722 if (flip_others == false && rl->size() == 1) {
2723 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
2725 mt->set_input_active (onoff);
2730 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
2732 PortSet& ps ((*rt)->input()->ports());
2734 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
2735 p->get_connections (connections);
2738 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
2739 routes_using_input_from (*s, rl2);
2742 /* scan all relevant routes to see if others are on or off */
2744 bool others_are_already_on = false;
2746 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2748 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2754 if ((*r) != (*rt)) {
2755 if (mt->input_active()) {
2756 others_are_already_on = true;
2759 /* this one needs changing */
2760 mt->set_input_active (onoff);
2766 /* globally reverse other routes */
2768 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
2769 if ((*r) != (*rt)) {
2770 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2772 mt->set_input_active (!others_are_already_on);
2781 Session::routes_using_input_from (const string& str, RouteList& rl)
2783 boost::shared_ptr<RouteList> r = routes.reader();
2785 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2786 if ((*i)->input()->connected_to (str)) {
2792 boost::shared_ptr<Route>
2793 Session::route_by_name (string name)
2795 boost::shared_ptr<RouteList> r = routes.reader ();
2797 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2798 if ((*i)->name() == name) {
2803 return boost::shared_ptr<Route> ((Route*) 0);
2806 boost::shared_ptr<Route>
2807 Session::route_by_id (PBD::ID id)
2809 boost::shared_ptr<RouteList> r = routes.reader ();
2811 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2812 if ((*i)->id() == id) {
2817 return boost::shared_ptr<Route> ((Route*) 0);
2820 boost::shared_ptr<Track>
2821 Session::track_by_diskstream_id (PBD::ID id)
2823 boost::shared_ptr<RouteList> r = routes.reader ();
2825 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2826 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
2827 if (t && t->using_diskstream_id (id)) {
2832 return boost::shared_ptr<Track> ();
2835 boost::shared_ptr<Route>
2836 Session::route_by_remote_id (uint32_t id)
2838 boost::shared_ptr<RouteList> r = routes.reader ();
2840 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2841 if ((*i)->remote_control_id() == id) {
2846 return boost::shared_ptr<Route> ((Route*) 0);
2850 Session::playlist_region_added (boost::weak_ptr<Region> w)
2852 boost::shared_ptr<Region> r = w.lock ();
2857 /* These are the operations that are currently in progress... */
2858 list<GQuark> curr = _current_trans_quarks;
2861 /* ...and these are the operations during which we want to update
2862 the session range location markers.
2865 ops.push_back (Operations::capture);
2866 ops.push_back (Operations::paste);
2867 ops.push_back (Operations::duplicate_region);
2868 ops.push_back (Operations::insert_file);
2869 ops.push_back (Operations::insert_region);
2870 ops.push_back (Operations::drag_region_brush);
2871 ops.push_back (Operations::region_drag);
2872 ops.push_back (Operations::selection_grab);
2873 ops.push_back (Operations::region_fill);
2874 ops.push_back (Operations::fill_selection);
2875 ops.push_back (Operations::create_region);
2876 ops.push_back (Operations::region_copy);
2877 ops.push_back (Operations::fixed_time_region_copy);
2880 /* See if any of the current operations match the ones that we want */
2882 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2884 /* If so, update the session range markers */
2886 maybe_update_session_range (r->position (), r->last_frame ());
2890 /** Update the session range markers if a is before the current start or
2891 * b is after the current end.
2894 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2896 if (_state_of_the_state & Loading) {
2900 if (_session_range_location == 0) {
2902 add_session_range_location (a, b);
2906 if (a < _session_range_location->start()) {
2907 _session_range_location->set_start (a);
2910 if (b > _session_range_location->end()) {
2911 _session_range_location->set_end (b);
2917 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2919 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2920 maybe_update_session_range (i->to, i->to + i->length);
2925 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2927 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2928 maybe_update_session_range (i->from, i->to);
2932 /* Region management */
2934 boost::shared_ptr<Region>
2935 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2937 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2938 RegionFactory::RegionMap::const_iterator i;
2939 boost::shared_ptr<Region> region;
2941 Glib::Threads::Mutex::Lock lm (region_lock);
2943 for (i = regions.begin(); i != regions.end(); ++i) {
2947 if (region->whole_file()) {
2949 if (child->source_equivalent (region)) {
2955 return boost::shared_ptr<Region> ();
2959 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2961 set<boost::shared_ptr<Region> > relevant_regions;
2963 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2964 RegionFactory::get_regions_using_source (*s, relevant_regions);
2967 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2968 set<boost::shared_ptr<Region> >::iterator tmp;
2973 playlists->destroy_region (*r);
2974 RegionFactory::map_remove (*r);
2976 (*r)->drop_sources ();
2977 (*r)->drop_references ();
2979 relevant_regions.erase (r);
2984 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2987 Glib::Threads::Mutex::Lock ls (source_lock);
2988 /* remove from the main source list */
2989 sources.erase ((*s)->id());
2992 (*s)->mark_for_remove ();
2993 (*s)->drop_references ();
3002 Session::remove_last_capture ()
3004 list<boost::shared_ptr<Source> > srcs;
3006 boost::shared_ptr<RouteList> rl = routes.reader ();
3007 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3008 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3013 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
3016 srcs.insert (srcs.end(), l.begin(), l.end());
3021 destroy_sources (srcs);
3023 save_state (_current_snapshot_name);
3028 /* Source Management */
3031 Session::add_source (boost::shared_ptr<Source> source)
3033 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3034 pair<SourceMap::iterator,bool> result;
3036 entry.first = source->id();
3037 entry.second = source;
3040 Glib::Threads::Mutex::Lock lm (source_lock);
3041 result = sources.insert (entry);
3044 if (result.second) {
3046 /* yay, new source */
3048 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
3051 if (!fs->within_session()) {
3052 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
3058 boost::shared_ptr<AudioFileSource> afs;
3060 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3061 if (Config->get_auto_analyse_audio()) {
3062 Analyser::queue_source_for_analysis (source, false);
3066 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
3071 Session::remove_source (boost::weak_ptr<Source> src)
3073 if (_state_of_the_state & Deletion) {
3077 SourceMap::iterator i;
3078 boost::shared_ptr<Source> source = src.lock();
3085 Glib::Threads::Mutex::Lock lm (source_lock);
3087 if ((i = sources.find (source->id())) != sources.end()) {
3092 if (!(_state_of_the_state & InCleanup)) {
3094 /* save state so we don't end up with a session file
3095 referring to non-existent sources.
3098 save_state (_current_snapshot_name);
3102 boost::shared_ptr<Source>
3103 Session::source_by_id (const PBD::ID& id)
3105 Glib::Threads::Mutex::Lock lm (source_lock);
3106 SourceMap::iterator i;
3107 boost::shared_ptr<Source> source;
3109 if ((i = sources.find (id)) != sources.end()) {
3116 boost::shared_ptr<Source>
3117 Session::source_by_path_and_channel (const string& path, uint16_t chn)
3119 Glib::Threads::Mutex::Lock lm (source_lock);
3121 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3122 boost::shared_ptr<AudioFileSource> afs
3123 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3125 if (afs && afs->path() == path && chn == afs->channel()) {
3129 return boost::shared_ptr<Source>();
3133 Session::count_sources_by_origin (const string& path)
3136 Glib::Threads::Mutex::Lock lm (source_lock);
3138 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3139 boost::shared_ptr<FileSource> fs
3140 = boost::dynamic_pointer_cast<FileSource>(i->second);
3142 if (fs && fs->origin() == path) {
3152 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3155 string old_basename = PBD::basename_nosuffix (oldname);
3156 string new_legalized = legalize_for_path (newname);
3158 /* note: we know (or assume) the old path is already valid */
3162 /* destructive file sources have a name of the form:
3164 /path/to/Tnnnn-NAME(%[LR])?.wav
3166 the task here is to replace NAME with the new name.
3171 string::size_type dash;
3173 dir = Glib::path_get_dirname (path);
3174 path = Glib::path_get_basename (path);
3176 /* '-' is not a legal character for the NAME part of the path */
3178 if ((dash = path.find_last_of ('-')) == string::npos) {
3182 prefix = path.substr (0, dash);
3186 path += new_legalized;
3187 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3188 path = Glib::build_filename (dir, path);
3192 /* non-destructive file sources have a name of the form:
3194 /path/to/NAME-nnnnn(%[LR])?.ext
3196 the task here is to replace NAME with the new name.
3201 string::size_type dash;
3202 string::size_type postfix;
3204 dir = Glib::path_get_dirname (path);
3205 path = Glib::path_get_basename (path);
3207 /* '-' is not a legal character for the NAME part of the path */
3209 if ((dash = path.find_last_of ('-')) == string::npos) {
3213 suffix = path.substr (dash+1);
3215 // Suffix is now everything after the dash. Now we need to eliminate
3216 // the nnnnn part, which is done by either finding a '%' or a '.'
3218 postfix = suffix.find_last_of ("%");
3219 if (postfix == string::npos) {
3220 postfix = suffix.find_last_of ('.');
3223 if (postfix != string::npos) {
3224 suffix = suffix.substr (postfix);
3226 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3230 const uint32_t limit = 10000;
3231 char buf[PATH_MAX+1];
3233 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3235 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
3237 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
3238 path = Glib::build_filename (dir, buf);
3246 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
3255 /** Return the full path (in some session directory) for a new within-session source.
3256 * \a name must be a session-unique name that does not contain slashes
3257 * (e.g. as returned by new_*_source_name)
3260 Session::new_source_path_from_name (DataType type, const string& name)
3262 assert(name.find("/") == string::npos);
3264 SessionDirectory sdir(get_best_session_directory_for_new_source());
3267 if (type == DataType::AUDIO) {
3268 p = sdir.sound_path();
3269 } else if (type == DataType::MIDI) {
3270 p = sdir.midi_path();
3272 error << "Unknown source type, unable to create file path" << endmsg;
3276 return Glib::build_filename (p, name);
3280 Session::peak_path (string base) const
3282 return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
3285 /** Return a unique name based on \a base for a new internal audio source */
3287 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3290 char buf[PATH_MAX+1];
3291 const uint32_t limit = 10000;
3293 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3296 legalized = legalize_for_path (base);
3298 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3299 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3301 vector<space_and_path>::iterator i;
3302 uint32_t existing = 0;
3304 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3309 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3310 cnt, legalized.c_str(), ext.c_str());
3311 } else if (nchan == 2) {
3313 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
3314 cnt, legalized.c_str(), ext.c_str());
3316 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
3317 cnt, legalized.c_str(), ext.c_str());
3319 } else if (nchan < 26) {
3320 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
3321 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
3323 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3324 cnt, legalized.c_str(), ext.c_str());
3330 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3331 } else if (nchan == 2) {
3333 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
3335 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
3337 } else if (nchan < 26) {
3338 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
3340 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3344 SessionDirectory sdir((*i).path);
3346 string spath = sdir.sound_path();
3348 /* note that we search *without* the extension so that
3349 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3350 in the event that this new name is required for
3351 a file format change.
3354 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
3360 if (existing == 0) {
3365 error << string_compose(
3366 _("There are already %1 recordings for %2, which I consider too many."),
3367 limit, base) << endmsg;
3369 throw failed_constructor();
3373 return Glib::path_get_basename (buf);
3376 /** Create a new within-session audio source */
3377 boost::shared_ptr<AudioFileSource>
3378 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3380 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3381 const string path = new_source_path_from_name(DataType::AUDIO, name);
3383 return boost::dynamic_pointer_cast<AudioFileSource> (
3384 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3387 /** Return a unique name based on \a base for a new internal MIDI source */
3389 Session::new_midi_source_name (const string& base)
3392 char buf[PATH_MAX+1];
3393 const uint32_t limit = 10000;
3397 legalized = legalize_for_path (base);
3399 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3400 for (cnt = 1; cnt <= limit; ++cnt) {
3402 vector<space_and_path>::iterator i;
3403 uint32_t existing = 0;
3405 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3407 SessionDirectory sdir((*i).path);
3409 std::string p = Glib::build_filename (sdir.midi_path(), legalized);
3411 snprintf (buf, sizeof(buf), "%s-%u.mid", p.c_str(), cnt);
3413 if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3418 if (existing == 0) {
3423 error << string_compose(
3424 _("There are already %1 recordings for %2, which I consider too many."),
3425 limit, base) << endmsg;
3427 throw failed_constructor();
3431 return Glib::path_get_basename(buf);
3435 /** Create a new within-session MIDI source */
3436 boost::shared_ptr<MidiSource>
3437 Session::create_midi_source_for_session (Track* track, string const & n)
3439 /* try to use the existing write source for the track, to keep numbering sane
3443 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3447 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3450 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3451 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3455 const string name = new_midi_source_name (n);
3456 const string path = new_source_path_from_name (DataType::MIDI, name);
3458 return boost::dynamic_pointer_cast<SMFSource> (
3459 SourceFactory::createWritable (
3460 DataType::MIDI, *this, path, false, frame_rate()));
3465 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3467 if (playlist->hidden()) {
3471 playlists->add (playlist);
3474 playlist->release();
3481 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3483 if (_state_of_the_state & Deletion) {
3487 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3493 playlists->remove (playlist);
3499 Session::set_audition (boost::shared_ptr<Region> r)
3501 pending_audition_region = r;
3502 add_post_transport_work (PostTransportAudition);
3503 _butler->schedule_transport_work ();
3507 Session::audition_playlist ()
3509 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3510 ev->region.reset ();
3515 Session::non_realtime_set_audition ()
3517 assert (pending_audition_region);
3518 auditioner->audition_region (pending_audition_region);
3519 pending_audition_region.reset ();
3520 AuditionActive (true); /* EMIT SIGNAL */
3524 Session::audition_region (boost::shared_ptr<Region> r)
3526 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3532 Session::cancel_audition ()
3534 if (auditioner->auditioning()) {
3535 auditioner->cancel_audition ();
3536 AuditionActive (false); /* EMIT SIGNAL */
3541 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3543 if (a->is_monitor()) {
3546 if (b->is_monitor()) {
3549 return a->order_key (MixerSort) < b->order_key (MixerSort);
3553 Session::is_auditioning () const
3555 /* can be called before we have an auditioner object */
3557 return auditioner->auditioning();
3564 Session::graph_reordered ()
3566 /* don't do this stuff if we are setting up connections
3567 from a set_state() call or creating new tracks. Ditto for deletion.
3570 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
3574 /* every track/bus asked for this to be handled but it was deferred because
3575 we were connecting. do it now.
3578 request_input_change_handling ();
3582 /* force all diskstreams to update their capture offset values to
3583 reflect any changes in latencies within the graph.
3586 boost::shared_ptr<RouteList> rl = routes.reader ();
3587 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3588 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3590 tr->set_capture_offset ();
3595 /** @return Number of frames that there is disk space available to write,
3598 boost::optional<framecnt_t>
3599 Session::available_capture_duration ()
3601 Glib::Threads::Mutex::Lock lm (space_lock);
3603 if (_total_free_4k_blocks_uncertain) {
3604 return boost::optional<framecnt_t> ();
3607 float sample_bytes_on_disk = 4.0; // keep gcc happy
3609 switch (config.get_native_file_data_format()) {
3611 sample_bytes_on_disk = 4.0;
3615 sample_bytes_on_disk = 3.0;
3619 sample_bytes_on_disk = 2.0;
3623 /* impossible, but keep some gcc versions happy */
3624 fatal << string_compose (_("programming error: %1"),
3625 X_("illegal native file data format"))
3630 double scale = 4096.0 / sample_bytes_on_disk;
3632 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3633 return max_framecnt;
3636 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3640 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3643 RCUWriter<BundleList> writer (_bundles);
3644 boost::shared_ptr<BundleList> b = writer.get_copy ();
3645 b->push_back (bundle);
3648 BundleAdded (bundle); /* EMIT SIGNAL */
3654 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3656 bool removed = false;
3659 RCUWriter<BundleList> writer (_bundles);
3660 boost::shared_ptr<BundleList> b = writer.get_copy ();
3661 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3663 if (i != b->end()) {
3670 BundleRemoved (bundle); /* EMIT SIGNAL */
3676 boost::shared_ptr<Bundle>
3677 Session::bundle_by_name (string name) const
3679 boost::shared_ptr<BundleList> b = _bundles.reader ();
3681 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3682 if ((*i)->name() == name) {
3687 return boost::shared_ptr<Bundle> ();
3691 Session::tempo_map_changed (const PropertyChange&)
3695 playlists->update_after_tempo_map_change ();
3697 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3703 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3705 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3706 (*i)->recompute_frames_from_bbt ();
3710 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3711 * the given count with the current block size.
3714 Session::ensure_buffers (ChanCount howmany)
3716 BufferManager::ensure_buffers (howmany);
3720 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3722 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3723 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3728 Session::next_insert_id ()
3730 /* this doesn't really loop forever. just think about it */
3733 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3734 if (!insert_bitset[n]) {
3735 insert_bitset[n] = true;
3741 /* none available, so resize and try again */
3743 insert_bitset.resize (insert_bitset.size() + 16, false);
3748 Session::next_send_id ()
3750 /* this doesn't really loop forever. just think about it */
3753 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3754 if (!send_bitset[n]) {
3755 send_bitset[n] = true;
3761 /* none available, so resize and try again */
3763 send_bitset.resize (send_bitset.size() + 16, false);
3768 Session::next_aux_send_id ()
3770 /* this doesn't really loop forever. just think about it */
3773 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
3774 if (!aux_send_bitset[n]) {
3775 aux_send_bitset[n] = true;
3781 /* none available, so resize and try again */
3783 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
3788 Session::next_return_id ()
3790 /* this doesn't really loop forever. just think about it */
3793 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3794 if (!return_bitset[n]) {
3795 return_bitset[n] = true;
3801 /* none available, so resize and try again */
3803 return_bitset.resize (return_bitset.size() + 16, false);
3808 Session::mark_send_id (uint32_t id)
3810 if (id >= send_bitset.size()) {
3811 send_bitset.resize (id+16, false);
3813 if (send_bitset[id]) {
3814 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3816 send_bitset[id] = true;
3820 Session::mark_aux_send_id (uint32_t id)
3822 if (id >= aux_send_bitset.size()) {
3823 aux_send_bitset.resize (id+16, false);
3825 if (aux_send_bitset[id]) {
3826 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
3828 aux_send_bitset[id] = true;
3832 Session::mark_return_id (uint32_t id)
3834 if (id >= return_bitset.size()) {
3835 return_bitset.resize (id+16, false);
3837 if (return_bitset[id]) {
3838 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3840 return_bitset[id] = true;
3844 Session::mark_insert_id (uint32_t id)
3846 if (id >= insert_bitset.size()) {
3847 insert_bitset.resize (id+16, false);
3849 if (insert_bitset[id]) {
3850 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3852 insert_bitset[id] = true;
3856 Session::unmark_send_id (uint32_t id)
3858 if (id < send_bitset.size()) {
3859 send_bitset[id] = false;
3864 Session::unmark_aux_send_id (uint32_t id)
3866 if (id < aux_send_bitset.size()) {
3867 aux_send_bitset[id] = false;
3872 Session::unmark_return_id (uint32_t id)
3874 if (id < return_bitset.size()) {
3875 return_bitset[id] = false;
3880 Session::unmark_insert_id (uint32_t id)
3882 if (id < insert_bitset.size()) {
3883 insert_bitset[id] = false;
3888 Session::reset_native_file_format ()
3890 boost::shared_ptr<RouteList> rl = routes.reader ();
3891 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3892 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3894 /* don't save state as we do this, there's no point
3897 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3898 tr->reset_write_sources (false);
3899 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3905 Session::route_name_unique (string n) const
3907 boost::shared_ptr<RouteList> r = routes.reader ();
3909 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3910 if ((*i)->name() == n) {
3919 Session::route_name_internal (string n) const
3921 if (auditioner && auditioner->name() == n) {
3925 if (_click_io && _click_io->name() == n) {
3933 Session::freeze_all (InterThreadInfo& itt)
3935 boost::shared_ptr<RouteList> r = routes.reader ();
3937 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3939 boost::shared_ptr<Track> t;
3941 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3942 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3952 boost::shared_ptr<Region>
3953 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3954 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3955 InterThreadInfo& itt,
3956 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
3959 boost::shared_ptr<Region> result;
3960 boost::shared_ptr<Playlist> playlist;
3961 boost::shared_ptr<AudioFileSource> fsource;
3963 char buf[PATH_MAX+1];
3964 ChanCount diskstream_channels (track.n_channels());
3965 framepos_t position;
3966 framecnt_t this_chunk;
3969 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3970 const string sound_dir = sdir.sound_path();
3971 framepos_t len = end - start;
3972 bool need_block_size_reset = false;
3974 ChanCount const max_proc = track.max_processor_streams ();
3977 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3978 end, start) << endmsg;
3982 const framecnt_t chunk_size = (256 * 1024)/4;
3984 // block all process callback handling
3986 block_processing ();
3988 /* call tree *MUST* hold route_lock */
3990 if ((playlist = track.playlist()) == 0) {
3994 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3996 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3998 for (x = 0; x < 99999; ++x) {
3999 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());
4000 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
4006 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4011 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4012 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4015 catch (failed_constructor& err) {
4016 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4020 srcs.push_back (fsource);
4023 /* tell redirects that care that we are about to use a much larger
4024 * blocksize. this will flush all plugins too, so that they are ready
4025 * to be used for this process.
4028 need_block_size_reset = true;
4029 track.set_block_size (chunk_size);
4034 /* create a set of reasonably-sized buffers */
4035 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
4036 buffers.set_count (max_proc);
4038 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4039 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4041 afs->prepare_for_peakfile_writes ();
4044 while (to_do && !itt.cancel) {
4046 this_chunk = min (to_do, chunk_size);
4048 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export)) {
4053 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4054 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4057 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4063 start += this_chunk;
4064 to_do -= this_chunk;
4066 itt.progress = (float) (1.0 - ((double) to_do / len));
4075 xnow = localtime (&now);
4077 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4078 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4081 afs->update_header (position, *xnow, now);
4082 afs->flush_header ();
4086 /* construct a region to represent the bounced material */
4090 plist.add (Properties::start, 0);
4091 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4092 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4094 result = RegionFactory::create (srcs, plist);
4100 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4101 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4104 afs->mark_for_remove ();
4107 (*src)->drop_references ();
4111 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4112 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4115 afs->done_with_peakfile_writes ();
4120 if (need_block_size_reset) {
4121 track.set_block_size (get_block_size());
4124 unblock_processing ();
4130 Session::gain_automation_buffer() const
4132 return ProcessThread::gain_automation_buffer ();
4136 Session::send_gain_automation_buffer() const
4138 return ProcessThread::send_gain_automation_buffer ();
4142 Session::pan_automation_buffer() const
4144 return ProcessThread::pan_automation_buffer ();
4148 Session::get_silent_buffers (ChanCount count)
4150 return ProcessThread::get_silent_buffers (count);
4154 Session::get_scratch_buffers (ChanCount count)
4156 return ProcessThread::get_scratch_buffers (count);
4160 Session::get_mix_buffers (ChanCount count)
4162 return ProcessThread::get_mix_buffers (count);
4166 Session::ntracks () const
4169 boost::shared_ptr<RouteList> r = routes.reader ();
4171 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4172 if (boost::dynamic_pointer_cast<Track> (*i)) {
4181 Session::nbusses () const
4184 boost::shared_ptr<RouteList> r = routes.reader ();
4186 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4187 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4196 Session::add_automation_list(AutomationList *al)
4198 automation_lists[al->id()] = al;
4201 /** @return true if there is at least one record-enabled track, otherwise false */
4203 Session::have_rec_enabled_track () const
4205 return g_atomic_int_get (const_cast<gint*>(&_have_rec_enabled_track)) == 1;
4208 /** Update the state of our rec-enabled tracks flag */
4210 Session::update_have_rec_enabled_track ()
4212 boost::shared_ptr<RouteList> rl = routes.reader ();
4213 RouteList::iterator i = rl->begin();
4214 while (i != rl->end ()) {
4216 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4217 if (tr && tr->record_enabled ()) {
4224 int const old = g_atomic_int_get (&_have_rec_enabled_track);
4226 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
4228 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
4229 RecordStateChanged (); /* EMIT SIGNAL */
4234 Session::listen_position_changed ()
4236 boost::shared_ptr<RouteList> r = routes.reader ();
4238 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4239 (*i)->listen_position_changed ();
4244 Session::solo_control_mode_changed ()
4246 /* cancel all solo or all listen when solo control mode changes */
4249 set_solo (get_routes(), false);
4250 } else if (listening()) {
4251 set_listen (get_routes(), false);
4255 /** Called when a property of one of our route groups changes */
4257 Session::route_group_property_changed (RouteGroup* rg)
4259 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
4262 /** Called when a route is added to one of our route groups */
4264 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4266 RouteAddedToRouteGroup (rg, r);
4269 /** Called when a route is removed from one of our route groups */
4271 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4273 RouteRemovedFromRouteGroup (rg, r);
4276 boost::shared_ptr<RouteList>
4277 Session::get_routes_with_regions_at (framepos_t const p) const
4279 boost::shared_ptr<RouteList> r = routes.reader ();
4280 boost::shared_ptr<RouteList> rl (new RouteList);
4282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4283 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4288 boost::shared_ptr<Playlist> pl = tr->playlist ();
4293 if (pl->has_region_at (p)) {
4302 Session::goto_end ()
4304 if (_session_range_location) {
4305 request_locate (_session_range_location->end(), false);
4307 request_locate (0, false);
4312 Session::goto_start ()
4314 if (_session_range_location) {
4315 request_locate (_session_range_location->start(), false);
4317 request_locate (0, false);
4322 Session::current_start_frame () const
4324 return _session_range_location ? _session_range_location->start() : 0;
4328 Session::current_end_frame () const
4330 return _session_range_location ? _session_range_location->end() : 0;
4334 Session::add_session_range_location (framepos_t start, framepos_t end)
4336 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4337 _locations->add (_session_range_location);
4341 Session::step_edit_status_change (bool yn)
4347 send = (_step_editors == 0);
4352 send = (_step_editors == 1);
4355 if (_step_editors > 0) {
4361 StepEditStatusChange (val);
4367 Session::start_time_changed (framepos_t old)
4369 /* Update the auto loop range to match the session range
4370 (unless the auto loop range has been changed by the user)
4373 Location* s = _locations->session_range_location ();
4378 Location* l = _locations->auto_loop_location ();
4380 if (l && l->start() == old) {
4381 l->set_start (s->start(), true);
4386 Session::end_time_changed (framepos_t old)
4388 /* Update the auto loop range to match the session range
4389 (unless the auto loop range has been changed by the user)
4392 Location* s = _locations->session_range_location ();
4397 Location* l = _locations->auto_loop_location ();
4399 if (l && l->end() == old) {
4400 l->set_end (s->end(), true);
4405 Session::source_search_path (DataType type) const
4409 if (session_dirs.size() == 1) {
4411 case DataType::AUDIO:
4412 s.push_back (_session_dir->sound_path());
4414 case DataType::MIDI:
4415 s.push_back (_session_dir->midi_path());
4419 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4420 SessionDirectory sdir (i->path);
4422 case DataType::AUDIO:
4423 s.push_back (sdir.sound_path());
4425 case DataType::MIDI:
4426 s.push_back (sdir.midi_path());
4432 if (type == DataType::AUDIO) {
4433 const string sound_path_2X = _session_dir->sound_path_2X();
4434 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
4435 if (find (s.begin(), s.end(), sound_path_2X) == s.end()) {
4436 s.push_back (sound_path_2X);
4441 /* now check the explicit (possibly user-specified) search path
4444 vector<string> dirs;
4447 case DataType::AUDIO:
4448 split (config.get_audio_search_path (), dirs, ':');
4450 case DataType::MIDI:
4451 split (config.get_midi_search_path (), dirs, ':');
4455 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4456 if (find (s.begin(), s.end(), *i) == s.end()) {
4463 for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) {
4464 if (!search_path.empty()) {
4474 Session::ensure_search_path_includes (const string& path, DataType type)
4477 vector<string> dirs;
4484 case DataType::AUDIO:
4485 search_path = config.get_audio_search_path ();
4487 case DataType::MIDI:
4488 search_path = config.get_midi_search_path ();
4492 split (search_path, dirs, ':');
4494 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4495 /* No need to add this new directory if it has the same inode as
4496 an existing one; checking inode rather than name prevents duplicated
4497 directories when we are using symlinks.
4499 On Windows, I think we could just do if (*i == path) here.
4501 if (PBD::equivalent_paths (*i, path)) {
4506 if (!search_path.empty()) {
4510 search_path += path;
4513 case DataType::AUDIO:
4514 config.set_audio_search_path (search_path);
4516 case DataType::MIDI:
4517 config.set_midi_search_path (search_path);
4522 boost::shared_ptr<Speakers>
4523 Session::get_speakers()
4529 Session::unknown_processors () const
4533 boost::shared_ptr<RouteList> r = routes.reader ();
4534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4535 list<string> t = (*i)->unknown_processors ();
4536 copy (t.begin(), t.end(), back_inserter (p));
4546 Session::update_latency (bool playback)
4548 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4550 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
4554 boost::shared_ptr<RouteList> r = routes.reader ();
4555 framecnt_t max_latency = 0;
4558 /* reverse the list so that we work backwards from the last route to run to the first */
4559 RouteList* rl = routes.reader().get();
4560 r.reset (new RouteList (*rl));
4561 reverse (r->begin(), r->end());
4564 /* compute actual latency values for the given direction and store them all in per-port
4565 structures. this will also publish the same values (to JACK) so that computation of latency
4566 for routes can consistently use public latency values.
4569 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4570 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4573 /* because we latency compensate playback, our published playback latencies should
4574 be the same for all output ports - all material played back by ardour has
4575 the same latency, whether its caused by plugins or by latency compensation. since
4576 these may differ from the values computed above, reset all playback port latencies
4580 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4582 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4583 (*i)->set_public_port_latencies (max_latency, playback);
4588 post_playback_latency ();
4592 post_capture_latency ();
4595 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
4599 Session::post_playback_latency ()
4601 set_worst_playback_latency ();
4603 boost::shared_ptr<RouteList> r = routes.reader ();
4605 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4606 if (!(*i)->is_hidden() && ((*i)->active())) {
4607 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
4611 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4612 (*i)->set_latency_compensation (_worst_track_latency);
4617 Session::post_capture_latency ()
4619 set_worst_capture_latency ();
4621 /* reflect any changes in capture latencies into capture offsets
4624 boost::shared_ptr<RouteList> rl = routes.reader();
4625 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4626 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4628 tr->set_capture_offset ();
4634 Session::initialize_latencies ()
4637 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
4638 update_latency (false);
4639 update_latency (true);
4642 set_worst_io_latencies ();
4646 Session::set_worst_io_latencies ()
4648 set_worst_playback_latency ();
4649 set_worst_capture_latency ();
4653 Session::set_worst_playback_latency ()
4655 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4659 _worst_output_latency = 0;
4661 if (!_engine.connected()) {
4665 boost::shared_ptr<RouteList> r = routes.reader ();
4667 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4668 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
4671 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
4675 Session::set_worst_capture_latency ()
4677 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4681 _worst_input_latency = 0;
4683 if (!_engine.connected()) {
4687 boost::shared_ptr<RouteList> r = routes.reader ();
4689 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4690 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
4693 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
4697 Session::update_latency_compensation (bool force_whole_graph)
4699 bool some_track_latency_changed = false;
4701 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4705 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
4707 _worst_track_latency = 0;
4709 boost::shared_ptr<RouteList> r = routes.reader ();
4711 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4712 if (!(*i)->is_hidden() && ((*i)->active())) {
4714 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
4715 some_track_latency_changed = true;
4717 _worst_track_latency = max (tl, _worst_track_latency);
4721 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
4722 (some_track_latency_changed ? "yes" : "no")));
4724 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
4726 if (some_track_latency_changed || force_whole_graph) {
4727 _engine.update_latencies ();
4731 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4732 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4736 tr->set_capture_offset ();
4741 Session::session_name_is_legal (const string& path)
4743 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
4745 for (int i = 0; illegal_chars[i]; ++i) {
4746 if (path.find (illegal_chars[i]) != string::npos) {
4747 return illegal_chars[i];
4755 Session::next_control_id () const
4759 /* the monitor bus remote ID is in a different
4760 * "namespace" than regular routes. its existence doesn't
4761 * affect normal (low) numbered routes.
4768 return nroutes() - subtract;
4772 Session::notify_remote_id_change ()
4774 if (deletion_in_progress()) {
4778 switch (Config->get_remote_model()) {
4781 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
4789 Session::sync_order_keys (RouteSortOrderKey sort_key_changed)
4791 if (deletion_in_progress()) {
4795 /* tell everyone that something has happened to the sort keys
4796 and let them sync up with the change(s)
4797 this will give objects that manage the sort order keys the
4798 opportunity to keep them in sync if they wish to.
4801 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("Sync Order Keys, based on %1\n", enum_2_string (sort_key_changed)));
4803 Route::SyncOrderKeys (sort_key_changed); /* EMIT SIGNAL */
4805 DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
4809 Session::operation_in_progress (GQuark op) const
4811 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
4814 boost::shared_ptr<Port>
4815 Session::ltc_input_port () const
4817 return _ltc_input->nth (0);
4820 boost::shared_ptr<Port>
4821 Session::ltc_output_port () const
4823 return _ltc_output->nth (0);
4827 Session::reconnect_ltc_input ()
4831 string src = Config->get_ltc_source_port();
4833 _ltc_input->disconnect (this);
4835 if (src != _("None") && !src.empty()) {
4836 _ltc_input->nth (0)->connect (src);
4842 Session::reconnect_ltc_output ()
4847 string src = Config->get_ltc_sink_port();
4849 _ltc_output->disconnect (this);
4851 if (src != _("None") && !src.empty()) {
4852 _ltc_output->nth (0)->connect (src);