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/vbap_speakers.h"
104 #include "midi++/port.h"
105 #include "midi++/mmc.h"
106 #include "midi++/manager.h"
111 using namespace ARDOUR;
113 using boost::shared_ptr;
114 using boost::weak_ptr;
116 bool Session::_disable_all_loaded_plugins = false;
118 PBD::Signal1<void,std::string> Session::Dialog;
119 PBD::Signal0<int> Session::AskAboutPendingState;
120 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
121 PBD::Signal0<void> Session::SendFeedback;
122 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
124 PBD::Signal0<void> Session::TimecodeOffsetChanged;
125 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
126 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
127 PBD::Signal0<void> Session::AutoBindingOn;
128 PBD::Signal0<void> Session::AutoBindingOff;
129 PBD::Signal2<void,std::string, std::string> Session::Exported;
130 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
131 PBD::Signal0<void> Session::Quit;
133 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
134 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
136 Session::Session (AudioEngine &eng,
137 const string& fullpath,
138 const string& snapshot_name,
139 BusProfile* bus_profile,
143 , _target_transport_speed (0.0)
144 , _requested_return_frame (-1)
145 , _session_dir (new SessionDirectory(fullpath))
147 , _state_of_the_state (Clean)
148 , _butler (new Butler (*this))
149 , _post_transport_work (0)
150 , _send_timecode_update (false)
151 , _all_route_group (new RouteGroup (*this, "all"))
152 , route_graph (new Graph(*this))
153 , routes (new RouteList)
154 , _total_free_4k_blocks (0)
155 , _bundles (new BundleList)
156 , _bundle_xml_node (0)
157 , _click_io ((IO*) 0)
159 , click_emphasis_data (0)
161 , _metadata (new SessionMetadata())
162 , _have_rec_enabled_track (false)
163 , _suspend_timecode_transmission (0)
165 _locations = new Locations (*this);
167 playlists.reset (new SessionPlaylists);
169 _all_route_group->set_active (true, this);
171 interpolation.add_channel_to (0, 0);
173 if (!eng.connected()) {
174 throw failed_constructor();
177 n_physical_outputs = _engine.n_physical_outputs ();
178 n_physical_inputs = _engine.n_physical_inputs ();
180 first_stage_init (fullpath, snapshot_name);
182 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
185 if (create (mix_template, bus_profile)) {
187 throw failed_constructor ();
191 if (second_stage_init ()) {
193 throw failed_constructor ();
196 store_recent_sessions(_name, _path);
198 bool was_dirty = dirty();
200 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
202 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
203 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
206 DirtyChanged (); /* EMIT SIGNAL */
209 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
210 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
223 vector<void*> debug_pointers;
225 /* if we got to here, leaving pending capture state around
229 remove_pending_capture_state ();
231 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
233 _engine.remove_session ();
235 /* clear history so that no references to objects are held any more */
239 /* clear state tree so that no references to objects are held any more */
243 /* remove all stubfiles that might still be lurking */
245 cleanup_stubfiles ();
247 /* reset dynamic state version back to default */
249 Stateful::loading_state_version = 0;
251 _butler->drop_references ();
253 delete midi_control_ui;
254 delete _all_route_group;
256 if (click_data != default_click) {
257 delete [] click_data;
260 if (click_emphasis_data != default_click_emphasis) {
261 delete [] click_emphasis_data;
266 /* clear out any pending dead wood from RCU managed objects */
271 AudioDiskstream::free_working_buffers();
273 /* tell everyone who is still standing that we're about to die */
276 /* tell everyone to drop references and delete objects as we go */
278 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
279 named_selections.clear ();
281 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
282 RegionFactory::delete_all_regions ();
284 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
286 /* reset these three references to special routes before we do the usual route delete thing */
289 _master_out.reset ();
290 _monitor_out.reset ();
293 RCUWriter<RouteList> writer (routes);
294 boost::shared_ptr<RouteList> r = writer.get_copy ();
296 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
297 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
298 (*i)->drop_references ();
302 /* writer goes out of scope and updates master */
306 boost::shared_ptr<RouteList> r = routes.reader ();
308 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
309 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
310 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
311 i->second->drop_references ();
316 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
317 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
322 Crossfade::set_buffer_size (0);
324 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
327 boost_debug_list_ptrs ();
332 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
336 Session::set_worst_io_latencies ()
338 _worst_output_latency = 0;
339 _worst_input_latency = 0;
341 if (!_engine.connected()) {
345 boost::shared_ptr<RouteList> r = routes.reader ();
347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
348 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
349 _worst_input_latency = max (_worst_input_latency, (*i)->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"));
439 set_worst_io_latencies ();
442 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
445 BootMessage (_("Set up standard connections"));
447 vector<string> inputs[DataType::num_types];
448 vector<string> outputs[DataType::num_types];
449 for (uint32_t i = 0; i < DataType::num_types; ++i) {
450 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
451 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
454 /* Create a set of Bundle objects that map
455 to the physical I/O currently available. We create both
456 mono and stereo bundles, so that the common cases of mono
457 and stereo tracks get bundles to put in their mixer strip
458 in / out menus. There may be a nicer way of achieving that;
459 it doesn't really scale that well to higher channel counts
462 /* mono output bundles */
464 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
466 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
468 shared_ptr<Bundle> c (new Bundle (buf, true));
469 c->add_channel (_("mono"), DataType::AUDIO);
470 c->set_port (0, outputs[DataType::AUDIO][np]);
475 /* stereo output bundles */
477 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
478 if (np + 1 < outputs[DataType::AUDIO].size()) {
480 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
481 shared_ptr<Bundle> c (new Bundle (buf, true));
482 c->add_channel (_("L"), DataType::AUDIO);
483 c->set_port (0, outputs[DataType::AUDIO][np]);
484 c->add_channel (_("R"), DataType::AUDIO);
485 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
491 /* mono input bundles */
493 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
495 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
497 shared_ptr<Bundle> c (new Bundle (buf, false));
498 c->add_channel (_("mono"), DataType::AUDIO);
499 c->set_port (0, inputs[DataType::AUDIO][np]);
504 /* stereo input bundles */
506 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
507 if (np + 1 < inputs[DataType::AUDIO].size()) {
509 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
511 shared_ptr<Bundle> c (new Bundle (buf, false));
512 c->add_channel (_("L"), DataType::AUDIO);
513 c->set_port (0, inputs[DataType::AUDIO][np]);
514 c->add_channel (_("R"), DataType::AUDIO);
515 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
521 /* MIDI input bundles */
523 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
524 string n = inputs[DataType::MIDI][np];
525 boost::erase_first (n, X_("alsa_pcm:"));
527 shared_ptr<Bundle> c (new Bundle (n, false));
528 c->add_channel ("", DataType::MIDI);
529 c->set_port (0, inputs[DataType::MIDI][np]);
533 /* MIDI output bundles */
535 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
536 string n = outputs[DataType::MIDI][np];
537 boost::erase_first (n, X_("alsa_pcm:"));
539 shared_ptr<Bundle> c (new Bundle (n, true));
540 c->add_channel ("", DataType::MIDI);
541 c->set_port (0, outputs[DataType::MIDI][np]);
545 BootMessage (_("Setup signal flow and plugins"));
549 if (_is_new && !no_auto_connect()) {
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 /* catch up on send+insert cnts */
654 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
656 /* hook us up to the engine */
658 BootMessage (_("Connect to engine"));
660 _engine.set_session (this);
664 Session::hookup_io ()
666 /* stop graph reordering notifications from
667 causing resorts, etc.
670 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
675 /* we delay creating the auditioner till now because
676 it makes its own connections to ports.
680 Auditioner* a = new Auditioner (*this);
683 throw failed_constructor();
685 a->use_new_diskstream ();
686 auditioner.reset (a);
689 catch (failed_constructor& err) {
690 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
694 /* load bundles, which we may have postponed earlier on */
695 if (_bundle_xml_node) {
696 load_bundles (*_bundle_xml_node);
697 delete _bundle_xml_node;
700 /* Tell all IO objects to connect themselves together */
702 IO::enable_connecting ();
703 MIDI::Port::MakeConnections ();
705 /* Now reset all panners */
707 Delivery::reset_panners ();
709 /* Connect tracks to monitor/listen bus if there is one.
710 Note that in an existing session, the internal sends will
711 already exist, but we want the routes to notice that
712 they connect to the control out specifically.
716 boost::shared_ptr<RouteList> r = routes.reader ();
717 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
719 if ((*x)->is_monitor()) {
723 } else if ((*x)->is_master()) {
729 (*x)->listen_via (_monitor_out,
730 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
736 /* Anyone who cares about input state, wake up and do something */
738 IOConnectionsComplete (); /* EMIT SIGNAL */
740 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
742 /* now handle the whole enchilada as if it was one
748 /* update the full solo state, which can't be
749 correctly determined on a per-route basis, but
750 needs the global overview that only the session
754 update_route_solo_state ();
758 Session::playlist_length_changed ()
760 update_session_range_location_marker ();
764 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
766 boost::shared_ptr<Track> track = wp.lock ();
771 boost::shared_ptr<Playlist> playlist;
773 if ((playlist = track->playlist()) != 0) {
774 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
777 update_session_range_location_marker ();
781 Session::record_enabling_legal () const
783 /* this used to be in here, but survey says.... we don't need to restrict it */
784 // if (record_status() == Recording) {
788 if (Config->get_all_safe()) {
795 Session::reset_input_monitor_state ()
797 if (transport_rolling()) {
799 boost::shared_ptr<RouteList> rl = routes.reader ();
800 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
801 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
802 if (tr && tr->record_enabled ()) {
803 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
804 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
810 boost::shared_ptr<RouteList> rl = routes.reader ();
811 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
812 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
813 if (tr && tr->record_enabled ()) {
814 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
815 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
822 Session::auto_punch_start_changed (Location* location)
824 replace_event (SessionEvent::PunchIn, location->start());
826 if (get_record_enabled() && config.get_punch_in()) {
827 /* capture start has been changed, so save new pending state */
828 save_state ("", true);
833 Session::auto_punch_end_changed (Location* location)
835 nframes_t when_to_stop = location->end();
836 // when_to_stop += _worst_output_latency + _worst_input_latency;
837 replace_event (SessionEvent::PunchOut, when_to_stop);
841 Session::auto_punch_changed (Location* location)
843 nframes_t when_to_stop = location->end();
845 replace_event (SessionEvent::PunchIn, location->start());
846 //when_to_stop += _worst_output_latency + _worst_input_latency;
847 replace_event (SessionEvent::PunchOut, when_to_stop);
851 Session::auto_loop_changed (Location* location)
853 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
855 if (transport_rolling() && play_loop) {
858 // if (_transport_frame > location->end()) {
860 if (_transport_frame < location->start() || _transport_frame > location->end()) {
861 // relocate to beginning of loop
862 clear_events (SessionEvent::LocateRoll);
864 request_locate (location->start(), true);
867 else if (Config->get_seamless_loop() && !loop_changing) {
869 // schedule a locate-roll to refill the diskstreams at the
871 loop_changing = true;
873 if (location->end() > last_loopend) {
874 clear_events (SessionEvent::LocateRoll);
875 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
882 last_loopend = location->end();
886 Session::set_auto_punch_location (Location* location)
890 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
891 punch_connections.drop_connections();
892 existing->set_auto_punch (false, this);
893 remove_event (existing->start(), SessionEvent::PunchIn);
894 clear_events (SessionEvent::PunchOut);
895 auto_punch_location_changed (0);
904 if (location->end() <= location->start()) {
905 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
909 punch_connections.drop_connections ();
911 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
912 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
913 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
915 location->set_auto_punch (true, this);
917 auto_punch_changed (location);
919 auto_punch_location_changed (location);
923 Session::set_auto_loop_location (Location* location)
927 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
928 loop_connections.drop_connections ();
929 existing->set_auto_loop (false, this);
930 remove_event (existing->end(), SessionEvent::AutoLoop);
931 auto_loop_location_changed (0);
940 if (location->end() <= location->start()) {
941 error << _("Session: you can't use a mark for auto loop") << endmsg;
945 last_loopend = location->end();
947 loop_connections.drop_connections ();
949 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
950 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
951 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
953 location->set_auto_loop (true, this);
955 /* take care of our stuff first */
957 auto_loop_changed (location);
959 /* now tell everyone else */
961 auto_loop_location_changed (location);
965 Session::locations_added (Location *)
971 Session::locations_changed ()
973 _locations->apply (*this, &Session::handle_locations_changed);
977 Session::handle_locations_changed (Locations::LocationList& locations)
979 Locations::LocationList::iterator i;
981 bool set_loop = false;
982 bool set_punch = false;
984 for (i = locations.begin(); i != locations.end(); ++i) {
988 if (location->is_auto_punch()) {
989 set_auto_punch_location (location);
992 if (location->is_auto_loop()) {
993 set_auto_loop_location (location);
997 if (location->is_session_range()) {
998 _session_range_location = location;
1003 set_auto_loop_location (0);
1006 set_auto_punch_location (0);
1013 Session::enable_record ()
1016 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1018 if (rs == Recording) {
1022 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1024 _last_record_location = _transport_frame;
1025 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1027 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1029 boost::shared_ptr<RouteList> rl = routes.reader ();
1030 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1031 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1032 if (tr && tr->record_enabled ()) {
1033 tr->monitor_input (true);
1038 RecordStateChanged ();
1045 Session::disable_record (bool rt_context, bool force)
1049 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1051 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1052 g_atomic_int_set (&_record_status, Disabled);
1053 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1055 if (rs == Recording) {
1056 g_atomic_int_set (&_record_status, Enabled);
1060 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1062 boost::shared_ptr<RouteList> rl = routes.reader ();
1063 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1064 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1065 if (tr && tr->record_enabled ()) {
1066 tr->monitor_input (false);
1071 RecordStateChanged (); /* emit signal */
1074 remove_pending_capture_state ();
1080 Session::step_back_from_record ()
1082 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1084 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1085 boost::shared_ptr<RouteList> rl = routes.reader ();
1086 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1087 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1088 if (tr && tr->record_enabled ()) {
1089 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1090 tr->monitor_input (false);
1098 Session::maybe_enable_record ()
1100 if (_step_editors > 0) {
1104 g_atomic_int_set (&_record_status, Enabled);
1106 /* This function is currently called from somewhere other than an RT thread.
1107 This save_state() call therefore doesn't impact anything. Doing it here
1108 means that we save pending state of which sources the next record will use,
1109 which gives us some chance of recovering from a crash during the record.
1112 save_state ("", true);
1114 if (_transport_speed) {
1115 if (!config.get_punch_in()) {
1119 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1120 RecordStateChanged (); /* EMIT SIGNAL */
1127 Session::audible_frame () const
1133 /* the first of these two possible settings for "offset"
1134 mean that the audible frame is stationary until
1135 audio emerges from the latency compensation
1138 the second means that the audible frame is stationary
1139 until audio would emerge from a physical port
1140 in the absence of any plugin latency compensation
1143 offset = _worst_output_latency;
1145 if (offset > current_block_size) {
1146 offset -= current_block_size;
1148 /* XXX is this correct? if we have no external
1149 physical connections and everything is internal
1150 then surely this is zero? still, how
1151 likely is that anyway?
1153 offset = current_block_size;
1156 if (synced_to_jack()) {
1157 tf = _engine.transport_frame();
1159 tf = _transport_frame;
1164 if (!non_realtime_work_pending()) {
1168 /* Check to see if we have passed the first guaranteed
1169 audible frame past our last start position. if not,
1170 return that last start point because in terms
1171 of audible frames, we have not moved yet.
1173 `Start position' in this context means the time we last
1174 either started or changed transport direction.
1177 if (_transport_speed > 0.0f) {
1179 if (!play_loop || !have_looped) {
1180 if (tf < _last_roll_or_reversal_location + offset) {
1181 return _last_roll_or_reversal_location;
1189 } else if (_transport_speed < 0.0f) {
1191 /* XXX wot? no backward looping? */
1193 if (tf > _last_roll_or_reversal_location - offset) {
1194 return _last_roll_or_reversal_location;
1206 Session::set_frame_rate (nframes_t frames_per_second)
1208 /** \fn void Session::set_frame_size(nframes_t)
1209 the AudioEngine object that calls this guarantees
1210 that it will not be called while we are also in
1211 ::process(). Its fine to do things that block
1215 _base_frame_rate = frames_per_second;
1219 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1223 // XXX we need some equivalent to this, somehow
1224 // SndFileSource::setup_standard_crossfades (frames_per_second);
1228 /* XXX need to reset/reinstantiate all LADSPA plugins */
1232 Session::set_block_size (nframes_t nframes)
1234 /* the AudioEngine guarantees
1235 that it will not be called while we are also in
1236 ::process(). It is therefore fine to do things that block
1241 current_block_size = nframes;
1245 boost::shared_ptr<RouteList> r = routes.reader ();
1247 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1248 (*i)->set_block_size (nframes);
1251 boost::shared_ptr<RouteList> rl = routes.reader ();
1252 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1253 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1255 tr->set_block_size (nframes);
1259 set_worst_io_latencies ();
1264 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1267 nframes_t fade_frames;
1269 /* Don't allow fade of less 1 frame */
1271 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1278 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1282 default_fade_msecs = fade_msecs;
1283 default_fade_steepness = steepness;
1286 // jlc, WTF is this!
1287 Glib::RWLock::ReaderLock lm (route_lock);
1288 AudioRegion::set_default_fade (steepness, fade_frames);
1293 /* XXX have to do this at some point */
1294 /* foreach region using default fade, reset, then
1295 refill_all_diskstream_buffers ();
1300 struct RouteSorter {
1301 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1302 if (r2->feeds (r1)) {
1304 } else if (r1->feeds (r2)) {
1307 if (r1->not_fed ()) {
1308 if (r2->not_fed ()) {
1309 /* no ardour-based connections inbound to either route. just use signal order */
1310 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1312 /* r2 has connections, r1 does not; run r1 early */
1316 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1323 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1325 shared_ptr<Route> r2;
1327 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1328 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1332 /* make a copy of the existing list of routes that feed r1 */
1334 Route::FedBy existing (r1->fed_by());
1336 /* for each route that feeds r1, recurse, marking it as feeding
1340 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1341 if (!(r2 = i->r.lock ())) {
1342 /* (*i) went away, ignore it */
1346 /* r2 is a route that feeds r1 which somehow feeds base. mark
1347 base as being fed by r2
1350 rbase->add_fed_by (r2, i->sends_only);
1354 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1358 if (r1->feeds (r2) && r2->feeds (r1)) {
1362 /* now recurse, so that we can mark base as being fed by
1363 all routes that feed r2
1366 trace_terminal (r2, rbase);
1373 Session::resort_routes ()
1375 /* don't do anything here with signals emitted
1376 by Routes while we are being destroyed.
1379 if (_state_of_the_state & Deletion) {
1384 RCUWriter<RouteList> writer (routes);
1385 shared_ptr<RouteList> r = writer.get_copy ();
1386 resort_routes_using (r);
1387 /* writer goes out of scope and forces update */
1390 //route_graph->dump(1);
1393 boost::shared_ptr<RouteList> rl = routes.reader ();
1394 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1395 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1397 const Route::FedBy& fb ((*i)->fed_by());
1399 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1400 boost::shared_ptr<Route> sf = f->r.lock();
1402 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1410 Session::resort_routes_using (shared_ptr<RouteList> r)
1412 RouteList::iterator i, j;
1414 for (i = r->begin(); i != r->end(); ++i) {
1416 (*i)->clear_fed_by ();
1418 for (j = r->begin(); j != r->end(); ++j) {
1420 /* although routes can feed themselves, it will
1421 cause an endless recursive descent if we
1422 detect it. so don't bother checking for
1430 bool via_sends_only;
1432 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1433 (*i)->add_fed_by (*j, via_sends_only);
1438 for (i = r->begin(); i != r->end(); ++i) {
1439 trace_terminal (*i, *i);
1445 route_graph->rechain (r);
1448 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1450 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1451 (*i)->name(), (*i)->order_key ("signal")));
1457 /** Find the route name starting with \a base with the lowest \a id.
1459 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1460 * The available route name with the lowest ID will be used, and \a id
1461 * will be set to the ID.
1463 * \return false if a route name could not be found, and \a track_name
1464 * and \a id do not reflect a free route name.
1467 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1470 snprintf (name, name_len, "%s %" PRIu32, base, id);
1472 if (route_by_name (name) == 0) {
1478 } while (id < (UINT_MAX-1));
1483 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1485 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1487 in = ChanCount::ZERO;
1488 out = ChanCount::ZERO;
1489 shared_ptr<RouteList> r = routes.reader ();
1490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1491 if (!(*i)->is_hidden()) {
1492 in += (*i)->n_inputs();
1493 out += (*i)->n_outputs();
1498 list<boost::shared_ptr<MidiTrack> >
1499 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1501 char track_name[32];
1502 uint32_t track_id = 0;
1503 ChanCount existing_inputs;
1504 ChanCount existing_outputs;
1506 RouteList new_routes;
1507 list<boost::shared_ptr<MidiTrack> > ret;
1508 uint32_t control_id;
1510 count_existing_route_channels (existing_inputs, existing_outputs);
1512 control_id = ntracks() + nbusses();
1515 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1516 error << "cannot find name for new midi track" << endmsg;
1520 shared_ptr<MidiTrack> track;
1523 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1530 mt->use_new_diskstream();
1532 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1533 track = boost::shared_ptr<MidiTrack>(mt);
1535 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1536 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1541 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1542 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1546 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1548 track->non_realtime_input_change();
1551 route_group->add (track);
1554 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1555 track->set_remote_control_id (control_id);
1557 new_routes.push_back (track);
1558 ret.push_back (track);
1561 catch (failed_constructor &err) {
1562 error << _("Session: could not create new midi track.") << endmsg;
1566 catch (AudioEngine::PortRegistrationFailure& pfe) {
1568 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;
1576 if (!new_routes.empty()) {
1577 add_routes (new_routes, false);
1578 save_state (_current_snapshot_name);
1584 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1585 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1586 * @param output_start As \a input_start, but for outputs.
1589 Session::auto_connect_route (
1590 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1593 /* If both inputs and outputs are auto-connected to physical ports,
1594 use the max of input and output offsets to ensure auto-connected
1595 port numbers always match up (e.g. the first audio input and the
1596 first audio output of the route will have the same physical
1597 port number). Otherwise just use the lowest input or output
1601 const bool in_out_physical =
1602 (Config->get_input_auto_connect() & AutoConnectPhysical)
1603 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1606 const ChanCount in_offset = in_out_physical
1607 ? ChanCount::max(existing_inputs, existing_outputs)
1610 const ChanCount out_offset = in_out_physical
1611 ? ChanCount::max(existing_inputs, existing_outputs)
1614 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1615 vector<string> physinputs;
1616 vector<string> physoutputs;
1618 _engine.get_physical_outputs (*t, physoutputs);
1619 _engine.get_physical_inputs (*t, physinputs);
1621 if (!physinputs.empty() && connect_inputs) {
1622 uint32_t nphysical_in = physinputs.size();
1623 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1626 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1627 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1630 if (!port.empty() && route->input()->connect (
1631 route->input()->ports().port(*t, i), port, this)) {
1637 if (!physoutputs.empty()) {
1638 uint32_t nphysical_out = physoutputs.size();
1639 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1642 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1643 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1644 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1645 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1646 port = _master_out->input()->ports().port(*t,
1647 i % _master_out->input()->n_ports().get(*t))->name();
1651 if (!port.empty() && route->output()->connect (
1652 route->output()->ports().port(*t, i), port, this)) {
1659 existing_inputs += route->n_inputs();
1660 existing_outputs += route->n_outputs();
1663 list< boost::shared_ptr<AudioTrack> >
1664 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1666 char track_name[32];
1667 uint32_t track_id = 0;
1668 ChanCount existing_inputs;
1669 ChanCount existing_outputs;
1671 RouteList new_routes;
1672 list<boost::shared_ptr<AudioTrack> > ret;
1673 uint32_t control_id;
1675 count_existing_route_channels (existing_inputs, existing_outputs);
1677 control_id = ntracks() + nbusses() + 1;
1680 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1681 error << "cannot find name for new audio track" << endmsg;
1685 shared_ptr<AudioTrack> track;
1688 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1695 at->use_new_diskstream();
1697 boost_debug_shared_ptr_mark_interesting (at, "Track");
1698 track = boost::shared_ptr<AudioTrack>(at);
1700 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1701 error << string_compose (
1702 _("cannot configure %1 in/%2 out configuration for new audio track"),
1703 input_channels, output_channels)
1708 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1709 error << string_compose (
1710 _("cannot configure %1 in/%2 out configuration for new audio track"),
1711 input_channels, output_channels)
1716 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1719 route_group->add (track);
1722 track->non_realtime_input_change();
1724 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1725 track->set_remote_control_id (control_id);
1728 new_routes.push_back (track);
1729 ret.push_back (track);
1732 catch (failed_constructor &err) {
1733 error << _("Session: could not create new audio track.") << endmsg;
1737 catch (AudioEngine::PortRegistrationFailure& pfe) {
1739 error << pfe.what() << endmsg;
1747 if (!new_routes.empty()) {
1748 add_routes (new_routes, true);
1755 Session::set_remote_control_ids ()
1757 RemoteModel m = Config->get_remote_model();
1758 bool emit_signal = false;
1760 shared_ptr<RouteList> r = routes.reader ();
1762 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1763 if (MixerOrdered == m) {
1764 int32_t order = (*i)->order_key(N_("signal"));
1765 (*i)->set_remote_control_id (order+1, false);
1767 } else if (EditorOrdered == m) {
1768 int32_t order = (*i)->order_key(N_("editor"));
1769 (*i)->set_remote_control_id (order+1, false);
1771 } else if (UserOrdered == m) {
1772 //do nothing ... only changes to remote id's are initiated by user
1777 Route::RemoteControlIDChange();
1783 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1786 uint32_t bus_id = 0;
1787 ChanCount existing_inputs;
1788 ChanCount existing_outputs;
1791 uint32_t control_id;
1793 count_existing_route_channels (existing_inputs, existing_outputs);
1795 control_id = ntracks() + nbusses() + 1;
1798 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1799 error << "cannot find name for new audio bus" << endmsg;
1804 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1811 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1812 shared_ptr<Route> bus (rt);
1814 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1815 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1816 input_channels, output_channels)
1822 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1823 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1824 input_channels, output_channels)
1829 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1832 route_group->add (bus);
1834 bus->set_remote_control_id (control_id);
1838 bus->add_internal_return ();
1841 ret.push_back (bus);
1845 catch (failed_constructor &err) {
1846 error << _("Session: could not create new audio route.") << endmsg;
1850 catch (AudioEngine::PortRegistrationFailure& pfe) {
1851 error << pfe.what() << endmsg;
1861 add_routes (ret, true);
1869 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1873 uint32_t control_id;
1875 uint32_t number = 0;
1877 if (!tree.read (template_path.c_str())) {
1881 XMLNode* node = tree.root();
1883 control_id = ntracks() + nbusses() + 1;
1887 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1889 std::string node_name = IO::name_from_state (*node_copy.children().front());
1891 /* generate a new name by adding a number to the end of the template name */
1892 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1893 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1897 /* set IO children to use the new name */
1898 XMLNodeList const & children = node_copy.children ();
1899 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1900 if ((*i)->name() == IO::state_node_name) {
1901 IO::set_name_in_state (**i, name);
1905 Track::zero_diskstream_id_in_xml (node_copy);
1908 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1911 error << _("Session: cannot create track/bus from template description") << endmsg;
1915 if (boost::dynamic_pointer_cast<Track>(route)) {
1916 /* force input/output change signals so that the new diskstream
1917 picks up the configuration of the route. During session
1918 loading this normally happens in a different way.
1920 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1921 change.after = route->input()->n_ports();
1922 route->input()->changed (change, this);
1923 change.after = route->output()->n_ports();
1924 route->output()->changed (change, this);
1927 route->set_remote_control_id (control_id);
1930 ret.push_back (route);
1933 catch (failed_constructor &err) {
1934 error << _("Session: could not create new route from template") << endmsg;
1938 catch (AudioEngine::PortRegistrationFailure& pfe) {
1939 error << pfe.what() << endmsg;
1948 add_routes (ret, true);
1955 Session::add_routes (RouteList& new_routes, bool save)
1958 RCUWriter<RouteList> writer (routes);
1959 shared_ptr<RouteList> r = writer.get_copy ();
1960 r->insert (r->end(), new_routes.begin(), new_routes.end());
1963 /* if there is no control out and we're not in the middle of loading,
1964 resort the graph here. if there is a control out, we will resort
1965 toward the end of this method. if we are in the middle of loading,
1966 we will resort when done.
1969 if (!_monitor_out && IO::connecting_legal) {
1970 resort_routes_using (r);
1974 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1976 boost::weak_ptr<Route> wpr (*x);
1977 boost::shared_ptr<Route> r (*x);
1979 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1980 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1981 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1982 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1983 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1984 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1985 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1987 if (r->is_master()) {
1991 if (r->is_monitor()) {
1995 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1997 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1998 track_playlist_changed (boost::weak_ptr<Track> (tr));
1999 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2001 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2003 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2008 if (_monitor_out && IO::connecting_legal) {
2010 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2011 if ((*x)->is_monitor()) {
2013 } else if ((*x)->is_master()) {
2016 (*x)->listen_via (_monitor_out,
2017 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2028 save_state (_current_snapshot_name);
2031 RouteAdded (new_routes); /* EMIT SIGNAL */
2032 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2036 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2038 boost::shared_ptr<RouteList> r = routes.reader ();
2039 boost::shared_ptr<Send> s;
2043 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2044 if (boost::dynamic_pointer_cast<Track>(*i)) {
2045 if ((s = (*i)->internal_send_for (dest)) != 0) {
2046 s->amp()->gain_control()->set_value (0.0);
2053 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2055 boost::shared_ptr<RouteList> r = routes.reader ();
2056 boost::shared_ptr<Send> s;
2060 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2061 if (boost::dynamic_pointer_cast<Track>(*i)) {
2062 if ((s = (*i)->internal_send_for (dest)) != 0) {
2063 s->amp()->gain_control()->set_value (1.0);
2070 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2072 boost::shared_ptr<RouteList> r = routes.reader ();
2073 boost::shared_ptr<Send> s;
2077 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2078 if (boost::dynamic_pointer_cast<Track>(*i)) {
2079 if ((s = (*i)->internal_send_for (dest)) != 0) {
2080 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2087 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2089 boost::shared_ptr<RouteList> r = routes.reader ();
2090 boost::shared_ptr<RouteList> t (new RouteList);
2092 /* only send tracks */
2094 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2095 if (boost::dynamic_pointer_cast<Track>(*i)) {
2100 add_internal_sends (dest, p, t);
2104 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2106 if (dest->is_monitor() || dest->is_master()) {
2110 if (!dest->internal_return()) {
2111 dest->add_internal_return();
2114 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2116 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2120 (*i)->listen_via (dest, p, true, true);
2127 Session::remove_route (shared_ptr<Route> route)
2129 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2133 route->set_solo (false, this);
2136 RCUWriter<RouteList> writer (routes);
2137 shared_ptr<RouteList> rs = writer.get_copy ();
2141 /* deleting the master out seems like a dumb
2142 idea, but its more of a UI policy issue
2146 if (route == _master_out) {
2147 _master_out = shared_ptr<Route> ();
2150 if (route == _monitor_out) {
2152 /* cancel control outs for all routes */
2154 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2155 (*r)->drop_listen (_monitor_out);
2158 _monitor_out.reset ();
2161 /* writer goes out of scope, forces route list update */
2164 update_route_solo_state ();
2165 update_session_range_location_marker ();
2167 // We need to disconnect the route's inputs and outputs
2169 route->input()->disconnect (0);
2170 route->output()->disconnect (0);
2172 /* if the route had internal sends sending to it, remove them */
2173 if (route->internal_return()) {
2175 boost::shared_ptr<RouteList> r = routes.reader ();
2176 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2177 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2179 (*i)->remove_processor (s);
2184 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2185 if (mt && mt->step_editing()) {
2186 if (_step_editors > 0) {
2191 update_latency_compensation (false, false);
2194 /* Re-sort routes to remove the graph's current references to the one that is
2195 * going away, then flush old references out of the graph.
2199 route_graph->clear_other_chain ();
2201 /* get rid of it from the dead wood collection in the route list manager */
2203 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2207 /* try to cause everyone to drop their references */
2209 route->drop_references ();
2211 sync_order_keys (N_("session"));
2213 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2215 /* save the new state of the world */
2217 if (save_state (_current_snapshot_name)) {
2218 save_history (_current_snapshot_name);
2223 Session::route_mute_changed (void* /*src*/)
2229 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2231 boost::shared_ptr<Route> route = wpr.lock();
2233 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2237 if (route->listening()) {
2239 if (Config->get_exclusive_solo()) {
2240 /* new listen: disable all other listen */
2241 shared_ptr<RouteList> r = routes.reader ();
2242 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2243 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2246 (*i)->set_listen (false, this);
2252 } else if (_listen_cnt > 0) {
2258 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2260 boost::shared_ptr<Route> route = wpr.lock ();
2263 /* should not happen */
2264 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2268 bool send_changed = false;
2270 if (route->solo_isolated()) {
2271 if (_solo_isolated_cnt == 0) {
2272 send_changed = true;
2274 _solo_isolated_cnt++;
2275 } else if (_solo_isolated_cnt > 0) {
2276 _solo_isolated_cnt--;
2277 if (_solo_isolated_cnt == 0) {
2278 send_changed = true;
2283 IsolatedChanged (); /* EMIT SIGNAL */
2288 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2290 if (!self_solo_change) {
2291 // session doesn't care about changes to soloed-by-others
2295 if (solo_update_disabled) {
2300 boost::shared_ptr<Route> route = wpr.lock ();
2303 /* should not happen */
2304 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2308 shared_ptr<RouteList> r = routes.reader ();
2311 if (route->self_soloed()) {
2317 if (delta == 1 && Config->get_exclusive_solo()) {
2318 /* new solo: disable all other solos */
2319 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2320 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2323 (*i)->set_solo (false, this);
2327 solo_update_disabled = true;
2329 RouteList uninvolved;
2331 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2332 bool via_sends_only;
2333 bool in_signal_flow;
2335 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2339 in_signal_flow = false;
2341 if ((*i)->feeds (route, &via_sends_only)) {
2342 if (!via_sends_only) {
2343 if (!route->soloed_by_others_upstream()) {
2344 (*i)->mod_solo_by_others_downstream (delta);
2346 in_signal_flow = true;
2350 if (route->feeds (*i, &via_sends_only)) {
2351 (*i)->mod_solo_by_others_upstream (delta);
2352 in_signal_flow = true;
2355 if (!in_signal_flow) {
2356 uninvolved.push_back (*i);
2360 solo_update_disabled = false;
2361 update_route_solo_state (r);
2363 /* now notify that the mute state of the routes not involved in the signal
2364 pathway of the just-solo-changed route may have altered.
2367 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2368 (*i)->mute_changed (this);
2371 SoloChanged (); /* EMIT SIGNAL */
2376 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2378 /* now figure out if anything that matters is soloed (or is "listening")*/
2380 bool something_soloed = false;
2381 uint32_t listeners = 0;
2382 uint32_t isolated = 0;
2385 r = routes.reader();
2388 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2389 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2390 something_soloed = true;
2393 if (!(*i)->is_hidden() && (*i)->listening()) {
2394 if (Config->get_solo_control_is_listen_control()) {
2397 (*i)->set_listen (false, this);
2401 if ((*i)->solo_isolated()) {
2406 if (something_soloed != _non_soloed_outs_muted) {
2407 _non_soloed_outs_muted = something_soloed;
2408 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2411 _listen_cnt = listeners;
2413 if (isolated != _solo_isolated_cnt) {
2414 _solo_isolated_cnt = isolated;
2415 IsolatedChanged (); /* EMIT SIGNAL */
2419 boost::shared_ptr<RouteList>
2420 Session::get_routes_with_internal_returns() const
2422 shared_ptr<RouteList> r = routes.reader ();
2423 boost::shared_ptr<RouteList> rl (new RouteList);
2425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2426 if ((*i)->internal_return ()) {
2434 Session::io_name_is_legal (const std::string& name)
2436 shared_ptr<RouteList> r = routes.reader ();
2438 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2439 if ((*i)->name() == name) {
2443 if ((*i)->has_io_processor_named (name)) {
2452 Session::route_by_name (string name)
2454 shared_ptr<RouteList> r = routes.reader ();
2456 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2457 if ((*i)->name() == name) {
2462 return shared_ptr<Route> ((Route*) 0);
2466 Session::route_by_id (PBD::ID id)
2468 shared_ptr<RouteList> r = routes.reader ();
2470 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2471 if ((*i)->id() == id) {
2476 return shared_ptr<Route> ((Route*) 0);
2480 Session::route_by_remote_id (uint32_t id)
2482 shared_ptr<RouteList> r = routes.reader ();
2484 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2485 if ((*i)->remote_control_id() == id) {
2490 return shared_ptr<Route> ((Route*) 0);
2493 /** If either end of the session range location marker lies inside the current
2494 * session extent, move it to the corresponding session extent.
2497 Session::update_session_range_location_marker ()
2499 if (_state_of_the_state & Loading) {
2503 pair<framepos_t, framepos_t> const ext = get_extent ();
2505 if (_session_range_location == 0) {
2506 /* we don't have a session range yet; use this one (provided it is valid) */
2507 if (ext.first != max_framepos) {
2508 add_session_range_location (ext.first, ext.second);
2511 /* update the existing session range */
2512 if (ext.first < _session_range_location->start()) {
2513 _session_range_location->set_start (ext.first);
2517 if (ext.second > _session_range_location->end()) {
2518 _session_range_location->set_end (ext.second);
2525 /** @return Extent of the session's contents; if the session is empty, the first value of
2526 * the pair will equal max_framepos.
2528 pair<framepos_t, framepos_t>
2529 Session::get_extent () const
2531 pair<framepos_t, framepos_t> ext (max_framepos, 0);
2533 boost::shared_ptr<RouteList> rl = routes.reader ();
2534 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2535 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2536 if (!tr || tr->destructive()) {
2537 // ignore tape tracks when getting extents
2541 pair<framepos_t, framepos_t> e = tr->playlist()->get_extent ();
2542 if (e.first < ext.first) {
2543 ext.first = e.first;
2545 if (e.second > ext.second) {
2546 ext.second = e.second;
2553 /* Region management */
2555 boost::shared_ptr<Region>
2556 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2558 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2559 RegionFactory::RegionMap::const_iterator i;
2560 boost::shared_ptr<Region> region;
2562 Glib::Mutex::Lock lm (region_lock);
2564 for (i = regions.begin(); i != regions.end(); ++i) {
2568 if (region->whole_file()) {
2570 if (child->source_equivalent (region)) {
2576 return boost::shared_ptr<Region> ();
2580 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2582 set<boost::shared_ptr<Region> > relevant_regions;
2584 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2585 RegionFactory::get_regions_using_source (*s, relevant_regions);
2588 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2590 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2591 set<boost::shared_ptr<Region> >::iterator tmp;
2596 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2598 playlists->destroy_region (*r);
2599 RegionFactory::map_remove (*r);
2601 (*r)->drop_sources ();
2602 (*r)->drop_references ();
2604 cerr << "\tdone UC = " << (*r).use_count() << endl;
2606 relevant_regions.erase (r);
2611 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2614 Glib::Mutex::Lock ls (source_lock);
2615 /* remove from the main source list */
2616 sources.erase ((*s)->id());
2619 (*s)->mark_for_remove ();
2620 (*s)->drop_references ();
2629 Session::remove_last_capture ()
2631 list<boost::shared_ptr<Source> > srcs;
2633 boost::shared_ptr<RouteList> rl = routes.reader ();
2634 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2635 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2640 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2643 srcs.insert (srcs.end(), l.begin(), l.end());
2648 destroy_sources (srcs);
2650 save_state (_current_snapshot_name);
2655 /* Source Management */
2658 Session::add_source (boost::shared_ptr<Source> source)
2660 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2661 pair<SourceMap::iterator,bool> result;
2663 entry.first = source->id();
2664 entry.second = source;
2667 Glib::Mutex::Lock lm (source_lock);
2668 result = sources.insert (entry);
2671 if (result.second) {
2673 /* yay, new source */
2677 boost::shared_ptr<AudioFileSource> afs;
2679 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2680 if (Config->get_auto_analyse_audio()) {
2681 Analyser::queue_source_for_analysis (source, false);
2688 Session::remove_source (boost::weak_ptr<Source> src)
2690 SourceMap::iterator i;
2691 boost::shared_ptr<Source> source = src.lock();
2698 Glib::Mutex::Lock lm (source_lock);
2700 if ((i = sources.find (source->id())) != sources.end()) {
2701 cerr << "Removing source " << source->name() << endl;
2706 if (!_state_of_the_state & InCleanup) {
2708 /* save state so we don't end up with a session file
2709 referring to non-existent sources.
2712 save_state (_current_snapshot_name);
2716 boost::shared_ptr<Source>
2717 Session::source_by_id (const PBD::ID& id)
2719 Glib::Mutex::Lock lm (source_lock);
2720 SourceMap::iterator i;
2721 boost::shared_ptr<Source> source;
2723 if ((i = sources.find (id)) != sources.end()) {
2730 boost::shared_ptr<Source>
2731 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2733 Glib::Mutex::Lock lm (source_lock);
2735 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2736 boost::shared_ptr<AudioFileSource> afs
2737 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2739 if (afs && afs->path() == path && chn == afs->channel()) {
2743 return boost::shared_ptr<Source>();
2747 Session::count_sources_by_origin (const string& path)
2750 Glib::Mutex::Lock lm (source_lock);
2752 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2753 boost::shared_ptr<FileSource> fs
2754 = boost::dynamic_pointer_cast<FileSource>(i->second);
2756 if (fs && fs->origin() == path) {
2766 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2769 string old_basename = PBD::basename_nosuffix (oldname);
2770 string new_legalized = legalize_for_path (newname);
2772 /* note: we know (or assume) the old path is already valid */
2776 /* destructive file sources have a name of the form:
2778 /path/to/Tnnnn-NAME(%[LR])?.wav
2780 the task here is to replace NAME with the new name.
2785 string::size_type dash;
2787 dir = Glib::path_get_dirname (path);
2788 path = Glib::path_get_basename (path);
2790 /* '-' is not a legal character for the NAME part of the path */
2792 if ((dash = path.find_last_of ('-')) == string::npos) {
2796 prefix = path.substr (0, dash);
2800 path += new_legalized;
2801 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2803 path = Glib::build_filename (dir, path);
2807 /* non-destructive file sources have a name of the form:
2809 /path/to/NAME-nnnnn(%[LR])?.ext
2811 the task here is to replace NAME with the new name.
2816 string::size_type dash;
2817 string::size_type postfix;
2819 dir = Glib::path_get_dirname (path);
2820 path = Glib::path_get_basename (path);
2822 /* '-' is not a legal character for the NAME part of the path */
2824 if ((dash = path.find_last_of ('-')) == string::npos) {
2828 suffix = path.substr (dash+1);
2830 // Suffix is now everything after the dash. Now we need to eliminate
2831 // the nnnnn part, which is done by either finding a '%' or a '.'
2833 postfix = suffix.find_last_of ("%");
2834 if (postfix == string::npos) {
2835 postfix = suffix.find_last_of ('.');
2838 if (postfix != string::npos) {
2839 suffix = suffix.substr (postfix);
2841 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2845 const uint32_t limit = 10000;
2846 char buf[PATH_MAX+1];
2848 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2850 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2852 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2853 path = Glib::build_filename (dir, buf);
2861 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2870 /** Return the full path (in some session directory) for a new within-session source.
2871 * \a name must be a session-unique name that does not contain slashes
2872 * (e.g. as returned by new_*_source_name)
2875 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2877 assert(name.find("/") == string::npos);
2879 SessionDirectory sdir(get_best_session_directory_for_new_source());
2882 if (type == DataType::AUDIO) {
2883 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2884 } else if (type == DataType::MIDI) {
2885 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2887 error << "Unknown source type, unable to create file path" << endmsg;
2892 return p.to_string();
2896 Session::peak_path (string base) const
2898 sys::path peakfile_path(_session_dir->peak_path());
2899 peakfile_path /= base + peakfile_suffix;
2900 return peakfile_path.to_string();
2903 /** Return a unique name based on \a base for a new internal audio source */
2905 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2908 char buf[PATH_MAX+1];
2909 const uint32_t limit = 10000;
2911 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2914 legalized = legalize_for_path (base);
2916 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2917 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2919 vector<space_and_path>::iterator i;
2920 uint32_t existing = 0;
2922 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2927 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2928 cnt, legalized.c_str(), ext.c_str());
2929 } else if (nchan == 2) {
2931 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2932 cnt, legalized.c_str(), ext.c_str());
2934 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2935 cnt, legalized.c_str(), ext.c_str());
2937 } else if (nchan < 26) {
2938 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2939 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2941 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2942 cnt, legalized.c_str(), ext.c_str());
2948 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2949 } else if (nchan == 2) {
2951 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2953 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2955 } else if (nchan < 26) {
2956 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2958 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2962 SessionDirectory sdir((*i).path);
2964 string spath = sdir.sound_path().to_string();
2965 string spath_stubs = sdir.sound_stub_path().to_string();
2967 /* note that we search *without* the extension so that
2968 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2969 in the event that this new name is required for
2970 a file format change.
2973 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2974 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
2980 if (existing == 0) {
2985 error << string_compose(
2986 _("There are already %1 recordings for %2, which I consider too many."),
2987 limit, base) << endmsg;
2989 throw failed_constructor();
2993 return Glib::path_get_basename (buf);
2996 /** Create a new within-session audio source */
2997 boost::shared_ptr<AudioFileSource>
2998 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
3000 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3001 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
3003 return boost::dynamic_pointer_cast<AudioFileSource> (
3004 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3007 /** Return a unique name based on \a base for a new internal MIDI source */
3009 Session::new_midi_source_name (const string& base)
3012 char buf[PATH_MAX+1];
3013 const uint32_t limit = 10000;
3017 legalized = legalize_for_path (base);
3019 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3020 for (cnt = 1; cnt <= limit; ++cnt) {
3022 vector<space_and_path>::iterator i;
3023 uint32_t existing = 0;
3025 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3027 SessionDirectory sdir((*i).path);
3029 sys::path p = sdir.midi_path();
3032 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3034 if (sys::exists (buf)) {
3039 if (existing == 0) {
3044 error << string_compose(
3045 _("There are already %1 recordings for %2, which I consider too many."),
3046 limit, base) << endmsg;
3048 throw failed_constructor();
3052 return Glib::path_get_basename(buf);
3056 /** Create a new within-session MIDI source */
3057 boost::shared_ptr<MidiSource>
3058 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3060 /* try to use the existing write source for the track, to keep numbering sane
3064 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3068 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3071 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3072 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3076 const string name = new_midi_source_name (n);
3077 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3079 return boost::dynamic_pointer_cast<SMFSource> (
3080 SourceFactory::createWritable (
3081 DataType::MIDI, *this, path, string(), false, frame_rate()));
3086 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3088 if (playlist->hidden()) {
3092 playlists->add (playlist);
3095 playlist->release();
3102 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3104 if (_state_of_the_state & Deletion) {
3108 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3114 playlists->remove (playlist);
3120 Session::set_audition (boost::shared_ptr<Region> r)
3122 pending_audition_region = r;
3123 add_post_transport_work (PostTransportAudition);
3124 _butler->schedule_transport_work ();
3128 Session::audition_playlist ()
3130 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3131 ev->region.reset ();
3136 Session::non_realtime_set_audition ()
3138 if (!pending_audition_region) {
3139 auditioner->audition_current_playlist ();
3141 auditioner->audition_region (pending_audition_region);
3142 pending_audition_region.reset ();
3144 AuditionActive (true); /* EMIT SIGNAL */
3148 Session::audition_region (boost::shared_ptr<Region> r)
3150 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3156 Session::cancel_audition ()
3158 if (auditioner->auditioning()) {
3159 auditioner->cancel_audition ();
3160 AuditionActive (false); /* EMIT SIGNAL */
3165 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3167 if (a->is_monitor()) {
3170 if (b->is_monitor()) {
3173 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3177 Session::is_auditioning () const
3179 /* can be called before we have an auditioner object */
3181 return auditioner->auditioning();
3188 Session::graph_reordered ()
3190 /* don't do this stuff if we are setting up connections
3191 from a set_state() call or creating new tracks. Ditto for deletion.
3194 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3198 /* every track/bus asked for this to be handled but it was deferred because
3199 we were connecting. do it now.
3202 request_input_change_handling ();
3206 /* force all diskstreams to update their capture offset values to
3207 reflect any changes in latencies within the graph.
3210 boost::shared_ptr<RouteList> rl = routes.reader ();
3211 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3212 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3214 tr->set_capture_offset ();
3220 Session::available_capture_duration ()
3222 float sample_bytes_on_disk = 4.0; // keep gcc happy
3224 switch (config.get_native_file_data_format()) {
3226 sample_bytes_on_disk = 4.0;
3230 sample_bytes_on_disk = 3.0;
3234 sample_bytes_on_disk = 2.0;
3238 /* impossible, but keep some gcc versions happy */
3239 fatal << string_compose (_("programming error: %1"),
3240 X_("illegal native file data format"))
3245 double scale = 4096.0 / sample_bytes_on_disk;
3247 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3248 return max_framecnt;
3251 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3255 Session::add_bundle (shared_ptr<Bundle> bundle)
3258 RCUWriter<BundleList> writer (_bundles);
3259 boost::shared_ptr<BundleList> b = writer.get_copy ();
3260 b->push_back (bundle);
3263 BundleAdded (bundle); /* EMIT SIGNAL */
3269 Session::remove_bundle (shared_ptr<Bundle> bundle)
3271 bool removed = false;
3274 RCUWriter<BundleList> writer (_bundles);
3275 boost::shared_ptr<BundleList> b = writer.get_copy ();
3276 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3278 if (i != b->end()) {
3285 BundleRemoved (bundle); /* EMIT SIGNAL */
3292 Session::bundle_by_name (string name) const
3294 boost::shared_ptr<BundleList> b = _bundles.reader ();
3296 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3297 if ((*i)->name() == name) {
3302 return boost::shared_ptr<Bundle> ();
3306 Session::tempo_map_changed (const PropertyChange&)
3310 playlists->update_after_tempo_map_change ();
3312 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3318 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3320 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3321 (*i)->recompute_frames_from_bbt ();
3325 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3326 * the given count with the current block size.
3329 Session::ensure_buffers (ChanCount howmany)
3331 BufferManager::ensure_buffers (howmany);
3335 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3337 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3338 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3343 Session::next_insert_id ()
3345 /* this doesn't really loop forever. just think about it */
3348 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3349 if (!insert_bitset[n]) {
3350 insert_bitset[n] = true;
3356 /* none available, so resize and try again */
3358 insert_bitset.resize (insert_bitset.size() + 16, false);
3363 Session::next_send_id ()
3365 /* this doesn't really loop forever. just think about it */
3368 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3369 if (!send_bitset[n]) {
3370 send_bitset[n] = true;
3376 /* none available, so resize and try again */
3378 send_bitset.resize (send_bitset.size() + 16, false);
3383 Session::next_return_id ()
3385 /* this doesn't really loop forever. just think about it */
3388 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3389 if (!return_bitset[n]) {
3390 return_bitset[n] = true;
3396 /* none available, so resize and try again */
3398 return_bitset.resize (return_bitset.size() + 16, false);
3403 Session::mark_send_id (uint32_t id)
3405 if (id >= send_bitset.size()) {
3406 send_bitset.resize (id+16, false);
3408 if (send_bitset[id]) {
3409 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3411 send_bitset[id] = true;
3415 Session::mark_return_id (uint32_t id)
3417 if (id >= return_bitset.size()) {
3418 return_bitset.resize (id+16, false);
3420 if (return_bitset[id]) {
3421 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3423 return_bitset[id] = true;
3427 Session::mark_insert_id (uint32_t id)
3429 if (id >= insert_bitset.size()) {
3430 insert_bitset.resize (id+16, false);
3432 if (insert_bitset[id]) {
3433 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3435 insert_bitset[id] = true;
3439 Session::unmark_send_id (uint32_t id)
3441 if (id < send_bitset.size()) {
3442 send_bitset[id] = false;
3447 Session::unmark_return_id (uint32_t id)
3449 if (id < return_bitset.size()) {
3450 return_bitset[id] = false;
3455 Session::unmark_insert_id (uint32_t id)
3457 if (id < insert_bitset.size()) {
3458 insert_bitset[id] = false;
3463 /* Named Selection management */
3465 boost::shared_ptr<NamedSelection>
3466 Session::named_selection_by_name (string name)
3468 Glib::Mutex::Lock lm (named_selection_lock);
3469 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3470 if ((*i)->name == name) {
3474 return boost::shared_ptr<NamedSelection>();
3478 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3481 Glib::Mutex::Lock lm (named_selection_lock);
3482 named_selections.insert (named_selections.begin(), named_selection);
3487 NamedSelectionAdded (); /* EMIT SIGNAL */
3491 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3493 bool removed = false;
3496 Glib::Mutex::Lock lm (named_selection_lock);
3498 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3500 if (i != named_selections.end()) {
3501 named_selections.erase (i);
3508 NamedSelectionRemoved (); /* EMIT SIGNAL */
3513 Session::reset_native_file_format ()
3515 boost::shared_ptr<RouteList> rl = routes.reader ();
3516 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3517 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3519 /* don't save state as we do this, there's no point
3522 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3523 tr->reset_write_sources (false);
3524 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3530 Session::route_name_unique (string n) const
3532 shared_ptr<RouteList> r = routes.reader ();
3534 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3535 if ((*i)->name() == n) {
3544 Session::route_name_internal (string n) const
3546 if (auditioner && auditioner->name() == n) {
3550 if (_click_io && _click_io->name() == n) {
3558 Session::freeze_all (InterThreadInfo& itt)
3560 shared_ptr<RouteList> r = routes.reader ();
3562 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3564 boost::shared_ptr<Track> t;
3566 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3567 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3577 boost::shared_ptr<Region>
3578 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3579 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3580 InterThreadInfo& itt, bool enable_processing)
3582 boost::shared_ptr<Region> result;
3583 boost::shared_ptr<Playlist> playlist;
3584 boost::shared_ptr<AudioFileSource> fsource;
3586 char buf[PATH_MAX+1];
3587 ChanCount nchans(track.n_channels());
3588 framepos_t position;
3589 framecnt_t this_chunk;
3592 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3593 const string sound_dir = sdir.sound_path().to_string();
3594 framepos_t len = end - start;
3595 bool need_block_size_reset = false;
3599 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3600 end, start) << endmsg;
3604 const framecnt_t chunk_size = (256 * 1024)/4;
3606 // block all process callback handling
3608 block_processing ();
3610 /* call tree *MUST* hold route_lock */
3612 if ((playlist = track.playlist()) == 0) {
3616 /* external redirects will be a problem */
3618 if (track.has_external_redirects()) {
3622 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3624 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3626 for (x = 0; x < 99999; ++x) {
3627 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());
3628 if (access (buf, F_OK) != 0) {
3634 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3639 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3640 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3643 catch (failed_constructor& err) {
3644 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3648 srcs.push_back (fsource);
3651 /* tell redirects that care that we are about to use a much larger blocksize */
3653 need_block_size_reset = true;
3654 track.set_block_size (chunk_size);
3656 /* XXX need to flush all redirects */
3661 /* create a set of reasonably-sized buffers */
3662 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3663 buffers.set_count(nchans);
3665 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3666 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3668 afs->prepare_for_peakfile_writes ();
3671 while (to_do && !itt.cancel) {
3673 this_chunk = min (to_do, chunk_size);
3675 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3680 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3681 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3684 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3690 start += this_chunk;
3691 to_do -= this_chunk;
3693 itt.progress = (float) (1.0 - ((double) to_do / len));
3702 xnow = localtime (&now);
3704 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3705 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3708 afs->update_header (position, *xnow, now);
3709 afs->flush_header ();
3713 /* construct a region to represent the bounced material */
3717 plist.add (Properties::start, 0);
3718 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3719 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3721 result = RegionFactory::create (srcs, plist);
3727 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3728 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3731 afs->mark_for_remove ();
3734 (*src)->drop_references ();
3738 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3739 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3742 afs->done_with_peakfile_writes ();
3747 if (need_block_size_reset) {
3748 track.set_block_size (get_block_size());
3751 unblock_processing ();
3757 Session::gain_automation_buffer() const
3759 return ProcessThread::gain_automation_buffer ();
3763 Session::pan_automation_buffer() const
3765 return ProcessThread::pan_automation_buffer ();
3769 Session::get_silent_buffers (ChanCount count)
3771 return ProcessThread::get_silent_buffers (count);
3773 assert(_silent_buffers->available() >= count);
3774 _silent_buffers->set_count(count);
3776 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3777 for (size_t i= 0; i < count.get(*t); ++i) {
3778 _silent_buffers->get(*t, i).clear();
3782 return *_silent_buffers;
3787 Session::get_scratch_buffers (ChanCount count)
3789 return ProcessThread::get_scratch_buffers (count);
3791 if (count != ChanCount::ZERO) {
3792 assert(_scratch_buffers->available() >= count);
3793 _scratch_buffers->set_count(count);
3795 _scratch_buffers->set_count (_scratch_buffers->available());
3798 return *_scratch_buffers;
3803 Session::get_mix_buffers (ChanCount count)
3805 return ProcessThread::get_mix_buffers (count);
3807 assert(_mix_buffers->available() >= count);
3808 _mix_buffers->set_count(count);
3809 return *_mix_buffers;
3814 Session::ntracks () const
3817 shared_ptr<RouteList> r = routes.reader ();
3819 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3820 if (boost::dynamic_pointer_cast<Track> (*i)) {
3829 Session::nbusses () const
3832 shared_ptr<RouteList> r = routes.reader ();
3834 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3835 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3844 Session::add_automation_list(AutomationList *al)
3846 automation_lists[al->id()] = al;
3850 Session::sync_order_keys (std::string const & base)
3852 if (deletion_in_progress()) {
3856 if (!Config->get_sync_all_route_ordering()) {
3857 /* leave order keys as they are */
3861 boost::shared_ptr<RouteList> r = routes.reader ();
3863 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3864 (*i)->sync_order_keys (base);
3867 Route::SyncOrderKeys (base); // EMIT SIGNAL
3869 /* this might not do anything */
3871 set_remote_control_ids ();
3874 /** @return true if there is at least one record-enabled track, otherwise false */
3876 Session::have_rec_enabled_track () const
3878 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3881 /** Update the state of our rec-enabled tracks flag */
3883 Session::update_have_rec_enabled_track ()
3885 boost::shared_ptr<RouteList> rl = routes.reader ();
3886 RouteList::iterator i = rl->begin();
3887 while (i != rl->end ()) {
3889 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3890 if (tr && tr->record_enabled ()) {
3897 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3899 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3901 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3902 RecordStateChanged (); /* EMIT SIGNAL */
3907 Session::listen_position_changed ()
3911 switch (Config->get_listen_position()) {
3912 case AfterFaderListen:
3916 case PreFaderListen:
3921 boost::shared_ptr<RouteList> r = routes.reader ();
3923 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3924 (*i)->put_monitor_send_at (p);
3929 Session::solo_control_mode_changed ()
3931 /* cancel all solo or all listen when solo control mode changes */
3934 set_solo (get_routes(), false);
3935 } else if (listening()) {
3936 set_listen (get_routes(), false);
3940 /** Called when anything about any of our route groups changes (membership, state etc.) */
3942 Session::route_group_changed ()
3944 RouteGroupChanged (); /* EMIT SIGNAL */
3948 Session::get_available_sync_options () const
3950 vector<SyncSource> ret;
3952 ret.push_back (JACK);
3953 ret.push_back (MTC);
3954 ret.push_back (MIDIClock);
3959 boost::shared_ptr<RouteList>
3960 Session::get_routes_with_regions_at (framepos_t const p) const
3962 shared_ptr<RouteList> r = routes.reader ();
3963 shared_ptr<RouteList> rl (new RouteList);
3965 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3966 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3971 boost::shared_ptr<Playlist> pl = tr->playlist ();
3976 if (pl->has_region_at (p)) {
3985 Session::goto_end ()
3987 if (_session_range_location) {
3988 request_locate (_session_range_location->end(), false);
3990 request_locate (0, false);
3995 Session::goto_start ()
3997 if (_session_range_location) {
3998 request_locate (_session_range_location->start(), false);
4000 request_locate (0, false);
4005 Session::current_start_frame () const
4007 return _session_range_location ? _session_range_location->start() : 0;
4011 Session::current_end_frame () const
4013 return _session_range_location ? _session_range_location->end() : 0;
4017 Session::add_session_range_location (nframes_t start, nframes_t end)
4019 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4020 _locations->add (_session_range_location);
4023 /** Called when one of our routes' order keys has changed */
4025 Session::route_order_key_changed ()
4027 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4031 Session::step_edit_status_change (bool yn)
4037 send = (_step_editors == 0);
4042 send = (_step_editors == 1);
4045 if (_step_editors > 0) {
4051 StepEditStatusChange (val);
4057 Session::start_time_changed (framepos_t old)
4059 /* Update the auto loop range to match the session range
4060 (unless the auto loop range has been changed by the user)
4063 Location* s = _locations->session_range_location ();
4064 Location* l = _locations->auto_loop_location ();
4066 if (l->start() == old) {
4067 l->set_start (s->start(), true);
4072 Session::end_time_changed (framepos_t old)
4074 /* Update the auto loop range to match the session range
4075 (unless the auto loop range has been changed by the user)
4078 Location* s = _locations->session_range_location ();
4079 Location* l = _locations->auto_loop_location ();
4081 if (l->end() == old) {
4082 l->set_end (s->end(), true);
4087 Session::source_search_path (DataType type) const
4091 if (session_dirs.size() == 1) {
4093 case DataType::AUDIO:
4094 search_path = _session_dir->sound_path().to_string();
4096 case DataType::MIDI:
4097 search_path = _session_dir->midi_path().to_string();
4101 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4102 SessionDirectory sdir (i->path);
4103 if (!search_path.empty()) {
4107 case DataType::AUDIO:
4108 search_path += sdir.sound_path().to_string();
4110 case DataType::MIDI:
4111 search_path += sdir.midi_path().to_string();
4117 /* now add user-specified locations
4120 vector<string> dirs;
4123 case DataType::AUDIO:
4124 split (config.get_audio_search_path (), dirs, ':');
4126 case DataType::MIDI:
4127 split (config.get_midi_search_path (), dirs, ':');
4131 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4141 Session::ensure_search_path_includes (const string& path, DataType type)
4144 vector<string> dirs;
4151 case DataType::AUDIO:
4152 search_path = config.get_audio_search_path ();
4154 case DataType::MIDI:
4155 search_path = config.get_midi_search_path ();
4159 split (search_path, dirs, ':');
4161 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4167 if (!search_path.empty()) {
4171 search_path += path;
4174 case DataType::AUDIO:
4175 config.set_audio_search_path (search_path);
4177 case DataType::MIDI:
4178 config.set_midi_search_path (search_path);
4184 Session::get_speakers()
4187 _speakers = new VBAPSpeakers;