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 /** @return true to run r1 before r2, otherwise false */
1302 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1303 if (r2->feeds (r1)) {
1304 /* r1 fed by r2; run r2 early */
1306 } else if (r1->feeds (r2)) {
1307 /* r2 fed by r1; run r1 early */
1310 if (r1->not_fed ()) {
1311 if (r2->not_fed ()) {
1312 /* no ardour-based connections inbound to either route. just use signal order */
1313 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1315 /* r2 has connections, r1 does not; run r1 early */
1319 if (r2->not_fed()) {
1320 /* r1 has connections, r2 does not; run r2 early */
1323 /* both r1 and r2 have connections, but not to each other. just use signal order */
1324 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1332 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1334 shared_ptr<Route> r2;
1336 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1337 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1341 /* make a copy of the existing list of routes that feed r1 */
1343 Route::FedBy existing (r1->fed_by());
1345 /* for each route that feeds r1, recurse, marking it as feeding
1349 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1350 if (!(r2 = i->r.lock ())) {
1351 /* (*i) went away, ignore it */
1355 /* r2 is a route that feeds r1 which somehow feeds base. mark
1356 base as being fed by r2
1359 rbase->add_fed_by (r2, i->sends_only);
1363 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1367 if (r1->feeds (r2) && r2->feeds (r1)) {
1371 /* now recurse, so that we can mark base as being fed by
1372 all routes that feed r2
1375 trace_terminal (r2, rbase);
1382 Session::resort_routes ()
1384 /* don't do anything here with signals emitted
1385 by Routes while we are being destroyed.
1388 if (_state_of_the_state & Deletion) {
1393 RCUWriter<RouteList> writer (routes);
1394 shared_ptr<RouteList> r = writer.get_copy ();
1395 resort_routes_using (r);
1396 /* writer goes out of scope and forces update */
1399 //route_graph->dump(1);
1402 boost::shared_ptr<RouteList> rl = routes.reader ();
1403 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1404 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1406 const Route::FedBy& fb ((*i)->fed_by());
1408 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1409 boost::shared_ptr<Route> sf = f->r.lock();
1411 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1419 Session::resort_routes_using (shared_ptr<RouteList> r)
1421 RouteList::iterator i, j;
1423 for (i = r->begin(); i != r->end(); ++i) {
1425 (*i)->clear_fed_by ();
1427 for (j = r->begin(); j != r->end(); ++j) {
1429 /* although routes can feed themselves, it will
1430 cause an endless recursive descent if we
1431 detect it. so don't bother checking for
1439 bool via_sends_only;
1441 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1442 (*i)->add_fed_by (*j, via_sends_only);
1447 for (i = r->begin(); i != r->end(); ++i) {
1448 trace_terminal (*i, *i);
1454 route_graph->rechain (r);
1457 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1458 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1459 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1460 (*i)->name(), (*i)->order_key ("signal")));
1466 /** Find the route name starting with \a base with the lowest \a id.
1468 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1469 * The available route name with the lowest ID will be used, and \a id
1470 * will be set to the ID.
1472 * \return false if a route name could not be found, and \a track_name
1473 * and \a id do not reflect a free route name.
1476 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1479 snprintf (name, name_len, "%s %" PRIu32, base, id);
1481 if (route_by_name (name) == 0) {
1487 } while (id < (UINT_MAX-1));
1492 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1494 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1496 in = ChanCount::ZERO;
1497 out = ChanCount::ZERO;
1498 shared_ptr<RouteList> r = routes.reader ();
1499 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1500 if (!(*i)->is_hidden()) {
1501 in += (*i)->n_inputs();
1502 out += (*i)->n_outputs();
1507 /** Caller must not hold process lock */
1508 list<boost::shared_ptr<MidiTrack> >
1509 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1511 char track_name[32];
1512 uint32_t track_id = 0;
1513 ChanCount existing_inputs;
1514 ChanCount existing_outputs;
1516 RouteList new_routes;
1517 list<boost::shared_ptr<MidiTrack> > ret;
1518 uint32_t control_id;
1520 count_existing_route_channels (existing_inputs, existing_outputs);
1522 control_id = ntracks() + nbusses();
1525 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1526 error << "cannot find name for new midi track" << endmsg;
1530 shared_ptr<MidiTrack> track;
1533 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1540 mt->use_new_diskstream();
1542 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1543 track = boost::shared_ptr<MidiTrack>(mt);
1546 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1547 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1548 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1552 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1553 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1558 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1560 track->non_realtime_input_change();
1563 route_group->add (track);
1566 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1567 track->set_remote_control_id (control_id);
1569 new_routes.push_back (track);
1570 ret.push_back (track);
1573 catch (failed_constructor &err) {
1574 error << _("Session: could not create new midi track.") << endmsg;
1578 catch (AudioEngine::PortRegistrationFailure& pfe) {
1580 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;
1588 if (!new_routes.empty()) {
1589 add_routes (new_routes, false);
1590 save_state (_current_snapshot_name);
1596 /** Caller must hold process lock.
1597 * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1598 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1599 * @param output_start As \a input_start, but for outputs.
1602 Session::auto_connect_route (
1603 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1606 /* If both inputs and outputs are auto-connected to physical ports,
1607 use the max of input and output offsets to ensure auto-connected
1608 port numbers always match up (e.g. the first audio input and the
1609 first audio output of the route will have the same physical
1610 port number). Otherwise just use the lowest input or output
1614 const bool in_out_physical =
1615 (Config->get_input_auto_connect() & AutoConnectPhysical)
1616 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1619 const ChanCount in_offset = in_out_physical
1620 ? ChanCount::max(existing_inputs, existing_outputs)
1623 const ChanCount out_offset = in_out_physical
1624 ? ChanCount::max(existing_inputs, existing_outputs)
1627 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1628 vector<string> physinputs;
1629 vector<string> physoutputs;
1631 _engine.get_physical_outputs (*t, physoutputs);
1632 _engine.get_physical_inputs (*t, physinputs);
1634 if (!physinputs.empty() && connect_inputs) {
1635 uint32_t nphysical_in = physinputs.size();
1636 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1639 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1640 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1643 if (!port.empty() && route->input()->connect (
1644 route->input()->ports().port(*t, i), port, this)) {
1650 if (!physoutputs.empty()) {
1651 uint32_t nphysical_out = physoutputs.size();
1652 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1655 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1656 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1657 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1658 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1659 port = _master_out->input()->ports().port(*t,
1660 i % _master_out->input()->n_ports().get(*t))->name();
1664 if (!port.empty() && route->output()->connect (
1665 route->output()->ports().port(*t, i), port, this)) {
1672 existing_inputs += route->n_inputs();
1673 existing_outputs += route->n_outputs();
1676 /** Caller must not hold process lock */
1677 list< boost::shared_ptr<AudioTrack> >
1678 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1680 char track_name[32];
1681 uint32_t track_id = 0;
1682 ChanCount existing_inputs;
1683 ChanCount existing_outputs;
1685 RouteList new_routes;
1686 list<boost::shared_ptr<AudioTrack> > ret;
1687 uint32_t control_id;
1689 count_existing_route_channels (existing_inputs, existing_outputs);
1691 control_id = ntracks() + nbusses() + 1;
1694 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1695 error << "cannot find name for new audio track" << endmsg;
1699 shared_ptr<AudioTrack> track;
1702 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1709 at->use_new_diskstream();
1711 boost_debug_shared_ptr_mark_interesting (at, "Track");
1712 track = boost::shared_ptr<AudioTrack>(at);
1715 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1717 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1718 error << string_compose (
1719 _("cannot configure %1 in/%2 out configuration for new audio track"),
1720 input_channels, output_channels)
1725 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1726 error << string_compose (
1727 _("cannot configure %1 in/%2 out configuration for new audio track"),
1728 input_channels, output_channels)
1733 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1737 route_group->add (track);
1740 track->non_realtime_input_change();
1742 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1743 track->set_remote_control_id (control_id);
1746 new_routes.push_back (track);
1747 ret.push_back (track);
1750 catch (failed_constructor &err) {
1751 error << _("Session: could not create new audio track.") << endmsg;
1755 catch (AudioEngine::PortRegistrationFailure& pfe) {
1757 error << pfe.what() << endmsg;
1765 if (!new_routes.empty()) {
1766 add_routes (new_routes, true);
1773 Session::set_remote_control_ids ()
1775 RemoteModel m = Config->get_remote_model();
1776 bool emit_signal = false;
1778 shared_ptr<RouteList> r = routes.reader ();
1780 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1781 if (MixerOrdered == m) {
1782 int32_t order = (*i)->order_key(N_("signal"));
1783 (*i)->set_remote_control_id (order+1, false);
1785 } else if (EditorOrdered == m) {
1786 int32_t order = (*i)->order_key(N_("editor"));
1787 (*i)->set_remote_control_id (order+1, false);
1789 } else if (UserOrdered == m) {
1790 //do nothing ... only changes to remote id's are initiated by user
1795 Route::RemoteControlIDChange();
1799 /** Caller must not hold process lock */
1801 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1804 uint32_t bus_id = 0;
1805 ChanCount existing_inputs;
1806 ChanCount existing_outputs;
1809 uint32_t control_id;
1811 count_existing_route_channels (existing_inputs, existing_outputs);
1813 control_id = ntracks() + nbusses() + 1;
1816 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1817 error << "cannot find name for new audio bus" << endmsg;
1822 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1829 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1830 shared_ptr<Route> bus (rt);
1833 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1835 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1836 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1837 input_channels, output_channels)
1843 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1844 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1845 input_channels, output_channels)
1850 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1854 route_group->add (bus);
1856 bus->set_remote_control_id (control_id);
1860 bus->add_internal_return ();
1863 ret.push_back (bus);
1867 catch (failed_constructor &err) {
1868 error << _("Session: could not create new audio route.") << endmsg;
1872 catch (AudioEngine::PortRegistrationFailure& pfe) {
1873 error << pfe.what() << endmsg;
1883 add_routes (ret, true);
1891 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1895 uint32_t control_id;
1897 uint32_t number = 0;
1899 if (!tree.read (template_path.c_str())) {
1903 XMLNode* node = tree.root();
1905 control_id = ntracks() + nbusses() + 1;
1909 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1911 std::string node_name = IO::name_from_state (*node_copy.children().front());
1913 /* generate a new name by adding a number to the end of the template name */
1914 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1915 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1919 /* set IO children to use the new name */
1920 XMLNodeList const & children = node_copy.children ();
1921 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1922 if ((*i)->name() == IO::state_node_name) {
1923 IO::set_name_in_state (**i, name);
1927 Track::zero_diskstream_id_in_xml (node_copy);
1930 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1933 error << _("Session: cannot create track/bus from template description") << endmsg;
1937 if (boost::dynamic_pointer_cast<Track>(route)) {
1938 /* force input/output change signals so that the new diskstream
1939 picks up the configuration of the route. During session
1940 loading this normally happens in a different way.
1942 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1943 change.after = route->input()->n_ports();
1944 route->input()->changed (change, this);
1945 change.after = route->output()->n_ports();
1946 route->output()->changed (change, this);
1949 route->set_remote_control_id (control_id);
1952 ret.push_back (route);
1955 catch (failed_constructor &err) {
1956 error << _("Session: could not create new route from template") << endmsg;
1960 catch (AudioEngine::PortRegistrationFailure& pfe) {
1961 error << pfe.what() << endmsg;
1970 add_routes (ret, true);
1977 Session::add_routes (RouteList& new_routes, bool save)
1980 RCUWriter<RouteList> writer (routes);
1981 shared_ptr<RouteList> r = writer.get_copy ();
1982 r->insert (r->end(), new_routes.begin(), new_routes.end());
1985 /* if there is no control out and we're not in the middle of loading,
1986 resort the graph here. if there is a control out, we will resort
1987 toward the end of this method. if we are in the middle of loading,
1988 we will resort when done.
1991 if (!_monitor_out && IO::connecting_legal) {
1992 resort_routes_using (r);
1996 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1998 boost::weak_ptr<Route> wpr (*x);
1999 boost::shared_ptr<Route> r (*x);
2001 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2002 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2003 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2004 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2005 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2006 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2007 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
2009 if (r->is_master()) {
2013 if (r->is_monitor()) {
2017 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2019 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2020 track_playlist_changed (boost::weak_ptr<Track> (tr));
2021 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2023 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2025 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2030 if (_monitor_out && IO::connecting_legal) {
2032 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2033 if ((*x)->is_monitor()) {
2035 } else if ((*x)->is_master()) {
2038 (*x)->listen_via (_monitor_out,
2039 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2050 save_state (_current_snapshot_name);
2053 RouteAdded (new_routes); /* EMIT SIGNAL */
2054 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2058 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2060 boost::shared_ptr<RouteList> r = routes.reader ();
2061 boost::shared_ptr<Send> s;
2065 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2066 if (boost::dynamic_pointer_cast<Track>(*i)) {
2067 if ((s = (*i)->internal_send_for (dest)) != 0) {
2068 s->amp()->gain_control()->set_value (0.0);
2075 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2077 boost::shared_ptr<RouteList> r = routes.reader ();
2078 boost::shared_ptr<Send> s;
2082 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2083 if (boost::dynamic_pointer_cast<Track>(*i)) {
2084 if ((s = (*i)->internal_send_for (dest)) != 0) {
2085 s->amp()->gain_control()->set_value (1.0);
2092 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2094 boost::shared_ptr<RouteList> r = routes.reader ();
2095 boost::shared_ptr<Send> s;
2099 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2100 if (boost::dynamic_pointer_cast<Track>(*i)) {
2101 if ((s = (*i)->internal_send_for (dest)) != 0) {
2102 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2109 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2111 boost::shared_ptr<RouteList> r = routes.reader ();
2112 boost::shared_ptr<RouteList> t (new RouteList);
2114 /* only send tracks */
2116 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2117 if (boost::dynamic_pointer_cast<Track>(*i)) {
2122 add_internal_sends (dest, p, t);
2126 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2128 if (dest->is_monitor() || dest->is_master()) {
2132 if (!dest->internal_return()) {
2133 dest->add_internal_return();
2136 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2138 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2142 (*i)->listen_via (dest, p, true, true);
2149 Session::remove_route (shared_ptr<Route> route)
2151 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2155 route->set_solo (false, this);
2158 RCUWriter<RouteList> writer (routes);
2159 shared_ptr<RouteList> rs = writer.get_copy ();
2163 /* deleting the master out seems like a dumb
2164 idea, but its more of a UI policy issue
2168 if (route == _master_out) {
2169 _master_out = shared_ptr<Route> ();
2172 if (route == _monitor_out) {
2174 /* cancel control outs for all routes */
2176 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2177 (*r)->drop_listen (_monitor_out);
2180 _monitor_out.reset ();
2183 /* writer goes out of scope, forces route list update */
2186 update_route_solo_state ();
2187 update_session_range_location_marker ();
2189 // We need to disconnect the route's inputs and outputs
2191 route->input()->disconnect (0);
2192 route->output()->disconnect (0);
2194 /* if the route had internal sends sending to it, remove them */
2195 if (route->internal_return()) {
2197 boost::shared_ptr<RouteList> r = routes.reader ();
2198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2199 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2201 (*i)->remove_processor (s);
2206 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2207 if (mt && mt->step_editing()) {
2208 if (_step_editors > 0) {
2213 update_latency_compensation (false, false);
2216 /* Re-sort routes to remove the graph's current references to the one that is
2217 * going away, then flush old references out of the graph.
2221 route_graph->clear_other_chain ();
2223 /* get rid of it from the dead wood collection in the route list manager */
2225 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2229 /* try to cause everyone to drop their references */
2231 route->drop_references ();
2233 sync_order_keys (N_("session"));
2235 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2237 /* save the new state of the world */
2239 if (save_state (_current_snapshot_name)) {
2240 save_history (_current_snapshot_name);
2245 Session::route_mute_changed (void* /*src*/)
2251 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2253 boost::shared_ptr<Route> route = wpr.lock();
2255 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2259 if (route->listening()) {
2261 if (Config->get_exclusive_solo()) {
2262 /* new listen: disable all other listen */
2263 shared_ptr<RouteList> r = routes.reader ();
2264 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2265 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2268 (*i)->set_listen (false, this);
2274 } else if (_listen_cnt > 0) {
2280 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2282 boost::shared_ptr<Route> route = wpr.lock ();
2285 /* should not happen */
2286 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2290 bool send_changed = false;
2292 if (route->solo_isolated()) {
2293 if (_solo_isolated_cnt == 0) {
2294 send_changed = true;
2296 _solo_isolated_cnt++;
2297 } else if (_solo_isolated_cnt > 0) {
2298 _solo_isolated_cnt--;
2299 if (_solo_isolated_cnt == 0) {
2300 send_changed = true;
2305 IsolatedChanged (); /* EMIT SIGNAL */
2310 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2312 if (!self_solo_change) {
2313 // session doesn't care about changes to soloed-by-others
2317 if (solo_update_disabled) {
2322 boost::shared_ptr<Route> route = wpr.lock ();
2325 /* should not happen */
2326 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2330 shared_ptr<RouteList> r = routes.reader ();
2333 if (route->self_soloed()) {
2339 if (delta == 1 && Config->get_exclusive_solo()) {
2340 /* new solo: disable all other solos */
2341 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2342 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2345 (*i)->set_solo (false, this);
2349 solo_update_disabled = true;
2351 RouteList uninvolved;
2353 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2354 bool via_sends_only;
2355 bool in_signal_flow;
2357 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2361 in_signal_flow = false;
2363 if ((*i)->feeds (route, &via_sends_only)) {
2364 if (!via_sends_only) {
2365 if (!route->soloed_by_others_upstream()) {
2366 (*i)->mod_solo_by_others_downstream (delta);
2368 in_signal_flow = true;
2372 if (route->feeds (*i, &via_sends_only)) {
2373 (*i)->mod_solo_by_others_upstream (delta);
2374 in_signal_flow = true;
2377 if (!in_signal_flow) {
2378 uninvolved.push_back (*i);
2382 solo_update_disabled = false;
2383 update_route_solo_state (r);
2385 /* now notify that the mute state of the routes not involved in the signal
2386 pathway of the just-solo-changed route may have altered.
2389 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2390 (*i)->mute_changed (this);
2393 SoloChanged (); /* EMIT SIGNAL */
2398 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2400 /* now figure out if anything that matters is soloed (or is "listening")*/
2402 bool something_soloed = false;
2403 uint32_t listeners = 0;
2404 uint32_t isolated = 0;
2407 r = routes.reader();
2410 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2411 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2412 something_soloed = true;
2415 if (!(*i)->is_hidden() && (*i)->listening()) {
2416 if (Config->get_solo_control_is_listen_control()) {
2419 (*i)->set_listen (false, this);
2423 if ((*i)->solo_isolated()) {
2428 if (something_soloed != _non_soloed_outs_muted) {
2429 _non_soloed_outs_muted = something_soloed;
2430 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2433 _listen_cnt = listeners;
2435 if (isolated != _solo_isolated_cnt) {
2436 _solo_isolated_cnt = isolated;
2437 IsolatedChanged (); /* EMIT SIGNAL */
2441 boost::shared_ptr<RouteList>
2442 Session::get_routes_with_internal_returns() const
2444 shared_ptr<RouteList> r = routes.reader ();
2445 boost::shared_ptr<RouteList> rl (new RouteList);
2447 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2448 if ((*i)->internal_return ()) {
2456 Session::io_name_is_legal (const std::string& name)
2458 shared_ptr<RouteList> r = routes.reader ();
2460 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2461 if ((*i)->name() == name) {
2465 if ((*i)->has_io_processor_named (name)) {
2474 Session::route_by_name (string name)
2476 shared_ptr<RouteList> r = routes.reader ();
2478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2479 if ((*i)->name() == name) {
2484 return shared_ptr<Route> ((Route*) 0);
2488 Session::route_by_id (PBD::ID id)
2490 shared_ptr<RouteList> r = routes.reader ();
2492 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2493 if ((*i)->id() == id) {
2498 return shared_ptr<Route> ((Route*) 0);
2502 Session::route_by_remote_id (uint32_t id)
2504 shared_ptr<RouteList> r = routes.reader ();
2506 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2507 if ((*i)->remote_control_id() == id) {
2512 return shared_ptr<Route> ((Route*) 0);
2515 /** If either end of the session range location marker lies inside the current
2516 * session extent, move it to the corresponding session extent.
2519 Session::update_session_range_location_marker ()
2521 if (_state_of_the_state & Loading) {
2525 pair<framepos_t, framepos_t> const ext = get_extent ();
2527 if (_session_range_location == 0) {
2528 /* we don't have a session range yet; use this one (provided it is valid) */
2529 if (ext.first != max_framepos) {
2530 add_session_range_location (ext.first, ext.second);
2533 /* update the existing session range */
2534 if (ext.first < _session_range_location->start()) {
2535 _session_range_location->set_start (ext.first);
2539 if (ext.second > _session_range_location->end()) {
2540 _session_range_location->set_end (ext.second);
2547 /** @return Extent of the session's contents; if the session is empty, the first value of
2548 * the pair will equal max_framepos.
2550 pair<framepos_t, framepos_t>
2551 Session::get_extent () const
2553 pair<framepos_t, framepos_t> ext (max_framepos, 0);
2555 boost::shared_ptr<RouteList> rl = routes.reader ();
2556 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2557 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2558 if (!tr || tr->destructive()) {
2559 // ignore tape tracks when getting extents
2563 pair<framepos_t, framepos_t> e = tr->playlist()->get_extent ();
2564 if (e.first < ext.first) {
2565 ext.first = e.first;
2567 if (e.second > ext.second) {
2568 ext.second = e.second;
2575 /* Region management */
2577 boost::shared_ptr<Region>
2578 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2580 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2581 RegionFactory::RegionMap::const_iterator i;
2582 boost::shared_ptr<Region> region;
2584 Glib::Mutex::Lock lm (region_lock);
2586 for (i = regions.begin(); i != regions.end(); ++i) {
2590 if (region->whole_file()) {
2592 if (child->source_equivalent (region)) {
2598 return boost::shared_ptr<Region> ();
2602 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2604 set<boost::shared_ptr<Region> > relevant_regions;
2606 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2607 RegionFactory::get_regions_using_source (*s, relevant_regions);
2610 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2612 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2613 set<boost::shared_ptr<Region> >::iterator tmp;
2618 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2620 playlists->destroy_region (*r);
2621 RegionFactory::map_remove (*r);
2623 (*r)->drop_sources ();
2624 (*r)->drop_references ();
2626 cerr << "\tdone UC = " << (*r).use_count() << endl;
2628 relevant_regions.erase (r);
2633 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2636 Glib::Mutex::Lock ls (source_lock);
2637 /* remove from the main source list */
2638 sources.erase ((*s)->id());
2641 (*s)->mark_for_remove ();
2642 (*s)->drop_references ();
2651 Session::remove_last_capture ()
2653 list<boost::shared_ptr<Source> > srcs;
2655 boost::shared_ptr<RouteList> rl = routes.reader ();
2656 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2657 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2662 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2665 srcs.insert (srcs.end(), l.begin(), l.end());
2670 destroy_sources (srcs);
2672 save_state (_current_snapshot_name);
2677 /* Source Management */
2680 Session::add_source (boost::shared_ptr<Source> source)
2682 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2683 pair<SourceMap::iterator,bool> result;
2685 entry.first = source->id();
2686 entry.second = source;
2689 Glib::Mutex::Lock lm (source_lock);
2690 result = sources.insert (entry);
2693 if (result.second) {
2695 /* yay, new source */
2699 boost::shared_ptr<AudioFileSource> afs;
2701 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2702 if (Config->get_auto_analyse_audio()) {
2703 Analyser::queue_source_for_analysis (source, false);
2710 Session::remove_source (boost::weak_ptr<Source> src)
2712 SourceMap::iterator i;
2713 boost::shared_ptr<Source> source = src.lock();
2720 Glib::Mutex::Lock lm (source_lock);
2722 if ((i = sources.find (source->id())) != sources.end()) {
2723 cerr << "Removing source " << source->name() << endl;
2728 if (!_state_of_the_state & InCleanup) {
2730 /* save state so we don't end up with a session file
2731 referring to non-existent sources.
2734 save_state (_current_snapshot_name);
2738 boost::shared_ptr<Source>
2739 Session::source_by_id (const PBD::ID& id)
2741 Glib::Mutex::Lock lm (source_lock);
2742 SourceMap::iterator i;
2743 boost::shared_ptr<Source> source;
2745 if ((i = sources.find (id)) != sources.end()) {
2752 boost::shared_ptr<Source>
2753 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2755 Glib::Mutex::Lock lm (source_lock);
2757 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2758 boost::shared_ptr<AudioFileSource> afs
2759 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2761 if (afs && afs->path() == path && chn == afs->channel()) {
2765 return boost::shared_ptr<Source>();
2769 Session::count_sources_by_origin (const string& path)
2772 Glib::Mutex::Lock lm (source_lock);
2774 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2775 boost::shared_ptr<FileSource> fs
2776 = boost::dynamic_pointer_cast<FileSource>(i->second);
2778 if (fs && fs->origin() == path) {
2788 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2791 string old_basename = PBD::basename_nosuffix (oldname);
2792 string new_legalized = legalize_for_path (newname);
2794 /* note: we know (or assume) the old path is already valid */
2798 /* destructive file sources have a name of the form:
2800 /path/to/Tnnnn-NAME(%[LR])?.wav
2802 the task here is to replace NAME with the new name.
2807 string::size_type dash;
2809 dir = Glib::path_get_dirname (path);
2810 path = Glib::path_get_basename (path);
2812 /* '-' is not a legal character for the NAME part of the path */
2814 if ((dash = path.find_last_of ('-')) == string::npos) {
2818 prefix = path.substr (0, dash);
2822 path += new_legalized;
2823 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2825 path = Glib::build_filename (dir, path);
2829 /* non-destructive file sources have a name of the form:
2831 /path/to/NAME-nnnnn(%[LR])?.ext
2833 the task here is to replace NAME with the new name.
2838 string::size_type dash;
2839 string::size_type postfix;
2841 dir = Glib::path_get_dirname (path);
2842 path = Glib::path_get_basename (path);
2844 /* '-' is not a legal character for the NAME part of the path */
2846 if ((dash = path.find_last_of ('-')) == string::npos) {
2850 suffix = path.substr (dash+1);
2852 // Suffix is now everything after the dash. Now we need to eliminate
2853 // the nnnnn part, which is done by either finding a '%' or a '.'
2855 postfix = suffix.find_last_of ("%");
2856 if (postfix == string::npos) {
2857 postfix = suffix.find_last_of ('.');
2860 if (postfix != string::npos) {
2861 suffix = suffix.substr (postfix);
2863 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2867 const uint32_t limit = 10000;
2868 char buf[PATH_MAX+1];
2870 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2872 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2874 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2875 path = Glib::build_filename (dir, buf);
2883 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2892 /** Return the full path (in some session directory) for a new within-session source.
2893 * \a name must be a session-unique name that does not contain slashes
2894 * (e.g. as returned by new_*_source_name)
2897 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2899 assert(name.find("/") == string::npos);
2901 SessionDirectory sdir(get_best_session_directory_for_new_source());
2904 if (type == DataType::AUDIO) {
2905 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2906 } else if (type == DataType::MIDI) {
2907 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2909 error << "Unknown source type, unable to create file path" << endmsg;
2914 return p.to_string();
2918 Session::peak_path (string base) const
2920 sys::path peakfile_path(_session_dir->peak_path());
2921 peakfile_path /= base + peakfile_suffix;
2922 return peakfile_path.to_string();
2925 /** Return a unique name based on \a base for a new internal audio source */
2927 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2930 char buf[PATH_MAX+1];
2931 const uint32_t limit = 10000;
2933 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2936 legalized = legalize_for_path (base);
2938 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2939 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2941 vector<space_and_path>::iterator i;
2942 uint32_t existing = 0;
2944 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2949 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2950 cnt, legalized.c_str(), ext.c_str());
2951 } else if (nchan == 2) {
2953 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2954 cnt, legalized.c_str(), ext.c_str());
2956 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2957 cnt, legalized.c_str(), ext.c_str());
2959 } else if (nchan < 26) {
2960 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2961 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2963 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2964 cnt, legalized.c_str(), ext.c_str());
2970 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2971 } else if (nchan == 2) {
2973 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2975 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2977 } else if (nchan < 26) {
2978 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2980 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2984 SessionDirectory sdir((*i).path);
2986 string spath = sdir.sound_path().to_string();
2987 string spath_stubs = sdir.sound_stub_path().to_string();
2989 /* note that we search *without* the extension so that
2990 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2991 in the event that this new name is required for
2992 a file format change.
2995 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2996 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
3002 if (existing == 0) {
3007 error << string_compose(
3008 _("There are already %1 recordings for %2, which I consider too many."),
3009 limit, base) << endmsg;
3011 throw failed_constructor();
3015 return Glib::path_get_basename (buf);
3018 /** Create a new within-session audio source */
3019 boost::shared_ptr<AudioFileSource>
3020 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
3022 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3023 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
3025 return boost::dynamic_pointer_cast<AudioFileSource> (
3026 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3029 /** Return a unique name based on \a base for a new internal MIDI source */
3031 Session::new_midi_source_name (const string& base)
3034 char buf[PATH_MAX+1];
3035 const uint32_t limit = 10000;
3039 legalized = legalize_for_path (base);
3041 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3042 for (cnt = 1; cnt <= limit; ++cnt) {
3044 vector<space_and_path>::iterator i;
3045 uint32_t existing = 0;
3047 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3049 SessionDirectory sdir((*i).path);
3051 sys::path p = sdir.midi_path();
3054 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3056 if (sys::exists (buf)) {
3061 if (existing == 0) {
3066 error << string_compose(
3067 _("There are already %1 recordings for %2, which I consider too many."),
3068 limit, base) << endmsg;
3070 throw failed_constructor();
3074 return Glib::path_get_basename(buf);
3078 /** Create a new within-session MIDI source */
3079 boost::shared_ptr<MidiSource>
3080 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3082 /* try to use the existing write source for the track, to keep numbering sane
3086 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3090 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3093 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3094 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3098 const string name = new_midi_source_name (n);
3099 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3101 return boost::dynamic_pointer_cast<SMFSource> (
3102 SourceFactory::createWritable (
3103 DataType::MIDI, *this, path, string(), false, frame_rate()));
3108 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3110 if (playlist->hidden()) {
3114 playlists->add (playlist);
3117 playlist->release();
3124 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3126 if (_state_of_the_state & Deletion) {
3130 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3136 playlists->remove (playlist);
3142 Session::set_audition (boost::shared_ptr<Region> r)
3144 pending_audition_region = r;
3145 add_post_transport_work (PostTransportAudition);
3146 _butler->schedule_transport_work ();
3150 Session::audition_playlist ()
3152 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3153 ev->region.reset ();
3158 Session::non_realtime_set_audition ()
3160 if (!pending_audition_region) {
3161 auditioner->audition_current_playlist ();
3163 auditioner->audition_region (pending_audition_region);
3164 pending_audition_region.reset ();
3166 AuditionActive (true); /* EMIT SIGNAL */
3170 Session::audition_region (boost::shared_ptr<Region> r)
3172 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3178 Session::cancel_audition ()
3180 if (auditioner->auditioning()) {
3181 auditioner->cancel_audition ();
3182 AuditionActive (false); /* EMIT SIGNAL */
3187 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3189 if (a->is_monitor()) {
3192 if (b->is_monitor()) {
3195 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3199 Session::is_auditioning () const
3201 /* can be called before we have an auditioner object */
3203 return auditioner->auditioning();
3210 Session::graph_reordered ()
3212 /* don't do this stuff if we are setting up connections
3213 from a set_state() call or creating new tracks. Ditto for deletion.
3216 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3220 /* every track/bus asked for this to be handled but it was deferred because
3221 we were connecting. do it now.
3224 request_input_change_handling ();
3228 /* force all diskstreams to update their capture offset values to
3229 reflect any changes in latencies within the graph.
3232 boost::shared_ptr<RouteList> rl = routes.reader ();
3233 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3234 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3236 tr->set_capture_offset ();
3242 Session::available_capture_duration ()
3244 float sample_bytes_on_disk = 4.0; // keep gcc happy
3246 switch (config.get_native_file_data_format()) {
3248 sample_bytes_on_disk = 4.0;
3252 sample_bytes_on_disk = 3.0;
3256 sample_bytes_on_disk = 2.0;
3260 /* impossible, but keep some gcc versions happy */
3261 fatal << string_compose (_("programming error: %1"),
3262 X_("illegal native file data format"))
3267 double scale = 4096.0 / sample_bytes_on_disk;
3269 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3270 return max_framecnt;
3273 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3277 Session::add_bundle (shared_ptr<Bundle> bundle)
3280 RCUWriter<BundleList> writer (_bundles);
3281 boost::shared_ptr<BundleList> b = writer.get_copy ();
3282 b->push_back (bundle);
3285 BundleAdded (bundle); /* EMIT SIGNAL */
3291 Session::remove_bundle (shared_ptr<Bundle> bundle)
3293 bool removed = false;
3296 RCUWriter<BundleList> writer (_bundles);
3297 boost::shared_ptr<BundleList> b = writer.get_copy ();
3298 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3300 if (i != b->end()) {
3307 BundleRemoved (bundle); /* EMIT SIGNAL */
3314 Session::bundle_by_name (string name) const
3316 boost::shared_ptr<BundleList> b = _bundles.reader ();
3318 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3319 if ((*i)->name() == name) {
3324 return boost::shared_ptr<Bundle> ();
3328 Session::tempo_map_changed (const PropertyChange&)
3332 playlists->update_after_tempo_map_change ();
3334 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3340 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3342 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3343 (*i)->recompute_frames_from_bbt ();
3347 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3348 * the given count with the current block size.
3351 Session::ensure_buffers (ChanCount howmany)
3353 BufferManager::ensure_buffers (howmany);
3357 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3359 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3360 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3365 Session::next_insert_id ()
3367 /* this doesn't really loop forever. just think about it */
3370 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3371 if (!insert_bitset[n]) {
3372 insert_bitset[n] = true;
3378 /* none available, so resize and try again */
3380 insert_bitset.resize (insert_bitset.size() + 16, false);
3385 Session::next_send_id ()
3387 /* this doesn't really loop forever. just think about it */
3390 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3391 if (!send_bitset[n]) {
3392 send_bitset[n] = true;
3398 /* none available, so resize and try again */
3400 send_bitset.resize (send_bitset.size() + 16, false);
3405 Session::next_return_id ()
3407 /* this doesn't really loop forever. just think about it */
3410 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3411 if (!return_bitset[n]) {
3412 return_bitset[n] = true;
3418 /* none available, so resize and try again */
3420 return_bitset.resize (return_bitset.size() + 16, false);
3425 Session::mark_send_id (uint32_t id)
3427 if (id >= send_bitset.size()) {
3428 send_bitset.resize (id+16, false);
3430 if (send_bitset[id]) {
3431 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3433 send_bitset[id] = true;
3437 Session::mark_return_id (uint32_t id)
3439 if (id >= return_bitset.size()) {
3440 return_bitset.resize (id+16, false);
3442 if (return_bitset[id]) {
3443 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3445 return_bitset[id] = true;
3449 Session::mark_insert_id (uint32_t id)
3451 if (id >= insert_bitset.size()) {
3452 insert_bitset.resize (id+16, false);
3454 if (insert_bitset[id]) {
3455 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3457 insert_bitset[id] = true;
3461 Session::unmark_send_id (uint32_t id)
3463 if (id < send_bitset.size()) {
3464 send_bitset[id] = false;
3469 Session::unmark_return_id (uint32_t id)
3471 if (id < return_bitset.size()) {
3472 return_bitset[id] = false;
3477 Session::unmark_insert_id (uint32_t id)
3479 if (id < insert_bitset.size()) {
3480 insert_bitset[id] = false;
3485 /* Named Selection management */
3487 boost::shared_ptr<NamedSelection>
3488 Session::named_selection_by_name (string name)
3490 Glib::Mutex::Lock lm (named_selection_lock);
3491 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3492 if ((*i)->name == name) {
3496 return boost::shared_ptr<NamedSelection>();
3500 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3503 Glib::Mutex::Lock lm (named_selection_lock);
3504 named_selections.insert (named_selections.begin(), named_selection);
3509 NamedSelectionAdded (); /* EMIT SIGNAL */
3513 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3515 bool removed = false;
3518 Glib::Mutex::Lock lm (named_selection_lock);
3520 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3522 if (i != named_selections.end()) {
3523 named_selections.erase (i);
3530 NamedSelectionRemoved (); /* EMIT SIGNAL */
3535 Session::reset_native_file_format ()
3537 boost::shared_ptr<RouteList> rl = routes.reader ();
3538 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3539 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3541 /* don't save state as we do this, there's no point
3544 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3545 tr->reset_write_sources (false);
3546 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3552 Session::route_name_unique (string n) const
3554 shared_ptr<RouteList> r = routes.reader ();
3556 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3557 if ((*i)->name() == n) {
3566 Session::route_name_internal (string n) const
3568 if (auditioner && auditioner->name() == n) {
3572 if (_click_io && _click_io->name() == n) {
3580 Session::freeze_all (InterThreadInfo& itt)
3582 shared_ptr<RouteList> r = routes.reader ();
3584 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3586 boost::shared_ptr<Track> t;
3588 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3589 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3599 boost::shared_ptr<Region>
3600 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3601 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3602 InterThreadInfo& itt, bool enable_processing)
3604 boost::shared_ptr<Region> result;
3605 boost::shared_ptr<Playlist> playlist;
3606 boost::shared_ptr<AudioFileSource> fsource;
3608 char buf[PATH_MAX+1];
3609 ChanCount nchans(track.n_channels());
3610 framepos_t position;
3611 framecnt_t this_chunk;
3614 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3615 const string sound_dir = sdir.sound_path().to_string();
3616 framepos_t len = end - start;
3617 bool need_block_size_reset = false;
3621 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3622 end, start) << endmsg;
3626 const framecnt_t chunk_size = (256 * 1024)/4;
3628 // block all process callback handling
3630 block_processing ();
3632 /* call tree *MUST* hold route_lock */
3634 if ((playlist = track.playlist()) == 0) {
3638 /* external redirects will be a problem */
3640 if (track.has_external_redirects()) {
3644 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3646 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3648 for (x = 0; x < 99999; ++x) {
3649 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());
3650 if (access (buf, F_OK) != 0) {
3656 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3661 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3662 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3665 catch (failed_constructor& err) {
3666 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3670 srcs.push_back (fsource);
3673 /* tell redirects that care that we are about to use a much larger blocksize */
3675 need_block_size_reset = true;
3676 track.set_block_size (chunk_size);
3678 /* XXX need to flush all redirects */
3683 /* create a set of reasonably-sized buffers */
3684 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3685 buffers.set_count(nchans);
3687 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3688 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3690 afs->prepare_for_peakfile_writes ();
3693 while (to_do && !itt.cancel) {
3695 this_chunk = min (to_do, chunk_size);
3697 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3702 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3703 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3706 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3712 start += this_chunk;
3713 to_do -= this_chunk;
3715 itt.progress = (float) (1.0 - ((double) to_do / len));
3724 xnow = localtime (&now);
3726 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3727 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3730 afs->update_header (position, *xnow, now);
3731 afs->flush_header ();
3735 /* construct a region to represent the bounced material */
3739 plist.add (Properties::start, 0);
3740 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3741 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3743 result = RegionFactory::create (srcs, plist);
3749 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3750 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3753 afs->mark_for_remove ();
3756 (*src)->drop_references ();
3760 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3761 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3764 afs->done_with_peakfile_writes ();
3769 if (need_block_size_reset) {
3770 track.set_block_size (get_block_size());
3773 unblock_processing ();
3779 Session::gain_automation_buffer() const
3781 return ProcessThread::gain_automation_buffer ();
3785 Session::pan_automation_buffer() const
3787 return ProcessThread::pan_automation_buffer ();
3791 Session::get_silent_buffers (ChanCount count)
3793 return ProcessThread::get_silent_buffers (count);
3795 assert(_silent_buffers->available() >= count);
3796 _silent_buffers->set_count(count);
3798 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3799 for (size_t i= 0; i < count.get(*t); ++i) {
3800 _silent_buffers->get(*t, i).clear();
3804 return *_silent_buffers;
3809 Session::get_scratch_buffers (ChanCount count)
3811 return ProcessThread::get_scratch_buffers (count);
3813 if (count != ChanCount::ZERO) {
3814 assert(_scratch_buffers->available() >= count);
3815 _scratch_buffers->set_count(count);
3817 _scratch_buffers->set_count (_scratch_buffers->available());
3820 return *_scratch_buffers;
3825 Session::get_mix_buffers (ChanCount count)
3827 return ProcessThread::get_mix_buffers (count);
3829 assert(_mix_buffers->available() >= count);
3830 _mix_buffers->set_count(count);
3831 return *_mix_buffers;
3836 Session::ntracks () const
3839 shared_ptr<RouteList> r = routes.reader ();
3841 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3842 if (boost::dynamic_pointer_cast<Track> (*i)) {
3851 Session::nbusses () const
3854 shared_ptr<RouteList> r = routes.reader ();
3856 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3857 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3866 Session::add_automation_list(AutomationList *al)
3868 automation_lists[al->id()] = al;
3872 Session::sync_order_keys (std::string const & base)
3874 if (deletion_in_progress()) {
3878 if (!Config->get_sync_all_route_ordering()) {
3879 /* leave order keys as they are */
3883 boost::shared_ptr<RouteList> r = routes.reader ();
3885 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3886 (*i)->sync_order_keys (base);
3889 Route::SyncOrderKeys (base); // EMIT SIGNAL
3891 /* this might not do anything */
3893 set_remote_control_ids ();
3896 /** @return true if there is at least one record-enabled track, otherwise false */
3898 Session::have_rec_enabled_track () const
3900 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3903 /** Update the state of our rec-enabled tracks flag */
3905 Session::update_have_rec_enabled_track ()
3907 boost::shared_ptr<RouteList> rl = routes.reader ();
3908 RouteList::iterator i = rl->begin();
3909 while (i != rl->end ()) {
3911 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3912 if (tr && tr->record_enabled ()) {
3919 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3921 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3923 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3924 RecordStateChanged (); /* EMIT SIGNAL */
3929 Session::listen_position_changed ()
3933 switch (Config->get_listen_position()) {
3934 case AfterFaderListen:
3938 case PreFaderListen:
3943 boost::shared_ptr<RouteList> r = routes.reader ();
3945 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3946 (*i)->put_monitor_send_at (p);
3951 Session::solo_control_mode_changed ()
3953 /* cancel all solo or all listen when solo control mode changes */
3956 set_solo (get_routes(), false);
3957 } else if (listening()) {
3958 set_listen (get_routes(), false);
3962 /** Called when anything about any of our route groups changes (membership, state etc.) */
3964 Session::route_group_changed ()
3966 RouteGroupChanged (); /* EMIT SIGNAL */
3970 Session::get_available_sync_options () const
3972 vector<SyncSource> ret;
3974 ret.push_back (JACK);
3975 ret.push_back (MTC);
3976 ret.push_back (MIDIClock);
3981 boost::shared_ptr<RouteList>
3982 Session::get_routes_with_regions_at (framepos_t const p) const
3984 shared_ptr<RouteList> r = routes.reader ();
3985 shared_ptr<RouteList> rl (new RouteList);
3987 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3988 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3993 boost::shared_ptr<Playlist> pl = tr->playlist ();
3998 if (pl->has_region_at (p)) {
4007 Session::goto_end ()
4009 if (_session_range_location) {
4010 request_locate (_session_range_location->end(), false);
4012 request_locate (0, false);
4017 Session::goto_start ()
4019 if (_session_range_location) {
4020 request_locate (_session_range_location->start(), false);
4022 request_locate (0, false);
4027 Session::current_start_frame () const
4029 return _session_range_location ? _session_range_location->start() : 0;
4033 Session::current_end_frame () const
4035 return _session_range_location ? _session_range_location->end() : 0;
4039 Session::add_session_range_location (nframes_t start, nframes_t end)
4041 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4042 _locations->add (_session_range_location);
4045 /** Called when one of our routes' order keys has changed */
4047 Session::route_order_key_changed ()
4049 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4053 Session::step_edit_status_change (bool yn)
4059 send = (_step_editors == 0);
4064 send = (_step_editors == 1);
4067 if (_step_editors > 0) {
4073 StepEditStatusChange (val);
4079 Session::start_time_changed (framepos_t old)
4081 /* Update the auto loop range to match the session range
4082 (unless the auto loop range has been changed by the user)
4085 Location* s = _locations->session_range_location ();
4086 Location* l = _locations->auto_loop_location ();
4088 if (l->start() == old) {
4089 l->set_start (s->start(), true);
4094 Session::end_time_changed (framepos_t old)
4096 /* Update the auto loop range to match the session range
4097 (unless the auto loop range has been changed by the user)
4100 Location* s = _locations->session_range_location ();
4101 Location* l = _locations->auto_loop_location ();
4103 if (l->end() == old) {
4104 l->set_end (s->end(), true);
4109 Session::source_search_path (DataType type) const
4113 if (session_dirs.size() == 1) {
4115 case DataType::AUDIO:
4116 search_path = _session_dir->sound_path().to_string();
4118 case DataType::MIDI:
4119 search_path = _session_dir->midi_path().to_string();
4123 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4124 SessionDirectory sdir (i->path);
4125 if (!search_path.empty()) {
4129 case DataType::AUDIO:
4130 search_path += sdir.sound_path().to_string();
4132 case DataType::MIDI:
4133 search_path += sdir.midi_path().to_string();
4139 /* now add user-specified locations
4142 vector<string> dirs;
4145 case DataType::AUDIO:
4146 split (config.get_audio_search_path (), dirs, ':');
4148 case DataType::MIDI:
4149 split (config.get_midi_search_path (), dirs, ':');
4153 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4163 Session::ensure_search_path_includes (const string& path, DataType type)
4166 vector<string> dirs;
4173 case DataType::AUDIO:
4174 search_path = config.get_audio_search_path ();
4176 case DataType::MIDI:
4177 search_path = config.get_midi_search_path ();
4181 split (search_path, dirs, ':');
4183 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4189 if (!search_path.empty()) {
4193 search_path += path;
4196 case DataType::AUDIO:
4197 config.set_audio_search_path (search_path);
4199 case DataType::MIDI:
4200 config.set_midi_search_path (search_path);
4206 Session::get_speakers()
4209 _speakers = new VBAPSpeakers;