Don't auto-connect buss inputs (#4211).
[ardour2.git] / libs / ardour / session.cc
blob9053797ad2c371a92e1ffe30d8992701b763b1bb
1 /*
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.
20 #include <stdint.h>
22 #include <algorithm>
23 #include <string>
24 #include <vector>
25 #include <sstream>
26 #include <fstream>
27 #include <cstdio> /* sprintf(3) ... grrr */
28 #include <cmath>
29 #include <cerrno>
30 #include <unistd.h>
31 #include <limits.h>
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"
49 #include "ardour/amp.h"
50 #include "ardour/analyser.h"
51 #include "ardour/audio_buffer.h"
52 #include "ardour/audio_diskstream.h"
53 #include "ardour/audio_port.h"
54 #include "ardour/audio_track.h"
55 #include "ardour/audioengine.h"
56 #include "ardour/audiofilesource.h"
57 #include "ardour/audioplaylist.h"
58 #include "ardour/audioregion.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/buffer_manager.h"
61 #include "ardour/buffer_set.h"
62 #include "ardour/bundle.h"
63 #include "ardour/butler.h"
64 #include "ardour/click.h"
65 #include "ardour/configuration.h"
66 #include "ardour/control_protocol_manager.h"
67 #include "ardour/crossfade.h"
68 #include "ardour/cycle_timer.h"
69 #include "ardour/data_type.h"
70 #include "ardour/debug.h"
71 #include "ardour/filename_extensions.h"
72 #include "ardour/internal_send.h"
73 #include "ardour/io_processor.h"
74 #include "ardour/midi_diskstream.h"
75 #include "ardour/midi_playlist.h"
76 #include "ardour/midi_region.h"
77 #include "ardour/midi_track.h"
78 #include "ardour/midi_ui.h"
79 #include "ardour/named_selection.h"
80 #include "ardour/process_thread.h"
81 #include "ardour/playlist.h"
82 #include "ardour/plugin_insert.h"
83 #include "ardour/port_insert.h"
84 #include "ardour/processor.h"
85 #include "ardour/rc_configuration.h"
86 #include "ardour/recent_sessions.h"
87 #include "ardour/region_factory.h"
88 #include "ardour/return.h"
89 #include "ardour/route_group.h"
90 #include "ardour/send.h"
91 #include "ardour/session.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_directory.h"
94 #include "ardour/session_metadata.h"
95 #include "ardour/session_playlists.h"
96 #include "ardour/slave.h"
97 #include "ardour/smf_source.h"
98 #include "ardour/source_factory.h"
99 #include "ardour/tape_file_matcher.h"
100 #include "ardour/tempo.h"
101 #include "ardour/utils.h"
102 #include "ardour/graph.h"
103 #include "ardour/speakers.h"
104 #include "ardour/operations.h"
106 #include "midi++/port.h"
107 #include "midi++/mmc.h"
108 #include "midi++/manager.h"
110 #include "i18n.h"
112 using namespace std;
113 using namespace ARDOUR;
114 using namespace PBD;
116 bool Session::_disable_all_loaded_plugins = false;
118 PBD::Signal1<void,std::string> Session::Dialog;
119 PBD::Signal0<int> Session::AskAboutPendingState;
120 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
121 PBD::Signal0<void> Session::SendFeedback;
122 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
124 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
125 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
126 PBD::Signal0<void> Session::AutoBindingOn;
127 PBD::Signal0<void> Session::AutoBindingOff;
128 PBD::Signal2<void,std::string, std::string> Session::Exported;
129 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
130 PBD::Signal0<void> Session::Quit;
132 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
133 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
135 Session::Session (AudioEngine &eng,
136 const string& fullpath,
137 const string& snapshot_name,
138 BusProfile* bus_profile,
139 string mix_template)
140 : _engine (eng)
141 , _target_transport_speed (0.0)
142 , _requested_return_frame (-1)
143 , _session_dir (new SessionDirectory(fullpath))
144 , state_tree (0)
145 , _state_of_the_state (Clean)
146 , _butler (new Butler (*this))
147 , _post_transport_work (0)
148 , _send_timecode_update (false)
149 , _all_route_group (new RouteGroup (*this, "all"))
150 , route_graph (new Graph(*this))
151 , routes (new RouteList)
152 , _total_free_4k_blocks (0)
153 , _bundles (new BundleList)
154 , _bundle_xml_node (0)
155 , _current_trans (0)
156 , _click_io ((IO*) 0)
157 , click_data (0)
158 , click_emphasis_data (0)
159 , main_outs (0)
160 , _metadata (new SessionMetadata())
161 , _have_rec_enabled_track (false)
162 , _suspend_timecode_transmission (0)
164 _locations = new Locations (*this);
166 playlists.reset (new SessionPlaylists);
168 _all_route_group->set_active (true, this);
170 interpolation.add_channel_to (0, 0);
172 if (!eng.connected()) {
173 throw failed_constructor();
176 n_physical_outputs = _engine.n_physical_outputs ();
177 n_physical_inputs = _engine.n_physical_inputs ();
179 first_stage_init (fullpath, snapshot_name);
181 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
183 if (_is_new) {
184 if (create (mix_template, bus_profile)) {
185 destroy ();
186 throw failed_constructor ();
190 if (second_stage_init ()) {
191 destroy ();
192 throw failed_constructor ();
195 store_recent_sessions(_name, _path);
197 bool was_dirty = dirty();
199 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
201 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
202 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
204 if (was_dirty) {
205 DirtyChanged (); /* EMIT SIGNAL */
208 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
209 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
211 _is_new = false;
214 Session::~Session ()
216 destroy ();
219 void
220 Session::destroy ()
222 vector<void*> debug_pointers;
224 /* if we got to here, leaving pending capture state around
225 is a mistake.
228 remove_pending_capture_state ();
230 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
232 _engine.remove_session ();
234 /* clear history so that no references to objects are held any more */
236 _history.clear ();
238 /* clear state tree so that no references to objects are held any more */
240 delete state_tree;
242 /* reset dynamic state version back to default */
244 Stateful::loading_state_version = 0;
246 _butler->drop_references ();
247 delete _butler;
248 delete midi_control_ui;
249 delete _all_route_group;
251 if (click_data != default_click) {
252 delete [] click_data;
255 if (click_emphasis_data != default_click_emphasis) {
256 delete [] click_emphasis_data;
259 clear_clicks ();
261 /* clear out any pending dead wood from RCU managed objects */
263 routes.flush ();
264 _bundles.flush ();
266 AudioDiskstream::free_working_buffers();
268 /* tell everyone who is still standing that we're about to die */
269 drop_references ();
271 /* tell everyone to drop references and delete objects as we go */
273 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
274 named_selections.clear ();
276 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
277 RegionFactory::delete_all_regions ();
279 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
281 /* reset these three references to special routes before we do the usual route delete thing */
283 auditioner.reset ();
284 _master_out.reset ();
285 _monitor_out.reset ();
288 RCUWriter<RouteList> writer (routes);
289 boost::shared_ptr<RouteList> r = writer.get_copy ();
291 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
292 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
293 (*i)->drop_references ();
296 r->clear ();
297 /* writer goes out of scope and updates master */
299 routes.flush ();
301 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
302 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
303 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
304 i->second->drop_references ();
307 sources.clear ();
309 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
310 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
312 delete *i;
315 Crossfade::set_buffer_size (0);
317 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
318 playlists.reset ();
320 delete _locations;
322 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
324 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
325 boost_debug_list_ptrs ();
326 #endif
329 void
330 Session::when_engine_running ()
332 string first_physical_output;
334 BootMessage (_("Set block size and sample rate"));
336 set_block_size (_engine.frames_per_cycle());
337 set_frame_rate (_engine.frame_rate());
339 BootMessage (_("Using configuration"));
341 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
342 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
344 Config->map_parameters (ff);
345 config.map_parameters (ft);
347 /* every time we reconnect, recompute worst case output latencies */
349 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
351 if (synced_to_jack()) {
352 _engine.transport_stop ();
355 if (config.get_jack_time_master()) {
356 _engine.transport_locate (_transport_frame);
359 _clicking = false;
361 try {
362 XMLNode* child = 0;
364 _click_io.reset (new ClickIO (*this, "click"));
366 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
368 /* existing state for Click */
369 int c;
371 if (Stateful::loading_state_version < 3000) {
372 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
373 } else {
374 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
378 if (c == 0) {
379 _clicking = Config->get_clicking ();
381 } else {
383 error << _("could not setup Click I/O") << endmsg;
384 _clicking = false;
388 } else {
390 /* default state for Click: dual-mono to first 2 physical outputs */
392 vector<string> outs;
393 _engine.get_physical_outputs (DataType::AUDIO, outs);
395 for (uint32_t physport = 0; physport < 2; ++physport) {
396 if (outs.size() > physport) {
397 if (_click_io->add_port (outs[physport], this)) {
398 // relax, even though its an error
403 if (_click_io->n_ports () > ChanCount::ZERO) {
404 _clicking = Config->get_clicking ();
409 catch (failed_constructor& err) {
410 error << _("cannot setup Click I/O") << endmsg;
413 BootMessage (_("Compute I/O Latencies"));
415 if (_clicking) {
416 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
419 BootMessage (_("Set up standard connections"));
421 vector<string> inputs[DataType::num_types];
422 vector<string> outputs[DataType::num_types];
423 for (uint32_t i = 0; i < DataType::num_types; ++i) {
424 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
425 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
428 /* Create a set of Bundle objects that map
429 to the physical I/O currently available. We create both
430 mono and stereo bundles, so that the common cases of mono
431 and stereo tracks get bundles to put in their mixer strip
432 in / out menus. There may be a nicer way of achieving that;
433 it doesn't really scale that well to higher channel counts
436 /* mono output bundles */
438 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
439 char buf[32];
440 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
442 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
443 c->add_channel (_("mono"), DataType::AUDIO);
444 c->set_port (0, outputs[DataType::AUDIO][np]);
446 add_bundle (c);
449 /* stereo output bundles */
451 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
452 if (np + 1 < outputs[DataType::AUDIO].size()) {
453 char buf[32];
454 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
455 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
456 c->add_channel (_("L"), DataType::AUDIO);
457 c->set_port (0, outputs[DataType::AUDIO][np]);
458 c->add_channel (_("R"), DataType::AUDIO);
459 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
461 add_bundle (c);
465 /* mono input bundles */
467 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
468 char buf[32];
469 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
471 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
472 c->add_channel (_("mono"), DataType::AUDIO);
473 c->set_port (0, inputs[DataType::AUDIO][np]);
475 add_bundle (c);
478 /* stereo input bundles */
480 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
481 if (np + 1 < inputs[DataType::AUDIO].size()) {
482 char buf[32];
483 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
485 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
486 c->add_channel (_("L"), DataType::AUDIO);
487 c->set_port (0, inputs[DataType::AUDIO][np]);
488 c->add_channel (_("R"), DataType::AUDIO);
489 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
491 add_bundle (c);
495 /* MIDI input bundles */
497 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
498 string n = inputs[DataType::MIDI][np];
499 boost::erase_first (n, X_("alsa_pcm:"));
501 boost::shared_ptr<Bundle> c (new Bundle (n, false));
502 c->add_channel ("", DataType::MIDI);
503 c->set_port (0, inputs[DataType::MIDI][np]);
504 add_bundle (c);
507 /* MIDI output bundles */
509 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
510 string n = outputs[DataType::MIDI][np];
511 boost::erase_first (n, X_("alsa_pcm:"));
513 boost::shared_ptr<Bundle> c (new Bundle (n, true));
514 c->add_channel ("", DataType::MIDI);
515 c->set_port (0, outputs[DataType::MIDI][np]);
516 add_bundle (c);
519 BootMessage (_("Setup signal flow and plugins"));
521 ControlProtocolManager::instance().set_session (this);
523 /* This must be done after the ControlProtocolManager set_session above,
524 as it will set states for ports which the ControlProtocolManager creates.
526 MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
528 /* And this must be done after the MIDI::Manager::set_port_states as
529 * it will try to make connections whose details are loaded by set_port_states.
532 hookup_io ();
534 if (_is_new && !no_auto_connect()) {
536 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
538 /* don't connect the master bus outputs if there is a monitor bus */
540 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
542 /* if requested auto-connect the outputs to the first N physical ports.
545 uint32_t limit = _master_out->n_outputs().n_total();
547 for (uint32_t n = 0; n < limit; ++n) {
548 Port* p = _master_out->output()->nth (n);
549 string connect_to;
550 if (outputs[p->type()].size() > n) {
551 connect_to = outputs[p->type()][n];
554 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
555 if (_master_out->output()->connect (p, connect_to, this)) {
556 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
557 << endmsg;
558 break;
564 if (_monitor_out) {
566 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
567 are undefined, at best.
570 /* control out listens to master bus (but ignores it
571 under some conditions)
574 uint32_t limit = _monitor_out->n_inputs().n_audio();
576 if (_master_out) {
577 for (uint32_t n = 0; n < limit; ++n) {
578 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
579 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
581 if (o) {
582 string connect_to = o->name();
583 if (_monitor_out->input()->connect (p, connect_to, this)) {
584 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
585 << endmsg;
586 break;
592 /* if control out is not connected, connect control out to physical outs
595 if (!_monitor_out->output()->connected ()) {
597 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
599 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
601 if (b) {
602 _monitor_out->output()->connect_ports_to_bundle (b, this);
603 } else {
604 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
605 Config->get_monitor_bus_preferred_bundle())
606 << endmsg;
609 } else {
611 /* Monitor bus is audio only */
612 uint32_t mod = n_physical_outputs.get (DataType::AUDIO);
613 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
615 if (mod != 0) {
617 for (uint32_t n = 0; n < limit; ++n) {
619 Port* p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
620 string connect_to;
621 if (outputs[DataType::AUDIO].size() > (n % mod)) {
622 connect_to = outputs[DataType::AUDIO][n % mod];
625 if (!connect_to.empty()) {
626 if (_monitor_out->output()->connect (p, connect_to, this)) {
627 error << string_compose (
628 _("cannot connect control output %1 to %2"),
629 n, connect_to)
630 << endmsg;
631 break;
641 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
643 /* hook us up to the engine */
645 BootMessage (_("Connect to engine"));
646 _engine.set_session (this);
648 update_latency_compensation (true);
651 void
652 Session::hookup_io ()
654 /* stop graph reordering notifications from
655 causing resorts, etc.
658 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
660 if (!auditioner) {
662 /* we delay creating the auditioner till now because
663 it makes its own connections to ports.
666 try {
667 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
668 if (a->init()) {
669 throw failed_constructor ();
671 a->use_new_diskstream ();
672 auditioner = a;
675 catch (failed_constructor& err) {
676 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
680 /* load bundles, which we may have postponed earlier on */
681 if (_bundle_xml_node) {
682 load_bundles (*_bundle_xml_node);
683 delete _bundle_xml_node;
686 /* Tell all IO objects to connect themselves together */
688 IO::enable_connecting ();
689 MIDI::Port::MakeConnections ();
691 /* Now reset all panners */
693 Delivery::reset_panners ();
695 /* Connect tracks to monitor/listen bus if there is one. Note that in an
696 existing session, the internal sends will already exist, but we want the
697 routes to notice that they connect to the control out specifically.
700 if (_monitor_out) {
701 boost::shared_ptr<RouteList> r = routes.reader ();
702 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
704 if ((*x)->is_monitor()) {
706 /* relax */
708 } else if ((*x)->is_master()) {
710 /* relax */
712 } else {
714 (*x)->listen_via_monitor ();
719 /* Anyone who cares about input state, wake up and do something */
721 IOConnectionsComplete (); /* EMIT SIGNAL */
723 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
725 /* now handle the whole enchilada as if it was one
726 graph reorder event.
729 graph_reordered ();
731 /* update the full solo state, which can't be
732 correctly determined on a per-route basis, but
733 needs the global overview that only the session
734 has.
737 update_route_solo_state ();
740 void
741 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
743 boost::shared_ptr<Track> track = wp.lock ();
744 if (!track) {
745 return;
748 boost::shared_ptr<Playlist> playlist;
750 if ((playlist = track->playlist()) != 0) {
751 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
752 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
753 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
757 bool
758 Session::record_enabling_legal () const
760 /* this used to be in here, but survey says.... we don't need to restrict it */
761 // if (record_status() == Recording) {
762 // return false;
763 // }
765 if (Config->get_all_safe()) {
766 return false;
768 return true;
771 void
772 Session::set_track_monitor_input_status (bool yn)
774 boost::shared_ptr<RouteList> rl = routes.reader ();
775 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
776 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
777 if (tr && tr->record_enabled ()) {
778 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
779 tr->monitor_input (yn);
784 void
785 Session::reset_input_monitor_state ()
787 if (transport_rolling()) {
788 set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
789 } else {
790 set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring);
794 void
795 Session::auto_punch_start_changed (Location* location)
797 replace_event (SessionEvent::PunchIn, location->start());
799 if (get_record_enabled() && config.get_punch_in()) {
800 /* capture start has been changed, so save new pending state */
801 save_state ("", true);
805 void
806 Session::auto_punch_end_changed (Location* location)
808 framepos_t when_to_stop = location->end();
809 // when_to_stop += _worst_output_latency + _worst_input_latency;
810 replace_event (SessionEvent::PunchOut, when_to_stop);
813 void
814 Session::auto_punch_changed (Location* location)
816 framepos_t when_to_stop = location->end();
818 replace_event (SessionEvent::PunchIn, location->start());
819 //when_to_stop += _worst_output_latency + _worst_input_latency;
820 replace_event (SessionEvent::PunchOut, when_to_stop);
823 void
824 Session::auto_loop_changed (Location* location)
826 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
828 if (transport_rolling() && play_loop) {
831 // if (_transport_frame > location->end()) {
833 if (_transport_frame < location->start() || _transport_frame > location->end()) {
834 // relocate to beginning of loop
835 clear_events (SessionEvent::LocateRoll);
837 request_locate (location->start(), true);
840 else if (Config->get_seamless_loop() && !loop_changing) {
842 // schedule a locate-roll to refill the diskstreams at the
843 // previous loop end
844 loop_changing = true;
846 if (location->end() > last_loopend) {
847 clear_events (SessionEvent::LocateRoll);
848 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
849 queue_event (ev);
855 last_loopend = location->end();
858 void
859 Session::set_auto_punch_location (Location* location)
861 Location* existing;
863 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
864 punch_connections.drop_connections();
865 existing->set_auto_punch (false, this);
866 remove_event (existing->start(), SessionEvent::PunchIn);
867 clear_events (SessionEvent::PunchOut);
868 auto_punch_location_changed (0);
871 set_dirty();
873 if (location == 0) {
874 return;
877 if (location->end() <= location->start()) {
878 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
879 return;
882 punch_connections.drop_connections ();
884 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
885 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
886 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
888 location->set_auto_punch (true, this);
890 auto_punch_changed (location);
892 auto_punch_location_changed (location);
895 void
896 Session::set_auto_loop_location (Location* location)
898 Location* existing;
900 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
901 loop_connections.drop_connections ();
902 existing->set_auto_loop (false, this);
903 remove_event (existing->end(), SessionEvent::AutoLoop);
904 auto_loop_location_changed (0);
907 set_dirty();
909 if (location == 0) {
910 return;
913 if (location->end() <= location->start()) {
914 error << _("Session: you can't use a mark for auto loop") << endmsg;
915 return;
918 last_loopend = location->end();
920 loop_connections.drop_connections ();
922 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
923 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
924 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
926 location->set_auto_loop (true, this);
928 /* take care of our stuff first */
930 auto_loop_changed (location);
932 /* now tell everyone else */
934 auto_loop_location_changed (location);
937 void
938 Session::locations_added (Location *)
940 set_dirty ();
943 void
944 Session::locations_changed ()
946 _locations->apply (*this, &Session::handle_locations_changed);
949 void
950 Session::handle_locations_changed (Locations::LocationList& locations)
952 Locations::LocationList::iterator i;
953 Location* location;
954 bool set_loop = false;
955 bool set_punch = false;
957 for (i = locations.begin(); i != locations.end(); ++i) {
959 location =* i;
961 if (location->is_auto_punch()) {
962 set_auto_punch_location (location);
963 set_punch = true;
965 if (location->is_auto_loop()) {
966 set_auto_loop_location (location);
967 set_loop = true;
970 if (location->is_session_range()) {
971 _session_range_location = location;
975 if (!set_loop) {
976 set_auto_loop_location (0);
978 if (!set_punch) {
979 set_auto_punch_location (0);
982 set_dirty();
985 void
986 Session::enable_record ()
988 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
989 /* no recording at anything except normal speed */
990 return;
993 while (1) {
994 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
996 if (rs == Recording) {
997 break;
1000 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1002 _last_record_location = _transport_frame;
1003 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1005 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1006 set_track_monitor_input_status (true);
1009 RecordStateChanged ();
1010 break;
1015 void
1016 Session::disable_record (bool rt_context, bool force)
1018 RecordState rs;
1020 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1022 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1023 g_atomic_int_set (&_record_status, Disabled);
1024 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1025 } else {
1026 if (rs == Recording) {
1027 g_atomic_int_set (&_record_status, Enabled);
1031 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1032 set_track_monitor_input_status (false);
1035 RecordStateChanged (); /* emit signal */
1037 if (!rt_context) {
1038 remove_pending_capture_state ();
1043 void
1044 Session::step_back_from_record ()
1046 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1048 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1049 set_track_monitor_input_status (false);
1054 void
1055 Session::maybe_enable_record ()
1057 if (_step_editors > 0) {
1058 return;
1061 g_atomic_int_set (&_record_status, Enabled);
1063 /* This function is currently called from somewhere other than an RT thread.
1064 This save_state() call therefore doesn't impact anything. Doing it here
1065 means that we save pending state of which sources the next record will use,
1066 which gives us some chance of recovering from a crash during the record.
1069 save_state ("", true);
1071 if (_transport_speed) {
1072 if (!config.get_punch_in()) {
1073 enable_record ();
1075 } else {
1076 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1077 RecordStateChanged (); /* EMIT SIGNAL */
1080 set_dirty();
1083 framepos_t
1084 Session::audible_frame () const
1086 framepos_t ret;
1087 framepos_t tf;
1088 framecnt_t offset;
1090 /* the first of these two possible settings for "offset"
1091 mean that the audible frame is stationary until
1092 audio emerges from the latency compensation
1093 "pseudo-pipeline".
1095 the second means that the audible frame is stationary
1096 until audio would emerge from a physical port
1097 in the absence of any plugin latency compensation
1100 offset = worst_playback_latency ();
1102 if (offset > current_block_size) {
1103 offset -= current_block_size;
1104 } else {
1105 /* XXX is this correct? if we have no external
1106 physical connections and everything is internal
1107 then surely this is zero? still, how
1108 likely is that anyway?
1110 offset = current_block_size;
1113 if (synced_to_jack()) {
1114 tf = _engine.transport_frame();
1115 } else {
1116 tf = _transport_frame;
1119 ret = tf;
1121 if (!non_realtime_work_pending()) {
1123 /* MOVING */
1125 /* Check to see if we have passed the first guaranteed
1126 audible frame past our last start position. if not,
1127 return that last start point because in terms
1128 of audible frames, we have not moved yet.
1130 `Start position' in this context means the time we last
1131 either started or changed transport direction.
1134 if (_transport_speed > 0.0f) {
1136 if (!play_loop || !have_looped) {
1137 if (tf < _last_roll_or_reversal_location + offset) {
1138 return _last_roll_or_reversal_location;
1143 /* forwards */
1144 ret -= offset;
1146 } else if (_transport_speed < 0.0f) {
1148 /* XXX wot? no backward looping? */
1150 if (tf > _last_roll_or_reversal_location - offset) {
1151 return _last_roll_or_reversal_location;
1152 } else {
1153 /* backwards */
1154 ret += offset;
1159 return ret;
1162 void
1163 Session::set_frame_rate (framecnt_t frames_per_second)
1165 /** \fn void Session::set_frame_size(framecnt_t)
1166 the AudioEngine object that calls this guarantees
1167 that it will not be called while we are also in
1168 ::process(). Its fine to do things that block
1169 here.
1172 _base_frame_rate = frames_per_second;
1174 sync_time_vars();
1176 Automatable::set_automation_interval (ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1178 clear_clicks ();
1180 // XXX we need some equivalent to this, somehow
1181 // SndFileSource::setup_standard_crossfades (frames_per_second);
1183 set_dirty();
1185 /* XXX need to reset/reinstantiate all LADSPA plugins */
1188 void
1189 Session::set_block_size (pframes_t nframes)
1191 /* the AudioEngine guarantees
1192 that it will not be called while we are also in
1193 ::process(). It is therefore fine to do things that block
1194 here.
1198 current_block_size = nframes;
1200 ensure_buffers ();
1202 boost::shared_ptr<RouteList> r = routes.reader ();
1204 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1205 (*i)->set_block_size (nframes);
1208 boost::shared_ptr<RouteList> rl = routes.reader ();
1209 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1210 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1211 if (tr) {
1212 tr->set_block_size (nframes);
1216 set_worst_io_latencies ();
1220 struct RouteSorter {
1221 /** @return true to run r1 before r2, otherwise false */
1222 bool sort_by_rec_enabled (const boost::shared_ptr<Route>& r1, const boost::shared_ptr<Route>& r2) {
1223 if (r1->record_enabled()) {
1224 if (r2->record_enabled()) {
1225 /* both rec-enabled, just use signal order */
1226 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1227 } else {
1228 /* r1 rec-enabled, r2 not rec-enabled, run r2 early */
1229 return false;
1231 } else {
1232 if (r2->record_enabled()) {
1233 /* r2 rec-enabled, r1 not rec-enabled, run r1 early */
1234 return true;
1235 } else {
1236 /* neither rec-enabled, use signal order */
1237 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1242 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1243 if (r2->feeds (r1)) {
1244 /* r1 fed by r2; run r2 early */
1245 return false;
1246 } else if (r1->feeds (r2)) {
1247 /* r2 fed by r1; run r1 early */
1248 return true;
1249 } else {
1250 if (r1->not_fed ()) {
1251 if (r2->not_fed ()) {
1252 /* no ardour-based connections inbound to either route. */
1253 return sort_by_rec_enabled (r1, r2);
1254 } else {
1255 /* r2 has connections, r1 does not; run r1 early */
1256 return true;
1258 } else {
1259 if (r2->not_fed()) {
1260 /* r1 has connections, r2 does not; run r2 early */
1261 return false;
1262 } else {
1263 /* both r1 and r2 have connections, but not to each other. just use signal order */
1264 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1271 static void
1272 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1274 boost::shared_ptr<Route> r2;
1276 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1277 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1278 return;
1281 /* make a copy of the existing list of routes that feed r1 */
1283 Route::FedBy existing (r1->fed_by());
1285 /* for each route that feeds r1, recurse, marking it as feeding
1286 rbase as well.
1289 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1290 if (!(r2 = i->r.lock ())) {
1291 /* (*i) went away, ignore it */
1292 continue;
1295 /* r2 is a route that feeds r1 which somehow feeds base. mark
1296 base as being fed by r2
1299 rbase->add_fed_by (r2, i->sends_only);
1301 if (r2 != rbase) {
1303 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1304 stop here.
1307 if (r1->feeds (r2) && r2->feeds (r1)) {
1308 continue;
1311 /* now recurse, so that we can mark base as being fed by
1312 all routes that feed r2
1315 trace_terminal (r2, rbase);
1321 void
1322 Session::resort_routes ()
1324 /* don't do anything here with signals emitted
1325 by Routes while we are being destroyed.
1328 if (_state_of_the_state & Deletion) {
1329 return;
1333 RCUWriter<RouteList> writer (routes);
1334 boost::shared_ptr<RouteList> r = writer.get_copy ();
1335 resort_routes_using (r);
1336 /* writer goes out of scope and forces update */
1339 //route_graph->dump(1);
1341 #ifndef NDEBUG
1342 boost::shared_ptr<RouteList> rl = routes.reader ();
1343 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1344 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1346 const Route::FedBy& fb ((*i)->fed_by());
1348 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1349 boost::shared_ptr<Route> sf = f->r.lock();
1350 if (sf) {
1351 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1355 #endif
1358 void
1359 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1361 RouteList::iterator i, j;
1363 for (i = r->begin(); i != r->end(); ++i) {
1365 (*i)->clear_fed_by ();
1367 for (j = r->begin(); j != r->end(); ++j) {
1369 /* although routes can feed themselves, it will
1370 cause an endless recursive descent if we
1371 detect it. so don't bother checking for
1372 self-feeding.
1375 if (*j == *i) {
1376 continue;
1379 bool via_sends_only;
1381 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1382 (*i)->add_fed_by (*j, via_sends_only);
1387 for (i = r->begin(); i != r->end(); ++i) {
1388 trace_terminal (*i, *i);
1391 RouteSorter cmp;
1392 r->sort (cmp);
1394 route_graph->rechain (r);
1396 #ifndef NDEBUG
1397 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1398 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1399 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1400 (*i)->name(), (*i)->order_key ("signal")));
1402 #endif
1406 /** Find a route name starting with \a base, maybe followed by the
1407 * lowest \a id. \a id will always be added if \a definitely_add_number
1408 * is true on entry; otherwise it will only be added if required
1409 * to make the name unique.
1411 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1412 * The available route name with the lowest ID will be used, and \a id
1413 * will be set to the ID.
1415 * \return false if a route name could not be found, and \a track_name
1416 * and \a id do not reflect a free route name.
1418 bool
1419 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1421 if (!definitely_add_number && route_by_name (base) == 0) {
1422 /* juse use the base */
1423 snprintf (name, name_len, "%s", base.c_str());
1424 return true;
1427 do {
1428 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1430 if (route_by_name (name) == 0) {
1431 return true;
1434 ++id;
1436 } while (id < (UINT_MAX-1));
1438 return false;
1441 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
1442 void
1443 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
1445 in = ChanCount::ZERO;
1446 out = ChanCount::ZERO;
1448 boost::shared_ptr<RouteList> r = routes.reader ();
1450 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1451 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1452 if (tr && !tr->is_hidden()) {
1453 in += tr->n_inputs();
1454 out += tr->n_outputs();
1459 /** Caller must not hold process lock
1460 * @param name_template string to use for the start of the name, or "" to use "Midi".
1462 list<boost::shared_ptr<MidiTrack> >
1463 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1465 char track_name[32];
1466 uint32_t track_id = 0;
1467 string port;
1468 RouteList new_routes;
1469 list<boost::shared_ptr<MidiTrack> > ret;
1470 uint32_t control_id;
1472 control_id = ntracks() + nbusses();
1474 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Midi");
1476 while (how_many) {
1477 if (!find_route_name (name_template.empty() ? _("Midi") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1478 error << "cannot find name for new midi track" << endmsg;
1479 goto failed;
1482 boost::shared_ptr<MidiTrack> track;
1484 try {
1485 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1487 if (track->init ()) {
1488 goto failed;
1491 track->use_new_diskstream();
1493 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1494 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1495 #endif
1497 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1498 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1499 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1500 goto failed;
1503 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1504 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1505 goto failed;
1509 track->non_realtime_input_change();
1511 if (route_group) {
1512 route_group->add (track);
1515 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1516 track->set_remote_control_id (control_id);
1518 new_routes.push_back (track);
1519 ret.push_back (track);
1522 catch (failed_constructor &err) {
1523 error << _("Session: could not create new midi track.") << endmsg;
1524 goto failed;
1527 catch (AudioEngine::PortRegistrationFailure& pfe) {
1529 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;
1530 goto failed;
1533 --how_many;
1536 failed:
1537 if (!new_routes.empty()) {
1538 add_routes (new_routes, true, true);
1541 return ret;
1544 void
1545 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
1547 boost::shared_ptr<Route> midi_track (wmt.lock());
1549 if (!midi_track) {
1550 return;
1553 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
1555 if (change.after.n_audio() <= change.before.n_audio()) {
1556 return;
1559 /* new audio ports: make sure the audio goes somewhere useful,
1560 unless the user has no-auto-connect selected.
1562 The existing ChanCounts don't matter for this call as they are only
1563 to do with matching input and output indices, and we are only changing
1564 outputs here.
1567 ChanCount dummy;
1569 auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
1573 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1574 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1575 * @param output_start As \a input_start, but for outputs.
1577 void
1578 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
1579 bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
1581 if (!IO::connecting_legal) {
1582 return;
1585 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::NOT_LOCK);
1587 if (with_lock) {
1588 lm.acquire ();
1591 /* If both inputs and outputs are auto-connected to physical ports,
1592 use the max of input and output offsets to ensure auto-connected
1593 port numbers always match up (e.g. the first audio input and the
1594 first audio output of the route will have the same physical
1595 port number). Otherwise just use the lowest input or output
1596 offset possible.
1599 DEBUG_TRACE (DEBUG::Graph,
1600 string_compose("Auto-connect: existing in = %1 out = %2\n",
1601 existing_inputs, existing_outputs));
1603 const bool in_out_physical =
1604 (Config->get_input_auto_connect() & AutoConnectPhysical)
1605 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1606 && connect_inputs;
1608 const ChanCount in_offset = in_out_physical
1609 ? ChanCount::max(existing_inputs, existing_outputs)
1610 : existing_inputs;
1612 const ChanCount out_offset = in_out_physical
1613 ? ChanCount::max(existing_inputs, existing_outputs)
1614 : existing_outputs;
1616 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1617 vector<string> physinputs;
1618 vector<string> physoutputs;
1620 _engine.get_physical_outputs (*t, physoutputs);
1621 _engine.get_physical_inputs (*t, physinputs);
1623 if (!physinputs.empty() && connect_inputs) {
1624 uint32_t nphysical_in = physinputs.size();
1626 DEBUG_TRACE (DEBUG::Graph,
1627 string_compose("There are %1 physical inputs of type %2\n",
1628 nphysical_in, *t));
1630 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1631 string port;
1633 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1634 DEBUG_TRACE (DEBUG::Graph,
1635 string_compose("Get index %1 + %2 % %3 = %4\n",
1636 in_offset.get(*t), i, nphysical_in,
1637 (in_offset.get(*t) + i) % nphysical_in));
1638 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1641 DEBUG_TRACE (DEBUG::Graph,
1642 string_compose("Connect route %1 IN to %2\n",
1643 route->name(), port));
1645 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
1646 break;
1649 ChanCount one_added (*t, 1);
1650 existing_inputs += one_added;
1654 if (!physoutputs.empty()) {
1655 uint32_t nphysical_out = physoutputs.size();
1656 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1657 string port;
1659 if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
1660 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1661 } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
1662 /* master bus is audio only */
1663 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1664 port = _master_out->input()->ports().port(*t,
1665 i % _master_out->input()->n_ports().get(*t))->name();
1669 DEBUG_TRACE (DEBUG::Graph,
1670 string_compose("Connect route %1 OUT to %2\n",
1671 route->name(), port));
1673 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
1674 break;
1677 ChanCount one_added (*t, 1);
1678 existing_outputs += one_added;
1684 /** Caller must not hold process lock
1685 * @param name_template string to use for the start of the name, or "" to use "Audio".
1687 list< boost::shared_ptr<AudioTrack> >
1688 Session::new_audio_track (
1689 int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template
1692 char track_name[32];
1693 uint32_t track_id = 0;
1694 string port;
1695 RouteList new_routes;
1696 list<boost::shared_ptr<AudioTrack> > ret;
1697 uint32_t control_id;
1699 control_id = ntracks() + nbusses() + 1;
1701 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
1703 while (how_many) {
1704 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1705 error << "cannot find name for new audio track" << endmsg;
1706 goto failed;
1709 boost::shared_ptr<AudioTrack> track;
1711 try {
1712 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1714 if (track->init ()) {
1715 goto failed;
1718 track->use_new_diskstream();
1720 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1721 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1722 #endif
1724 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1726 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1727 error << string_compose (
1728 _("cannot configure %1 in/%2 out configuration for new audio track"),
1729 input_channels, output_channels)
1730 << endmsg;
1731 goto failed;
1734 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1735 error << string_compose (
1736 _("cannot configure %1 in/%2 out configuration for new audio track"),
1737 input_channels, output_channels)
1738 << endmsg;
1739 goto failed;
1743 if (route_group) {
1744 route_group->add (track);
1747 track->non_realtime_input_change();
1749 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1750 track->set_remote_control_id (control_id);
1751 ++control_id;
1753 new_routes.push_back (track);
1754 ret.push_back (track);
1757 catch (failed_constructor &err) {
1758 error << _("Session: could not create new audio track.") << endmsg;
1759 goto failed;
1762 catch (AudioEngine::PortRegistrationFailure& pfe) {
1764 error << pfe.what() << endmsg;
1765 goto failed;
1768 --how_many;
1771 failed:
1772 if (!new_routes.empty()) {
1773 add_routes (new_routes, true, true);
1776 return ret;
1779 void
1780 Session::set_remote_control_ids ()
1782 RemoteModel m = Config->get_remote_model();
1783 bool emit_signal = false;
1785 boost::shared_ptr<RouteList> r = routes.reader ();
1787 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1788 if (MixerOrdered == m) {
1789 int32_t order = (*i)->order_key(N_("signal"));
1790 (*i)->set_remote_control_id (order+1, false);
1791 emit_signal = true;
1792 } else if (EditorOrdered == m) {
1793 int32_t order = (*i)->order_key(N_("editor"));
1794 (*i)->set_remote_control_id (order+1, false);
1795 emit_signal = true;
1796 } else if (UserOrdered == m) {
1797 //do nothing ... only changes to remote id's are initiated by user
1801 if (emit_signal) {
1802 Route::RemoteControlIDChange();
1806 /** Caller must not hold process lock.
1807 * @param name_template string to use for the start of the name, or "" to use "Bus".
1809 RouteList
1810 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1812 char bus_name[32];
1813 uint32_t bus_id = 0;
1814 string port;
1815 RouteList ret;
1816 uint32_t control_id;
1818 control_id = ntracks() + nbusses() + 1;
1820 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
1822 while (how_many) {
1823 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1824 error << "cannot find name for new audio bus" << endmsg;
1825 goto failure;
1828 try {
1829 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1831 if (bus->init ()) {
1832 goto failure;
1835 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1836 boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1837 #endif
1839 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1841 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1842 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1843 input_channels, output_channels)
1844 << endmsg;
1845 goto failure;
1849 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1850 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1851 input_channels, output_channels)
1852 << endmsg;
1853 goto failure;
1857 if (route_group) {
1858 route_group->add (bus);
1860 bus->set_remote_control_id (control_id);
1861 ++control_id;
1863 bus->add_internal_return ();
1865 ret.push_back (bus);
1869 catch (failed_constructor &err) {
1870 error << _("Session: could not create new audio route.") << endmsg;
1871 goto failure;
1874 catch (AudioEngine::PortRegistrationFailure& pfe) {
1875 error << pfe.what() << endmsg;
1876 goto failure;
1880 --how_many;
1883 failure:
1884 if (!ret.empty()) {
1885 add_routes (ret, false, true);
1888 return ret;
1892 RouteList
1893 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1895 char name[32];
1896 RouteList ret;
1897 uint32_t control_id;
1898 XMLTree tree;
1899 uint32_t number = 0;
1901 if (!tree.read (template_path.c_str())) {
1902 return ret;
1905 XMLNode* node = tree.root();
1907 control_id = ntracks() + nbusses() + 1;
1909 while (how_many) {
1911 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1913 std::string node_name = IO::name_from_state (*node_copy.children().front());
1915 /* generate a new name by adding a number to the end of the template name */
1916 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name), true)) {
1917 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1918 /*NOTREACHED*/
1921 /* set IO children to use the new name */
1922 XMLNodeList const & children = node_copy.children ();
1923 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1924 if ((*i)->name() == IO::state_node_name) {
1925 IO::set_name_in_state (**i, name);
1929 Track::zero_diskstream_id_in_xml (node_copy);
1931 try {
1932 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1934 if (route == 0) {
1935 error << _("Session: cannot create track/bus from template description") << endmsg;
1936 goto out;
1939 if (boost::dynamic_pointer_cast<Track>(route)) {
1940 /* force input/output change signals so that the new diskstream
1941 picks up the configuration of the route. During session
1942 loading this normally happens in a different way.
1945 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1947 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1948 change.after = route->input()->n_ports();
1949 route->input()->changed (change, this);
1950 change.after = route->output()->n_ports();
1951 route->output()->changed (change, this);
1954 route->set_remote_control_id (control_id);
1955 ++control_id;
1957 ret.push_back (route);
1960 catch (failed_constructor &err) {
1961 error << _("Session: could not create new route from template") << endmsg;
1962 goto out;
1965 catch (AudioEngine::PortRegistrationFailure& pfe) {
1966 error << pfe.what() << endmsg;
1967 goto out;
1970 --how_many;
1973 out:
1974 if (!ret.empty()) {
1975 add_routes (ret, true, true);
1978 return ret;
1981 void
1982 Session::add_routes (RouteList& new_routes, bool auto_connect, bool save)
1984 ChanCount existing_inputs;
1985 ChanCount existing_outputs;
1987 count_existing_track_channels (existing_inputs, existing_outputs);
1990 RCUWriter<RouteList> writer (routes);
1991 boost::shared_ptr<RouteList> r = writer.get_copy ();
1992 r->insert (r->end(), new_routes.begin(), new_routes.end());
1994 /* if there is no control out and we're not in the middle of loading,
1995 resort the graph here. if there is a control out, we will resort
1996 toward the end of this method. if we are in the middle of loading,
1997 we will resort when done.
2000 if (!_monitor_out && IO::connecting_legal) {
2001 resort_routes_using (r);
2005 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2007 boost::weak_ptr<Route> wpr (*x);
2008 boost::shared_ptr<Route> r (*x);
2010 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2011 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2012 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2013 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2014 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2015 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2016 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
2018 if (r->is_master()) {
2019 _master_out = r;
2022 if (r->is_monitor()) {
2023 _monitor_out = r;
2026 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2027 if (tr) {
2028 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2029 track_playlist_changed (boost::weak_ptr<Track> (tr));
2030 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2032 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2033 if (mt) {
2034 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2035 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
2039 if (auto_connect) {
2040 auto_connect_route (r, existing_inputs, existing_outputs, true);
2044 if (_monitor_out && IO::connecting_legal) {
2046 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2047 if ((*x)->is_monitor()) {
2048 /* relax */
2049 } else if ((*x)->is_master()) {
2050 /* relax */
2051 } else {
2052 (*x)->listen_via_monitor ();
2056 resort_routes ();
2059 set_dirty();
2061 if (save) {
2062 save_state (_current_snapshot_name);
2065 RouteAdded (new_routes); /* EMIT SIGNAL */
2066 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2069 void
2070 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2072 boost::shared_ptr<RouteList> r = routes.reader ();
2073 boost::shared_ptr<Send> s;
2075 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2076 if ((s = (*i)->internal_send_for (dest)) != 0) {
2077 s->amp()->gain_control()->set_value (0.0);
2082 void
2083 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2085 boost::shared_ptr<RouteList> r = routes.reader ();
2086 boost::shared_ptr<Send> s;
2088 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2089 if ((s = (*i)->internal_send_for (dest)) != 0) {
2090 s->amp()->gain_control()->set_value (1.0);
2095 void
2096 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2098 boost::shared_ptr<RouteList> r = routes.reader ();
2099 boost::shared_ptr<Send> s;
2101 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2102 if ((s = (*i)->internal_send_for (dest)) != 0) {
2103 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2108 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2109 void
2110 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2112 boost::shared_ptr<RouteList> r = routes.reader ();
2113 boost::shared_ptr<RouteList> t (new RouteList);
2115 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2116 /* no MIDI sends because there are no MIDI busses yet */
2117 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2118 t->push_back (*i);
2122 add_internal_sends (dest, p, t);
2125 void
2126 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2128 if (dest->is_monitor() || dest->is_master()) {
2129 return;
2132 if (!dest->internal_return()) {
2133 dest->add_internal_return();
2136 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2138 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2139 continue;
2142 (*i)->listen_via (dest, p);
2145 graph_reordered ();
2148 void
2149 Session::remove_route (boost::shared_ptr<Route> route)
2151 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2152 return;
2155 route->set_solo (false, this);
2158 RCUWriter<RouteList> writer (routes);
2159 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2161 rs->remove (route);
2163 /* deleting the master out seems like a dumb
2164 idea, but its more of a UI policy issue
2165 than our concern.
2168 if (route == _master_out) {
2169 _master_out = boost::shared_ptr<Route> ();
2172 if (route == _monitor_out) {
2174 /* cancel control outs for all routes */
2176 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2177 (*r)->drop_listen (_monitor_out);
2180 _monitor_out.reset ();
2183 /* writer goes out of scope, forces route list update */
2186 update_route_solo_state ();
2188 // We need to disconnect the route's inputs and outputs
2190 route->input()->disconnect (0);
2191 route->output()->disconnect (0);
2193 /* if the route had internal sends sending to it, remove them */
2194 if (route->internal_return()) {
2196 boost::shared_ptr<RouteList> r = routes.reader ();
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2199 if (s) {
2200 (*i)->remove_processor (s);
2205 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2206 if (mt && mt->step_editing()) {
2207 if (_step_editors > 0) {
2208 _step_editors--;
2212 update_latency_compensation ();
2213 set_dirty();
2215 /* Re-sort routes to remove the graph's current references to the one that is
2216 * going away, then flush old references out of the graph.
2219 resort_routes ();
2220 route_graph->clear_other_chain ();
2222 /* get rid of it from the dead wood collection in the route list manager */
2224 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2226 routes.flush ();
2228 /* try to cause everyone to drop their references */
2230 route->drop_references ();
2232 sync_order_keys (N_("session"));
2234 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2236 /* save the new state of the world */
2238 if (save_state (_current_snapshot_name)) {
2239 save_history (_current_snapshot_name);
2243 void
2244 Session::route_mute_changed (void* /*src*/)
2246 set_dirty ();
2249 void
2250 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2252 boost::shared_ptr<Route> route = wpr.lock();
2253 if (!route) {
2254 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2255 return;
2258 if (route->listening_via_monitor ()) {
2260 if (Config->get_exclusive_solo()) {
2261 /* new listen: disable all other listen */
2262 boost::shared_ptr<RouteList> r = routes.reader ();
2263 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2264 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2265 continue;
2267 (*i)->set_listen (false, this);
2271 _listen_cnt++;
2273 } else if (_listen_cnt > 0) {
2275 _listen_cnt--;
2278 update_route_solo_state ();
2280 void
2281 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2283 boost::shared_ptr<Route> route = wpr.lock ();
2285 if (!route) {
2286 /* should not happen */
2287 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2288 return;
2291 bool send_changed = false;
2293 if (route->solo_isolated()) {
2294 if (_solo_isolated_cnt == 0) {
2295 send_changed = true;
2297 _solo_isolated_cnt++;
2298 } else if (_solo_isolated_cnt > 0) {
2299 _solo_isolated_cnt--;
2300 if (_solo_isolated_cnt == 0) {
2301 send_changed = true;
2305 if (send_changed) {
2306 IsolatedChanged (); /* EMIT SIGNAL */
2310 void
2311 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2313 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
2315 if (!self_solo_change) {
2316 // session doesn't care about changes to soloed-by-others
2317 return;
2320 if (solo_update_disabled) {
2321 // We know already
2322 DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
2323 return;
2326 boost::shared_ptr<Route> route = wpr.lock ();
2327 assert (route);
2329 boost::shared_ptr<RouteList> r = routes.reader ();
2330 int32_t delta;
2332 if (route->self_soloed()) {
2333 delta = 1;
2334 } else {
2335 delta = -1;
2338 RouteGroup* rg = route->route_group ();
2339 bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
2341 if (delta == 1 && Config->get_exclusive_solo()) {
2343 /* new solo: disable all other solos, but not the group if its solo-enabled */
2345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2346 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2347 (leave_group_alone && ((*i)->route_group() == rg))) {
2348 continue;
2350 (*i)->set_solo (false, this);
2354 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
2356 solo_update_disabled = true;
2358 RouteList uninvolved;
2360 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
2362 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2363 bool via_sends_only;
2364 bool in_signal_flow;
2366 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() ||
2367 (leave_group_alone && ((*i)->route_group() == rg))) {
2368 continue;
2371 in_signal_flow = false;
2373 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
2375 if ((*i)->feeds (route, &via_sends_only)) {
2376 if (!via_sends_only) {
2377 if (!route->soloed_by_others_upstream()) {
2378 (*i)->mod_solo_by_others_downstream (delta);
2381 in_signal_flow = true;
2382 } else {
2383 DEBUG_TRACE (DEBUG::Solo, "\tno feed from\n");
2386 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
2388 if (route->feeds (*i, &via_sends_only)) {
2389 /* propagate solo upstream only if routing other than
2390 sends is involved, but do consider the other route
2391 (*i) to be part of the signal flow even if only
2392 sends are involved.
2394 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
2395 route->name(),
2396 (*i)->name(),
2397 via_sends_only,
2398 route->soloed_by_others_downstream(),
2399 route->soloed_by_others_upstream()));
2400 if (!via_sends_only) {
2401 if (!route->soloed_by_others_downstream()) {
2402 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
2403 (*i)->mod_solo_by_others_upstream (delta);
2406 in_signal_flow = true;
2407 } else {
2408 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
2411 if (!in_signal_flow) {
2412 uninvolved.push_back (*i);
2416 solo_update_disabled = false;
2417 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
2419 update_route_solo_state (r);
2421 /* now notify that the mute state of the routes not involved in the signal
2422 pathway of the just-solo-changed route may have altered.
2425 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2426 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1\n", (*i)->name()));
2427 (*i)->mute_changed (this);
2430 SoloChanged (); /* EMIT SIGNAL */
2431 set_dirty();
2434 void
2435 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2437 /* now figure out if anything that matters is soloed (or is "listening")*/
2439 bool something_soloed = false;
2440 uint32_t listeners = 0;
2441 uint32_t isolated = 0;
2443 if (!r) {
2444 r = routes.reader();
2447 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2448 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2449 something_soloed = true;
2452 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2453 if (Config->get_solo_control_is_listen_control()) {
2454 listeners++;
2455 } else {
2456 (*i)->set_listen (false, this);
2460 if ((*i)->solo_isolated()) {
2461 isolated++;
2465 if (something_soloed != _non_soloed_outs_muted) {
2466 _non_soloed_outs_muted = something_soloed;
2467 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2470 _listen_cnt = listeners;
2472 if (isolated != _solo_isolated_cnt) {
2473 _solo_isolated_cnt = isolated;
2474 IsolatedChanged (); /* EMIT SIGNAL */
2478 boost::shared_ptr<RouteList>
2479 Session::get_routes_with_internal_returns() const
2481 boost::shared_ptr<RouteList> r = routes.reader ();
2482 boost::shared_ptr<RouteList> rl (new RouteList);
2484 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2485 if ((*i)->internal_return ()) {
2486 rl->push_back (*i);
2489 return rl;
2492 bool
2493 Session::io_name_is_legal (const std::string& name)
2495 boost::shared_ptr<RouteList> r = routes.reader ();
2497 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2498 if ((*i)->name() == name) {
2499 return false;
2502 if ((*i)->has_io_processor_named (name)) {
2503 return false;
2507 return true;
2510 void
2511 Session::set_exclusive_input_active (boost::shared_ptr<Route> rt, bool others_on)
2513 RouteList rl;
2514 vector<string> connections;
2516 PortSet& ps (rt->input()->ports());
2518 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
2519 p->get_connections (connections);
2522 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
2523 routes_using_input_from (*s, rl);
2526 /* scan all relevant routes to see if others are on or off */
2528 bool others_are_already_on = false;
2530 for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
2531 if ((*r) != rt) {
2532 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2533 if (mt) {
2534 if (mt->input_active()) {
2535 others_are_already_on = true;
2536 break;
2542 /* globally reverse other routes */
2544 for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
2545 if ((*r) != rt) {
2546 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
2547 if (mt) {
2548 mt->set_input_active (!others_are_already_on);
2554 void
2555 Session::routes_using_input_from (const string& str, RouteList& rl)
2557 boost::shared_ptr<RouteList> r = routes.reader ();
2559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2560 if ((*i)->input()->connected_to (str)) {
2561 rl.push_back (*i);
2566 boost::shared_ptr<Route>
2567 Session::route_by_name (string name)
2569 boost::shared_ptr<RouteList> r = routes.reader ();
2571 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2572 if ((*i)->name() == name) {
2573 return *i;
2577 return boost::shared_ptr<Route> ((Route*) 0);
2580 boost::shared_ptr<Route>
2581 Session::route_by_id (PBD::ID id)
2583 boost::shared_ptr<RouteList> r = routes.reader ();
2585 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2586 if ((*i)->id() == id) {
2587 return *i;
2591 return boost::shared_ptr<Route> ((Route*) 0);
2594 boost::shared_ptr<Route>
2595 Session::route_by_remote_id (uint32_t id)
2597 boost::shared_ptr<RouteList> r = routes.reader ();
2599 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2600 if ((*i)->remote_control_id() == id) {
2601 return *i;
2605 return boost::shared_ptr<Route> ((Route*) 0);
2608 void
2609 Session::playlist_region_added (boost::weak_ptr<Region> w)
2611 boost::shared_ptr<Region> r = w.lock ();
2612 if (!r) {
2613 return;
2616 /* These are the operations that are currently in progress... */
2617 list<GQuark> curr = _current_trans_quarks;
2618 curr.sort ();
2620 /* ...and these are the operations during which we want to update
2621 the session range location markers.
2623 list<GQuark> ops;
2624 ops.push_back (Operations::capture);
2625 ops.push_back (Operations::paste);
2626 ops.push_back (Operations::duplicate_region);
2627 ops.push_back (Operations::insert_file);
2628 ops.push_back (Operations::insert_region);
2629 ops.push_back (Operations::drag_region_brush);
2630 ops.push_back (Operations::region_drag);
2631 ops.push_back (Operations::selection_grab);
2632 ops.push_back (Operations::region_fill);
2633 ops.push_back (Operations::fill_selection);
2634 ops.push_back (Operations::create_region);
2635 ops.push_back (Operations::region_copy);
2636 ops.push_back (Operations::fixed_time_region_copy);
2637 ops.sort ();
2639 /* See if any of the current operations match the ones that we want */
2640 list<GQuark> in;
2641 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2643 /* If so, update the session range markers */
2644 if (!in.empty ()) {
2645 maybe_update_session_range (r->position (), r->last_frame ());
2649 /** Update the session range markers if a is before the current start or
2650 * b is after the current end.
2652 void
2653 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2655 if (_state_of_the_state & Loading) {
2656 return;
2659 if (_session_range_location == 0) {
2661 add_session_range_location (a, b);
2663 } else {
2665 if (a < _session_range_location->start()) {
2666 _session_range_location->set_start (a);
2669 if (b > _session_range_location->end()) {
2670 _session_range_location->set_end (b);
2675 void
2676 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2678 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2679 maybe_update_session_range (i->to, i->to + i->length);
2683 void
2684 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2686 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2687 maybe_update_session_range (i->from, i->to);
2691 /* Region management */
2693 boost::shared_ptr<Region>
2694 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2696 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2697 RegionFactory::RegionMap::const_iterator i;
2698 boost::shared_ptr<Region> region;
2700 Glib::Mutex::Lock lm (region_lock);
2702 for (i = regions.begin(); i != regions.end(); ++i) {
2704 region = i->second;
2706 if (region->whole_file()) {
2708 if (child->source_equivalent (region)) {
2709 return region;
2714 return boost::shared_ptr<Region> ();
2718 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2720 set<boost::shared_ptr<Region> > relevant_regions;
2722 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2723 RegionFactory::get_regions_using_source (*s, relevant_regions);
2726 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2727 set<boost::shared_ptr<Region> >::iterator tmp;
2729 tmp = r;
2730 ++tmp;
2732 playlists->destroy_region (*r);
2733 RegionFactory::map_remove (*r);
2735 (*r)->drop_sources ();
2736 (*r)->drop_references ();
2738 relevant_regions.erase (r);
2740 r = tmp;
2743 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2746 Glib::Mutex::Lock ls (source_lock);
2747 /* remove from the main source list */
2748 sources.erase ((*s)->id());
2751 (*s)->mark_for_remove ();
2752 (*s)->drop_references ();
2754 s = srcs.erase (s);
2757 return 0;
2761 Session::remove_last_capture ()
2763 list<boost::shared_ptr<Source> > srcs;
2765 boost::shared_ptr<RouteList> rl = routes.reader ();
2766 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2767 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2768 if (!tr) {
2769 continue;
2772 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2774 if (!l.empty()) {
2775 srcs.insert (srcs.end(), l.begin(), l.end());
2776 l.clear ();
2780 destroy_sources (srcs);
2782 save_state (_current_snapshot_name);
2784 return 0;
2787 /* Source Management */
2789 void
2790 Session::add_source (boost::shared_ptr<Source> source)
2792 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2793 pair<SourceMap::iterator,bool> result;
2795 entry.first = source->id();
2796 entry.second = source;
2799 Glib::Mutex::Lock lm (source_lock);
2800 result = sources.insert (entry);
2803 if (result.second) {
2805 /* yay, new source */
2807 set_dirty();
2809 boost::shared_ptr<AudioFileSource> afs;
2811 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2812 if (Config->get_auto_analyse_audio()) {
2813 Analyser::queue_source_for_analysis (source, false);
2817 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
2821 void
2822 Session::remove_source (boost::weak_ptr<Source> src)
2824 if (_state_of_the_state & Deletion) {
2825 return;
2828 SourceMap::iterator i;
2829 boost::shared_ptr<Source> source = src.lock();
2831 if (!source) {
2832 return;
2836 Glib::Mutex::Lock lm (source_lock);
2838 if ((i = sources.find (source->id())) != sources.end()) {
2839 sources.erase (i);
2843 if (!_state_of_the_state & InCleanup) {
2845 /* save state so we don't end up with a session file
2846 referring to non-existent sources.
2849 save_state (_current_snapshot_name);
2853 boost::shared_ptr<Source>
2854 Session::source_by_id (const PBD::ID& id)
2856 Glib::Mutex::Lock lm (source_lock);
2857 SourceMap::iterator i;
2858 boost::shared_ptr<Source> source;
2860 if ((i = sources.find (id)) != sources.end()) {
2861 source = i->second;
2864 return source;
2867 boost::shared_ptr<Source>
2868 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2870 Glib::Mutex::Lock lm (source_lock);
2872 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2873 boost::shared_ptr<AudioFileSource> afs
2874 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2876 if (afs && afs->path() == path && chn == afs->channel()) {
2877 return afs;
2880 return boost::shared_ptr<Source>();
2883 uint32_t
2884 Session::count_sources_by_origin (const string& path)
2886 uint32_t cnt = 0;
2887 Glib::Mutex::Lock lm (source_lock);
2889 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2890 boost::shared_ptr<FileSource> fs
2891 = boost::dynamic_pointer_cast<FileSource>(i->second);
2893 if (fs && fs->origin() == path) {
2894 ++cnt;
2898 return cnt;
2902 string
2903 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2905 string look_for;
2906 string old_basename = PBD::basename_nosuffix (oldname);
2907 string new_legalized = legalize_for_path (newname);
2909 /* note: we know (or assume) the old path is already valid */
2911 if (destructive) {
2913 /* destructive file sources have a name of the form:
2915 /path/to/Tnnnn-NAME(%[LR])?.wav
2917 the task here is to replace NAME with the new name.
2920 string dir;
2921 string prefix;
2922 string::size_type dash;
2924 dir = Glib::path_get_dirname (path);
2925 path = Glib::path_get_basename (path);
2927 /* '-' is not a legal character for the NAME part of the path */
2929 if ((dash = path.find_last_of ('-')) == string::npos) {
2930 return "";
2933 prefix = path.substr (0, dash);
2935 path += prefix;
2936 path += '-';
2937 path += new_legalized;
2938 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2939 path = Glib::build_filename (dir, path);
2941 } else {
2943 /* non-destructive file sources have a name of the form:
2945 /path/to/NAME-nnnnn(%[LR])?.ext
2947 the task here is to replace NAME with the new name.
2950 string dir;
2951 string suffix;
2952 string::size_type dash;
2953 string::size_type postfix;
2955 dir = Glib::path_get_dirname (path);
2956 path = Glib::path_get_basename (path);
2958 /* '-' is not a legal character for the NAME part of the path */
2960 if ((dash = path.find_last_of ('-')) == string::npos) {
2961 return "";
2964 suffix = path.substr (dash+1);
2966 // Suffix is now everything after the dash. Now we need to eliminate
2967 // the nnnnn part, which is done by either finding a '%' or a '.'
2969 postfix = suffix.find_last_of ("%");
2970 if (postfix == string::npos) {
2971 postfix = suffix.find_last_of ('.');
2974 if (postfix != string::npos) {
2975 suffix = suffix.substr (postfix);
2976 } else {
2977 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2978 return "";
2981 const uint32_t limit = 10000;
2982 char buf[PATH_MAX+1];
2984 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2986 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2988 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2989 path = Glib::build_filename (dir, buf);
2990 break;
2993 path = "";
2996 if (path.empty()) {
2997 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2998 newname) << endl;
2999 /*NOTREACHED*/
3003 return path;
3006 /** Return the full path (in some session directory) for a new within-session source.
3007 * \a name must be a session-unique name that does not contain slashes
3008 * (e.g. as returned by new_*_source_name)
3010 string
3011 Session::new_source_path_from_name (DataType type, const string& name)
3013 assert(name.find("/") == string::npos);
3015 SessionDirectory sdir(get_best_session_directory_for_new_source());
3017 sys::path p;
3018 if (type == DataType::AUDIO) {
3019 p = sdir.sound_path();
3020 } else if (type == DataType::MIDI) {
3021 p = sdir.midi_path();
3022 } else {
3023 error << "Unknown source type, unable to create file path" << endmsg;
3024 return "";
3027 p /= name;
3028 return p.to_string();
3031 string
3032 Session::peak_path (string base) const
3034 sys::path peakfile_path(_session_dir->peak_path());
3035 peakfile_path /= base + peakfile_suffix;
3036 return peakfile_path.to_string();
3039 /** Return a unique name based on \a base for a new internal audio source */
3040 string
3041 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3043 uint32_t cnt;
3044 char buf[PATH_MAX+1];
3045 const uint32_t limit = 10000;
3046 string legalized;
3047 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3049 buf[0] = '\0';
3050 legalized = legalize_for_path (base);
3052 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3053 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3055 vector<space_and_path>::iterator i;
3056 uint32_t existing = 0;
3058 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3060 if (destructive) {
3062 if (nchan < 2) {
3063 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3064 cnt, legalized.c_str(), ext.c_str());
3065 } else if (nchan == 2) {
3066 if (chan == 0) {
3067 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
3068 cnt, legalized.c_str(), ext.c_str());
3069 } else {
3070 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
3071 cnt, legalized.c_str(), ext.c_str());
3073 } else if (nchan < 26) {
3074 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
3075 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
3076 } else {
3077 snprintf (buf, sizeof(buf), "T%04d-%s%s",
3078 cnt, legalized.c_str(), ext.c_str());
3081 } else {
3083 if (nchan < 2) {
3084 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3085 } else if (nchan == 2) {
3086 if (chan == 0) {
3087 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
3088 } else {
3089 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
3091 } else if (nchan < 26) {
3092 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
3093 } else {
3094 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
3098 SessionDirectory sdir((*i).path);
3100 string spath = sdir.sound_path().to_string();
3102 /* note that we search *without* the extension so that
3103 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
3104 in the event that this new name is required for
3105 a file format change.
3108 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
3109 existing++;
3110 break;
3114 if (existing == 0) {
3115 break;
3118 if (cnt > limit) {
3119 error << string_compose(
3120 _("There are already %1 recordings for %2, which I consider too many."),
3121 limit, base) << endmsg;
3122 destroy ();
3123 throw failed_constructor();
3127 return Glib::path_get_basename (buf);
3130 /** Create a new within-session audio source */
3131 boost::shared_ptr<AudioFileSource>
3132 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3134 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3135 const string path = new_source_path_from_name(DataType::AUDIO, name);
3137 return boost::dynamic_pointer_cast<AudioFileSource> (
3138 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3141 /** Return a unique name based on \a base for a new internal MIDI source */
3142 string
3143 Session::new_midi_source_name (const string& base)
3145 uint32_t cnt;
3146 char buf[PATH_MAX+1];
3147 const uint32_t limit = 10000;
3148 string legalized;
3150 buf[0] = '\0';
3151 legalized = legalize_for_path (base);
3153 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3154 for (cnt = 1; cnt <= limit; ++cnt) {
3156 vector<space_and_path>::iterator i;
3157 uint32_t existing = 0;
3159 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3161 SessionDirectory sdir((*i).path);
3163 sys::path p = sdir.midi_path();
3164 p /= legalized;
3166 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3168 if (sys::exists (buf)) {
3169 existing++;
3173 if (existing == 0) {
3174 break;
3177 if (cnt > limit) {
3178 error << string_compose(
3179 _("There are already %1 recordings for %2, which I consider too many."),
3180 limit, base) << endmsg;
3181 destroy ();
3182 throw failed_constructor();
3186 return Glib::path_get_basename(buf);
3190 /** Create a new within-session MIDI source */
3191 boost::shared_ptr<MidiSource>
3192 Session::create_midi_source_for_session (Track* track, string const & n)
3194 /* try to use the existing write source for the track, to keep numbering sane
3197 if (track) {
3198 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3199 assert (mt);
3202 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3204 if (!l.empty()) {
3205 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3206 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3210 const string name = new_midi_source_name (n);
3211 const string path = new_source_path_from_name (DataType::MIDI, name);
3213 return boost::dynamic_pointer_cast<SMFSource> (
3214 SourceFactory::createWritable (
3215 DataType::MIDI, *this, path, string(), false, frame_rate()));
3219 void
3220 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3222 if (playlist->hidden()) {
3223 return;
3226 playlists->add (playlist);
3228 if (unused) {
3229 playlist->release();
3232 set_dirty();
3235 void
3236 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3238 if (_state_of_the_state & Deletion) {
3239 return;
3242 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3244 if (!playlist) {
3245 return;
3248 playlists->remove (playlist);
3250 set_dirty();
3253 void
3254 Session::set_audition (boost::shared_ptr<Region> r)
3256 pending_audition_region = r;
3257 add_post_transport_work (PostTransportAudition);
3258 _butler->schedule_transport_work ();
3261 void
3262 Session::audition_playlist ()
3264 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3265 ev->region.reset ();
3266 queue_event (ev);
3269 void
3270 Session::non_realtime_set_audition ()
3272 if (!pending_audition_region) {
3273 auditioner->audition_current_playlist ();
3274 } else {
3275 auditioner->audition_region (pending_audition_region);
3276 pending_audition_region.reset ();
3278 AuditionActive (true); /* EMIT SIGNAL */
3281 void
3282 Session::audition_region (boost::shared_ptr<Region> r)
3284 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3285 ev->region = r;
3286 queue_event (ev);
3289 void
3290 Session::cancel_audition ()
3292 if (auditioner->auditioning()) {
3293 auditioner->cancel_audition ();
3294 AuditionActive (false); /* EMIT SIGNAL */
3298 bool
3299 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3301 if (a->is_monitor()) {
3302 return true;
3304 if (b->is_monitor()) {
3305 return false;
3307 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3310 bool
3311 Session::is_auditioning () const
3313 /* can be called before we have an auditioner object */
3314 if (auditioner) {
3315 return auditioner->auditioning();
3316 } else {
3317 return false;
3321 void
3322 Session::graph_reordered ()
3324 /* don't do this stuff if we are setting up connections
3325 from a set_state() call or creating new tracks. Ditto for deletion.
3328 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3329 return;
3332 /* every track/bus asked for this to be handled but it was deferred because
3333 we were connecting. do it now.
3336 request_input_change_handling ();
3338 resort_routes ();
3340 /* force all diskstreams to update their capture offset values to
3341 reflect any changes in latencies within the graph.
3344 boost::shared_ptr<RouteList> rl = routes.reader ();
3345 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3346 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3347 if (tr) {
3348 tr->set_capture_offset ();
3353 framecnt_t
3354 Session::available_capture_duration ()
3356 float sample_bytes_on_disk = 4.0; // keep gcc happy
3358 switch (config.get_native_file_data_format()) {
3359 case FormatFloat:
3360 sample_bytes_on_disk = 4.0;
3361 break;
3363 case FormatInt24:
3364 sample_bytes_on_disk = 3.0;
3365 break;
3367 case FormatInt16:
3368 sample_bytes_on_disk = 2.0;
3369 break;
3371 default:
3372 /* impossible, but keep some gcc versions happy */
3373 fatal << string_compose (_("programming error: %1"),
3374 X_("illegal native file data format"))
3375 << endmsg;
3376 /*NOTREACHED*/
3379 double scale = 4096.0 / sample_bytes_on_disk;
3381 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3382 return max_framecnt;
3385 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3388 void
3389 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3392 RCUWriter<BundleList> writer (_bundles);
3393 boost::shared_ptr<BundleList> b = writer.get_copy ();
3394 b->push_back (bundle);
3397 BundleAdded (bundle); /* EMIT SIGNAL */
3399 set_dirty();
3402 void
3403 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3405 bool removed = false;
3408 RCUWriter<BundleList> writer (_bundles);
3409 boost::shared_ptr<BundleList> b = writer.get_copy ();
3410 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3412 if (i != b->end()) {
3413 b->erase (i);
3414 removed = true;
3418 if (removed) {
3419 BundleRemoved (bundle); /* EMIT SIGNAL */
3422 set_dirty();
3425 boost::shared_ptr<Bundle>
3426 Session::bundle_by_name (string name) const
3428 boost::shared_ptr<BundleList> b = _bundles.reader ();
3430 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3431 if ((*i)->name() == name) {
3432 return* i;
3436 return boost::shared_ptr<Bundle> ();
3439 void
3440 Session::tempo_map_changed (const PropertyChange&)
3442 clear_clicks ();
3444 playlists->update_after_tempo_map_change ();
3446 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3448 set_dirty ();
3451 void
3452 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3454 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3455 (*i)->recompute_frames_from_bbt ();
3459 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3460 * the given count with the current block size.
3462 void
3463 Session::ensure_buffers (ChanCount howmany)
3465 BufferManager::ensure_buffers (howmany);
3468 void
3469 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3471 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3472 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3476 uint32_t
3477 Session::next_insert_id ()
3479 /* this doesn't really loop forever. just think about it */
3481 while (true) {
3482 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3483 if (!insert_bitset[n]) {
3484 insert_bitset[n] = true;
3485 return n;
3490 /* none available, so resize and try again */
3492 insert_bitset.resize (insert_bitset.size() + 16, false);
3496 uint32_t
3497 Session::next_send_id ()
3499 /* this doesn't really loop forever. just think about it */
3501 while (true) {
3502 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3503 if (!send_bitset[n]) {
3504 send_bitset[n] = true;
3505 return n;
3510 /* none available, so resize and try again */
3512 send_bitset.resize (send_bitset.size() + 16, false);
3516 uint32_t
3517 Session::next_return_id ()
3519 /* this doesn't really loop forever. just think about it */
3521 while (true) {
3522 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3523 if (!return_bitset[n]) {
3524 return_bitset[n] = true;
3525 return n;
3530 /* none available, so resize and try again */
3532 return_bitset.resize (return_bitset.size() + 16, false);
3536 void
3537 Session::mark_send_id (uint32_t id)
3539 if (id >= send_bitset.size()) {
3540 send_bitset.resize (id+16, false);
3542 if (send_bitset[id]) {
3543 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3545 send_bitset[id] = true;
3548 void
3549 Session::mark_return_id (uint32_t id)
3551 if (id >= return_bitset.size()) {
3552 return_bitset.resize (id+16, false);
3554 if (return_bitset[id]) {
3555 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3557 return_bitset[id] = true;
3560 void
3561 Session::mark_insert_id (uint32_t id)
3563 if (id >= insert_bitset.size()) {
3564 insert_bitset.resize (id+16, false);
3566 if (insert_bitset[id]) {
3567 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3569 insert_bitset[id] = true;
3572 void
3573 Session::unmark_send_id (uint32_t id)
3575 if (id < send_bitset.size()) {
3576 send_bitset[id] = false;
3580 void
3581 Session::unmark_return_id (uint32_t id)
3583 if (id < return_bitset.size()) {
3584 return_bitset[id] = false;
3588 void
3589 Session::unmark_insert_id (uint32_t id)
3591 if (id < insert_bitset.size()) {
3592 insert_bitset[id] = false;
3597 /* Named Selection management */
3599 boost::shared_ptr<NamedSelection>
3600 Session::named_selection_by_name (string name)
3602 Glib::Mutex::Lock lm (named_selection_lock);
3603 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3604 if ((*i)->name == name) {
3605 return *i;
3608 return boost::shared_ptr<NamedSelection>();
3611 void
3612 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3615 Glib::Mutex::Lock lm (named_selection_lock);
3616 named_selections.insert (named_selections.begin(), named_selection);
3619 set_dirty();
3621 NamedSelectionAdded (); /* EMIT SIGNAL */
3624 void
3625 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3627 bool removed = false;
3630 Glib::Mutex::Lock lm (named_selection_lock);
3632 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3634 if (i != named_selections.end()) {
3635 named_selections.erase (i);
3636 set_dirty();
3637 removed = true;
3641 if (removed) {
3642 NamedSelectionRemoved (); /* EMIT SIGNAL */
3646 void
3647 Session::reset_native_file_format ()
3649 boost::shared_ptr<RouteList> rl = routes.reader ();
3650 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3651 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3652 if (tr) {
3653 /* don't save state as we do this, there's no point
3656 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3657 tr->reset_write_sources (false);
3658 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3663 bool
3664 Session::route_name_unique (string n) const
3666 boost::shared_ptr<RouteList> r = routes.reader ();
3668 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3669 if ((*i)->name() == n) {
3670 return false;
3674 return true;
3677 bool
3678 Session::route_name_internal (string n) const
3680 if (auditioner && auditioner->name() == n) {
3681 return true;
3684 if (_click_io && _click_io->name() == n) {
3685 return true;
3688 return false;
3692 Session::freeze_all (InterThreadInfo& itt)
3694 boost::shared_ptr<RouteList> r = routes.reader ();
3696 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3698 boost::shared_ptr<Track> t;
3700 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3701 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3702 of every track.
3704 t->freeze_me (itt);
3708 return 0;
3711 boost::shared_ptr<Region>
3712 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3713 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3714 InterThreadInfo& itt, bool enable_processing)
3716 boost::shared_ptr<Region> result;
3717 boost::shared_ptr<Playlist> playlist;
3718 boost::shared_ptr<AudioFileSource> fsource;
3719 uint32_t x;
3720 char buf[PATH_MAX+1];
3721 ChanCount diskstream_channels (track.n_channels());
3722 framepos_t position;
3723 framecnt_t this_chunk;
3724 framepos_t to_do;
3725 BufferSet buffers;
3726 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3727 const string sound_dir = sdir.sound_path().to_string();
3728 framepos_t len = end - start;
3729 bool need_block_size_reset = false;
3730 string ext;
3731 ChanCount const max_proc = track.max_processor_streams ();
3733 if (end <= start) {
3734 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3735 end, start) << endmsg;
3736 return result;
3739 const framecnt_t chunk_size = (256 * 1024)/4;
3741 // block all process callback handling
3743 block_processing ();
3745 /* call tree *MUST* hold route_lock */
3747 if ((playlist = track.playlist()) == 0) {
3748 goto out;
3751 /* external redirects will be a problem */
3753 if (track.has_external_redirects()) {
3754 goto out;
3757 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3759 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3761 for (x = 0; x < 99999; ++x) {
3762 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());
3763 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
3764 break;
3768 if (x == 99999) {
3769 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3770 goto out;
3773 try {
3774 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3775 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3778 catch (failed_constructor& err) {
3779 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3780 goto out;
3783 srcs.push_back (fsource);
3786 /* tell redirects that care that we are about to use a much larger blocksize */
3788 need_block_size_reset = true;
3789 track.set_block_size (chunk_size);
3791 /* XXX need to flush all redirects */
3793 position = start;
3794 to_do = len;
3796 /* create a set of reasonably-sized buffers */
3797 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
3798 buffers.set_count (max_proc);
3800 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3801 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3802 if (afs)
3803 afs->prepare_for_peakfile_writes ();
3806 while (to_do && !itt.cancel) {
3808 this_chunk = min (to_do, chunk_size);
3810 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3811 goto out;
3814 uint32_t n = 0;
3815 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3816 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3818 if (afs) {
3819 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3820 goto out;
3825 start += this_chunk;
3826 to_do -= this_chunk;
3828 itt.progress = (float) (1.0 - ((double) to_do / len));
3832 if (!itt.cancel) {
3834 time_t now;
3835 struct tm* xnow;
3836 time (&now);
3837 xnow = localtime (&now);
3839 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3840 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3842 if (afs) {
3843 afs->update_header (position, *xnow, now);
3844 afs->flush_header ();
3848 /* construct a region to represent the bounced material */
3850 PropertyList plist;
3852 plist.add (Properties::start, 0);
3853 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3854 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3856 result = RegionFactory::create (srcs, plist);
3860 out:
3861 if (!result) {
3862 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3863 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3865 if (afs) {
3866 afs->mark_for_remove ();
3869 (*src)->drop_references ();
3872 } else {
3873 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3874 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3876 if (afs)
3877 afs->done_with_peakfile_writes ();
3882 if (need_block_size_reset) {
3883 track.set_block_size (get_block_size());
3886 unblock_processing ();
3888 return result;
3891 gain_t*
3892 Session::gain_automation_buffer() const
3894 return ProcessThread::gain_automation_buffer ();
3897 pan_t**
3898 Session::pan_automation_buffer() const
3900 return ProcessThread::pan_automation_buffer ();
3903 BufferSet&
3904 Session::get_silent_buffers (ChanCount count)
3906 return ProcessThread::get_silent_buffers (count);
3909 BufferSet&
3910 Session::get_scratch_buffers (ChanCount count)
3912 return ProcessThread::get_scratch_buffers (count);
3915 BufferSet&
3916 Session::get_mix_buffers (ChanCount count)
3918 return ProcessThread::get_mix_buffers (count);
3921 uint32_t
3922 Session::ntracks () const
3924 uint32_t n = 0;
3925 boost::shared_ptr<RouteList> r = routes.reader ();
3927 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3928 if (boost::dynamic_pointer_cast<Track> (*i)) {
3929 ++n;
3933 return n;
3936 uint32_t
3937 Session::nbusses () const
3939 uint32_t n = 0;
3940 boost::shared_ptr<RouteList> r = routes.reader ();
3942 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3943 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3944 ++n;
3948 return n;
3951 void
3952 Session::add_automation_list(AutomationList *al)
3954 automation_lists[al->id()] = al;
3957 void
3958 Session::sync_order_keys (std::string const & base)
3960 if (deletion_in_progress()) {
3961 return;
3964 if (!Config->get_sync_all_route_ordering()) {
3965 /* leave order keys as they are */
3966 return;
3969 boost::shared_ptr<RouteList> r = routes.reader ();
3971 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3972 (*i)->sync_order_keys (base);
3975 Route::SyncOrderKeys (base); // EMIT SIGNAL
3977 /* this might not do anything */
3979 set_remote_control_ids ();
3982 /** @return true if there is at least one record-enabled track, otherwise false */
3983 bool
3984 Session::have_rec_enabled_track () const
3986 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3989 /** Update the state of our rec-enabled tracks flag */
3990 void
3991 Session::update_have_rec_enabled_track ()
3993 boost::shared_ptr<RouteList> rl = routes.reader ();
3994 RouteList::iterator i = rl->begin();
3995 while (i != rl->end ()) {
3997 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3998 if (tr && tr->record_enabled ()) {
3999 break;
4002 ++i;
4005 int const old = g_atomic_int_get (&_have_rec_enabled_track);
4007 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
4009 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
4010 RecordStateChanged (); /* EMIT SIGNAL */
4014 void
4015 Session::listen_position_changed ()
4017 boost::shared_ptr<RouteList> r = routes.reader ();
4019 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4020 (*i)->listen_position_changed ();
4024 void
4025 Session::solo_control_mode_changed ()
4027 /* cancel all solo or all listen when solo control mode changes */
4029 if (soloing()) {
4030 set_solo (get_routes(), false);
4031 } else if (listening()) {
4032 set_listen (get_routes(), false);
4036 /** Called when anything about any of our route groups changes (membership, state etc.) */
4037 void
4038 Session::route_group_changed ()
4040 RouteGroupChanged (); /* EMIT SIGNAL */
4043 vector<SyncSource>
4044 Session::get_available_sync_options () const
4046 vector<SyncSource> ret;
4048 ret.push_back (JACK);
4049 ret.push_back (MTC);
4050 ret.push_back (MIDIClock);
4052 return ret;
4055 boost::shared_ptr<RouteList>
4056 Session::get_routes_with_regions_at (framepos_t const p) const
4058 boost::shared_ptr<RouteList> r = routes.reader ();
4059 boost::shared_ptr<RouteList> rl (new RouteList);
4061 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4062 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4063 if (!tr) {
4064 continue;
4067 boost::shared_ptr<Playlist> pl = tr->playlist ();
4068 if (!pl) {
4069 continue;
4072 if (pl->has_region_at (p)) {
4073 rl->push_back (*i);
4077 return rl;
4080 void
4081 Session::goto_end ()
4083 if (_session_range_location) {
4084 request_locate (_session_range_location->end(), false);
4085 } else {
4086 request_locate (0, false);
4090 void
4091 Session::goto_start ()
4093 if (_session_range_location) {
4094 request_locate (_session_range_location->start(), false);
4095 } else {
4096 request_locate (0, false);
4100 framepos_t
4101 Session::current_start_frame () const
4103 return _session_range_location ? _session_range_location->start() : 0;
4106 framepos_t
4107 Session::current_end_frame () const
4109 return _session_range_location ? _session_range_location->end() : 0;
4112 void
4113 Session::add_session_range_location (framepos_t start, framepos_t end)
4115 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4116 _locations->add (_session_range_location);
4119 /** Called when one of our routes' order keys has changed */
4120 void
4121 Session::route_order_key_changed ()
4123 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4126 void
4127 Session::step_edit_status_change (bool yn)
4129 bool send = false;
4131 bool val = false;
4132 if (yn) {
4133 send = (_step_editors == 0);
4134 val = true;
4136 _step_editors++;
4137 } else {
4138 send = (_step_editors == 1);
4139 val = false;
4141 if (_step_editors > 0) {
4142 _step_editors--;
4146 if (send) {
4147 StepEditStatusChange (val);
4152 void
4153 Session::start_time_changed (framepos_t old)
4155 /* Update the auto loop range to match the session range
4156 (unless the auto loop range has been changed by the user)
4159 Location* s = _locations->session_range_location ();
4160 if (s == 0) {
4161 return;
4164 Location* l = _locations->auto_loop_location ();
4166 if (l->start() == old) {
4167 l->set_start (s->start(), true);
4171 void
4172 Session::end_time_changed (framepos_t old)
4174 /* Update the auto loop range to match the session range
4175 (unless the auto loop range has been changed by the user)
4178 Location* s = _locations->session_range_location ();
4179 if (s == 0) {
4180 return;
4183 Location* l = _locations->auto_loop_location ();
4185 if (l->end() == old) {
4186 l->set_end (s->end(), true);
4190 string
4191 Session::source_search_path (DataType type) const
4193 string search_path;
4195 if (session_dirs.size() == 1) {
4196 switch (type) {
4197 case DataType::AUDIO:
4198 search_path = _session_dir->sound_path().to_string();
4199 break;
4200 case DataType::MIDI:
4201 search_path = _session_dir->midi_path().to_string();
4202 break;
4204 } else {
4205 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4206 SessionDirectory sdir (i->path);
4207 if (!search_path.empty()) {
4208 search_path += ':';
4210 switch (type) {
4211 case DataType::AUDIO:
4212 search_path += sdir.sound_path().to_string();
4213 break;
4214 case DataType::MIDI:
4215 search_path += sdir.midi_path().to_string();
4216 break;
4221 /* now add user-specified locations
4224 vector<string> dirs;
4226 switch (type) {
4227 case DataType::AUDIO:
4228 split (config.get_audio_search_path (), dirs, ':');
4229 break;
4230 case DataType::MIDI:
4231 split (config.get_midi_search_path (), dirs, ':');
4232 break;
4235 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4236 search_path += ':';
4237 search_path += *i;
4241 return search_path;
4244 void
4245 Session::ensure_search_path_includes (const string& path, DataType type)
4247 string search_path;
4248 vector<string> dirs;
4250 if (path == ".") {
4251 return;
4254 switch (type) {
4255 case DataType::AUDIO:
4256 search_path = config.get_audio_search_path ();
4257 break;
4258 case DataType::MIDI:
4259 search_path = config.get_midi_search_path ();
4260 break;
4263 split (search_path, dirs, ':');
4265 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4266 if (*i == path) {
4267 return;
4271 if (!search_path.empty()) {
4272 search_path += ':';
4275 search_path += path;
4277 switch (type) {
4278 case DataType::AUDIO:
4279 config.set_audio_search_path (search_path);
4280 break;
4281 case DataType::MIDI:
4282 config.set_midi_search_path (search_path);
4283 break;
4287 boost::shared_ptr<Speakers>
4288 Session::get_speakers()
4290 return _speakers;
4293 list<string>
4294 Session::unknown_processors () const
4296 list<string> p;
4298 boost::shared_ptr<RouteList> r = routes.reader ();
4299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4300 list<string> t = (*i)->unknown_processors ();
4301 copy (t.begin(), t.end(), back_inserter (p));
4304 p.sort ();
4305 p.unique ();
4307 return p;
4310 void
4311 Session::update_latency (bool playback)
4313 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4315 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4316 return;
4319 boost::shared_ptr<RouteList> r = routes.reader ();
4320 framecnt_t max_latency = 0;
4322 if (playback) {
4323 /* reverse the list so that we work backwards from the last route to run to the first */
4324 reverse (r->begin(), r->end());
4327 /* compute actual latency values for the given direction and store them all in per-port
4328 structures. this will also publish the same values (to JACK) so that computation of latency
4329 for routes can consistently use public latency values.
4332 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4333 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4336 /* because we latency compensate playback, our published playback latencies should
4337 be the same for all output ports - all material played back by ardour has
4338 the same latency, whether its caused by plugins or by latency compensation. since
4339 these may differ from the values computed above, reset all playback port latencies
4340 to the same value.
4343 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4346 (*i)->set_public_port_latencies (max_latency, playback);
4349 if (playback) {
4351 post_playback_latency ();
4353 } else {
4355 post_capture_latency ();
4358 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
4361 void
4362 Session::post_playback_latency ()
4364 set_worst_playback_latency ();
4366 boost::shared_ptr<RouteList> r = routes.reader ();
4367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4368 if (!(*i)->is_hidden() && ((*i)->active())) {
4369 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
4372 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4373 (*i)->set_latency_compensation (_worst_track_latency);
4378 void
4379 Session::post_capture_latency ()
4381 set_worst_capture_latency ();
4383 /* reflect any changes in capture latencies into capture offsets
4386 boost::shared_ptr<RouteList> rl = routes.reader();
4387 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4388 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4389 if (tr) {
4390 tr->set_capture_offset ();
4395 void
4396 Session::set_worst_io_latencies ()
4398 set_worst_playback_latency ();
4399 set_worst_capture_latency ();
4402 void
4403 Session::set_worst_playback_latency ()
4405 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4406 return;
4409 _worst_output_latency = 0;
4411 if (!_engine.connected()) {
4412 return;
4415 boost::shared_ptr<RouteList> r = routes.reader ();
4417 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4418 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
4421 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
4424 void
4425 Session::set_worst_capture_latency ()
4427 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4428 return;
4431 _worst_input_latency = 0;
4433 if (!_engine.connected()) {
4434 return;
4437 boost::shared_ptr<RouteList> r = routes.reader ();
4439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4440 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
4443 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
4446 void
4447 Session::update_latency_compensation (bool force_whole_graph)
4449 bool some_track_latency_changed = false;
4451 if (_state_of_the_state & (InitialConnecting|Deletion)) {
4452 return;
4455 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
4457 _worst_track_latency = 0;
4459 boost::shared_ptr<RouteList> r = routes.reader ();
4461 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4462 if (!(*i)->is_hidden() && ((*i)->active())) {
4463 framecnt_t tl;
4464 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
4465 some_track_latency_changed = true;
4467 _worst_track_latency = max (tl, _worst_track_latency);
4471 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
4472 (some_track_latency_changed ? "yes" : "no")));
4474 if (force_whole_graph || some_track_latency_changed) {
4475 /* trigger a full recompute of latency numbers for the graph.
4476 everything else that we need to do will be done in the latency
4477 callback.
4479 _engine.update_total_latencies ();
4480 return; // everything else will be done in the latency callback
4483 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n")