2 Copyright (C) 1999-2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/thread.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/error.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
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/crossfade.h"
67 #include "ardour/cycle_timer.h"
68 #include "ardour/data_type.h"
69 #include "ardour/debug.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/internal_send.h"
72 #include "ardour/io_processor.h"
73 #include "ardour/midi_diskstream.h"
74 #include "ardour/midi_playlist.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/midi_track.h"
77 #include "ardour/midi_ui.h"
78 #include "ardour/named_selection.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/playlist.h"
81 #include "ardour/plugin_insert.h"
82 #include "ardour/port_insert.h"
83 #include "ardour/processor.h"
84 #include "ardour/rc_configuration.h"
85 #include "ardour/recent_sessions.h"
86 #include "ardour/region_factory.h"
87 #include "ardour/return.h"
88 #include "ardour/route_group.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_metadata.h"
94 #include "ardour/session_playlists.h"
95 #include "ardour/slave.h"
96 #include "ardour/smf_source.h"
97 #include "ardour/source_factory.h"
98 #include "ardour/tape_file_matcher.h"
99 #include "ardour/tempo.h"
100 #include "ardour/utils.h"
101 #include "ardour/graph.h"
102 #include "ardour/speakers.h"
103 #include "ardour/operations.h"
105 #include "midi++/port.h"
106 #include "midi++/mmc.h"
107 #include "midi++/manager.h"
112 using namespace ARDOUR;
115 bool Session::_disable_all_loaded_plugins = false;
117 PBD::Signal1<void,std::string> Session::Dialog;
118 PBD::Signal0<int> Session::AskAboutPendingState;
119 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
120 PBD::Signal0<void> Session::SendFeedback;
121 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
123 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
124 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
125 PBD::Signal0<void> Session::AutoBindingOn;
126 PBD::Signal0<void> Session::AutoBindingOff;
127 PBD::Signal2<void,std::string, std::string> Session::Exported;
128 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
129 PBD::Signal0<void> Session::Quit;
131 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
132 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
134 Session::Session (AudioEngine &eng,
135 const string& fullpath,
136 const string& snapshot_name,
137 BusProfile* bus_profile,
140 , _target_transport_speed (0.0)
141 , _requested_return_frame (-1)
142 , _session_dir (new SessionDirectory(fullpath))
144 , _state_of_the_state (Clean)
145 , _butler (new Butler (*this))
146 , _post_transport_work (0)
147 , _send_timecode_update (false)
148 , _all_route_group (new RouteGroup (*this, "all"))
149 , route_graph (new Graph(*this))
150 , routes (new RouteList)
151 , _total_free_4k_blocks (0)
152 , _bundles (new BundleList)
153 , _bundle_xml_node (0)
155 , _click_io ((IO*) 0)
157 , click_emphasis_data (0)
159 , _metadata (new SessionMetadata())
160 , _have_rec_enabled_track (false)
161 , _suspend_timecode_transmission (0)
163 _locations = new Locations (*this);
165 playlists.reset (new SessionPlaylists);
167 _all_route_group->set_active (true, this);
169 interpolation.add_channel_to (0, 0);
171 if (!eng.connected()) {
172 throw failed_constructor();
175 n_physical_outputs = _engine.n_physical_outputs ();
176 n_physical_inputs = _engine.n_physical_inputs ();
178 first_stage_init (fullpath, snapshot_name);
180 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
183 if (create (mix_template, bus_profile)) {
185 throw failed_constructor ();
189 if (second_stage_init ()) {
191 throw failed_constructor ();
194 store_recent_sessions(_name, _path);
196 bool was_dirty = dirty();
198 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
200 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
201 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
204 DirtyChanged (); /* EMIT SIGNAL */
207 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
208 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
221 vector<void*> debug_pointers;
223 /* if we got to here, leaving pending capture state around
227 remove_pending_capture_state ();
229 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
231 _engine.remove_session ();
233 /* clear history so that no references to objects are held any more */
237 /* clear state tree so that no references to objects are held any more */
241 /* reset dynamic state version back to default */
243 Stateful::loading_state_version = 0;
245 _butler->drop_references ();
247 delete midi_control_ui;
248 delete _all_route_group;
250 if (click_data != default_click) {
251 delete [] click_data;
254 if (click_emphasis_data != default_click_emphasis) {
255 delete [] click_emphasis_data;
260 /* clear out any pending dead wood from RCU managed objects */
265 AudioDiskstream::free_working_buffers();
267 /* tell everyone who is still standing that we're about to die */
270 /* tell everyone to drop references and delete objects as we go */
272 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
273 named_selections.clear ();
275 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
276 RegionFactory::delete_all_regions ();
278 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
280 /* reset these three references to special routes before we do the usual route delete thing */
283 _master_out.reset ();
284 _monitor_out.reset ();
287 RCUWriter<RouteList> writer (routes);
288 boost::shared_ptr<RouteList> r = writer.get_copy ();
290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
291 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
292 (*i)->drop_references ();
296 /* writer goes out of scope and updates master */
300 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
301 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
302 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
303 i->second->drop_references ();
308 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
309 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
314 Crossfade::set_buffer_size (0);
316 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
321 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
323 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
324 boost_debug_list_ptrs ();
329 Session::set_worst_io_latencies ()
331 if (_state_of_the_state & InitialConnecting) {
335 _worst_output_latency = 0;
336 _worst_input_latency = 0;
338 if (!_engine.connected()) {
342 boost::shared_ptr<RouteList> r = routes.reader ();
344 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
345 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
346 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
349 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1 Worst input latency: %2\n",
350 _worst_output_latency, _worst_input_latency));
354 Session::when_engine_running ()
356 string first_physical_output;
358 BootMessage (_("Set block size and sample rate"));
360 set_block_size (_engine.frames_per_cycle());
361 set_frame_rate (_engine.frame_rate());
363 BootMessage (_("Using configuration"));
365 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
366 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
368 Config->map_parameters (ff);
369 config.map_parameters (ft);
371 /* every time we reconnect, recompute worst case output latencies */
373 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
375 if (synced_to_jack()) {
376 _engine.transport_stop ();
379 if (config.get_jack_time_master()) {
380 _engine.transport_locate (_transport_frame);
388 _click_io.reset (new ClickIO (*this, "click"));
390 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
392 /* existing state for Click */
395 if (Stateful::loading_state_version < 3000) {
396 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
398 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
403 _clicking = Config->get_clicking ();
407 error << _("could not setup Click I/O") << endmsg;
414 /* default state for Click: dual-mono to first 2 physical outputs */
417 _engine.get_physical_outputs (DataType::AUDIO, outs);
419 for (uint32_t physport = 0; physport < 2; ++physport) {
420 if (outs.size() > physport) {
421 if (_click_io->add_port (outs[physport], this)) {
422 // relax, even though its an error
427 if (_click_io->n_ports () > ChanCount::ZERO) {
428 _clicking = Config->get_clicking ();
433 catch (failed_constructor& err) {
434 error << _("cannot setup Click I/O") << endmsg;
437 BootMessage (_("Compute I/O Latencies"));
440 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
443 BootMessage (_("Set up standard connections"));
445 vector<string> inputs[DataType::num_types];
446 vector<string> outputs[DataType::num_types];
447 for (uint32_t i = 0; i < DataType::num_types; ++i) {
448 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
449 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
452 /* Create a set of Bundle objects that map
453 to the physical I/O currently available. We create both
454 mono and stereo bundles, so that the common cases of mono
455 and stereo tracks get bundles to put in their mixer strip
456 in / out menus. There may be a nicer way of achieving that;
457 it doesn't really scale that well to higher channel counts
460 /* mono output bundles */
462 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
464 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
466 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
467 c->add_channel (_("mono"), DataType::AUDIO);
468 c->set_port (0, outputs[DataType::AUDIO][np]);
473 /* stereo output bundles */
475 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
476 if (np + 1 < outputs[DataType::AUDIO].size()) {
478 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
479 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
480 c->add_channel (_("L"), DataType::AUDIO);
481 c->set_port (0, outputs[DataType::AUDIO][np]);
482 c->add_channel (_("R"), DataType::AUDIO);
483 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
489 /* mono input bundles */
491 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
493 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
495 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
496 c->add_channel (_("mono"), DataType::AUDIO);
497 c->set_port (0, inputs[DataType::AUDIO][np]);
502 /* stereo input bundles */
504 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
505 if (np + 1 < inputs[DataType::AUDIO].size()) {
507 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
509 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
510 c->add_channel (_("L"), DataType::AUDIO);
511 c->set_port (0, inputs[DataType::AUDIO][np]);
512 c->add_channel (_("R"), DataType::AUDIO);
513 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
519 /* MIDI input bundles */
521 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
522 string n = inputs[DataType::MIDI][np];
523 boost::erase_first (n, X_("alsa_pcm:"));
525 boost::shared_ptr<Bundle> c (new Bundle (n, false));
526 c->add_channel ("", DataType::MIDI);
527 c->set_port (0, inputs[DataType::MIDI][np]);
531 /* MIDI output bundles */
533 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
534 string n = outputs[DataType::MIDI][np];
535 boost::erase_first (n, X_("alsa_pcm:"));
537 boost::shared_ptr<Bundle> c (new Bundle (n, true));
538 c->add_channel ("", DataType::MIDI);
539 c->set_port (0, outputs[DataType::MIDI][np]);
543 BootMessage (_("Setup signal flow and plugins"));
547 if (_is_new && !no_auto_connect()) {
549 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
551 /* don't connect the master bus outputs if there is a monitor bus */
553 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
555 /* if requested auto-connect the outputs to the first N physical ports.
558 uint32_t limit = _master_out->n_outputs().n_total();
560 for (uint32_t n = 0; n < limit; ++n) {
561 Port* p = _master_out->output()->nth (n);
563 if (outputs[p->type()].size() > n) {
564 connect_to = outputs[p->type()][n];
567 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
568 if (_master_out->output()->connect (p, connect_to, this)) {
569 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
579 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
580 are undefined, at best.
583 /* control out listens to master bus (but ignores it
584 under some conditions)
587 uint32_t limit = _monitor_out->n_inputs().n_audio();
590 for (uint32_t n = 0; n < limit; ++n) {
591 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
592 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
595 string connect_to = o->name();
596 if (_monitor_out->input()->connect (p, connect_to, this)) {
597 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
605 /* if control out is not connected, connect control out to physical outs
608 if (!_monitor_out->output()->connected ()) {
610 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
612 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
615 _monitor_out->output()->connect_ports_to_bundle (b, this);
617 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
618 Config->get_monitor_bus_preferred_bundle())
624 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
625 uint32_t mod = n_physical_outputs.get (*t);
626 uint32_t limit = _monitor_out->n_outputs().get(*t);
628 for (uint32_t n = 0; n < limit; ++n) {
630 Port* p = _monitor_out->output()->ports().port(*t, n);
632 if (outputs[*t].size() > (n % mod)) {
633 connect_to = outputs[*t][n % mod];
636 if (!connect_to.empty()) {
637 if (_monitor_out->output()->connect (p, connect_to, this)) {
638 error << string_compose (
639 _("cannot connect control output %1 to %2"),
652 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
654 /* hook us up to the engine */
656 BootMessage (_("Connect to engine"));
657 _engine.set_session (this);
659 update_latency_compensation (false, false, true);
663 Session::hookup_io ()
665 /* stop graph reordering notifications from
666 causing resorts, etc.
669 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
673 /* we delay creating the auditioner till now because
674 it makes its own connections to ports.
678 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
680 throw failed_constructor ();
682 a->use_new_diskstream ();
686 catch (failed_constructor& err) {
687 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
691 /* load bundles, which we may have postponed earlier on */
692 if (_bundle_xml_node) {
693 load_bundles (*_bundle_xml_node);
694 delete _bundle_xml_node;
697 /* Tell all IO objects to connect themselves together */
699 IO::enable_connecting ();
700 MIDI::Port::MakeConnections ();
702 /* Now reset all panners */
704 Delivery::reset_panners ();
706 /* Connect tracks to monitor/listen bus if there is one.
707 Note that in an existing session, the internal sends will
708 already exist, but we want the routes to notice that
709 they connect to the control out specifically.
713 boost::shared_ptr<RouteList> r = routes.reader ();
714 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
716 if ((*x)->is_monitor()) {
720 } else if ((*x)->is_master()) {
726 (*x)->listen_via_monitor ();
731 /* Anyone who cares about input state, wake up and do something */
733 IOConnectionsComplete (); /* EMIT SIGNAL */
735 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
737 /* now handle the whole enchilada as if it was one
743 /* update the full solo state, which can't be
744 correctly determined on a per-route basis, but
745 needs the global overview that only the session
749 update_route_solo_state ();
753 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
755 boost::shared_ptr<Track> track = wp.lock ();
760 boost::shared_ptr<Playlist> playlist;
762 if ((playlist = track->playlist()) != 0) {
763 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
764 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
765 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
770 Session::record_enabling_legal () const
772 /* this used to be in here, but survey says.... we don't need to restrict it */
773 // if (record_status() == Recording) {
777 if (Config->get_all_safe()) {
784 Session::set_track_monitor_input_status (bool yn)
786 boost::shared_ptr<RouteList> rl = routes.reader ();
787 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
788 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
789 if (tr && tr->record_enabled ()) {
790 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
791 tr->monitor_input (yn);
797 Session::reset_input_monitor_state ()
799 if (transport_rolling()) {
800 set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
802 set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring);
807 Session::auto_punch_start_changed (Location* location)
809 replace_event (SessionEvent::PunchIn, location->start());
811 if (get_record_enabled() && config.get_punch_in()) {
812 /* capture start has been changed, so save new pending state */
813 save_state ("", true);
818 Session::auto_punch_end_changed (Location* location)
820 framepos_t when_to_stop = location->end();
821 // when_to_stop += _worst_output_latency + _worst_input_latency;
822 replace_event (SessionEvent::PunchOut, when_to_stop);
826 Session::auto_punch_changed (Location* location)
828 framepos_t when_to_stop = location->end();
830 replace_event (SessionEvent::PunchIn, location->start());
831 //when_to_stop += _worst_output_latency + _worst_input_latency;
832 replace_event (SessionEvent::PunchOut, when_to_stop);
836 Session::auto_loop_changed (Location* location)
838 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
840 if (transport_rolling() && play_loop) {
843 // if (_transport_frame > location->end()) {
845 if (_transport_frame < location->start() || _transport_frame > location->end()) {
846 // relocate to beginning of loop
847 clear_events (SessionEvent::LocateRoll);
849 request_locate (location->start(), true);
852 else if (Config->get_seamless_loop() && !loop_changing) {
854 // schedule a locate-roll to refill the diskstreams at the
856 loop_changing = true;
858 if (location->end() > last_loopend) {
859 clear_events (SessionEvent::LocateRoll);
860 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
867 last_loopend = location->end();
871 Session::set_auto_punch_location (Location* location)
875 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
876 punch_connections.drop_connections();
877 existing->set_auto_punch (false, this);
878 remove_event (existing->start(), SessionEvent::PunchIn);
879 clear_events (SessionEvent::PunchOut);
880 auto_punch_location_changed (0);
889 if (location->end() <= location->start()) {
890 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
894 punch_connections.drop_connections ();
896 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
897 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
898 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
900 location->set_auto_punch (true, this);
902 auto_punch_changed (location);
904 auto_punch_location_changed (location);
908 Session::set_auto_loop_location (Location* location)
912 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
913 loop_connections.drop_connections ();
914 existing->set_auto_loop (false, this);
915 remove_event (existing->end(), SessionEvent::AutoLoop);
916 auto_loop_location_changed (0);
925 if (location->end() <= location->start()) {
926 error << _("Session: you can't use a mark for auto loop") << endmsg;
930 last_loopend = location->end();
932 loop_connections.drop_connections ();
934 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
935 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
936 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
938 location->set_auto_loop (true, this);
940 /* take care of our stuff first */
942 auto_loop_changed (location);
944 /* now tell everyone else */
946 auto_loop_location_changed (location);
950 Session::locations_added (Location *)
956 Session::locations_changed ()
958 _locations->apply (*this, &Session::handle_locations_changed);
962 Session::handle_locations_changed (Locations::LocationList& locations)
964 Locations::LocationList::iterator i;
966 bool set_loop = false;
967 bool set_punch = false;
969 for (i = locations.begin(); i != locations.end(); ++i) {
973 if (location->is_auto_punch()) {
974 set_auto_punch_location (location);
977 if (location->is_auto_loop()) {
978 set_auto_loop_location (location);
982 if (location->is_session_range()) {
983 _session_range_location = location;
988 set_auto_loop_location (0);
991 set_auto_punch_location (0);
998 Session::enable_record ()
1001 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1003 if (rs == Recording) {
1007 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1009 _last_record_location = _transport_frame;
1010 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1012 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1013 set_track_monitor_input_status (true);
1016 RecordStateChanged ();
1023 Session::disable_record (bool rt_context, bool force)
1027 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1029 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1030 g_atomic_int_set (&_record_status, Disabled);
1031 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1033 if (rs == Recording) {
1034 g_atomic_int_set (&_record_status, Enabled);
1038 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1039 set_track_monitor_input_status (false);
1042 RecordStateChanged (); /* emit signal */
1045 remove_pending_capture_state ();
1051 Session::step_back_from_record ()
1053 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1055 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1056 set_track_monitor_input_status (false);
1062 Session::maybe_enable_record ()
1064 if (_step_editors > 0) {
1068 g_atomic_int_set (&_record_status, Enabled);
1070 /* This function is currently called from somewhere other than an RT thread.
1071 This save_state() call therefore doesn't impact anything. Doing it here
1072 means that we save pending state of which sources the next record will use,
1073 which gives us some chance of recovering from a crash during the record.
1076 save_state ("", true);
1078 if (_transport_speed) {
1079 if (!config.get_punch_in()) {
1083 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1084 RecordStateChanged (); /* EMIT SIGNAL */
1091 Session::audible_frame () const
1097 /* the first of these two possible settings for "offset"
1098 mean that the audible frame is stationary until
1099 audio emerges from the latency compensation
1102 the second means that the audible frame is stationary
1103 until audio would emerge from a physical port
1104 in the absence of any plugin latency compensation
1107 offset = worst_playback_latency ();
1109 if (offset > current_block_size) {
1110 offset -= current_block_size;
1112 /* XXX is this correct? if we have no external
1113 physical connections and everything is internal
1114 then surely this is zero? still, how
1115 likely is that anyway?
1117 offset = current_block_size;
1120 if (synced_to_jack()) {
1121 tf = _engine.transport_frame();
1123 tf = _transport_frame;
1128 if (!non_realtime_work_pending()) {
1132 /* Check to see if we have passed the first guaranteed
1133 audible frame past our last start position. if not,
1134 return that last start point because in terms
1135 of audible frames, we have not moved yet.
1137 `Start position' in this context means the time we last
1138 either started or changed transport direction.
1141 if (_transport_speed > 0.0f) {
1143 if (!play_loop || !have_looped) {
1144 if (tf < _last_roll_or_reversal_location + offset) {
1145 return _last_roll_or_reversal_location;
1153 } else if (_transport_speed < 0.0f) {
1155 /* XXX wot? no backward looping? */
1157 if (tf > _last_roll_or_reversal_location - offset) {
1158 return _last_roll_or_reversal_location;
1170 Session::set_frame_rate (framecnt_t frames_per_second)
1172 /** \fn void Session::set_frame_size(framecnt_t)
1173 the AudioEngine object that calls this guarantees
1174 that it will not be called while we are also in
1175 ::process(). Its fine to do things that block
1179 _base_frame_rate = frames_per_second;
1183 Automatable::set_automation_interval (ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1187 // XXX we need some equivalent to this, somehow
1188 // SndFileSource::setup_standard_crossfades (frames_per_second);
1192 /* XXX need to reset/reinstantiate all LADSPA plugins */
1196 Session::set_block_size (pframes_t nframes)
1198 /* the AudioEngine guarantees
1199 that it will not be called while we are also in
1200 ::process(). It is therefore fine to do things that block
1205 current_block_size = nframes;
1209 boost::shared_ptr<RouteList> r = routes.reader ();
1211 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1212 (*i)->set_block_size (nframes);
1215 boost::shared_ptr<RouteList> rl = routes.reader ();
1216 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1217 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1219 tr->set_block_size (nframes);
1223 set_worst_io_latencies ();
1227 struct RouteSorter {
1228 /** @return true to run r1 before r2, otherwise false */
1229 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1230 if (r2->feeds (r1)) {
1231 /* r1 fed by r2; run r2 early */
1233 } else if (r1->feeds (r2)) {
1234 /* r2 fed by r1; run r1 early */
1237 if (r1->not_fed ()) {
1238 if (r2->not_fed ()) {
1239 /* no ardour-based connections inbound to either route. just use signal order */
1240 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1242 /* r2 has connections, r1 does not; run r1 early */
1246 if (r2->not_fed()) {
1247 /* r1 has connections, r2 does not; run r2 early */
1250 /* both r1 and r2 have connections, but not to each other. just use signal order */
1251 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1259 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1261 boost::shared_ptr<Route> r2;
1263 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1264 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1268 /* make a copy of the existing list of routes that feed r1 */
1270 Route::FedBy existing (r1->fed_by());
1272 /* for each route that feeds r1, recurse, marking it as feeding
1276 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1277 if (!(r2 = i->r.lock ())) {
1278 /* (*i) went away, ignore it */
1282 /* r2 is a route that feeds r1 which somehow feeds base. mark
1283 base as being fed by r2
1286 rbase->add_fed_by (r2, i->sends_only);
1290 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1294 if (r1->feeds (r2) && r2->feeds (r1)) {
1298 /* now recurse, so that we can mark base as being fed by
1299 all routes that feed r2
1302 trace_terminal (r2, rbase);
1309 Session::resort_routes ()
1311 /* don't do anything here with signals emitted
1312 by Routes while we are being destroyed.
1315 if (_state_of_the_state & Deletion) {
1320 RCUWriter<RouteList> writer (routes);
1321 boost::shared_ptr<RouteList> r = writer.get_copy ();
1322 resort_routes_using (r);
1323 /* writer goes out of scope and forces update */
1326 //route_graph->dump(1);
1329 boost::shared_ptr<RouteList> rl = routes.reader ();
1330 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1331 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1333 const Route::FedBy& fb ((*i)->fed_by());
1335 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1336 boost::shared_ptr<Route> sf = f->r.lock();
1338 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1346 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1348 RouteList::iterator i, j;
1350 for (i = r->begin(); i != r->end(); ++i) {
1352 (*i)->clear_fed_by ();
1354 for (j = r->begin(); j != r->end(); ++j) {
1356 /* although routes can feed themselves, it will
1357 cause an endless recursive descent if we
1358 detect it. so don't bother checking for
1366 bool via_sends_only;
1368 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1369 (*i)->add_fed_by (*j, via_sends_only);
1374 for (i = r->begin(); i != r->end(); ++i) {
1375 trace_terminal (*i, *i);
1381 route_graph->rechain (r);
1384 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1385 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1386 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1387 (*i)->name(), (*i)->order_key ("signal")));
1393 /** Find a route name starting with \a base, maybe followed by the
1394 * lowest \a id. \a id will always be added if \a definitely_add_number
1395 * is true on entry; otherwise it will only be added if required
1396 * to make the name unique.
1398 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1399 * The available route name with the lowest ID will be used, and \a id
1400 * will be set to the ID.
1402 * \return false if a route name could not be found, and \a track_name
1403 * and \a id do not reflect a free route name.
1406 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1408 if (!definitely_add_number && route_by_name (base) == 0) {
1409 /* juse use the base */
1410 snprintf (name, name_len, "%s", base.c_str());
1415 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1417 if (route_by_name (name) == 0) {
1423 } while (id < (UINT_MAX-1));
1428 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1430 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1432 in = ChanCount::ZERO;
1433 out = ChanCount::ZERO;
1434 boost::shared_ptr<RouteList> r = routes.reader ();
1435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1436 if (!(*i)->is_hidden()) {
1437 in += (*i)->n_inputs();
1438 out += (*i)->n_outputs();
1443 /** Caller must not hold process lock
1444 * @param name_template string to use for the start of the name, or "" to use "Midi".
1446 list<boost::shared_ptr<MidiTrack> >
1447 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1449 char track_name[32];
1450 uint32_t track_id = 0;
1451 ChanCount existing_inputs;
1452 ChanCount existing_outputs;
1454 RouteList new_routes;
1455 list<boost::shared_ptr<MidiTrack> > ret;
1456 uint32_t control_id;
1458 count_existing_route_channels (existing_inputs, existing_outputs);
1460 control_id = ntracks() + nbusses();
1462 bool const use_number = (how_many != 1);
1465 if (!find_route_name (name_template.empty() ? _("Midi") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1466 error << "cannot find name for new midi track" << endmsg;
1470 boost::shared_ptr<MidiTrack> track;
1473 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1475 if (track->init ()) {
1479 track->use_new_diskstream();
1481 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1482 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1485 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1486 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1487 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1491 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1492 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1497 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1499 track->non_realtime_input_change();
1502 route_group->add (track);
1505 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1506 track->set_remote_control_id (control_id);
1508 new_routes.push_back (track);
1509 ret.push_back (track);
1512 catch (failed_constructor &err) {
1513 error << _("Session: could not create new midi track.") << endmsg;
1517 catch (AudioEngine::PortRegistrationFailure& pfe) {
1519 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;
1527 if (!new_routes.empty()) {
1528 add_routes (new_routes, false);
1529 save_state (_current_snapshot_name);
1535 /** Caller must hold process lock.
1536 * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1537 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1538 * @param output_start As \a input_start, but for outputs.
1541 Session::auto_connect_route (
1542 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1545 /* If both inputs and outputs are auto-connected to physical ports,
1546 use the max of input and output offsets to ensure auto-connected
1547 port numbers always match up (e.g. the first audio input and the
1548 first audio output of the route will have the same physical
1549 port number). Otherwise just use the lowest input or output
1553 const bool in_out_physical =
1554 (Config->get_input_auto_connect() & AutoConnectPhysical)
1555 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1558 const ChanCount in_offset = in_out_physical
1559 ? ChanCount::max(existing_inputs, existing_outputs)
1562 const ChanCount out_offset = in_out_physical
1563 ? ChanCount::max(existing_inputs, existing_outputs)
1566 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1567 vector<string> physinputs;
1568 vector<string> physoutputs;
1570 _engine.get_physical_outputs (*t, physoutputs);
1571 _engine.get_physical_inputs (*t, physinputs);
1573 if (!physinputs.empty() && connect_inputs) {
1574 uint32_t nphysical_in = physinputs.size();
1575 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1578 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1579 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1582 if (!port.empty() && route->input()->connect (
1583 route->input()->ports().port(*t, i), port, this)) {
1589 if (!physoutputs.empty()) {
1590 uint32_t nphysical_out = physoutputs.size();
1591 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1594 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1595 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1596 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1597 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1598 port = _master_out->input()->ports().port(*t,
1599 i % _master_out->input()->n_ports().get(*t))->name();
1603 if (!port.empty() && route->output()->connect (
1604 route->output()->ports().port(*t, i), port, this)) {
1611 existing_inputs += route->n_inputs();
1612 existing_outputs += route->n_outputs();
1615 /** Caller must not hold process lock
1616 * @param name_template string to use for the start of the name, or "" to use "Audio".
1618 list< boost::shared_ptr<AudioTrack> >
1619 Session::new_audio_track (
1620 int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template
1623 char track_name[32];
1624 uint32_t track_id = 0;
1625 ChanCount existing_inputs;
1626 ChanCount existing_outputs;
1628 RouteList new_routes;
1629 list<boost::shared_ptr<AudioTrack> > ret;
1630 uint32_t control_id;
1632 count_existing_route_channels (existing_inputs, existing_outputs);
1634 control_id = ntracks() + nbusses() + 1;
1636 bool const use_number = (how_many != 1);
1639 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1640 error << "cannot find name for new audio track" << endmsg;
1644 boost::shared_ptr<AudioTrack> track;
1647 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1649 if (track->init ()) {
1653 track->use_new_diskstream();
1655 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1656 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1659 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1661 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1662 error << string_compose (
1663 _("cannot configure %1 in/%2 out configuration for new audio track"),
1664 input_channels, output_channels)
1669 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1670 error << string_compose (
1671 _("cannot configure %1 in/%2 out configuration for new audio track"),
1672 input_channels, output_channels)
1677 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1681 route_group->add (track);
1684 track->non_realtime_input_change();
1686 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1687 track->set_remote_control_id (control_id);
1690 new_routes.push_back (track);
1691 ret.push_back (track);
1694 catch (failed_constructor &err) {
1695 error << _("Session: could not create new audio track.") << endmsg;
1699 catch (AudioEngine::PortRegistrationFailure& pfe) {
1701 error << pfe.what() << endmsg;
1709 if (!new_routes.empty()) {
1710 add_routes (new_routes, true);
1717 Session::set_remote_control_ids ()
1719 RemoteModel m = Config->get_remote_model();
1720 bool emit_signal = false;
1722 boost::shared_ptr<RouteList> r = routes.reader ();
1724 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1725 if (MixerOrdered == m) {
1726 int32_t order = (*i)->order_key(N_("signal"));
1727 (*i)->set_remote_control_id (order+1, false);
1729 } else if (EditorOrdered == m) {
1730 int32_t order = (*i)->order_key(N_("editor"));
1731 (*i)->set_remote_control_id (order+1, false);
1733 } else if (UserOrdered == m) {
1734 //do nothing ... only changes to remote id's are initiated by user
1739 Route::RemoteControlIDChange();
1743 /** Caller must not hold process lock.
1744 * @param name_template string to use for the start of the name, or "" to use "Bus".
1747 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1750 uint32_t bus_id = 0;
1751 ChanCount existing_inputs;
1752 ChanCount existing_outputs;
1755 uint32_t control_id;
1757 count_existing_route_channels (existing_inputs, existing_outputs);
1759 control_id = ntracks() + nbusses() + 1;
1761 bool const use_number = (how_many != 1);
1763 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1764 error << "cannot find name for new audio bus" << endmsg;
1769 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1775 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1776 boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1779 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1781 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1782 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1783 input_channels, output_channels)
1789 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1790 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1791 input_channels, output_channels)
1796 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1800 route_group->add (bus);
1802 bus->set_remote_control_id (control_id);
1805 bus->add_internal_return ();
1807 ret.push_back (bus);
1811 catch (failed_constructor &err) {
1812 error << _("Session: could not create new audio route.") << endmsg;
1816 catch (AudioEngine::PortRegistrationFailure& pfe) {
1817 error << pfe.what() << endmsg;
1827 add_routes (ret, true);
1835 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1839 uint32_t control_id;
1841 uint32_t number = 0;
1843 if (!tree.read (template_path.c_str())) {
1847 XMLNode* node = tree.root();
1849 control_id = ntracks() + nbusses() + 1;
1853 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1855 std::string node_name = IO::name_from_state (*node_copy.children().front());
1857 /* generate a new name by adding a number to the end of the template name */
1858 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name), true)) {
1859 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1863 /* set IO children to use the new name */
1864 XMLNodeList const & children = node_copy.children ();
1865 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1866 if ((*i)->name() == IO::state_node_name) {
1867 IO::set_name_in_state (**i, name);
1871 Track::zero_diskstream_id_in_xml (node_copy);
1874 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1877 error << _("Session: cannot create track/bus from template description") << endmsg;
1881 if (boost::dynamic_pointer_cast<Track>(route)) {
1882 /* force input/output change signals so that the new diskstream
1883 picks up the configuration of the route. During session
1884 loading this normally happens in a different way.
1887 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1889 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1890 change.after = route->input()->n_ports();
1891 route->input()->changed (change, this);
1892 change.after = route->output()->n_ports();
1893 route->output()->changed (change, this);
1896 route->set_remote_control_id (control_id);
1899 ret.push_back (route);
1902 catch (failed_constructor &err) {
1903 error << _("Session: could not create new route from template") << endmsg;
1907 catch (AudioEngine::PortRegistrationFailure& pfe) {
1908 error << pfe.what() << endmsg;
1917 add_routes (ret, true);
1924 Session::add_routes (RouteList& new_routes, bool save)
1927 RCUWriter<RouteList> writer (routes);
1928 boost::shared_ptr<RouteList> r = writer.get_copy ();
1929 r->insert (r->end(), new_routes.begin(), new_routes.end());
1932 /* if there is no control out and we're not in the middle of loading,
1933 resort the graph here. if there is a control out, we will resort
1934 toward the end of this method. if we are in the middle of loading,
1935 we will resort when done.
1938 if (!_monitor_out && IO::connecting_legal) {
1939 resort_routes_using (r);
1943 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1945 boost::weak_ptr<Route> wpr (*x);
1946 boost::shared_ptr<Route> r (*x);
1948 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1949 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1950 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1951 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1952 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1953 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1954 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1956 if (r->is_master()) {
1960 if (r->is_monitor()) {
1964 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1966 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1967 track_playlist_changed (boost::weak_ptr<Track> (tr));
1968 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1970 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
1972 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
1977 if (_monitor_out && IO::connecting_legal) {
1979 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1980 if ((*x)->is_monitor()) {
1982 } else if ((*x)->is_master()) {
1985 (*x)->listen_via_monitor ();
1995 save_state (_current_snapshot_name);
1998 RouteAdded (new_routes); /* EMIT SIGNAL */
1999 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2003 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2005 boost::shared_ptr<RouteList> r = routes.reader ();
2006 boost::shared_ptr<Send> s;
2008 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2009 if ((s = (*i)->internal_send_for (dest)) != 0) {
2010 s->amp()->gain_control()->set_value (0.0);
2016 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2018 boost::shared_ptr<RouteList> r = routes.reader ();
2019 boost::shared_ptr<Send> s;
2021 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2022 if ((s = (*i)->internal_send_for (dest)) != 0) {
2023 s->amp()->gain_control()->set_value (1.0);
2029 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2031 boost::shared_ptr<RouteList> r = routes.reader ();
2032 boost::shared_ptr<Send> s;
2034 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2035 if ((s = (*i)->internal_send_for (dest)) != 0) {
2036 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2041 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2043 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2045 boost::shared_ptr<RouteList> r = routes.reader ();
2046 boost::shared_ptr<RouteList> t (new RouteList);
2048 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2049 if (include_buses || boost::dynamic_pointer_cast<Track>(*i)) {
2054 add_internal_sends (dest, p, t);
2058 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2060 if (dest->is_monitor() || dest->is_master()) {
2064 if (!dest->internal_return()) {
2065 dest->add_internal_return();
2068 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2070 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2074 (*i)->listen_via (dest, p);
2081 Session::remove_route (boost::shared_ptr<Route> route)
2083 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2087 route->set_solo (false, this);
2090 RCUWriter<RouteList> writer (routes);
2091 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2095 /* deleting the master out seems like a dumb
2096 idea, but its more of a UI policy issue
2100 if (route == _master_out) {
2101 _master_out = boost::shared_ptr<Route> ();
2104 if (route == _monitor_out) {
2106 /* cancel control outs for all routes */
2108 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2109 (*r)->drop_listen (_monitor_out);
2112 _monitor_out.reset ();
2115 /* writer goes out of scope, forces route list update */
2118 update_route_solo_state ();
2120 // We need to disconnect the route's inputs and outputs
2122 route->input()->disconnect (0);
2123 route->output()->disconnect (0);
2125 /* if the route had internal sends sending to it, remove them */
2126 if (route->internal_return()) {
2128 boost::shared_ptr<RouteList> r = routes.reader ();
2129 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2130 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2132 (*i)->remove_processor (s);
2137 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2138 if (mt && mt->step_editing()) {
2139 if (_step_editors > 0) {
2144 update_latency_compensation (false, false);
2147 /* Re-sort routes to remove the graph's current references to the one that is
2148 * going away, then flush old references out of the graph.
2152 route_graph->clear_other_chain ();
2154 /* get rid of it from the dead wood collection in the route list manager */
2156 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2160 /* try to cause everyone to drop their references */
2162 route->drop_references ();
2164 sync_order_keys (N_("session"));
2166 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2168 /* save the new state of the world */
2170 if (save_state (_current_snapshot_name)) {
2171 save_history (_current_snapshot_name);
2176 Session::route_mute_changed (void* /*src*/)
2182 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2184 boost::shared_ptr<Route> route = wpr.lock();
2186 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2190 if (route->listening_via_monitor ()) {
2192 if (Config->get_exclusive_solo()) {
2193 /* new listen: disable all other listen */
2194 boost::shared_ptr<RouteList> r = routes.reader ();
2195 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2196 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2199 (*i)->set_listen (false, this);
2205 } else if (_listen_cnt > 0) {
2210 update_route_solo_state ();
2213 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2215 boost::shared_ptr<Route> route = wpr.lock ();
2218 /* should not happen */
2219 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2223 bool send_changed = false;
2225 if (route->solo_isolated()) {
2226 if (_solo_isolated_cnt == 0) {
2227 send_changed = true;
2229 _solo_isolated_cnt++;
2230 } else if (_solo_isolated_cnt > 0) {
2231 _solo_isolated_cnt--;
2232 if (_solo_isolated_cnt == 0) {
2233 send_changed = true;
2238 IsolatedChanged (); /* EMIT SIGNAL */
2243 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2245 if (!self_solo_change) {
2246 // session doesn't care about changes to soloed-by-others
2250 if (solo_update_disabled) {
2255 boost::shared_ptr<Route> route = wpr.lock ();
2258 /* should not happen */
2259 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2263 boost::shared_ptr<RouteList> r = routes.reader ();
2266 if (route->self_soloed()) {
2272 if (delta == 1 && Config->get_exclusive_solo()) {
2273 /* new solo: disable all other solos */
2274 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2275 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2278 (*i)->set_solo (false, this);
2282 solo_update_disabled = true;
2284 RouteList uninvolved;
2286 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2287 bool via_sends_only;
2288 bool in_signal_flow;
2290 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2294 in_signal_flow = false;
2296 if ((*i)->feeds (route, &via_sends_only)) {
2297 if (!via_sends_only) {
2298 if (!route->soloed_by_others_upstream()) {
2299 (*i)->mod_solo_by_others_downstream (delta);
2301 in_signal_flow = true;
2305 if (route->feeds (*i, &via_sends_only)) {
2306 (*i)->mod_solo_by_others_upstream (delta);
2307 in_signal_flow = true;
2310 if (!in_signal_flow) {
2311 uninvolved.push_back (*i);
2315 solo_update_disabled = false;
2316 update_route_solo_state (r);
2318 /* now notify that the mute state of the routes not involved in the signal
2319 pathway of the just-solo-changed route may have altered.
2322 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2323 (*i)->mute_changed (this);
2326 SoloChanged (); /* EMIT SIGNAL */
2331 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2333 /* now figure out if anything that matters is soloed (or is "listening")*/
2335 bool something_soloed = false;
2336 uint32_t listeners = 0;
2337 uint32_t isolated = 0;
2340 r = routes.reader();
2343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2344 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2345 something_soloed = true;
2348 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2349 if (Config->get_solo_control_is_listen_control()) {
2352 (*i)->set_listen (false, this);
2356 if ((*i)->solo_isolated()) {
2361 if (something_soloed != _non_soloed_outs_muted) {
2362 _non_soloed_outs_muted = something_soloed;
2363 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2366 _listen_cnt = listeners;
2368 if (isolated != _solo_isolated_cnt) {
2369 _solo_isolated_cnt = isolated;
2370 IsolatedChanged (); /* EMIT SIGNAL */
2374 boost::shared_ptr<RouteList>
2375 Session::get_routes_with_internal_returns() const
2377 boost::shared_ptr<RouteList> r = routes.reader ();
2378 boost::shared_ptr<RouteList> rl (new RouteList);
2380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2381 if ((*i)->internal_return ()) {
2389 Session::io_name_is_legal (const std::string& name)
2391 boost::shared_ptr<RouteList> r = routes.reader ();
2393 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2394 if ((*i)->name() == name) {
2398 if ((*i)->has_io_processor_named (name)) {
2406 boost::shared_ptr<Route>
2407 Session::route_by_name (string name)
2409 boost::shared_ptr<RouteList> r = routes.reader ();
2411 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2412 if ((*i)->name() == name) {
2417 return boost::shared_ptr<Route> ((Route*) 0);
2420 boost::shared_ptr<Route>
2421 Session::route_by_id (PBD::ID id)
2423 boost::shared_ptr<RouteList> r = routes.reader ();
2425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2426 if ((*i)->id() == id) {
2431 return boost::shared_ptr<Route> ((Route*) 0);
2434 boost::shared_ptr<Route>
2435 Session::route_by_remote_id (uint32_t id)
2437 boost::shared_ptr<RouteList> r = routes.reader ();
2439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2440 if ((*i)->remote_control_id() == id) {
2445 return boost::shared_ptr<Route> ((Route*) 0);
2449 Session::playlist_region_added (boost::weak_ptr<Region> w)
2451 boost::shared_ptr<Region> r = w.lock ();
2456 /* These are the operations that are currently in progress... */
2457 list<GQuark> curr = _current_trans_quarks;
2460 /* ...and these are the operations during which we want to update
2461 the session range location markers.
2464 ops.push_back (Operations::capture);
2465 ops.push_back (Operations::paste);
2466 ops.push_back (Operations::duplicate_region);
2467 ops.push_back (Operations::insert_file);
2468 ops.push_back (Operations::insert_region);
2469 ops.push_back (Operations::drag_region_brush);
2470 ops.push_back (Operations::region_drag);
2471 ops.push_back (Operations::selection_grab);
2472 ops.push_back (Operations::region_fill);
2473 ops.push_back (Operations::fill_selection);
2474 ops.push_back (Operations::create_region);
2477 /* See if any of the current operations match the ones that we want */
2479 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2481 /* If so, update the session range markers */
2483 maybe_update_session_range (r->position (), r->last_frame ());
2487 /** Update the session range markers if a is before the current start or
2488 * b is after the current end.
2491 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2493 if (_state_of_the_state & Loading) {
2497 if (_session_range_location == 0) {
2499 add_session_range_location (a, b);
2503 if (a < _session_range_location->start()) {
2504 _session_range_location->set_start (a);
2507 if (b > _session_range_location->end()) {
2508 _session_range_location->set_end (b);
2514 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2516 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2517 maybe_update_session_range (i->to, i->to + i->length);
2522 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2524 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2525 maybe_update_session_range (i->from, i->to);
2529 /* Region management */
2531 boost::shared_ptr<Region>
2532 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2534 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2535 RegionFactory::RegionMap::const_iterator i;
2536 boost::shared_ptr<Region> region;
2538 Glib::Mutex::Lock lm (region_lock);
2540 for (i = regions.begin(); i != regions.end(); ++i) {
2544 if (region->whole_file()) {
2546 if (child->source_equivalent (region)) {
2552 return boost::shared_ptr<Region> ();
2556 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2558 set<boost::shared_ptr<Region> > relevant_regions;
2560 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2561 RegionFactory::get_regions_using_source (*s, relevant_regions);
2564 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2566 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2567 set<boost::shared_ptr<Region> >::iterator tmp;
2572 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2574 playlists->destroy_region (*r);
2575 RegionFactory::map_remove (*r);
2577 (*r)->drop_sources ();
2578 (*r)->drop_references ();
2580 cerr << "\tdone UC = " << (*r).use_count() << endl;
2582 relevant_regions.erase (r);
2587 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2590 Glib::Mutex::Lock ls (source_lock);
2591 /* remove from the main source list */
2592 sources.erase ((*s)->id());
2595 (*s)->mark_for_remove ();
2596 (*s)->drop_references ();
2605 Session::remove_last_capture ()
2607 list<boost::shared_ptr<Source> > srcs;
2609 boost::shared_ptr<RouteList> rl = routes.reader ();
2610 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2611 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2616 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2619 srcs.insert (srcs.end(), l.begin(), l.end());
2624 destroy_sources (srcs);
2626 save_state (_current_snapshot_name);
2631 /* Source Management */
2634 Session::add_source (boost::shared_ptr<Source> source)
2636 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2637 pair<SourceMap::iterator,bool> result;
2639 entry.first = source->id();
2640 entry.second = source;
2643 Glib::Mutex::Lock lm (source_lock);
2644 result = sources.insert (entry);
2647 if (result.second) {
2649 /* yay, new source */
2653 boost::shared_ptr<AudioFileSource> afs;
2655 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2656 if (Config->get_auto_analyse_audio()) {
2657 Analyser::queue_source_for_analysis (source, false);
2661 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
2666 Session::remove_source (boost::weak_ptr<Source> src)
2668 if (_state_of_the_state & Deletion) {
2672 SourceMap::iterator i;
2673 boost::shared_ptr<Source> source = src.lock();
2680 Glib::Mutex::Lock lm (source_lock);
2682 if ((i = sources.find (source->id())) != sources.end()) {
2687 if (!_state_of_the_state & InCleanup) {
2689 /* save state so we don't end up with a session file
2690 referring to non-existent sources.
2693 save_state (_current_snapshot_name);
2697 boost::shared_ptr<Source>
2698 Session::source_by_id (const PBD::ID& id)
2700 Glib::Mutex::Lock lm (source_lock);
2701 SourceMap::iterator i;
2702 boost::shared_ptr<Source> source;
2704 if ((i = sources.find (id)) != sources.end()) {
2711 boost::shared_ptr<Source>
2712 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2714 Glib::Mutex::Lock lm (source_lock);
2716 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2717 boost::shared_ptr<AudioFileSource> afs
2718 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2720 if (afs && afs->path() == path && chn == afs->channel()) {
2724 return boost::shared_ptr<Source>();
2728 Session::count_sources_by_origin (const string& path)
2731 Glib::Mutex::Lock lm (source_lock);
2733 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2734 boost::shared_ptr<FileSource> fs
2735 = boost::dynamic_pointer_cast<FileSource>(i->second);
2737 if (fs && fs->origin() == path) {
2747 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2750 string old_basename = PBD::basename_nosuffix (oldname);
2751 string new_legalized = legalize_for_path (newname);
2753 /* note: we know (or assume) the old path is already valid */
2757 /* destructive file sources have a name of the form:
2759 /path/to/Tnnnn-NAME(%[LR])?.wav
2761 the task here is to replace NAME with the new name.
2766 string::size_type dash;
2768 dir = Glib::path_get_dirname (path);
2769 path = Glib::path_get_basename (path);
2771 /* '-' is not a legal character for the NAME part of the path */
2773 if ((dash = path.find_last_of ('-')) == string::npos) {
2777 prefix = path.substr (0, dash);
2781 path += new_legalized;
2782 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2783 path = Glib::build_filename (dir, path);
2787 /* non-destructive file sources have a name of the form:
2789 /path/to/NAME-nnnnn(%[LR])?.ext
2791 the task here is to replace NAME with the new name.
2796 string::size_type dash;
2797 string::size_type postfix;
2799 dir = Glib::path_get_dirname (path);
2800 path = Glib::path_get_basename (path);
2802 /* '-' is not a legal character for the NAME part of the path */
2804 if ((dash = path.find_last_of ('-')) == string::npos) {
2808 suffix = path.substr (dash+1);
2810 // Suffix is now everything after the dash. Now we need to eliminate
2811 // the nnnnn part, which is done by either finding a '%' or a '.'
2813 postfix = suffix.find_last_of ("%");
2814 if (postfix == string::npos) {
2815 postfix = suffix.find_last_of ('.');
2818 if (postfix != string::npos) {
2819 suffix = suffix.substr (postfix);
2821 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2825 const uint32_t limit = 10000;
2826 char buf[PATH_MAX+1];
2828 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2830 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2832 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2833 path = Glib::build_filename (dir, buf);
2841 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2850 /** Return the full path (in some session directory) for a new within-session source.
2851 * \a name must be a session-unique name that does not contain slashes
2852 * (e.g. as returned by new_*_source_name)
2855 Session::new_source_path_from_name (DataType type, const string& name)
2857 assert(name.find("/") == string::npos);
2859 SessionDirectory sdir(get_best_session_directory_for_new_source());
2862 if (type == DataType::AUDIO) {
2863 p = sdir.sound_path();
2864 } else if (type == DataType::MIDI) {
2865 p = sdir.midi_path();
2867 error << "Unknown source type, unable to create file path" << endmsg;
2872 return p.to_string();
2876 Session::peak_path (string base) const
2878 sys::path peakfile_path(_session_dir->peak_path());
2879 peakfile_path /= base + peakfile_suffix;
2880 return peakfile_path.to_string();
2883 /** Return a unique name based on \a base for a new internal audio source */
2885 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2888 char buf[PATH_MAX+1];
2889 const uint32_t limit = 10000;
2891 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2894 legalized = legalize_for_path (base);
2896 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2897 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2899 vector<space_and_path>::iterator i;
2900 uint32_t existing = 0;
2902 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2907 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2908 cnt, legalized.c_str(), ext.c_str());
2909 } else if (nchan == 2) {
2911 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2912 cnt, legalized.c_str(), ext.c_str());
2914 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2915 cnt, legalized.c_str(), ext.c_str());
2917 } else if (nchan < 26) {
2918 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2919 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2921 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2922 cnt, legalized.c_str(), ext.c_str());
2928 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2929 } else if (nchan == 2) {
2931 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2933 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2935 } else if (nchan < 26) {
2936 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2938 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2942 SessionDirectory sdir((*i).path);
2944 string spath = sdir.sound_path().to_string();
2946 /* note that we search *without* the extension so that
2947 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2948 in the event that this new name is required for
2949 a file format change.
2952 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
2958 if (existing == 0) {
2963 error << string_compose(
2964 _("There are already %1 recordings for %2, which I consider too many."),
2965 limit, base) << endmsg;
2967 throw failed_constructor();
2971 return Glib::path_get_basename (buf);
2974 /** Create a new within-session audio source */
2975 boost::shared_ptr<AudioFileSource>
2976 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
2978 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2979 const string path = new_source_path_from_name(DataType::AUDIO, name);
2981 return boost::dynamic_pointer_cast<AudioFileSource> (
2982 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
2985 /** Return a unique name based on \a base for a new internal MIDI source */
2987 Session::new_midi_source_name (const string& base)
2990 char buf[PATH_MAX+1];
2991 const uint32_t limit = 10000;
2995 legalized = legalize_for_path (base);
2997 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2998 for (cnt = 1; cnt <= limit; ++cnt) {
3000 vector<space_and_path>::iterator i;
3001 uint32_t existing = 0;
3003 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3005 SessionDirectory sdir((*i).path);
3007 sys::path p = sdir.midi_path();
3010 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3012 if (sys::exists (buf)) {
3017 if (existing == 0) {
3022 error << string_compose(
3023 _("There are already %1 recordings for %2, which I consider too many."),
3024 limit, base) << endmsg;
3026 throw failed_constructor();
3030 return Glib::path_get_basename(buf);
3034 /** Create a new within-session MIDI source */
3035 boost::shared_ptr<MidiSource>
3036 Session::create_midi_source_for_session (Track* track, string const & n)
3038 /* try to use the existing write source for the track, to keep numbering sane
3042 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3046 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3049 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3050 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3054 const string name = new_midi_source_name (n);
3055 const string path = new_source_path_from_name (DataType::MIDI, name);
3057 return boost::dynamic_pointer_cast<SMFSource> (
3058 SourceFactory::createWritable (
3059 DataType::MIDI, *this, path, string(), false, frame_rate()));
3064 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3066 if (playlist->hidden()) {
3070 playlists->add (playlist);
3073 playlist->release();
3080 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3082 if (_state_of_the_state & Deletion) {
3086 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3092 playlists->remove (playlist);
3098 Session::set_audition (boost::shared_ptr<Region> r)
3100 pending_audition_region = r;
3101 add_post_transport_work (PostTransportAudition);
3102 _butler->schedule_transport_work ();
3106 Session::audition_playlist ()
3108 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3109 ev->region.reset ();
3114 Session::non_realtime_set_audition ()
3116 if (!pending_audition_region) {
3117 auditioner->audition_current_playlist ();
3119 auditioner->audition_region (pending_audition_region);
3120 pending_audition_region.reset ();
3122 AuditionActive (true); /* EMIT SIGNAL */
3126 Session::audition_region (boost::shared_ptr<Region> r)
3128 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3134 Session::cancel_audition ()
3136 if (auditioner->auditioning()) {
3137 auditioner->cancel_audition ();
3138 AuditionActive (false); /* EMIT SIGNAL */
3143 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3145 if (a->is_monitor()) {
3148 if (b->is_monitor()) {
3151 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3155 Session::is_auditioning () const
3157 /* can be called before we have an auditioner object */
3159 return auditioner->auditioning();
3166 Session::graph_reordered ()
3168 /* don't do this stuff if we are setting up connections
3169 from a set_state() call or creating new tracks. Ditto for deletion.
3172 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3176 /* every track/bus asked for this to be handled but it was deferred because
3177 we were connecting. do it now.
3180 request_input_change_handling ();
3184 /* force all diskstreams to update their capture offset values to
3185 reflect any changes in latencies within the graph.
3188 boost::shared_ptr<RouteList> rl = routes.reader ();
3189 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3190 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3192 tr->set_capture_offset ();
3198 Session::available_capture_duration ()
3200 float sample_bytes_on_disk = 4.0; // keep gcc happy
3202 switch (config.get_native_file_data_format()) {
3204 sample_bytes_on_disk = 4.0;
3208 sample_bytes_on_disk = 3.0;
3212 sample_bytes_on_disk = 2.0;
3216 /* impossible, but keep some gcc versions happy */
3217 fatal << string_compose (_("programming error: %1"),
3218 X_("illegal native file data format"))
3223 double scale = 4096.0 / sample_bytes_on_disk;
3225 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3226 return max_framecnt;
3229 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3233 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3236 RCUWriter<BundleList> writer (_bundles);
3237 boost::shared_ptr<BundleList> b = writer.get_copy ();
3238 b->push_back (bundle);
3241 BundleAdded (bundle); /* EMIT SIGNAL */
3247 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3249 bool removed = false;
3252 RCUWriter<BundleList> writer (_bundles);
3253 boost::shared_ptr<BundleList> b = writer.get_copy ();
3254 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3256 if (i != b->end()) {
3263 BundleRemoved (bundle); /* EMIT SIGNAL */
3269 boost::shared_ptr<Bundle>
3270 Session::bundle_by_name (string name) const
3272 boost::shared_ptr<BundleList> b = _bundles.reader ();
3274 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3275 if ((*i)->name() == name) {
3280 return boost::shared_ptr<Bundle> ();
3284 Session::tempo_map_changed (const PropertyChange&)
3288 playlists->update_after_tempo_map_change ();
3290 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3296 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3298 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3299 (*i)->recompute_frames_from_bbt ();
3303 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3304 * the given count with the current block size.
3307 Session::ensure_buffers (ChanCount howmany)
3309 BufferManager::ensure_buffers (howmany);
3313 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3315 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3316 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3321 Session::next_insert_id ()
3323 /* this doesn't really loop forever. just think about it */
3326 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3327 if (!insert_bitset[n]) {
3328 insert_bitset[n] = true;
3334 /* none available, so resize and try again */
3336 insert_bitset.resize (insert_bitset.size() + 16, false);
3341 Session::next_send_id ()
3343 /* this doesn't really loop forever. just think about it */
3346 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3347 if (!send_bitset[n]) {
3348 send_bitset[n] = true;
3354 /* none available, so resize and try again */
3356 send_bitset.resize (send_bitset.size() + 16, false);
3361 Session::next_return_id ()
3363 /* this doesn't really loop forever. just think about it */
3366 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3367 if (!return_bitset[n]) {
3368 return_bitset[n] = true;
3374 /* none available, so resize and try again */
3376 return_bitset.resize (return_bitset.size() + 16, false);
3381 Session::mark_send_id (uint32_t id)
3383 if (id >= send_bitset.size()) {
3384 send_bitset.resize (id+16, false);
3386 if (send_bitset[id]) {
3387 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3389 send_bitset[id] = true;
3393 Session::mark_return_id (uint32_t id)
3395 if (id >= return_bitset.size()) {
3396 return_bitset.resize (id+16, false);
3398 if (return_bitset[id]) {
3399 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3401 return_bitset[id] = true;
3405 Session::mark_insert_id (uint32_t id)
3407 if (id >= insert_bitset.size()) {
3408 insert_bitset.resize (id+16, false);
3410 if (insert_bitset[id]) {
3411 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3413 insert_bitset[id] = true;
3417 Session::unmark_send_id (uint32_t id)
3419 if (id < send_bitset.size()) {
3420 send_bitset[id] = false;
3425 Session::unmark_return_id (uint32_t id)
3427 if (id < return_bitset.size()) {
3428 return_bitset[id] = false;
3433 Session::unmark_insert_id (uint32_t id)
3435 if (id < insert_bitset.size()) {
3436 insert_bitset[id] = false;
3441 /* Named Selection management */
3443 boost::shared_ptr<NamedSelection>
3444 Session::named_selection_by_name (string name)
3446 Glib::Mutex::Lock lm (named_selection_lock);
3447 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3448 if ((*i)->name == name) {
3452 return boost::shared_ptr<NamedSelection>();
3456 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3459 Glib::Mutex::Lock lm (named_selection_lock);
3460 named_selections.insert (named_selections.begin(), named_selection);
3465 NamedSelectionAdded (); /* EMIT SIGNAL */
3469 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3471 bool removed = false;
3474 Glib::Mutex::Lock lm (named_selection_lock);
3476 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3478 if (i != named_selections.end()) {
3479 named_selections.erase (i);
3486 NamedSelectionRemoved (); /* EMIT SIGNAL */
3491 Session::reset_native_file_format ()
3493 boost::shared_ptr<RouteList> rl = routes.reader ();
3494 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3495 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3497 /* don't save state as we do this, there's no point
3500 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3501 tr->reset_write_sources (false);
3502 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3508 Session::route_name_unique (string n) const
3510 boost::shared_ptr<RouteList> r = routes.reader ();
3512 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3513 if ((*i)->name() == n) {
3522 Session::route_name_internal (string n) const
3524 if (auditioner && auditioner->name() == n) {
3528 if (_click_io && _click_io->name() == n) {
3536 Session::freeze_all (InterThreadInfo& itt)
3538 boost::shared_ptr<RouteList> r = routes.reader ();
3540 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3542 boost::shared_ptr<Track> t;
3544 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3545 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3555 boost::shared_ptr<Region>
3556 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3557 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3558 InterThreadInfo& itt, bool enable_processing)
3560 boost::shared_ptr<Region> result;
3561 boost::shared_ptr<Playlist> playlist;
3562 boost::shared_ptr<AudioFileSource> fsource;
3564 char buf[PATH_MAX+1];
3565 ChanCount diskstream_channels (track.n_channels());
3566 framepos_t position;
3567 framecnt_t this_chunk;
3570 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3571 const string sound_dir = sdir.sound_path().to_string();
3572 framepos_t len = end - start;
3573 bool need_block_size_reset = false;
3575 ChanCount const max_proc = track.max_processor_streams ();
3578 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3579 end, start) << endmsg;
3583 const framecnt_t chunk_size = (256 * 1024)/4;
3585 // block all process callback handling
3587 block_processing ();
3589 /* call tree *MUST* hold route_lock */
3591 if ((playlist = track.playlist()) == 0) {
3595 /* external redirects will be a problem */
3597 if (track.has_external_redirects()) {
3601 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3603 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3605 for (x = 0; x < 99999; ++x) {
3606 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());
3607 if (access (buf, F_OK) != 0) {
3613 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3618 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3619 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3622 catch (failed_constructor& err) {
3623 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3627 srcs.push_back (fsource);
3630 /* tell redirects that care that we are about to use a much larger blocksize */
3632 need_block_size_reset = true;
3633 track.set_block_size (chunk_size);
3635 /* XXX need to flush all redirects */
3640 /* create a set of reasonably-sized buffers */
3641 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
3642 buffers.set_count (max_proc);
3644 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3645 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3647 afs->prepare_for_peakfile_writes ();
3650 while (to_do && !itt.cancel) {
3652 this_chunk = min (to_do, chunk_size);
3654 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3659 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3660 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3663 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3669 start += this_chunk;
3670 to_do -= this_chunk;
3672 itt.progress = (float) (1.0 - ((double) to_do / len));
3681 xnow = localtime (&now);
3683 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3684 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3687 afs->update_header (position, *xnow, now);
3688 afs->flush_header ();
3692 /* construct a region to represent the bounced material */
3696 plist.add (Properties::start, 0);
3697 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3698 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3700 result = RegionFactory::create (srcs, plist);
3706 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3707 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3710 afs->mark_for_remove ();
3713 (*src)->drop_references ();
3717 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3718 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3721 afs->done_with_peakfile_writes ();
3726 if (need_block_size_reset) {
3727 track.set_block_size (get_block_size());
3730 unblock_processing ();
3736 Session::gain_automation_buffer() const
3738 return ProcessThread::gain_automation_buffer ();
3742 Session::pan_automation_buffer() const
3744 return ProcessThread::pan_automation_buffer ();
3748 Session::get_silent_buffers (ChanCount count)
3750 return ProcessThread::get_silent_buffers (count);
3754 Session::get_scratch_buffers (ChanCount count)
3756 return ProcessThread::get_scratch_buffers (count);
3760 Session::get_mix_buffers (ChanCount count)
3762 return ProcessThread::get_mix_buffers (count);
3766 Session::ntracks () const
3769 boost::shared_ptr<RouteList> r = routes.reader ();
3771 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3772 if (boost::dynamic_pointer_cast<Track> (*i)) {
3781 Session::nbusses () const
3784 boost::shared_ptr<RouteList> r = routes.reader ();
3786 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3787 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3796 Session::add_automation_list(AutomationList *al)
3798 automation_lists[al->id()] = al;
3802 Session::sync_order_keys (std::string const & base)
3804 if (deletion_in_progress()) {
3808 if (!Config->get_sync_all_route_ordering()) {
3809 /* leave order keys as they are */
3813 boost::shared_ptr<RouteList> r = routes.reader ();
3815 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3816 (*i)->sync_order_keys (base);
3819 Route::SyncOrderKeys (base); // EMIT SIGNAL
3821 /* this might not do anything */
3823 set_remote_control_ids ();
3826 /** @return true if there is at least one record-enabled track, otherwise false */
3828 Session::have_rec_enabled_track () const
3830 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3833 /** Update the state of our rec-enabled tracks flag */
3835 Session::update_have_rec_enabled_track ()
3837 boost::shared_ptr<RouteList> rl = routes.reader ();
3838 RouteList::iterator i = rl->begin();
3839 while (i != rl->end ()) {
3841 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3842 if (tr && tr->record_enabled ()) {
3849 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3851 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3853 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3854 RecordStateChanged (); /* EMIT SIGNAL */
3859 Session::listen_position_changed ()
3861 boost::shared_ptr<RouteList> r = routes.reader ();
3863 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3864 (*i)->listen_position_changed ();
3869 Session::solo_control_mode_changed ()
3871 /* cancel all solo or all listen when solo control mode changes */
3874 set_solo (get_routes(), false);
3875 } else if (listening()) {
3876 set_listen (get_routes(), false);
3880 /** Called when anything about any of our route groups changes (membership, state etc.) */
3882 Session::route_group_changed ()
3884 RouteGroupChanged (); /* EMIT SIGNAL */
3888 Session::get_available_sync_options () const
3890 vector<SyncSource> ret;
3892 ret.push_back (JACK);
3893 ret.push_back (MTC);
3894 ret.push_back (MIDIClock);
3899 boost::shared_ptr<RouteList>
3900 Session::get_routes_with_regions_at (framepos_t const p) const
3902 boost::shared_ptr<RouteList> r = routes.reader ();
3903 boost::shared_ptr<RouteList> rl (new RouteList);
3905 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3906 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3911 boost::shared_ptr<Playlist> pl = tr->playlist ();
3916 if (pl->has_region_at (p)) {
3925 Session::goto_end ()
3927 if (_session_range_location) {
3928 request_locate (_session_range_location->end(), false);
3930 request_locate (0, false);
3935 Session::goto_start ()
3937 if (_session_range_location) {
3938 request_locate (_session_range_location->start(), false);
3940 request_locate (0, false);
3945 Session::current_start_frame () const
3947 return _session_range_location ? _session_range_location->start() : 0;
3951 Session::current_end_frame () const
3953 return _session_range_location ? _session_range_location->end() : 0;
3957 Session::add_session_range_location (framepos_t start, framepos_t end)
3959 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
3960 _locations->add (_session_range_location);
3963 /** Called when one of our routes' order keys has changed */
3965 Session::route_order_key_changed ()
3967 RouteOrderKeyChanged (); /* EMIT SIGNAL */
3971 Session::step_edit_status_change (bool yn)
3977 send = (_step_editors == 0);
3982 send = (_step_editors == 1);
3985 if (_step_editors > 0) {
3991 StepEditStatusChange (val);
3997 Session::start_time_changed (framepos_t old)
3999 /* Update the auto loop range to match the session range
4000 (unless the auto loop range has been changed by the user)
4003 Location* s = _locations->session_range_location ();
4008 Location* l = _locations->auto_loop_location ();
4010 if (l->start() == old) {
4011 l->set_start (s->start(), true);
4016 Session::end_time_changed (framepos_t old)
4018 /* Update the auto loop range to match the session range
4019 (unless the auto loop range has been changed by the user)
4022 Location* s = _locations->session_range_location ();
4027 Location* l = _locations->auto_loop_location ();
4029 if (l->end() == old) {
4030 l->set_end (s->end(), true);
4035 Session::source_search_path (DataType type) const
4039 if (session_dirs.size() == 1) {
4041 case DataType::AUDIO:
4042 search_path = _session_dir->sound_path().to_string();
4044 case DataType::MIDI:
4045 search_path = _session_dir->midi_path().to_string();
4049 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4050 SessionDirectory sdir (i->path);
4051 if (!search_path.empty()) {
4055 case DataType::AUDIO:
4056 search_path += sdir.sound_path().to_string();
4058 case DataType::MIDI:
4059 search_path += sdir.midi_path().to_string();
4065 /* now add user-specified locations
4068 vector<string> dirs;
4071 case DataType::AUDIO:
4072 split (config.get_audio_search_path (), dirs, ':');
4074 case DataType::MIDI:
4075 split (config.get_midi_search_path (), dirs, ':');
4079 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4089 Session::ensure_search_path_includes (const string& path, DataType type)
4092 vector<string> dirs;
4099 case DataType::AUDIO:
4100 search_path = config.get_audio_search_path ();
4102 case DataType::MIDI:
4103 search_path = config.get_midi_search_path ();
4107 split (search_path, dirs, ':');
4109 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4115 if (!search_path.empty()) {
4119 search_path += path;
4122 case DataType::AUDIO:
4123 config.set_audio_search_path (search_path);
4125 case DataType::MIDI:
4126 config.set_midi_search_path (search_path);
4131 boost::shared_ptr<Speakers>
4132 Session::get_speakers()
4138 Session::unknown_processors () const
4142 boost::shared_ptr<RouteList> r = routes.reader ();
4143 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4144 list<string> t = (*i)->unknown_processors ();
4145 copy (t.begin(), t.end(), back_inserter (p));
4155 Session::update_latency (bool playback)
4157 DEBUG_TRACE (DEBUG::Latency, string_compose ("\n\nJACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
4159 boost::shared_ptr<RouteList> r = routes.reader ();
4160 framecnt_t max_latency = 0;
4163 /* reverse the list so that we work backwards from the last route to run to the first */
4164 reverse (r->begin(), r->end());
4167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4168 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
4172 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
4174 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4175 (*i)->set_public_port_latencies (max_latency, playback);