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/thread.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/strsplit.h"
49 #include "pbd/unwind.h"
51 #include "ardour/amp.h"
52 #include "ardour/analyser.h"
53 #include "ardour/audio_buffer.h"
54 #include "ardour/audio_diskstream.h"
55 #include "ardour/audio_port.h"
56 #include "ardour/audio_track.h"
57 #include "ardour/audioengine.h"
58 #include "ardour/audiofilesource.h"
59 #include "ardour/audioplaylist.h"
60 #include "ardour/audioregion.h"
61 #include "ardour/auditioner.h"
62 #include "ardour/buffer_manager.h"
63 #include "ardour/buffer_set.h"
64 #include "ardour/bundle.h"
65 #include "ardour/butler.h"
66 #include "ardour/click.h"
67 #include "ardour/configuration.h"
68 #include "ardour/control_protocol_manager.h"
69 #include "ardour/crossfade.h"
70 #include "ardour/cycle_timer.h"
71 #include "ardour/data_type.h"
72 #include "ardour/debug.h"
73 #include "ardour/filename_extensions.h"
74 #include "ardour/internal_send.h"
75 #include "ardour/io_processor.h"
76 #include "ardour/midi_diskstream.h"
77 #include "ardour/midi_playlist.h"
78 #include "ardour/midi_region.h"
79 #include "ardour/midi_track.h"
80 #include "ardour/midi_ui.h"
81 #include "ardour/named_selection.h"
82 #include "ardour/process_thread.h"
83 #include "ardour/playlist.h"
84 #include "ardour/plugin.h"
85 #include "ardour/plugin_insert.h"
86 #include "ardour/port_insert.h"
87 #include "ardour/processor.h"
88 #include "ardour/rc_configuration.h"
89 #include "ardour/recent_sessions.h"
90 #include "ardour/region_factory.h"
91 #include "ardour/return.h"
92 #include "ardour/route_graph.h"
93 #include "ardour/route_group.h"
94 #include "ardour/send.h"
95 #include "ardour/session.h"
96 #include "ardour/session_directory.h"
97 #include "ardour/session_directory.h"
98 #include "ardour/session_metadata.h"
99 #include "ardour/session_playlists.h"
100 #include "ardour/slave.h"
101 #include "ardour/smf_source.h"
102 #include "ardour/source_factory.h"
103 #include "ardour/tape_file_matcher.h"
104 #include "ardour/tempo.h"
105 #include "ardour/utils.h"
106 #include "ardour/graph.h"
107 #include "ardour/speakers.h"
108 #include "ardour/operations.h"
110 #include "midi++/port.h"
111 #include "midi++/mmc.h"
112 #include "midi++/manager.h"
117 using namespace ARDOUR;
120 bool Session::_disable_all_loaded_plugins = false;
122 PBD::Signal1<void,std::string> Session::Dialog;
123 PBD::Signal0<int> Session::AskAboutPendingState;
124 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
125 PBD::Signal0<void> Session::SendFeedback;
126 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
128 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
129 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
130 PBD::Signal0<void> Session::AutoBindingOn;
131 PBD::Signal0<void> Session::AutoBindingOff;
132 PBD::Signal2<void,std::string, std::string> Session::Exported;
133 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
134 PBD::Signal0<void> Session::Quit;
135 PBD::Signal0<void> Session::FeedbackDetected;
136 PBD::Signal0<void> Session::SuccessfulGraphSort;
138 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
139 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
141 /** @param snapshot_name Snapshot name, without .ardour prefix */
142 Session::Session (AudioEngine &eng,
143 const string& fullpath,
144 const string& snapshot_name,
145 BusProfile* bus_profile,
148 , _target_transport_speed (0.0)
149 , _requested_return_frame (-1)
150 , _session_dir (new SessionDirectory(fullpath))
152 , _state_of_the_state (Clean)
153 , _butler (new Butler (*this))
154 , _post_transport_work (0)
155 , _send_timecode_update (false)
156 , _all_route_group (new RouteGroup (*this, "all"))
157 , routes (new RouteList)
158 , _total_free_4k_blocks (0)
159 , _bundles (new BundleList)
160 , _bundle_xml_node (0)
162 , _click_io ((IO*) 0)
164 , click_emphasis_data (0)
166 , _metadata (new SessionMetadata())
167 , _have_rec_enabled_track (false)
168 , _suspend_timecode_transmission (0)
170 _locations = new Locations (*this);
172 if (how_many_dsp_threads () > 1) {
173 /* For now, only create the graph if we are using >1 DSP threads, as
174 it is a bit slower than the old code with 1 thread.
176 _process_graph.reset (new Graph (*this));
179 playlists.reset (new SessionPlaylists);
181 _all_route_group->set_active (true, this);
183 interpolation.add_channel_to (0, 0);
185 if (!eng.connected()) {
186 throw failed_constructor();
189 n_physical_outputs = _engine.n_physical_outputs ();
190 n_physical_inputs = _engine.n_physical_inputs ();
192 first_stage_init (fullpath, snapshot_name);
194 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
197 if (create (mix_template, bus_profile)) {
199 throw failed_constructor ();
203 if (second_stage_init ()) {
205 throw failed_constructor ();
208 store_recent_sessions(_name, _path);
210 bool was_dirty = dirty();
212 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
214 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
215 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
218 DirtyChanged (); /* EMIT SIGNAL */
221 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
222 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
238 vector<void*> debug_pointers;
240 /* if we got to here, leaving pending capture state around
244 remove_pending_capture_state ();
246 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
248 _engine.remove_session ();
250 /* clear history so that no references to objects are held any more */
254 /* clear state tree so that no references to objects are held any more */
258 /* reset dynamic state version back to default */
260 Stateful::loading_state_version = 0;
262 _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 named selections\n");
290 named_selections.clear ();
292 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
293 RegionFactory::delete_all_regions ();
295 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
297 /* reset these three references to special routes before we do the usual route delete thing */
300 _master_out.reset ();
301 _monitor_out.reset ();
304 RCUWriter<RouteList> writer (routes);
305 boost::shared_ptr<RouteList> r = writer.get_copy ();
307 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
308 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
309 (*i)->drop_references ();
313 /* writer goes out of scope and updates master */
317 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
318 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
319 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
320 i->second->drop_references ();
325 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
326 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
331 Crossfade::set_buffer_size (0);
333 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
338 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
340 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
341 boost_debug_list_ptrs ();
346 Session::when_engine_running ()
348 string first_physical_output;
350 BootMessage (_("Set block size and sample rate"));
352 set_block_size (_engine.frames_per_cycle());
353 set_frame_rate (_engine.frame_rate());
355 BootMessage (_("Using configuration"));
357 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
358 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
360 Config->map_parameters (ff);
361 config.map_parameters (ft);
363 /* every time we reconnect, recompute worst case output latencies */
365 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
367 if (synced_to_jack()) {
368 _engine.transport_stop ();
371 if (config.get_jack_time_master()) {
372 _engine.transport_locate (_transport_frame);
380 _click_io.reset (new ClickIO (*this, "click"));
381 _click_gain.reset (new Amp (*this));
382 _click_gain->activate ();
384 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
386 /* existing state for Click */
389 if (Stateful::loading_state_version < 3000) {
390 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
392 const XMLNodeList& children (child->children());
393 XMLNodeList::const_iterator i = children.begin();
394 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
396 if (i != children.end()) {
397 c = _click_gain->set_state (**i, Stateful::loading_state_version);
403 _clicking = Config->get_clicking ();
407 error << _("could not setup Click I/O") << endmsg;
414 /* default state for Click: dual-mono to first 2 physical outputs */
417 _engine.get_physical_outputs (DataType::AUDIO, outs);
419 for (uint32_t physport = 0; physport < 2; ++physport) {
420 if (outs.size() > physport) {
421 if (_click_io->add_port (outs[physport], this)) {
422 // relax, even though its an error
427 if (_click_io->n_ports () > ChanCount::ZERO) {
428 _clicking = Config->get_clicking ();
433 catch (failed_constructor& err) {
434 error << _("cannot setup Click I/O") << endmsg;
437 BootMessage (_("Compute I/O Latencies"));
440 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
443 BootMessage (_("Set up standard connections"));
445 vector<string> inputs[DataType::num_types];
446 vector<string> outputs[DataType::num_types];
447 for (uint32_t i = 0; i < DataType::num_types; ++i) {
448 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
449 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
452 /* Create a set of Bundle objects that map
453 to the physical I/O currently available. We create both
454 mono and stereo bundles, so that the common cases of mono
455 and stereo tracks get bundles to put in their mixer strip
456 in / out menus. There may be a nicer way of achieving that;
457 it doesn't really scale that well to higher channel counts
460 /* mono output bundles */
462 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
464 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
466 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
467 c->add_channel (_("mono"), DataType::AUDIO);
468 c->set_port (0, outputs[DataType::AUDIO][np]);
473 /* stereo output bundles */
475 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
476 if (np + 1 < outputs[DataType::AUDIO].size()) {
478 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
479 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
480 c->add_channel (_("L"), DataType::AUDIO);
481 c->set_port (0, outputs[DataType::AUDIO][np]);
482 c->add_channel (_("R"), DataType::AUDIO);
483 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
489 /* mono input bundles */
491 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
493 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
495 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
496 c->add_channel (_("mono"), DataType::AUDIO);
497 c->set_port (0, inputs[DataType::AUDIO][np]);
502 /* stereo input bundles */
504 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
505 if (np + 1 < inputs[DataType::AUDIO].size()) {
507 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
509 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
510 c->add_channel (_("L"), DataType::AUDIO);
511 c->set_port (0, inputs[DataType::AUDIO][np]);
512 c->add_channel (_("R"), DataType::AUDIO);
513 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
519 /* MIDI input bundles */
521 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
522 string n = inputs[DataType::MIDI][np];
523 boost::erase_first (n, X_("alsa_pcm:"));
525 boost::shared_ptr<Bundle> c (new Bundle (n, false));
526 c->add_channel ("", DataType::MIDI);
527 c->set_port (0, inputs[DataType::MIDI][np]);
531 /* MIDI output bundles */
533 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
534 string n = outputs[DataType::MIDI][np];
535 boost::erase_first (n, X_("alsa_pcm:"));
537 boost::shared_ptr<Bundle> c (new Bundle (n, true));
538 c->add_channel ("", DataType::MIDI);
539 c->set_port (0, outputs[DataType::MIDI][np]);
543 BootMessage (_("Setup signal flow and plugins"));
545 ControlProtocolManager::instance().set_session (this);
547 /* This must be done after the ControlProtocolManager set_session above,
548 as it will set states for ports which the ControlProtocolManager creates.
550 MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
552 /* And this must be done after the MIDI::Manager::set_port_states as
553 * it will try to make connections whose details are loaded by set_port_states.
558 if (_is_new && !no_auto_connect()) {
559 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
560 auto_connect_master_bus ();
563 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
565 /* update latencies */
567 initialize_latencies ();
569 /* hook us up to the engine */
571 BootMessage (_("Connect to engine"));
572 _engine.set_session (this);
576 Session::auto_connect_master_bus ()
578 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
582 /* if requested auto-connect the outputs to the first N physical ports.
585 uint32_t limit = _master_out->n_outputs().n_total();
586 vector<string> outputs[DataType::num_types];
588 for (uint32_t i = 0; i < DataType::num_types; ++i) {
589 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
592 for (uint32_t n = 0; n < limit; ++n) {
593 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
595 if (outputs[p->type()].size() > n) {
596 connect_to = outputs[p->type()][n];
599 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
600 if (_master_out->output()->connect (p, connect_to, this)) {
601 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
610 Session::remove_monitor_section ()
616 /* force reversion to Solo-In-Place */
617 Config->set_solo_control_is_listen_control (false);
620 /* Hold process lock while doing this so that we don't hear bits and
621 * pieces of audio as we work on each route.
624 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
626 /* Connect tracks to monitor section. Note that in an
627 existing session, the internal sends will already exist, but we want the
628 routes to notice that they connect to the control out specifically.
632 boost::shared_ptr<RouteList> r = routes.reader ();
633 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
635 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
637 if ((*x)->is_monitor()) {
639 } else if ((*x)->is_master()) {
642 (*x)->remove_aux_or_listen (_monitor_out);
647 remove_route (_monitor_out);
648 auto_connect_master_bus ();
652 Session::add_monitor_section ()
656 if (_monitor_out || !_master_out) {
660 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
666 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
667 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
670 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
671 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
672 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
676 add_routes (rl, false, false, false);
678 assert (_monitor_out);
680 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
681 are undefined, at best.
684 uint32_t limit = _monitor_out->n_inputs().n_audio();
688 /* connect the inputs to the master bus outputs. this
689 * represents a separate data feed from the internal sends from
690 * each route. as of jan 2011, it allows the monitor section to
691 * conditionally ignore either the internal sends or the normal
692 * input feed, but we should really find a better way to do
696 _master_out->output()->disconnect (this);
698 for (uint32_t n = 0; n < limit; ++n) {
699 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
700 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
703 string connect_to = o->name();
704 if (_monitor_out->input()->connect (p, connect_to, this)) {
705 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
713 /* if monitor section is not connected, connect it to physical outs
716 if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
718 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
720 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
723 _monitor_out->output()->connect_ports_to_bundle (b, this);
725 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
726 Config->get_monitor_bus_preferred_bundle())
732 /* Monitor bus is audio only */
734 uint32_t mod = n_physical_outputs.get (DataType::AUDIO);
735 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
736 vector<string> outputs[DataType::num_types];
738 for (uint32_t i = 0; i < DataType::num_types; ++i) {
739 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
745 for (uint32_t n = 0; n < limit; ++n) {
747 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
749 if (outputs[DataType::AUDIO].size() > (n % mod)) {
750 connect_to = outputs[DataType::AUDIO][n % mod];
753 if (!connect_to.empty()) {
754 if (_monitor_out->output()->connect (p, connect_to, this)) {
755 error << string_compose (
756 _("cannot connect control output %1 to %2"),
767 /* Hold process lock while doing this so that we don't hear bits and
768 * pieces of audio as we work on each route.
771 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
773 /* Connect tracks to monitor section. Note that in an
774 existing session, the internal sends will already exist, but we want the
775 routes to notice that they connect to the control out specifically.
779 boost::shared_ptr<RouteList> rls = routes.reader ();
781 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
783 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
785 if ((*x)->is_monitor()) {
787 } else if ((*x)->is_master()) {
790 (*x)->enable_monitor_send ();
796 Session::hookup_io ()
798 /* stop graph reordering notifications from
799 causing resorts, etc.
802 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
806 /* we delay creating the auditioner till now because
807 it makes its own connections to ports.
811 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
813 throw failed_constructor ();
815 a->use_new_diskstream ();
819 catch (failed_constructor& err) {
820 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
824 /* load bundles, which we may have postponed earlier on */
825 if (_bundle_xml_node) {
826 load_bundles (*_bundle_xml_node);
827 delete _bundle_xml_node;
830 /* Tell all IO objects to connect themselves together */
832 IO::enable_connecting ();
833 MIDI::Port::MakeConnections ();
835 /* Now reset all panners */
837 Delivery::reset_panners ();
839 /* Anyone who cares about input state, wake up and do something */
841 IOConnectionsComplete (); /* EMIT SIGNAL */
843 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
845 /* now handle the whole enchilada as if it was one
851 /* update the full solo state, which can't be
852 correctly determined on a per-route basis, but
853 needs the global overview that only the session
857 update_route_solo_state ();
861 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
863 boost::shared_ptr<Track> track = wp.lock ();
868 boost::shared_ptr<Playlist> playlist;
870 if ((playlist = track->playlist()) != 0) {
871 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
872 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
873 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
878 Session::record_enabling_legal () const
880 /* this used to be in here, but survey says.... we don't need to restrict it */
881 // if (record_status() == Recording) {
885 if (Config->get_all_safe()) {
892 Session::set_track_monitor_input_status (bool yn)
894 boost::shared_ptr<RouteList> rl = routes.reader ();
895 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
896 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
897 if (tr && tr->record_enabled ()) {
898 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
899 tr->request_jack_monitors_input (yn);
905 Session::auto_punch_start_changed (Location* location)
907 replace_event (SessionEvent::PunchIn, location->start());
909 if (get_record_enabled() && config.get_punch_in()) {
910 /* capture start has been changed, so save new pending state */
911 save_state ("", true);
916 Session::auto_punch_end_changed (Location* location)
918 framepos_t when_to_stop = location->end();
919 // when_to_stop += _worst_output_latency + _worst_input_latency;
920 replace_event (SessionEvent::PunchOut, when_to_stop);
924 Session::auto_punch_changed (Location* location)
926 framepos_t when_to_stop = location->end();
928 replace_event (SessionEvent::PunchIn, location->start());
929 //when_to_stop += _worst_output_latency + _worst_input_latency;
930 replace_event (SessionEvent::PunchOut, when_to_stop);
934 Session::auto_loop_changed (Location* location)
936 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
938 if (transport_rolling() && play_loop) {
941 // if (_transport_frame > location->end()) {
943 if (_transport_frame < location->start() || _transport_frame > location->end()) {
944 // relocate to beginning of loop
945 clear_events (SessionEvent::LocateRoll);
947 request_locate (location->start(), true);
950 else if (Config->get_seamless_loop() && !loop_changing) {
952 // schedule a locate-roll to refill the diskstreams at the
954 loop_changing = true;
956 if (location->end() > last_loopend) {
957 clear_events (SessionEvent::LocateRoll);
958 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
965 last_loopend = location->end();
969 Session::set_auto_punch_location (Location* location)
973 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
974 punch_connections.drop_connections();
975 existing->set_auto_punch (false, this);
976 remove_event (existing->start(), SessionEvent::PunchIn);
977 clear_events (SessionEvent::PunchOut);
978 auto_punch_location_changed (0);
987 if (location->end() <= location->start()) {
988 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
992 punch_connections.drop_connections ();
994 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
995 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
996 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
998 location->set_auto_punch (true, this);
1000 auto_punch_changed (location);
1002 auto_punch_location_changed (location);
1006 Session::set_auto_loop_location (Location* location)
1010 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1011 loop_connections.drop_connections ();
1012 existing->set_auto_loop (false, this);
1013 remove_event (existing->end(), SessionEvent::AutoLoop);
1014 auto_loop_location_changed (0);
1019 if (location == 0) {
1023 if (location->end() <= location->start()) {
1024 error << _("Session: you can't use a mark for auto loop") << endmsg;
1028 last_loopend = location->end();
1030 loop_connections.drop_connections ();
1032 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1033 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1034 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1036 location->set_auto_loop (true, this);
1038 /* take care of our stuff first */
1040 auto_loop_changed (location);
1042 /* now tell everyone else */
1044 auto_loop_location_changed (location);
1048 Session::locations_added (Location *)
1054 Session::locations_changed ()
1056 _locations->apply (*this, &Session::handle_locations_changed);
1060 Session::handle_locations_changed (Locations::LocationList& locations)
1062 Locations::LocationList::iterator i;
1064 bool set_loop = false;
1065 bool set_punch = false;
1067 for (i = locations.begin(); i != locations.end(); ++i) {
1071 if (location->is_auto_punch()) {
1072 set_auto_punch_location (location);
1075 if (location->is_auto_loop()) {
1076 set_auto_loop_location (location);
1080 if (location->is_session_range()) {
1081 _session_range_location = location;
1086 set_auto_loop_location (0);
1089 set_auto_punch_location (0);
1096 Session::enable_record ()
1098 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1099 /* no recording at anything except normal speed */
1104 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1106 if (rs == Recording) {
1110 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1112 _last_record_location = _transport_frame;
1113 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1115 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1116 set_track_monitor_input_status (true);
1119 RecordStateChanged ();
1126 Session::disable_record (bool rt_context, bool force)
1130 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1132 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1133 g_atomic_int_set (&_record_status, Disabled);
1134 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1136 if (rs == Recording) {
1137 g_atomic_int_set (&_record_status, Enabled);
1141 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1142 set_track_monitor_input_status (false);
1145 RecordStateChanged (); /* emit signal */
1148 remove_pending_capture_state ();
1154 Session::step_back_from_record ()
1156 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1158 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1159 set_track_monitor_input_status (false);
1162 RecordStateChanged (); /* emit signal */
1167 Session::maybe_enable_record ()
1169 if (_step_editors > 0) {
1173 g_atomic_int_set (&_record_status, Enabled);
1175 /* This function is currently called from somewhere other than an RT thread.
1176 This save_state() call therefore doesn't impact anything. Doing it here
1177 means that we save pending state of which sources the next record will use,
1178 which gives us some chance of recovering from a crash during the record.
1181 save_state ("", true);
1183 if (_transport_speed) {
1184 if (!config.get_punch_in()) {
1188 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1189 RecordStateChanged (); /* EMIT SIGNAL */
1196 Session::audible_frame () const
1202 /* the first of these two possible settings for "offset"
1203 mean that the audible frame is stationary until
1204 audio emerges from the latency compensation
1207 the second means that the audible frame is stationary
1208 until audio would emerge from a physical port
1209 in the absence of any plugin latency compensation
1212 offset = worst_playback_latency ();
1214 if (offset > current_block_size) {
1215 offset -= current_block_size;
1217 /* XXX is this correct? if we have no external
1218 physical connections and everything is internal
1219 then surely this is zero? still, how
1220 likely is that anyway?
1222 offset = current_block_size;
1225 if (synced_to_jack()) {
1226 tf = _engine.transport_frame();
1228 tf = _transport_frame;
1233 if (!non_realtime_work_pending()) {
1237 /* Check to see if we have passed the first guaranteed
1238 audible frame past our last start position. if not,
1239 return that last start point because in terms
1240 of audible frames, we have not moved yet.
1242 `Start position' in this context means the time we last
1243 either started or changed transport direction.
1246 if (_transport_speed > 0.0f) {
1248 if (!play_loop || !have_looped) {
1249 if (tf < _last_roll_or_reversal_location + offset) {
1250 return _last_roll_or_reversal_location;
1258 } else if (_transport_speed < 0.0f) {
1260 /* XXX wot? no backward looping? */
1262 if (tf > _last_roll_or_reversal_location - offset) {
1263 return _last_roll_or_reversal_location;
1275 Session::set_frame_rate (framecnt_t frames_per_second)
1277 /** \fn void Session::set_frame_size(framecnt_t)
1278 the AudioEngine object that calls this guarantees
1279 that it will not be called while we are also in
1280 ::process(). Its fine to do things that block
1284 _base_frame_rate = frames_per_second;
1288 Automatable::set_automation_interval (ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1292 // XXX we need some equivalent to this, somehow
1293 // SndFileSource::setup_standard_crossfades (frames_per_second);
1297 /* XXX need to reset/reinstantiate all LADSPA plugins */
1301 Session::set_block_size (pframes_t nframes)
1303 /* the AudioEngine guarantees
1304 that it will not be called while we are also in
1305 ::process(). It is therefore fine to do things that block
1310 current_block_size = nframes;
1314 boost::shared_ptr<RouteList> r = routes.reader ();
1316 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1317 (*i)->set_block_size (nframes);
1320 boost::shared_ptr<RouteList> rl = routes.reader ();
1321 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1322 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1324 tr->set_block_size (nframes);
1328 set_worst_io_latencies ();
1334 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1336 boost::shared_ptr<Route> r2;
1338 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1339 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1343 /* make a copy of the existing list of routes that feed r1 */
1345 Route::FedBy existing (r1->fed_by());
1347 /* for each route that feeds r1, recurse, marking it as feeding
1351 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1352 if (!(r2 = i->r.lock ())) {
1353 /* (*i) went away, ignore it */
1357 /* r2 is a route that feeds r1 which somehow feeds base. mark
1358 base as being fed by r2
1361 rbase->add_fed_by (r2, i->sends_only);
1365 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1369 if (r1->feeds (r2) && r2->feeds (r1)) {
1373 /* now recurse, so that we can mark base as being fed by
1374 all routes that feed r2
1377 trace_terminal (r2, rbase);
1384 Session::resort_routes ()
1386 /* don't do anything here with signals emitted
1387 by Routes during initial setup or while we
1388 are being destroyed.
1391 if (_state_of_the_state & (InitialConnecting | Deletion)) {
1396 RCUWriter<RouteList> writer (routes);
1397 boost::shared_ptr<RouteList> r = writer.get_copy ();
1398 resort_routes_using (r);
1399 /* writer goes out of scope and forces update */
1403 boost::shared_ptr<RouteList> rl = routes.reader ();
1404 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1405 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1407 const Route::FedBy& fb ((*i)->fed_by());
1409 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1410 boost::shared_ptr<Route> sf = f->r.lock();
1412 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1420 /** This is called whenever we need to rebuild the graph of how we will process
1422 * @param r List of routes, in any order.
1426 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1428 /* We are going to build a directed graph of our routes;
1429 this is where the edges of that graph are put.
1434 /* Go through all routes doing two things:
1436 * 1. Collect the edges of the route graph. Each of these edges
1437 * is a pair of routes, one of which directly feeds the other
1438 * either by a JACK connection or by an internal send.
1440 * 2. Begin the process of making routes aware of which other
1441 * routes directly or indirectly feed them. This information
1442 * is used by the solo code.
1445 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1447 /* Clear out the route's list of direct or indirect feeds */
1448 (*i)->clear_fed_by ();
1450 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
1452 bool via_sends_only;
1454 /* See if this *j feeds *i according to the current state of the JACK
1455 connections and internal sends.
1457 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
1458 /* add the edge to the graph (part #1) */
1459 edges.add (*j, *i, via_sends_only);
1460 /* tell the route (for part #2) */
1461 (*i)->add_fed_by (*j, via_sends_only);
1466 /* Attempt a topological sort of the route graph */
1467 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
1469 if (sorted_routes) {
1470 /* We got a satisfactory topological sort, so there is no feedback;
1473 Note: the process graph rechain does not require a
1474 topologically-sorted list, but hey ho.
1476 if (_process_graph) {
1477 _process_graph->rechain (sorted_routes, edges);
1480 _current_route_graph = edges;
1482 /* Complete the building of the routes' lists of what directly
1483 or indirectly feeds them.
1485 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1486 trace_terminal (*i, *i);
1492 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1493 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1494 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1495 (*i)->name(), (*i)->order_key ("signal")));
1499 SuccessfulGraphSort (); /* EMIT SIGNAL */
1502 /* The topological sort failed, so we have a problem. Tell everyone
1503 and stick to the old graph; this will continue to be processed, so
1504 until the feedback is fixed, what is played back will not quite
1505 reflect what is actually connected. Note also that we do not
1506 do trace_terminal here, as it would fail due to an endless recursion,
1507 so the solo code will think that everything is still connected
1511 FeedbackDetected (); /* EMIT SIGNAL */
1516 /** Find a route name starting with \a base, maybe followed by the
1517 * lowest \a id. \a id will always be added if \a definitely_add_number
1518 * is true on entry; otherwise it will only be added if required
1519 * to make the name unique.
1521 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1522 * The available route name with the lowest ID will be used, and \a id
1523 * will be set to the ID.
1525 * \return false if a route name could not be found, and \a track_name
1526 * and \a id do not reflect a free route name.
1529 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1531 if (!definitely_add_number && route_by_name (base) == 0) {
1532 /* juse use the base */
1533 snprintf (name, name_len, "%s", base.c_str());
1538 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1540 if (route_by_name (name) == 0) {
1546 } while (id < (UINT_MAX-1));
1551 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
1553 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
1555 in = ChanCount::ZERO;
1556 out = ChanCount::ZERO;
1558 boost::shared_ptr<RouteList> r = routes.reader ();
1560 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1561 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1562 if (tr && !tr->is_hidden()) {
1563 in += tr->n_inputs();
1564 out += tr->n_outputs();
1569 /** Caller must not hold process lock
1570 * @param name_template string to use for the start of the name, or "" to use "MIDI".
1571 * @param instrument plugin info for the instrument to insert pre-fader, if any
1573 list<boost::shared_ptr<MidiTrack> >
1574 Session::new_midi_track (boost::shared_ptr<PluginInfo> instrument, TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1576 char track_name[32];
1577 uint32_t track_id = 0;
1579 RouteList new_routes;
1580 list<boost::shared_ptr<MidiTrack> > ret;
1581 uint32_t control_id;
1583 control_id = next_control_id ();
1585 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
1588 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1589 error << "cannot find name for new midi track" << endmsg;
1593 boost::shared_ptr<MidiTrack> track;
1596 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1598 if (track->init ()) {
1602 track->use_new_diskstream();
1604 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1605 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1608 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1609 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1610 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1614 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1615 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1620 track->non_realtime_input_change();
1623 route_group->add (track);
1626 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1627 track->set_remote_control_id (control_id);
1629 new_routes.push_back (track);
1630 ret.push_back (track);
1633 catch (failed_constructor &err) {
1634 error << _("Session: could not create new midi track.") << endmsg;
1638 catch (AudioEngine::PortRegistrationFailure& pfe) {
1640 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
1648 if (!new_routes.empty()) {
1649 add_routes (new_routes, true, true, true);
1652 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
1653 PluginPtr plugin = instrument->load (*this);
1654 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
1655 (*r)->add_processor (p, PreFader);
1665 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
1667 boost::shared_ptr<Route> midi_track (wmt.lock());
1673 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
1675 if (change.after.n_audio() <= change.before.n_audio()) {
1679 /* new audio ports: make sure the audio goes somewhere useful,
1680 unless the user has no-auto-connect selected.
1682 The existing ChanCounts don't matter for this call as they are only
1683 to do with matching input and output indices, and we are only changing
1689 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
1693 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1694 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1695 * @param output_start As \a input_start, but for outputs.
1698 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
1699 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
1701 if (!IO::connecting_legal) {
1705 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::NOT_LOCK);
1711 /* If both inputs and outputs are auto-connected to physical ports,
1712 use the max of input and output offsets to ensure auto-connected
1713 port numbers always match up (e.g. the first audio input and the
1714 first audio output of the route will have the same physical
1715 port number). Otherwise just use the lowest input or output
1719 DEBUG_TRACE (DEBUG::Graph,
1720 string_compose("Auto-connect: existing in = %1 out = %2\n",
1721 existing_inputs, existing_outputs));
1723 const bool in_out_physical =
1724 (Config->get_input_auto_connect() & AutoConnectPhysical)
1725 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1728 const ChanCount in_offset = in_out_physical
1729 ? ChanCount::max(existing_inputs, existing_outputs)
1732 const ChanCount out_offset = in_out_physical
1733 ? ChanCount::max(existing_inputs, existing_outputs)
1736 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1737 vector<string> physinputs;
1738 vector<string> physoutputs;
1740 _engine.get_physical_outputs (*t, physoutputs);
1741 _engine.get_physical_inputs (*t, physinputs);
1743 if (!physinputs.empty() && connect_inputs) {
1744 uint32_t nphysical_in = physinputs.size();
1746 DEBUG_TRACE (DEBUG::Graph,
1747 string_compose("There are %1 physical inputs of type %2\n",
1750 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1753 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1754 DEBUG_TRACE (DEBUG::Graph,
1755 string_compose("Get index %1 + %2 % %3 = %4\n",
1756 in_offset.get(*t), i, nphysical_in,
1757 (in_offset.get(*t) + i) % nphysical_in));
1758 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1761 DEBUG_TRACE (DEBUG::Graph,
1762 string_compose("Connect route %1 IN to %2\n",
1763 route->name(), port));
1765 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
1769 ChanCount one_added (*t, 1);
1770 existing_inputs += one_added;
1774 if (!physoutputs.empty()) {
1775 uint32_t nphysical_out = physoutputs.size();
1776 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1779 if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
1780 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1781 } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
1782 /* master bus is audio only */
1783 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1784 port = _master_out->input()->ports().port(*t,
1785 i % _master_out->input()->n_ports().get(*t))->name();
1789 DEBUG_TRACE (DEBUG::Graph,
1790 string_compose("Connect route %1 OUT to %2\n",
1791 route->name(), port));
1793 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
1797 ChanCount one_added (*t, 1);
1798 existing_outputs += one_added;
1804 /** Caller must not hold process lock
1805 * @param name_template string to use for the start of the name, or "" to use "Audio".
1807 list< boost::shared_ptr<AudioTrack> >
1808 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
1809 uint32_t how_many, string name_template)
1811 char track_name[32];
1812 uint32_t track_id = 0;
1814 RouteList new_routes;
1815 list<boost::shared_ptr<AudioTrack> > ret;
1816 uint32_t control_id;
1818 control_id = next_control_id ();
1820 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
1823 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1824 error << "cannot find name for new audio track" << endmsg;
1828 boost::shared_ptr<AudioTrack> track;
1831 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1833 if (track->init ()) {
1837 track->use_new_diskstream();
1839 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1840 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1843 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1845 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1846 error << string_compose (
1847 _("cannot configure %1 in/%2 out configuration for new audio track"),
1848 input_channels, output_channels)
1853 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1854 error << string_compose (
1855 _("cannot configure %1 in/%2 out configuration for new audio track"),
1856 input_channels, output_channels)
1863 route_group->add (track);
1866 track->non_realtime_input_change();
1868 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1869 track->set_remote_control_id (control_id);
1872 new_routes.push_back (track);
1873 ret.push_back (track);
1876 catch (failed_constructor &err) {
1877 error << _("Session: could not create new audio track.") << endmsg;
1881 catch (AudioEngine::PortRegistrationFailure& pfe) {
1883 error << pfe.what() << endmsg;
1891 if (!new_routes.empty()) {
1892 add_routes (new_routes, true, true, true);
1899 Session::set_remote_control_ids ()
1901 RemoteModel m = Config->get_remote_model();
1902 bool emit_signal = false;
1904 boost::shared_ptr<RouteList> r = routes.reader ();
1906 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1907 if (MixerOrdered == m) {
1908 int32_t order = (*i)->order_key(N_("signal"));
1909 (*i)->set_remote_control_id (order+1, false);
1911 } else if (EditorOrdered == m) {
1912 int32_t order = (*i)->order_key(N_("editor"));
1913 (*i)->set_remote_control_id (order+1, false);
1915 } else if (UserOrdered == m) {
1916 //do nothing ... only changes to remote id's are initiated by user
1921 Route::RemoteControlIDChange();
1925 /** Caller must not hold process lock.
1926 * @param name_template string to use for the start of the name, or "" to use "Bus".
1929 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1932 uint32_t bus_id = 0;
1935 uint32_t control_id;
1937 control_id = next_control_id ();
1939 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
1942 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1943 error << "cannot find name for new audio bus" << endmsg;
1948 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1954 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1955 // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1958 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1960 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1961 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1962 input_channels, output_channels)
1968 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1969 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1970 input_channels, output_channels)
1977 route_group->add (bus);
1979 bus->set_remote_control_id (control_id);
1982 bus->add_internal_return ();
1984 ret.push_back (bus);
1988 catch (failed_constructor &err) {
1989 error << _("Session: could not create new audio route.") << endmsg;
1993 catch (AudioEngine::PortRegistrationFailure& pfe) {
1994 error << pfe.what() << endmsg;
2004 add_routes (ret, false, true, true); // autoconnect outputs only
2012 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2015 uint32_t control_id;
2017 uint32_t number = 0;
2019 if (!tree.read (template_path.c_str())) {
2023 XMLNode* node = tree.root();
2025 IO::disable_connecting ();
2027 control_id = next_control_id ();
2031 XMLNode node_copy (*node);
2033 /* Remove IDs of everything so that new ones are used */
2034 node_copy.remove_property_recursively (X_("id"));
2037 string const route_name = node_copy.property(X_("name"))->value ();
2039 /* generate a new name by adding a number to the end of the template name */
2041 if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
2042 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2046 /* set this name in the XML description that we are about to use */
2047 Route::set_name_in_state (node_copy, name);
2049 /* trim bitslots from listen sends so that new ones are used */
2050 XMLNodeList children = node_copy.children ();
2051 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2052 if ((*i)->name() == X_("Processor")) {
2053 XMLProperty* role = (*i)->property (X_("role"));
2054 if (role && role->value() == X_("Listen")) {
2055 (*i)->remove_property (X_("bitslot"));
2060 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2063 error << _("Session: cannot create track/bus from template description") << endmsg;
2067 if (boost::dynamic_pointer_cast<Track>(route)) {
2068 /* force input/output change signals so that the new diskstream
2069 picks up the configuration of the route. During session
2070 loading this normally happens in a different way.
2073 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2075 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
2076 change.after = route->input()->n_ports();
2077 route->input()->changed (change, this);
2078 change.after = route->output()->n_ports();
2079 route->output()->changed (change, this);
2082 route->set_remote_control_id (control_id);
2085 ret.push_back (route);
2088 catch (failed_constructor &err) {
2089 error << _("Session: could not create new route from template") << endmsg;
2093 catch (AudioEngine::PortRegistrationFailure& pfe) {
2094 error << pfe.what() << endmsg;
2103 add_routes (ret, true, true, true);
2104 IO::enable_connecting ();
2111 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
2113 ChanCount existing_inputs;
2114 ChanCount existing_outputs;
2116 count_existing_track_channels (existing_inputs, existing_outputs);
2119 RCUWriter<RouteList> writer (routes);
2120 boost::shared_ptr<RouteList> r = writer.get_copy ();
2121 r->insert (r->end(), new_routes.begin(), new_routes.end());
2123 /* if there is no control out and we're not in the middle of loading,
2124 resort the graph here. if there is a control out, we will resort
2125 toward the end of this method. if we are in the middle of loading,
2126 we will resort when done.
2129 if (!_monitor_out && IO::connecting_legal) {
2130 resort_routes_using (r);
2134 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2136 boost::weak_ptr<Route> wpr (*x);
2137 boost::shared_ptr<Route> r (*x);
2139 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2140 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2141 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2142 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2143 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2144 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2145 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
2147 if (r->is_master()) {
2151 if (r->is_monitor()) {
2155 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2157 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2158 track_playlist_changed (boost::weak_ptr<Track> (tr));
2159 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2161 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2163 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2164 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2168 if (input_auto_connect || output_auto_connect) {
2169 auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
2173 if (_monitor_out && IO::connecting_legal) {
2176 Glib::Mutex::Lock lm (_engine.process_lock());
2178 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2179 if ((*x)->is_monitor()) {
2181 } else if ((*x)->is_master()) {
2184 (*x)->enable_monitor_send ();
2195 save_state (_current_snapshot_name);
2198 RouteAdded (new_routes); /* EMIT SIGNAL */
2199 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2203 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2205 boost::shared_ptr<RouteList> r = routes.reader ();
2206 boost::shared_ptr<Send> s;
2208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2209 if ((s = (*i)->internal_send_for (dest)) != 0) {
2210 s->amp()->gain_control()->set_value (0.0);
2216 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2218 boost::shared_ptr<RouteList> r = routes.reader ();
2219 boost::shared_ptr<Send> s;
2221 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2222 if ((s = (*i)->internal_send_for (dest)) != 0) {
2223 s->amp()->gain_control()->set_value (1.0);
2229 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2231 boost::shared_ptr<RouteList> r = routes.reader ();
2232 boost::shared_ptr<Send> s;
2234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2235 if ((s = (*i)->internal_send_for (dest)) != 0) {
2236 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2241 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2243 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2245 boost::shared_ptr<RouteList> r = routes.reader ();
2246 boost::shared_ptr<RouteList> t (new RouteList);
2248 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2249 /* no MIDI sends because there are no MIDI busses yet */
2250 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2255 add_internal_sends (dest, p, t);
2259 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2261 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2262 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
2267 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
2269 add_internal_send (dest, sender->before_processor_for_index (index), sender);
2273 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
2275 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
2279 if (!dest->internal_return()) {
2280 dest->add_internal_return ();
2283 sender->add_aux_send (dest, before);
2289 Session::remove_route (boost::shared_ptr<Route> route)
2291 if (route == _master_out) {
2295 route->set_solo (false, this);
2298 RCUWriter<RouteList> writer (routes);
2299 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2303 /* deleting the master out seems like a dumb
2304 idea, but its more of a UI policy issue
2308 if (route == _master_out) {
2309 _master_out = boost::shared_ptr<Route> ();
2312 if (route == _monitor_out) {
2313 _monitor_out.reset ();
2316 /* writer goes out of scope, forces route list update */
2319 update_route_solo_state ();
2321 // We need to disconnect the route's inputs and outputs
2323 route->input()->disconnect (0);
2324 route->output()->disconnect (0);
2326 /* if the route had internal sends sending to it, remove them */
2327 if (route->internal_return()) {
2329 boost::shared_ptr<RouteList> r = routes.reader ();
2330 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2331 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2333 (*i)->remove_processor (s);
2338 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2339 if (mt && mt->step_editing()) {
2340 if (_step_editors > 0) {
2345 update_latency_compensation ();
2348 /* Re-sort routes to remove the graph's current references to the one that is
2349 * going away, then flush old references out of the graph.
2353 if (_process_graph) {
2354 _process_graph->clear_other_chain ();
2357 /* get rid of it from the dead wood collection in the route list manager */
2359 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2363 /* try to cause everyone to drop their references */
2365 route->drop_references ();
2367 sync_order_keys (N_("session"));
2369 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2371 /* save the new state of the world */
2373 if (save_state (_current_snapshot_name)) {
2374 save_history (_current_snapshot_name);
2379 Session::route_mute_changed (void* /*src*/)
2385 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2387 boost::shared_ptr<Route> route = wpr.lock();
2389 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2393 if (route->listening_via_monitor ()) {
2395 if (Config->get_exclusive_solo()) {
2396 /* new listen: disable all other listen */
2397 boost::shared_ptr<RouteList> r = routes.reader ();
2398 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2399 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2402 (*i)->set_listen (false, this);
2408 } else if (_listen_cnt > 0) {
2413 update_route_solo_state ();
2416 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2418 boost::shared_ptr<Route> route = wpr.lock ();
2421 /* should not happen */
2422 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2426 bool send_changed = false;
2428 if (route->solo_isolated()) {
2429 if (_solo_isolated_cnt == 0) {
2430 send_changed = true;
2432 _solo_isolated_cnt++;
2433 } else if (_solo_isolated_cnt > 0) {
2434 _solo_isolated_cnt--;
2435 if (_solo_isolated_cnt == 0) {
2436 send_changed = true;
2441 IsolatedChanged (); /* EMIT SIGNAL */
2446 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2448 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
2450 if (!self_solo_change) {
2451 // session doesn't care about changes to soloed-by-others
2455 if (solo_update_disabled) {
2457 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
2461 boost::shared_ptr<Route> route = wpr.lock ();
2464 boost::shared_ptr<RouteList> r = routes.reader ();
2467 if (route->self_soloed()) {
2473 RouteGroup* rg = route->route_group ();
2474 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
2476 if (delta == 1 && Config->get_exclusive_solo()) {
2478 /* new solo: disable all other solos, but not the group if its solo-enabled */
2480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2481 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2482 (leave_group_alone && ((*i)->route_group() == rg))) {
2485 (*i)->set_solo (false, this);
2489 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
2491 solo_update_disabled = true;
2493 RouteList uninvolved;
2495 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
2497 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2498 bool via_sends_only;
2499 bool in_signal_flow;
2501 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2502 (leave_group_alone && ((*i)->route_group() == rg))) {
2506 in_signal_flow = false;
2508 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
2510 if ((*i)->feeds (route, &via_sends_only)) {
2511 if (!via_sends_only) {
2512 if (!route->soloed_by_others_upstream()) {
2513 (*i)->mod_solo_by_others_downstream (delta);
2516 in_signal_flow = true;
2518 DEBUG_TRACE (DEBUG::Solo, "\tno feed from\n");
2521 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
2523 if (route->feeds (*i, &via_sends_only)) {
2524 /* propagate solo upstream only if routing other than
2525 sends is involved, but do consider the other route
2526 (*i) to be part of the signal flow even if only
2529 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
2533 route->soloed_by_others_downstream(),
2534 route->soloed_by_others_upstream()));
2535 if (!via_sends_only) {
2536 if (!route->soloed_by_others_downstream()) {
2537 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
2538 (*i)->mod_solo_by_others_upstream (delta);
2541 in_signal_flow = true;
2543 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
2546 if (!in_signal_flow) {
2547 uninvolved.push_back (*i);
2551 solo_update_disabled = false;
2552 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
2554 update_route_solo_state (r);
2556 /* now notify that the mute state of the routes not involved in the signal
2557 pathway of the just-solo-changed route may have altered.
2560 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2561 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1\n", (*i)->name()));
2562 (*i)->mute_changed (this);
2565 SoloChanged (); /* EMIT SIGNAL */
2570 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2572 /* now figure out if anything that matters is soloed (or is "listening")*/
2574 bool something_soloed = false;
2575 uint32_t listeners = 0;
2576 uint32_t isolated = 0;
2579 r = routes.reader();
2582 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2583 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2584 something_soloed = true;
2587 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2588 if (Config->get_solo_control_is_listen_control()) {
2591 (*i)->set_listen (false, this);
2595 if ((*i)->solo_isolated()) {
2600 if (something_soloed != _non_soloed_outs_muted) {
2601 _non_soloed_outs_muted = something_soloed;
2602 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2605 _listen_cnt = listeners;
2607 if (isolated != _solo_isolated_cnt) {
2608 _solo_isolated_cnt = isolated;
2609 IsolatedChanged (); /* EMIT SIGNAL */
2613 boost::shared_ptr<RouteList>
2614 Session::get_routes_with_internal_returns() const
2616 boost::shared_ptr<RouteList> r = routes.reader ();
2617 boost::shared_ptr<RouteList> rl (new RouteList);
2619 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2620 if ((*i)->internal_return ()) {
2628 Session::io_name_is_legal (const std::string& name)
2630 boost::shared_ptr<RouteList> r = routes.reader ();
2632 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2633 if ((*i)->name() == name) {
2637 if ((*i)->has_io_processor_named (name)) {
2646 Session::set_exclusive_input_active (boost::shared_ptr<Route> rt, bool /*others_on*/)
2649 vector<string> connections;
2651 PortSet& ps (rt->input()->ports());
2653 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
2654 p->get_connections (connections);
2657 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
2658 routes_using_input_from (*s, rl);
2661 /* scan all relevant routes to see if others are on or off */
2663 bool others_are_already_on = false;
2665 for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
2667 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2669 if (mt->input_active()) {
2670 others_are_already_on = true;
2677 /* globally reverse other routes */
2679 for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
2681 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2683 mt->set_input_active (!others_are_already_on);
2690 Session::routes_using_input_from (const string& str, RouteList& rl)
2692 boost::shared_ptr<RouteList> r = routes.reader ();
2694 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2695 if ((*i)->input()->connected_to (str)) {
2701 boost::shared_ptr<Route>
2702 Session::route_by_name (string name)
2704 boost::shared_ptr<RouteList> r = routes.reader ();
2706 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2707 if ((*i)->name() == name) {
2712 return boost::shared_ptr<Route> ((Route*) 0);
2715 boost::shared_ptr<Route>
2716 Session::route_by_id (PBD::ID id)
2718 boost::shared_ptr<RouteList> r = routes.reader ();
2720 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2721 if ((*i)->id() == id) {
2726 return boost::shared_ptr<Route> ((Route*) 0);
2729 boost::shared_ptr<Track>
2730 Session::track_by_diskstream_id (PBD::ID id)
2732 boost::shared_ptr<RouteList> r = routes.reader ();
2734 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2735 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
2736 if (t && t->using_diskstream_id (id)) {
2741 return boost::shared_ptr<Track> ();
2744 boost::shared_ptr<Route>
2745 Session::route_by_remote_id (uint32_t id)
2747 boost::shared_ptr<RouteList> r = routes.reader ();
2749 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2750 if ((*i)->remote_control_id() == id) {
2755 return boost::shared_ptr<Route> ((Route*) 0);
2759 Session::playlist_region_added (boost::weak_ptr<Region> w)
2761 boost::shared_ptr<Region> r = w.lock ();
2766 /* These are the operations that are currently in progress... */
2767 list<GQuark> curr = _current_trans_quarks;
2770 /* ...and these are the operations during which we want to update
2771 the session range location markers.
2774 ops.push_back (Operations::capture);
2775 ops.push_back (Operations::paste);
2776 ops.push_back (Operations::duplicate_region);
2777 ops.push_back (Operations::insert_file);
2778 ops.push_back (Operations::insert_region);
2779 ops.push_back (Operations::drag_region_brush);
2780 ops.push_back (Operations::region_drag);
2781 ops.push_back (Operations::selection_grab);
2782 ops.push_back (Operations::region_fill);
2783 ops.push_back (Operations::fill_selection);
2784 ops.push_back (Operations::create_region);
2785 ops.push_back (Operations::region_copy);
2786 ops.push_back (Operations::fixed_time_region_copy);
2789 /* See if any of the current operations match the ones that we want */
2791 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2793 /* If so, update the session range markers */
2795 maybe_update_session_range (r->position (), r->last_frame ());
2799 /** Update the session range markers if a is before the current start or
2800 * b is after the current end.
2803 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2805 if (_state_of_the_state & Loading) {
2809 if (_session_range_location == 0) {
2811 add_session_range_location (a, b);
2815 if (a < _session_range_location->start()) {
2816 _session_range_location->set_start (a);
2819 if (b > _session_range_location->end()) {
2820 _session_range_location->set_end (b);
2826 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2828 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2829 maybe_update_session_range (i->to, i->to + i->length);
2834 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2836 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2837 maybe_update_session_range (i->from, i->to);
2841 /* Region management */
2843 boost::shared_ptr<Region>
2844 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2846 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2847 RegionFactory::RegionMap::const_iterator i;
2848 boost::shared_ptr<Region> region;
2850 Glib::Mutex::Lock lm (region_lock);
2852 for (i = regions.begin(); i != regions.end(); ++i) {
2856 if (region->whole_file()) {
2858 if (child->source_equivalent (region)) {
2864 return boost::shared_ptr<Region> ();
2868 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2870 set<boost::shared_ptr<Region> > relevant_regions;
2872 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2873 RegionFactory::get_regions_using_source (*s, relevant_regions);
2876 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2877 set<boost::shared_ptr<Region> >::iterator tmp;
2882 playlists->destroy_region (*r);
2883 RegionFactory::map_remove (*r);
2885 (*r)->drop_sources ();
2886 (*r)->drop_references ();
2888 relevant_regions.erase (r);
2893 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2896 Glib::Mutex::Lock ls (source_lock);
2897 /* remove from the main source list */
2898 sources.erase ((*s)->id());
2901 (*s)->mark_for_remove ();
2902 (*s)->drop_references ();
2911 Session::remove_last_capture ()
2913 list<boost::shared_ptr<Source> > srcs;
2915 boost::shared_ptr<RouteList> rl = routes.reader ();
2916 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2917 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2922 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2925 srcs.insert (srcs.end(), l.begin(), l.end());
2930 destroy_sources (srcs);
2932 save_state (_current_snapshot_name);
2937 /* Source Management */
2940 Session::add_source (boost::shared_ptr<Source> source)
2942 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2943 pair<SourceMap::iterator,bool> result;
2945 entry.first = source->id();
2946 entry.second = source;
2949 Glib::Mutex::Lock lm (source_lock);
2950 result = sources.insert (entry);
2953 if (result.second) {
2955 /* yay, new source */
2959 boost::shared_ptr<AudioFileSource> afs;
2961 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2962 if (Config->get_auto_analyse_audio()) {
2963 Analyser::queue_source_for_analysis (source, false);
2967 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
2972 Session::remove_source (boost::weak_ptr<Source> src)
2974 if (_state_of_the_state & Deletion) {
2978 SourceMap::iterator i;
2979 boost::shared_ptr<Source> source = src.lock();
2986 Glib::Mutex::Lock lm (source_lock);
2988 if ((i = sources.find (source->id())) != sources.end()) {
2993 if (!(_state_of_the_state & InCleanup)) {
2995 /* save state so we don't end up with a session file
2996 referring to non-existent sources.
2999 save_state (_current_snapshot_name);
3003 boost::shared_ptr<Source>
3004 Session::source_by_id (const PBD::ID& id)
3006 Glib::Mutex::Lock lm (source_lock);
3007 SourceMap::iterator i;
3008 boost::shared_ptr<Source> source;
3010 if ((i = sources.find (id)) != sources.end()) {
3017 boost::shared_ptr<Source>
3018 Session::source_by_path_and_channel (const string& path, uint16_t chn)
3020 Glib::Mutex::Lock lm (source_lock);
3022 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3023 boost::shared_ptr<AudioFileSource> afs
3024 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3026 if (afs && afs->path() == path && chn == afs->channel()) {
3030 return boost::shared_ptr<Source>();
3034 Session::count_sources_by_origin (const string& path)
3037 Glib::Mutex::Lock lm (source_lock);
3039 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3040 boost::shared_ptr<FileSource> fs
3041 = boost::dynamic_pointer_cast<FileSource>(i->second);
3043 if (fs && fs->origin() == path) {
3053 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3056 string old_basename = PBD::basename_nosuffix (oldname);
3057 string new_legalized = legalize_for_path (newname);
3059 /* note: we know (or assume) the old path is already valid */
3063 /* destructive file sources have a name of the form:
3065 /path/to/Tnnnn-NAME(%[LR])?.wav
3067 the task here is to replace NAME with the new name.
3072 string::size_type dash;
3074 dir = Glib::path_get_dirname (path);
3075 path = Glib::path_get_basename (path);
3077 /* '-' is not a legal character for the NAME part of the path */
3079 if ((dash = path.find_last_of ('-')) == string::npos) {
3083 prefix = path.substr (0, dash);
3087 path += new_legalized;
3088 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3089 path = Glib::build_filename (dir, path);
3093 /* non-destructive file sources have a name of the form:
3095 /path/to/NAME-nnnnn(%[LR])?.ext
3097 the task here is to replace NAME with the new name.
3102 string::size_type dash;
3103 string::size_type postfix;
3105 dir = Glib::path_get_dirname (path);
3106 path = Glib::path_get_basename (path);
3108 /* '-' is not a legal character for the NAME part of the path */
3110 if ((dash = path.find_last_of ('-')) == string::npos) {
3114 suffix = path.substr (dash+1);
3116 // Suffix is now everything after the dash. Now we need to eliminate
3117 // the nnnnn part, which is done by either finding a '%' or a '.'
3119 postfix = suffix.find_last_of ("%");
3120 if (postfix == string::npos) {
3121 postfix = suffix.find_last_of ('.');
3124 if (postfix != string::npos) {
3125 suffix = suffix.substr (postfix);
3127 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3131 const uint32_t limit = 10000;
3132 char buf[PATH_MAX+1];
3134 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3136 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
3138 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
3139 path = Glib::build_filename (dir, buf);
3147 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
3156 /** Return the full path (in some session directory) for a new within-session source.
3157 * \a name must be a session-unique name that does not contain slashes
3158 * (e.g. as returned by new_*_source_name)
3161 Session::new_source_path_from_name (DataType type, const string& name)
3163 assert(name.find("/") == string::npos);
3165 SessionDirectory sdir(get_best_session_directory_for_new_source());
3168 if (type == DataType::AUDIO) {
3169 p = sdir.sound_path();
3170 } else if (type == DataType::MIDI) {
3171 p = sdir.midi_path();
3173 error << "Unknown source type, unable to create file path" << endmsg;
3178 return p.to_string();
3182 Session::peak_path (string base) const
3184 sys::path peakfile_path(_session_dir->peak_path());
3185 peakfile_path /= base + peakfile_suffix;
3186 return peakfile_path.to_string();
3189 /** Return a unique name based on \a base for a new internal audio source */
3191 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3194 char buf[PATH_MAX+1];
3195 const uint32_t limit = 10000;
3197 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3200 legalized = legalize_for_path (base);
3202 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3203 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3205 vector<space_and_path>::iterator i;
3206 uint32_t existing = 0;
3208 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3213 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3214 cnt, legalized.c_str(), ext.c_str());
3215 } else if (nchan == 2) {
3217 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
3218 cnt, legalized.c_str(), ext.c_str());
3220 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
3221 cnt, legalized.c_str(), ext.c_str());
3223 } else if (nchan < 26) {
3224 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
3225 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
3227 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3228 cnt, legalized.c_str(), ext.c_str());
3234 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3235 } else if (nchan == 2) {
3237 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
3239 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
3241 } else if (nchan < 26) {
3242 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
3244 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3248 SessionDirectory sdir((*i).path);
3250 string spath = sdir.sound_path().to_string();
3252 /* note that we search *without* the extension so that
3253 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3254 in the event that this new name is required for
3255 a file format change.
3258 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
3264 if (existing == 0) {
3269 error << string_compose(
3270 _("There are already %1 recordings for %2, which I consider too many."),
3271 limit, base) << endmsg;
3273 throw failed_constructor();
3277 return Glib::path_get_basename (buf);
3280 /** Create a new within-session audio source */
3281 boost::shared_ptr<AudioFileSource>
3282 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3284 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3285 const string path = new_source_path_from_name(DataType::AUDIO, name);
3287 return boost::dynamic_pointer_cast<AudioFileSource> (
3288 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3291 /** Return a unique name based on \a base for a new internal MIDI source */
3293 Session::new_midi_source_name (const string& base)
3296 char buf[PATH_MAX+1];
3297 const uint32_t limit = 10000;
3301 legalized = legalize_for_path (base);
3303 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3304 for (cnt = 1; cnt <= limit; ++cnt) {
3306 vector<space_and_path>::iterator i;
3307 uint32_t existing = 0;
3309 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3311 SessionDirectory sdir((*i).path);
3313 sys::path p = sdir.midi_path();
3316 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3318 if (sys::exists (buf)) {
3323 if (existing == 0) {
3328 error << string_compose(
3329 _("There are already %1 recordings for %2, which I consider too many."),
3330 limit, base) << endmsg;
3332 throw failed_constructor();
3336 return Glib::path_get_basename(buf);
3340 /** Create a new within-session MIDI source */
3341 boost::shared_ptr<MidiSource>
3342 Session::create_midi_source_for_session (Track* track, string const & n)
3344 /* try to use the existing write source for the track, to keep numbering sane
3348 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3352 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3355 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3356 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3360 const string name = new_midi_source_name (n);
3361 const string path = new_source_path_from_name (DataType::MIDI, name);
3363 return boost::dynamic_pointer_cast<SMFSource> (
3364 SourceFactory::createWritable (
3365 DataType::MIDI, *this, path, string(), false, frame_rate()));
3370 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3372 if (playlist->hidden()) {
3376 playlists->add (playlist);
3379 playlist->release();
3386 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3388 if (_state_of_the_state & Deletion) {
3392 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3398 playlists->remove (playlist);
3404 Session::set_audition (boost::shared_ptr<Region> r)
3406 pending_audition_region = r;
3407 add_post_transport_work (PostTransportAudition);
3408 _butler->schedule_transport_work ();
3412 Session::audition_playlist ()
3414 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3415 ev->region.reset ();
3420 Session::non_realtime_set_audition ()
3422 if (!pending_audition_region) {
3423 auditioner->audition_current_playlist ();
3425 auditioner->audition_region (pending_audition_region);
3426 pending_audition_region.reset ();
3428 AuditionActive (true); /* EMIT SIGNAL */
3432 Session::audition_region (boost::shared_ptr<Region> r)
3434 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3440 Session::cancel_audition ()
3442 if (auditioner->auditioning()) {
3443 auditioner->cancel_audition ();
3444 AuditionActive (false); /* EMIT SIGNAL */
3449 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3451 if (a->is_monitor()) {
3454 if (b->is_monitor()) {
3457 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3461 Session::is_auditioning () const
3463 /* can be called before we have an auditioner object */
3465 return auditioner->auditioning();
3472 Session::graph_reordered ()
3474 /* don't do this stuff if we are setting up connections
3475 from a set_state() call or creating new tracks. Ditto for deletion.
3478 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3482 /* every track/bus asked for this to be handled but it was deferred because
3483 we were connecting. do it now.
3486 request_input_change_handling ();
3490 /* force all diskstreams to update their capture offset values to
3491 reflect any changes in latencies within the graph.
3494 boost::shared_ptr<RouteList> rl = routes.reader ();
3495 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3496 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3498 tr->set_capture_offset ();
3504 Session::available_capture_duration ()
3506 float sample_bytes_on_disk = 4.0; // keep gcc happy
3508 switch (config.get_native_file_data_format()) {
3510 sample_bytes_on_disk = 4.0;
3514 sample_bytes_on_disk = 3.0;
3518 sample_bytes_on_disk = 2.0;
3522 /* impossible, but keep some gcc versions happy */
3523 fatal << string_compose (_("programming error: %1"),
3524 X_("illegal native file data format"))
3529 double scale = 4096.0 / sample_bytes_on_disk;
3531 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3532 return max_framecnt;
3535 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3539 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3542 RCUWriter<BundleList> writer (_bundles);
3543 boost::shared_ptr<BundleList> b = writer.get_copy ();
3544 b->push_back (bundle);
3547 BundleAdded (bundle); /* EMIT SIGNAL */
3553 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3555 bool removed = false;
3558 RCUWriter<BundleList> writer (_bundles);
3559 boost::shared_ptr<BundleList> b = writer.get_copy ();
3560 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3562 if (i != b->end()) {
3569 BundleRemoved (bundle); /* EMIT SIGNAL */
3575 boost::shared_ptr<Bundle>
3576 Session::bundle_by_name (string name) const
3578 boost::shared_ptr<BundleList> b = _bundles.reader ();
3580 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3581 if ((*i)->name() == name) {
3586 return boost::shared_ptr<Bundle> ();
3590 Session::tempo_map_changed (const PropertyChange&)
3594 playlists->update_after_tempo_map_change ();
3596 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3602 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3604 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3605 (*i)->recompute_frames_from_bbt ();
3609 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3610 * the given count with the current block size.
3613 Session::ensure_buffers (ChanCount howmany)
3615 BufferManager::ensure_buffers (howmany);
3619 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3621 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3622 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3627 Session::next_insert_id ()
3629 /* this doesn't really loop forever. just think about it */
3632 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3633 if (!insert_bitset[n]) {
3634 insert_bitset[n] = true;
3640 /* none available, so resize and try again */
3642 insert_bitset.resize (insert_bitset.size() + 16, false);
3647 Session::next_send_id ()
3649 /* this doesn't really loop forever. just think about it */
3652 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3653 if (!send_bitset[n]) {
3654 send_bitset[n] = true;
3660 /* none available, so resize and try again */
3662 send_bitset.resize (send_bitset.size() + 16, false);
3667 Session::next_aux_send_id ()
3669 /* this doesn't really loop forever. just think about it */
3672 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
3673 if (!aux_send_bitset[n]) {
3674 aux_send_bitset[n] = true;
3680 /* none available, so resize and try again */
3682 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
3687 Session::next_return_id ()
3689 /* this doesn't really loop forever. just think about it */
3692 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3693 if (!return_bitset[n]) {
3694 return_bitset[n] = true;
3700 /* none available, so resize and try again */
3702 return_bitset.resize (return_bitset.size() + 16, false);
3707 Session::mark_send_id (uint32_t id)
3709 if (id >= send_bitset.size()) {
3710 send_bitset.resize (id+16, false);
3712 if (send_bitset[id]) {
3713 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3715 send_bitset[id] = true;
3719 Session::mark_aux_send_id (uint32_t id)
3721 if (id >= aux_send_bitset.size()) {
3722 aux_send_bitset.resize (id+16, false);
3724 if (aux_send_bitset[id]) {
3725 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
3727 aux_send_bitset[id] = true;
3731 Session::mark_return_id (uint32_t id)
3733 if (id >= return_bitset.size()) {
3734 return_bitset.resize (id+16, false);
3736 if (return_bitset[id]) {
3737 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3739 return_bitset[id] = true;
3743 Session::mark_insert_id (uint32_t id)
3745 if (id >= insert_bitset.size()) {
3746 insert_bitset.resize (id+16, false);
3748 if (insert_bitset[id]) {
3749 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3751 insert_bitset[id] = true;
3755 Session::unmark_send_id (uint32_t id)
3757 if (id < send_bitset.size()) {
3758 send_bitset[id] = false;
3763 Session::unmark_aux_send_id (uint32_t id)
3765 if (id < aux_send_bitset.size()) {
3766 aux_send_bitset[id] = false;
3771 Session::unmark_return_id (uint32_t id)
3773 if (id < return_bitset.size()) {
3774 return_bitset[id] = false;
3779 Session::unmark_insert_id (uint32_t id)
3781 if (id < insert_bitset.size()) {
3782 insert_bitset[id] = false;
3787 /* Named Selection management */
3789 boost::shared_ptr<NamedSelection>
3790 Session::named_selection_by_name (string name)
3792 Glib::Mutex::Lock lm (named_selection_lock);
3793 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3794 if ((*i)->name == name) {
3798 return boost::shared_ptr<NamedSelection>();
3802 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3805 Glib::Mutex::Lock lm (named_selection_lock);
3806 named_selections.insert (named_selections.begin(), named_selection);
3811 NamedSelectionAdded (); /* EMIT SIGNAL */
3815 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3817 bool removed = false;
3820 Glib::Mutex::Lock lm (named_selection_lock);
3822 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3824 if (i != named_selections.end()) {
3825 named_selections.erase (i);
3832 NamedSelectionRemoved (); /* EMIT SIGNAL */
3837 Session::reset_native_file_format ()
3839 boost::shared_ptr<RouteList> rl = routes.reader ();
3840 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3841 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3843 /* don't save state as we do this, there's no point
3846 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3847 tr->reset_write_sources (false);
3848 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3854 Session::route_name_unique (string n) const
3856 boost::shared_ptr<RouteList> r = routes.reader ();
3858 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3859 if ((*i)->name() == n) {
3868 Session::route_name_internal (string n) const
3870 if (auditioner && auditioner->name() == n) {
3874 if (_click_io && _click_io->name() == n) {
3882 Session::freeze_all (InterThreadInfo& itt)
3884 boost::shared_ptr<RouteList> r = routes.reader ();
3886 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3888 boost::shared_ptr<Track> t;
3890 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3891 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3901 boost::shared_ptr<Region>
3902 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3903 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3904 InterThreadInfo& itt,
3905 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
3908 boost::shared_ptr<Region> result;
3909 boost::shared_ptr<Playlist> playlist;
3910 boost::shared_ptr<AudioFileSource> fsource;
3912 char buf[PATH_MAX+1];
3913 ChanCount diskstream_channels (track.n_channels());
3914 framepos_t position;
3915 framecnt_t this_chunk;
3918 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3919 const string sound_dir = sdir.sound_path().to_string();
3920 framepos_t len = end - start;
3921 bool need_block_size_reset = false;
3923 ChanCount const max_proc = track.max_processor_streams ();
3926 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3927 end, start) << endmsg;
3931 const framecnt_t chunk_size = (256 * 1024)/4;
3933 // block all process callback handling
3935 block_processing ();
3937 /* call tree *MUST* hold route_lock */
3939 if ((playlist = track.playlist()) == 0) {
3943 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3945 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3947 for (x = 0; x < 99999; ++x) {
3948 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());
3949 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3955 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3960 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3961 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3964 catch (failed_constructor& err) {
3965 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3969 srcs.push_back (fsource);
3972 /* tell redirects that care that we are about to use a much larger
3973 * blocksize. this will flush all plugins too, so that they are ready
3974 * to be used for this process.
3977 need_block_size_reset = true;
3978 track.set_block_size (chunk_size);
3983 /* create a set of reasonably-sized buffers */
3984 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
3985 buffers.set_count (max_proc);
3987 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3988 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3990 afs->prepare_for_peakfile_writes ();
3993 while (to_do && !itt.cancel) {
3995 this_chunk = min (to_do, chunk_size);
3997 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export)) {
4002 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4003 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4006 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4012 start += this_chunk;
4013 to_do -= this_chunk;
4015 itt.progress = (float) (1.0 - ((double) to_do / len));
4024 xnow = localtime (&now);
4026 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4027 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4030 afs->update_header (position, *xnow, now);
4031 afs->flush_header ();
4035 /* construct a region to represent the bounced material */
4039 plist.add (Properties::start, 0);
4040 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
4041 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
4043 result = RegionFactory::create (srcs, plist);
4049 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4050 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4053 afs->mark_for_remove ();
4056 (*src)->drop_references ();
4060 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4061 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4064 afs->done_with_peakfile_writes ();
4069 if (need_block_size_reset) {
4070 track.set_block_size (get_block_size());
4073 unblock_processing ();
4079 Session::gain_automation_buffer() const
4081 return ProcessThread::gain_automation_buffer ();
4085 Session::pan_automation_buffer() const
4087 return ProcessThread::pan_automation_buffer ();
4091 Session::get_silent_buffers (ChanCount count)
4093 return ProcessThread::get_silent_buffers (count);
4097 Session::get_scratch_buffers (ChanCount count)
4099 return ProcessThread::get_scratch_buffers (count);
4103 Session::get_mix_buffers (ChanCount count)
4105 return ProcessThread::get_mix_buffers (count);
4109 Session::ntracks () const
4112 boost::shared_ptr<RouteList> r = routes.reader ();
4114 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4115 if (boost::dynamic_pointer_cast<Track> (*i)) {
4124 Session::nbusses () const
4127 boost::shared_ptr<RouteList> r = routes.reader ();
4129 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4130 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4139 Session::add_automation_list(AutomationList *al)
4141 automation_lists[al->id()] = al;
4145 Session::sync_order_keys (std::string const & base)
4147 if (deletion_in_progress()) {
4151 if (!Config->get_sync_all_route_ordering()) {
4152 /* leave order keys as they are */
4156 boost::shared_ptr<RouteList> r = routes.reader ();
4158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4159 (*i)->sync_order_keys (base);
4162 Route::SyncOrderKeys (base); // EMIT SIGNAL
4164 /* this might not do anything */
4166 set_remote_control_ids ();
4169 /** @return true if there is at least one record-enabled track, otherwise false */
4171 Session::have_rec_enabled_track () const
4173 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
4176 /** Update the state of our rec-enabled tracks flag */
4178 Session::update_have_rec_enabled_track ()
4180 boost::shared_ptr<RouteList> rl = routes.reader ();
4181 RouteList::iterator i = rl->begin();
4182 while (i != rl->end ()) {
4184 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4185 if (tr && tr->record_enabled ()) {
4192 int const old = g_atomic_int_get (&_have_rec_enabled_track);
4194 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
4196 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
4197 RecordStateChanged (); /* EMIT SIGNAL */
4202 Session::listen_position_changed ()
4204 boost::shared_ptr<RouteList> r = routes.reader ();
4206 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4207 (*i)->listen_position_changed ();
4212 Session::solo_control_mode_changed ()
4214 /* cancel all solo or all listen when solo control mode changes */
4217 set_solo (get_routes(), false);
4218 } else if (listening()) {
4219 set_listen (get_routes(), false);
4223 /** Called when a property of one of our route groups changes */
4225 Session::route_group_property_changed (RouteGroup* rg)
4227 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
4230 /** Called when a route is added to one of our route groups */
4232 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4234 RouteAddedToRouteGroup (rg, r);
4237 /** Called when a route is removed from one of our route groups */
4239 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
4241 RouteRemovedFromRouteGroup (rg, r);
4245 Session::get_available_sync_options () const
4247 vector<SyncSource> ret;
4249 ret.push_back (JACK);
4250 ret.push_back (MTC);
4251 ret.push_back (MIDIClock);
4256 boost::shared_ptr<RouteList>
4257 Session::get_routes_with_regions_at (framepos_t const p) const
4259 boost::shared_ptr<RouteList> r = routes.reader ();
4260 boost::shared_ptr<RouteList> rl (new RouteList);
4262 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4263 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4268 boost::shared_ptr<Playlist> pl = tr->playlist ();
4273 if (pl->has_region_at (p)) {
4282 Session::goto_end ()
4284 if (_session_range_location) {
4285 request_locate (_session_range_location->end(), false);
4287 request_locate (0, false);
4292 Session::goto_start ()
4294 if (_session_range_location) {
4295 request_locate (_session_range_location->start(), false);
4297 request_locate (0, false);
4302 Session::current_start_frame () const
4304 return _session_range_location ? _session_range_location->start() : 0;
4308 Session::current_end_frame () const
4310 return _session_range_location ? _session_range_location->end() : 0;
4314 Session::add_session_range_location (framepos_t start, framepos_t end)
4316 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4317 _locations->add (_session_range_location);
4320 /** Called when one of our routes' order keys has changed */
4322 Session::route_order_key_changed ()
4324 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4328 Session::step_edit_status_change (bool yn)
4334 send = (_step_editors == 0);
4339 send = (_step_editors == 1);
4342 if (_step_editors > 0) {
4348 StepEditStatusChange (val);
4354 Session::start_time_changed (framepos_t old)
4356 /* Update the auto loop range to match the session range
4357 (unless the auto loop range has been changed by the user)
4360 Location* s = _locations->session_range_location ();
4365 Location* l = _locations->auto_loop_location ();
4367 if (l && l->start() == old) {
4368 l->set_start (s->start(), true);
4373 Session::end_time_changed (framepos_t old)
4375 /* Update the auto loop range to match the session range
4376 (unless the auto loop range has been changed by the user)
4379 Location* s = _locations->session_range_location ();
4384 Location* l = _locations->auto_loop_location ();
4386 if (l && l->end() == old) {
4387 l->set_end (s->end(), true);
4392 Session::source_search_path (DataType type) const
4396 if (session_dirs.size() == 1) {
4398 case DataType::AUDIO:
4399 s.push_back ( _session_dir->sound_path().to_string());
4401 case DataType::MIDI:
4402 s.push_back (_session_dir->midi_path().to_string());
4406 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4407 SessionDirectory sdir (i->path);
4409 case DataType::AUDIO:
4410 s.push_back (sdir.sound_path().to_string());
4412 case DataType::MIDI:
4413 s.push_back (sdir.midi_path().to_string());
4419 /* now check the explicit (possibly user-specified) search path
4422 vector<string> dirs;
4425 case DataType::AUDIO:
4426 split (config.get_audio_search_path (), dirs, ':');
4428 case DataType::MIDI:
4429 split (config.get_midi_search_path (), dirs, ':');
4433 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4435 vector<string>::iterator si;
4437 for (si = s.begin(); si != s.end(); ++si) {
4443 if (si == s.end()) {
4450 for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) {
4451 if (!search_path.empty()) {
4461 Session::ensure_search_path_includes (const string& path, DataType type)
4464 vector<string> dirs;
4471 case DataType::AUDIO:
4472 search_path = config.get_audio_search_path ();
4474 case DataType::MIDI:
4475 search_path = config.get_midi_search_path ();
4479 split (search_path, dirs, ':');
4481 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4482 /* No need to add this new directory if it has the same inode as
4483 an existing one; checking inode rather than name prevents duplicated
4484 directories when we are using symlinks.
4486 On Windows, I think we could just do if (*i == path) here.
4488 if (inodes_same (*i, path)) {
4493 if (!search_path.empty()) {
4497 search_path += path;
4500 case DataType::AUDIO:
4501 config.set_audio_search_path (search_path);
4503 case DataType::MIDI:
4504 config.set_midi_search_path (search_path);
4509 boost::shared_ptr<Speakers>
4510 Session::get_speakers()
4516 Session::unknown_processors () const
4520 boost::shared_ptr<RouteList> r = routes.reader ();
4521 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4522 list<string> t = (*i)->unknown_processors ();
4523 copy (t.begin(), t.end(), back_inserter (p));
4533 Session::update_latency (bool playback)
4535 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4537 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4541 boost::shared_ptr<RouteList> r = routes.reader ();
4542 framecnt_t max_latency = 0;
4545 /* reverse the list so that we work backwards from the last route to run to the first */
4546 RouteList* rl = routes.reader().get();
4547 r.reset (new RouteList (*rl));
4548 reverse (r->begin(), r->end());
4551 /* compute actual latency values for the given direction and store them all in per-port
4552 structures. this will also publish the same values (to JACK) so that computation of latency
4553 for routes can consistently use public latency values.
4556 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4557 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4560 /* because we latency compensate playback, our published playback latencies should
4561 be the same for all output ports - all material played back by ardour has
4562 the same latency, whether its caused by plugins or by latency compensation. since
4563 these may differ from the values computed above, reset all playback port latencies
4567 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4569 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4570 (*i)->set_public_port_latencies (max_latency, playback);
4575 post_playback_latency ();
4579 post_capture_latency ();
4582 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
4586 Session::post_playback_latency ()
4588 set_worst_playback_latency ();
4590 boost::shared_ptr<RouteList> r = routes.reader ();
4592 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4593 if (!(*i)->is_hidden() && ((*i)->active())) {
4594 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
4598 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4599 (*i)->set_latency_compensation (_worst_track_latency);
4604 Session::post_capture_latency ()
4606 set_worst_capture_latency ();
4608 /* reflect any changes in capture latencies into capture offsets
4611 boost::shared_ptr<RouteList> rl = routes.reader();
4612 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4613 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4615 tr->set_capture_offset ();
4621 Session::initialize_latencies ()
4624 Glib::Mutex::Lock lm (_engine.process_lock());
4625 update_latency (false);
4626 update_latency (true);
4629 set_worst_io_latencies ();
4633 Session::set_worst_io_latencies ()
4635 set_worst_playback_latency ();
4636 set_worst_capture_latency ();
4640 Session::set_worst_playback_latency ()
4642 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4646 _worst_output_latency = 0;
4648 if (!_engine.connected()) {
4652 boost::shared_ptr<RouteList> r = routes.reader ();
4654 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4655 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
4658 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
4662 Session::set_worst_capture_latency ()
4664 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4668 _worst_input_latency = 0;
4670 if (!_engine.connected()) {
4674 boost::shared_ptr<RouteList> r = routes.reader ();
4676 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4677 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
4680 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
4684 Session::update_latency_compensation (bool force_whole_graph)
4686 bool some_track_latency_changed = false;
4688 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4692 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
4694 _worst_track_latency = 0;
4696 boost::shared_ptr<RouteList> r = routes.reader ();
4698 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4699 if (!(*i)->is_hidden() && ((*i)->active())) {
4701 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
4702 some_track_latency_changed = true;
4704 _worst_track_latency = max (tl, _worst_track_latency);
4708 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
4709 (some_track_latency_changed ? "yes" : "no")));
4711 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
4713 if (some_track_latency_changed || force_whole_graph) {
4714 _engine.update_latencies ();
4718 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4719 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4723 tr->set_capture_offset ();
4728 Session::session_name_is_legal (const string& path)
4730 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
4732 for (int i = 0; illegal_chars[i]; ++i) {
4733 if (path.find (illegal_chars[i]) != string::npos) {
4734 return illegal_chars[i];
4742 Session::next_control_id () const
4744 return ntracks() + nbusses() + 1;