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 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
553 /* don't connect the master bus outputs if there is a monitor bus */
555 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
557 /* if requested auto-connect the outputs to the first N physical ports.
560 uint32_t limit = _master_out->n_outputs().n_total();
562 for (uint32_t n = 0; n < limit; ++n) {
563 Port* p = _master_out->output()->nth (n);
565 if (outputs[p->type()].size() > n) {
566 connect_to = outputs[p->type()][n];
569 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
570 if (_master_out->output()->connect (p, connect_to, this)) {
571 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
581 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
582 are undefined, at best.
585 /* control out listens to master bus (but ignores it
586 under some conditions)
589 uint32_t limit = _monitor_out->n_inputs().n_audio();
592 for (uint32_t n = 0; n < limit; ++n) {
593 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
594 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
597 string connect_to = o->name();
598 if (_monitor_out->input()->connect (p, connect_to, this)) {
599 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
607 /* if control out is not connected, connect control out to physical outs
610 if (!_monitor_out->output()->connected ()) {
612 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
614 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
617 _monitor_out->output()->connect_ports_to_bundle (b, this);
619 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
620 Config->get_monitor_bus_preferred_bundle())
626 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
627 uint32_t mod = n_physical_outputs.get (*t);
628 uint32_t limit = _monitor_out->n_outputs().get(*t);
630 for (uint32_t n = 0; n < limit; ++n) {
632 Port* p = _monitor_out->output()->ports().port(*t, n);
634 if (outputs[*t].size() > (n % mod)) {
635 connect_to = outputs[*t][n % mod];
638 if (!connect_to.empty()) {
639 if (_monitor_out->output()->connect (p, connect_to, this)) {
640 error << string_compose (
641 _("cannot connect control output %1 to %2"),
654 /* catch up on send+insert cnts */
656 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
658 /* hook us up to the engine */
660 BootMessage (_("Connect to engine"));
662 _engine.set_session (this);
666 Session::hookup_io ()
668 /* stop graph reordering notifications from
669 causing resorts, etc.
672 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
677 /* we delay creating the auditioner till now because
678 it makes its own connections to ports.
682 Auditioner* a = new Auditioner (*this);
685 throw failed_constructor();
687 a->use_new_diskstream ();
688 auditioner.reset (a);
691 catch (failed_constructor& err) {
692 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
696 /* load bundles, which we may have postponed earlier on */
697 if (_bundle_xml_node) {
698 load_bundles (*_bundle_xml_node);
699 delete _bundle_xml_node;
702 /* Tell all IO objects to connect themselves together */
704 IO::enable_connecting ();
705 MIDI::Port::MakeConnections ();
707 /* Now reset all panners */
709 Delivery::reset_panners ();
711 /* Connect tracks to monitor/listen bus if there is one.
712 Note that in an existing session, the internal sends will
713 already exist, but we want the routes to notice that
714 they connect to the control out specifically.
718 boost::shared_ptr<RouteList> r = routes.reader ();
719 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
721 if ((*x)->is_monitor()) {
725 } else if ((*x)->is_master()) {
731 (*x)->listen_via (_monitor_out,
732 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
738 /* Anyone who cares about input state, wake up and do something */
740 IOConnectionsComplete (); /* EMIT SIGNAL */
742 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
744 /* now handle the whole enchilada as if it was one
750 /* update the full solo state, which can't be
751 correctly determined on a per-route basis, but
752 needs the global overview that only the session
756 update_route_solo_state ();
760 Session::playlist_length_changed ()
762 update_session_range_location_marker ();
766 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
768 boost::shared_ptr<Track> track = wp.lock ();
773 boost::shared_ptr<Playlist> playlist;
775 if ((playlist = track->playlist()) != 0) {
776 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
779 update_session_range_location_marker ();
783 Session::record_enabling_legal () const
785 /* this used to be in here, but survey says.... we don't need to restrict it */
786 // if (record_status() == Recording) {
790 if (Config->get_all_safe()) {
797 Session::reset_input_monitor_state ()
799 if (transport_rolling()) {
801 boost::shared_ptr<RouteList> rl = routes.reader ();
802 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
803 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
804 if (tr && tr->record_enabled ()) {
805 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
806 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
812 boost::shared_ptr<RouteList> rl = routes.reader ();
813 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
814 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
815 if (tr && tr->record_enabled ()) {
816 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
817 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
824 Session::auto_punch_start_changed (Location* location)
826 replace_event (SessionEvent::PunchIn, location->start());
828 if (get_record_enabled() && config.get_punch_in()) {
829 /* capture start has been changed, so save new pending state */
830 save_state ("", true);
835 Session::auto_punch_end_changed (Location* location)
837 nframes_t when_to_stop = location->end();
838 // when_to_stop += _worst_output_latency + _worst_input_latency;
839 replace_event (SessionEvent::PunchOut, when_to_stop);
843 Session::auto_punch_changed (Location* location)
845 nframes_t when_to_stop = location->end();
847 replace_event (SessionEvent::PunchIn, location->start());
848 //when_to_stop += _worst_output_latency + _worst_input_latency;
849 replace_event (SessionEvent::PunchOut, when_to_stop);
853 Session::auto_loop_changed (Location* location)
855 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
857 if (transport_rolling() && play_loop) {
860 // if (_transport_frame > location->end()) {
862 if (_transport_frame < location->start() || _transport_frame > location->end()) {
863 // relocate to beginning of loop
864 clear_events (SessionEvent::LocateRoll);
866 request_locate (location->start(), true);
869 else if (Config->get_seamless_loop() && !loop_changing) {
871 // schedule a locate-roll to refill the diskstreams at the
873 loop_changing = true;
875 if (location->end() > last_loopend) {
876 clear_events (SessionEvent::LocateRoll);
877 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
884 last_loopend = location->end();
888 Session::set_auto_punch_location (Location* location)
892 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
893 punch_connections.drop_connections();
894 existing->set_auto_punch (false, this);
895 remove_event (existing->start(), SessionEvent::PunchIn);
896 clear_events (SessionEvent::PunchOut);
897 auto_punch_location_changed (0);
906 if (location->end() <= location->start()) {
907 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
911 punch_connections.drop_connections ();
913 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
914 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
915 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
917 location->set_auto_punch (true, this);
919 auto_punch_changed (location);
921 auto_punch_location_changed (location);
925 Session::set_auto_loop_location (Location* location)
929 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
930 loop_connections.drop_connections ();
931 existing->set_auto_loop (false, this);
932 remove_event (existing->end(), SessionEvent::AutoLoop);
933 auto_loop_location_changed (0);
942 if (location->end() <= location->start()) {
943 error << _("Session: you can't use a mark for auto loop") << endmsg;
947 last_loopend = location->end();
949 loop_connections.drop_connections ();
951 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
952 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
953 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
955 location->set_auto_loop (true, this);
957 /* take care of our stuff first */
959 auto_loop_changed (location);
961 /* now tell everyone else */
963 auto_loop_location_changed (location);
967 Session::locations_added (Location *)
973 Session::locations_changed ()
975 _locations->apply (*this, &Session::handle_locations_changed);
979 Session::handle_locations_changed (Locations::LocationList& locations)
981 Locations::LocationList::iterator i;
983 bool set_loop = false;
984 bool set_punch = false;
986 for (i = locations.begin(); i != locations.end(); ++i) {
990 if (location->is_auto_punch()) {
991 set_auto_punch_location (location);
994 if (location->is_auto_loop()) {
995 set_auto_loop_location (location);
999 if (location->is_session_range()) {
1000 _session_range_location = location;
1005 set_auto_loop_location (0);
1008 set_auto_punch_location (0);
1015 Session::enable_record ()
1018 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1020 if (rs == Recording) {
1024 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1026 _last_record_location = _transport_frame;
1027 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1029 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1031 boost::shared_ptr<RouteList> rl = routes.reader ();
1032 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1033 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1034 if (tr && tr->record_enabled ()) {
1035 tr->monitor_input (true);
1040 RecordStateChanged ();
1047 Session::disable_record (bool rt_context, bool force)
1051 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1053 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1054 g_atomic_int_set (&_record_status, Disabled);
1055 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1057 if (rs == Recording) {
1058 g_atomic_int_set (&_record_status, Enabled);
1062 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1064 boost::shared_ptr<RouteList> rl = routes.reader ();
1065 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1066 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1067 if (tr && tr->record_enabled ()) {
1068 tr->monitor_input (false);
1073 RecordStateChanged (); /* emit signal */
1076 remove_pending_capture_state ();
1082 Session::step_back_from_record ()
1084 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1086 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1087 boost::shared_ptr<RouteList> rl = routes.reader ();
1088 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1089 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1090 if (tr && tr->record_enabled ()) {
1091 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1092 tr->monitor_input (false);
1100 Session::maybe_enable_record ()
1102 if (_step_editors > 0) {
1106 g_atomic_int_set (&_record_status, Enabled);
1108 /* This function is currently called from somewhere other than an RT thread.
1109 This save_state() call therefore doesn't impact anything. Doing it here
1110 means that we save pending state of which sources the next record will use,
1111 which gives us some chance of recovering from a crash during the record.
1114 save_state ("", true);
1116 if (_transport_speed) {
1117 if (!config.get_punch_in()) {
1121 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1122 RecordStateChanged (); /* EMIT SIGNAL */
1129 Session::audible_frame () const
1135 /* the first of these two possible settings for "offset"
1136 mean that the audible frame is stationary until
1137 audio emerges from the latency compensation
1140 the second means that the audible frame is stationary
1141 until audio would emerge from a physical port
1142 in the absence of any plugin latency compensation
1145 offset = _worst_output_latency;
1147 if (offset > current_block_size) {
1148 offset -= current_block_size;
1150 /* XXX is this correct? if we have no external
1151 physical connections and everything is internal
1152 then surely this is zero? still, how
1153 likely is that anyway?
1155 offset = current_block_size;
1158 if (synced_to_jack()) {
1159 tf = _engine.transport_frame();
1161 tf = _transport_frame;
1166 if (!non_realtime_work_pending()) {
1170 /* Check to see if we have passed the first guaranteed
1171 audible frame past our last start position. if not,
1172 return that last start point because in terms
1173 of audible frames, we have not moved yet.
1175 `Start position' in this context means the time we last
1176 either started or changed transport direction.
1179 if (_transport_speed > 0.0f) {
1181 if (!play_loop || !have_looped) {
1182 if (tf < _last_roll_or_reversal_location + offset) {
1183 return _last_roll_or_reversal_location;
1191 } else if (_transport_speed < 0.0f) {
1193 /* XXX wot? no backward looping? */
1195 if (tf > _last_roll_or_reversal_location - offset) {
1196 return _last_roll_or_reversal_location;
1208 Session::set_frame_rate (nframes_t frames_per_second)
1210 /** \fn void Session::set_frame_size(nframes_t)
1211 the AudioEngine object that calls this guarantees
1212 that it will not be called while we are also in
1213 ::process(). Its fine to do things that block
1217 _base_frame_rate = frames_per_second;
1221 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1225 // XXX we need some equivalent to this, somehow
1226 // SndFileSource::setup_standard_crossfades (frames_per_second);
1230 /* XXX need to reset/reinstantiate all LADSPA plugins */
1234 Session::set_block_size (nframes_t nframes)
1236 /* the AudioEngine guarantees
1237 that it will not be called while we are also in
1238 ::process(). It is therefore fine to do things that block
1243 current_block_size = nframes;
1247 boost::shared_ptr<RouteList> r = routes.reader ();
1249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1250 (*i)->set_block_size (nframes);
1253 boost::shared_ptr<RouteList> rl = routes.reader ();
1254 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1255 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1257 tr->set_block_size (nframes);
1261 set_worst_io_latencies ();
1266 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1269 nframes_t fade_frames;
1271 /* Don't allow fade of less 1 frame */
1273 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1280 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1284 default_fade_msecs = fade_msecs;
1285 default_fade_steepness = steepness;
1288 // jlc, WTF is this!
1289 Glib::RWLock::ReaderLock lm (route_lock);
1290 AudioRegion::set_default_fade (steepness, fade_frames);
1295 /* XXX have to do this at some point */
1296 /* foreach region using default fade, reset, then
1297 refill_all_diskstream_buffers ();
1302 struct RouteSorter {
1303 /** @return true to run r1 before r2, otherwise false */
1304 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1305 if (r2->feeds (r1)) {
1306 /* r1 fed by r2; run r2 early */
1308 } else if (r1->feeds (r2)) {
1309 /* r2 fed by r1; run r1 early */
1312 if (r1->not_fed ()) {
1313 if (r2->not_fed ()) {
1314 /* no ardour-based connections inbound to either route. just use signal order */
1315 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1317 /* r2 has connections, r1 does not; run r1 early */
1321 if (r2->not_fed()) {
1322 /* r1 has connections, r2 does not; run r2 early */
1325 /* both r1 and r2 have connections, but not to each other. just use signal order */
1326 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1334 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1336 shared_ptr<Route> r2;
1338 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1339 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1343 /* make a copy of the existing list of routes that feed r1 */
1345 Route::FedBy existing (r1->fed_by());
1347 /* for each route that feeds r1, recurse, marking it as feeding
1351 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1352 if (!(r2 = i->r.lock ())) {
1353 /* (*i) went away, ignore it */
1357 /* r2 is a route that feeds r1 which somehow feeds base. mark
1358 base as being fed by r2
1361 rbase->add_fed_by (r2, i->sends_only);
1365 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1369 if (r1->feeds (r2) && r2->feeds (r1)) {
1373 /* now recurse, so that we can mark base as being fed by
1374 all routes that feed r2
1377 trace_terminal (r2, rbase);
1384 Session::resort_routes ()
1386 /* don't do anything here with signals emitted
1387 by Routes while we are being destroyed.
1390 if (_state_of_the_state & Deletion) {
1395 RCUWriter<RouteList> writer (routes);
1396 shared_ptr<RouteList> r = writer.get_copy ();
1397 resort_routes_using (r);
1398 /* writer goes out of scope and forces update */
1401 //route_graph->dump(1);
1404 boost::shared_ptr<RouteList> rl = routes.reader ();
1405 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1406 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1408 const Route::FedBy& fb ((*i)->fed_by());
1410 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1411 boost::shared_ptr<Route> sf = f->r.lock();
1413 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1421 Session::resort_routes_using (shared_ptr<RouteList> r)
1423 RouteList::iterator i, j;
1425 for (i = r->begin(); i != r->end(); ++i) {
1427 (*i)->clear_fed_by ();
1429 for (j = r->begin(); j != r->end(); ++j) {
1431 /* although routes can feed themselves, it will
1432 cause an endless recursive descent if we
1433 detect it. so don't bother checking for
1441 bool via_sends_only;
1443 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1444 (*i)->add_fed_by (*j, via_sends_only);
1449 for (i = r->begin(); i != r->end(); ++i) {
1450 trace_terminal (*i, *i);
1456 route_graph->rechain (r);
1459 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1460 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1461 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1462 (*i)->name(), (*i)->order_key ("signal")));
1468 /** Find the route name starting with \a base with the lowest \a id.
1470 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1471 * The available route name with the lowest ID will be used, and \a id
1472 * will be set to the ID.
1474 * \return false if a route name could not be found, and \a track_name
1475 * and \a id do not reflect a free route name.
1478 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1481 snprintf (name, name_len, "%s %" PRIu32, base, id);
1483 if (route_by_name (name) == 0) {
1489 } while (id < (UINT_MAX-1));
1494 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1496 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1498 in = ChanCount::ZERO;
1499 out = ChanCount::ZERO;
1500 shared_ptr<RouteList> r = routes.reader ();
1501 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1502 if (!(*i)->is_hidden()) {
1503 in += (*i)->n_inputs();
1504 out += (*i)->n_outputs();
1509 /** Caller must not hold process lock */
1510 list<boost::shared_ptr<MidiTrack> >
1511 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1513 char track_name[32];
1514 uint32_t track_id = 0;
1515 ChanCount existing_inputs;
1516 ChanCount existing_outputs;
1518 RouteList new_routes;
1519 list<boost::shared_ptr<MidiTrack> > ret;
1520 uint32_t control_id;
1522 count_existing_route_channels (existing_inputs, existing_outputs);
1524 control_id = ntracks() + nbusses();
1527 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1528 error << "cannot find name for new midi track" << endmsg;
1532 shared_ptr<MidiTrack> track;
1535 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1542 mt->use_new_diskstream();
1544 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1545 track = boost::shared_ptr<MidiTrack>(mt);
1548 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1549 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1550 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1554 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1555 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1560 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1562 track->non_realtime_input_change();
1565 route_group->add (track);
1568 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1569 track->set_remote_control_id (control_id);
1571 new_routes.push_back (track);
1572 ret.push_back (track);
1575 catch (failed_constructor &err) {
1576 error << _("Session: could not create new midi track.") << endmsg;
1580 catch (AudioEngine::PortRegistrationFailure& pfe) {
1582 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;
1590 if (!new_routes.empty()) {
1591 add_routes (new_routes, false);
1592 save_state (_current_snapshot_name);
1598 /** Caller must hold process lock.
1599 * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1600 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1601 * @param output_start As \a input_start, but for outputs.
1604 Session::auto_connect_route (
1605 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1608 /* If both inputs and outputs are auto-connected to physical ports,
1609 use the max of input and output offsets to ensure auto-connected
1610 port numbers always match up (e.g. the first audio input and the
1611 first audio output of the route will have the same physical
1612 port number). Otherwise just use the lowest input or output
1616 const bool in_out_physical =
1617 (Config->get_input_auto_connect() & AutoConnectPhysical)
1618 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1621 const ChanCount in_offset = in_out_physical
1622 ? ChanCount::max(existing_inputs, existing_outputs)
1625 const ChanCount out_offset = in_out_physical
1626 ? ChanCount::max(existing_inputs, existing_outputs)
1629 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1630 vector<string> physinputs;
1631 vector<string> physoutputs;
1633 _engine.get_physical_outputs (*t, physoutputs);
1634 _engine.get_physical_inputs (*t, physinputs);
1636 if (!physinputs.empty() && connect_inputs) {
1637 uint32_t nphysical_in = physinputs.size();
1638 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1641 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1642 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1645 if (!port.empty() && route->input()->connect (
1646 route->input()->ports().port(*t, i), port, this)) {
1652 if (!physoutputs.empty()) {
1653 uint32_t nphysical_out = physoutputs.size();
1654 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1657 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1658 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1659 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1660 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1661 port = _master_out->input()->ports().port(*t,
1662 i % _master_out->input()->n_ports().get(*t))->name();
1666 if (!port.empty() && route->output()->connect (
1667 route->output()->ports().port(*t, i), port, this)) {
1674 existing_inputs += route->n_inputs();
1675 existing_outputs += route->n_outputs();
1678 /** Caller must not hold process lock */
1679 list< boost::shared_ptr<AudioTrack> >
1680 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1682 char track_name[32];
1683 uint32_t track_id = 0;
1684 ChanCount existing_inputs;
1685 ChanCount existing_outputs;
1687 RouteList new_routes;
1688 list<boost::shared_ptr<AudioTrack> > ret;
1689 uint32_t control_id;
1691 count_existing_route_channels (existing_inputs, existing_outputs);
1693 control_id = ntracks() + nbusses() + 1;
1696 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1697 error << "cannot find name for new audio track" << endmsg;
1701 shared_ptr<AudioTrack> track;
1704 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1711 at->use_new_diskstream();
1713 boost_debug_shared_ptr_mark_interesting (at, "Track");
1714 track = boost::shared_ptr<AudioTrack>(at);
1717 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1719 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1720 error << string_compose (
1721 _("cannot configure %1 in/%2 out configuration for new audio track"),
1722 input_channels, output_channels)
1727 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1728 error << string_compose (
1729 _("cannot configure %1 in/%2 out configuration for new audio track"),
1730 input_channels, output_channels)
1735 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1739 route_group->add (track);
1742 track->non_realtime_input_change();
1744 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1745 track->set_remote_control_id (control_id);
1748 new_routes.push_back (track);
1749 ret.push_back (track);
1752 catch (failed_constructor &err) {
1753 error << _("Session: could not create new audio track.") << endmsg;
1757 catch (AudioEngine::PortRegistrationFailure& pfe) {
1759 error << pfe.what() << endmsg;
1767 if (!new_routes.empty()) {
1768 add_routes (new_routes, true);
1775 Session::set_remote_control_ids ()
1777 RemoteModel m = Config->get_remote_model();
1778 bool emit_signal = false;
1780 shared_ptr<RouteList> r = routes.reader ();
1782 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1783 if (MixerOrdered == m) {
1784 int32_t order = (*i)->order_key(N_("signal"));
1785 (*i)->set_remote_control_id (order+1, false);
1787 } else if (EditorOrdered == m) {
1788 int32_t order = (*i)->order_key(N_("editor"));
1789 (*i)->set_remote_control_id (order+1, false);
1791 } else if (UserOrdered == m) {
1792 //do nothing ... only changes to remote id's are initiated by user
1797 Route::RemoteControlIDChange();
1801 /** Caller must not hold process lock */
1803 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1806 uint32_t bus_id = 0;
1807 ChanCount existing_inputs;
1808 ChanCount existing_outputs;
1811 uint32_t control_id;
1813 count_existing_route_channels (existing_inputs, existing_outputs);
1815 control_id = ntracks() + nbusses() + 1;
1818 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1819 error << "cannot find name for new audio bus" << endmsg;
1824 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1831 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1832 shared_ptr<Route> bus (rt);
1835 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1837 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1838 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1839 input_channels, output_channels)
1845 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1846 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1847 input_channels, output_channels)
1852 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1856 route_group->add (bus);
1858 bus->set_remote_control_id (control_id);
1862 bus->add_internal_return ();
1865 ret.push_back (bus);
1869 catch (failed_constructor &err) {
1870 error << _("Session: could not create new audio route.") << endmsg;
1874 catch (AudioEngine::PortRegistrationFailure& pfe) {
1875 error << pfe.what() << endmsg;
1885 add_routes (ret, true);
1893 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1897 uint32_t control_id;
1899 uint32_t number = 0;
1901 if (!tree.read (template_path.c_str())) {
1905 XMLNode* node = tree.root();
1907 control_id = ntracks() + nbusses() + 1;
1911 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1913 std::string node_name = IO::name_from_state (*node_copy.children().front());
1915 /* generate a new name by adding a number to the end of the template name */
1916 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1917 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1921 /* set IO children to use the new name */
1922 XMLNodeList const & children = node_copy.children ();
1923 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1924 if ((*i)->name() == IO::state_node_name) {
1925 IO::set_name_in_state (**i, name);
1929 Track::zero_diskstream_id_in_xml (node_copy);
1932 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1935 error << _("Session: cannot create track/bus from template description") << endmsg;
1939 if (boost::dynamic_pointer_cast<Track>(route)) {
1940 /* force input/output change signals so that the new diskstream
1941 picks up the configuration of the route. During session
1942 loading this normally happens in a different way.
1944 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1945 change.after = route->input()->n_ports();
1946 route->input()->changed (change, this);
1947 change.after = route->output()->n_ports();
1948 route->output()->changed (change, this);
1951 route->set_remote_control_id (control_id);
1954 ret.push_back (route);
1957 catch (failed_constructor &err) {
1958 error << _("Session: could not create new route from template") << endmsg;
1962 catch (AudioEngine::PortRegistrationFailure& pfe) {
1963 error << pfe.what() << endmsg;
1972 add_routes (ret, true);
1979 Session::add_routes (RouteList& new_routes, bool save)
1982 RCUWriter<RouteList> writer (routes);
1983 shared_ptr<RouteList> r = writer.get_copy ();
1984 r->insert (r->end(), new_routes.begin(), new_routes.end());
1987 /* if there is no control out and we're not in the middle of loading,
1988 resort the graph here. if there is a control out, we will resort
1989 toward the end of this method. if we are in the middle of loading,
1990 we will resort when done.
1993 if (!_monitor_out && IO::connecting_legal) {
1994 resort_routes_using (r);
1998 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2000 boost::weak_ptr<Route> wpr (*x);
2001 boost::shared_ptr<Route> r (*x);
2003 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2004 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2005 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2006 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2007 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2008 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2009 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
2011 if (r->is_master()) {
2015 if (r->is_monitor()) {
2019 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2021 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2022 track_playlist_changed (boost::weak_ptr<Track> (tr));
2023 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2025 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2027 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2032 if (_monitor_out && IO::connecting_legal) {
2034 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2035 if ((*x)->is_monitor()) {
2037 } else if ((*x)->is_master()) {
2040 (*x)->listen_via (_monitor_out,
2041 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2052 save_state (_current_snapshot_name);
2055 RouteAdded (new_routes); /* EMIT SIGNAL */
2056 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2060 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2062 boost::shared_ptr<RouteList> r = routes.reader ();
2063 boost::shared_ptr<Send> s;
2067 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2068 if (boost::dynamic_pointer_cast<Track>(*i)) {
2069 if ((s = (*i)->internal_send_for (dest)) != 0) {
2070 s->amp()->gain_control()->set_value (0.0);
2077 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2079 boost::shared_ptr<RouteList> r = routes.reader ();
2080 boost::shared_ptr<Send> s;
2084 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2085 if (boost::dynamic_pointer_cast<Track>(*i)) {
2086 if ((s = (*i)->internal_send_for (dest)) != 0) {
2087 s->amp()->gain_control()->set_value (1.0);
2094 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2096 boost::shared_ptr<RouteList> r = routes.reader ();
2097 boost::shared_ptr<Send> s;
2101 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2102 if (boost::dynamic_pointer_cast<Track>(*i)) {
2103 if ((s = (*i)->internal_send_for (dest)) != 0) {
2104 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2111 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2113 boost::shared_ptr<RouteList> r = routes.reader ();
2114 boost::shared_ptr<RouteList> t (new RouteList);
2116 /* only send tracks */
2118 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2119 if (boost::dynamic_pointer_cast<Track>(*i)) {
2124 add_internal_sends (dest, p, t);
2128 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2130 if (dest->is_monitor() || dest->is_master()) {
2134 if (!dest->internal_return()) {
2135 dest->add_internal_return();
2138 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2140 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2144 (*i)->listen_via (dest, p, true, true);
2151 Session::remove_route (shared_ptr<Route> route)
2153 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2157 route->set_solo (false, this);
2160 RCUWriter<RouteList> writer (routes);
2161 shared_ptr<RouteList> rs = writer.get_copy ();
2165 /* deleting the master out seems like a dumb
2166 idea, but its more of a UI policy issue
2170 if (route == _master_out) {
2171 _master_out = shared_ptr<Route> ();
2174 if (route == _monitor_out) {
2176 /* cancel control outs for all routes */
2178 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2179 (*r)->drop_listen (_monitor_out);
2182 _monitor_out.reset ();
2185 /* writer goes out of scope, forces route list update */
2188 update_route_solo_state ();
2189 update_session_range_location_marker ();
2191 // We need to disconnect the route's inputs and outputs
2193 route->input()->disconnect (0);
2194 route->output()->disconnect (0);
2196 /* if the route had internal sends sending to it, remove them */
2197 if (route->internal_return()) {
2199 boost::shared_ptr<RouteList> r = routes.reader ();
2200 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2201 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2203 (*i)->remove_processor (s);
2208 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2209 if (mt && mt->step_editing()) {
2210 if (_step_editors > 0) {
2215 update_latency_compensation (false, false);
2218 /* Re-sort routes to remove the graph's current references to the one that is
2219 * going away, then flush old references out of the graph.
2223 route_graph->clear_other_chain ();
2225 /* get rid of it from the dead wood collection in the route list manager */
2227 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2231 /* try to cause everyone to drop their references */
2233 route->drop_references ();
2235 sync_order_keys (N_("session"));
2237 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2239 /* save the new state of the world */
2241 if (save_state (_current_snapshot_name)) {
2242 save_history (_current_snapshot_name);
2247 Session::route_mute_changed (void* /*src*/)
2253 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2255 boost::shared_ptr<Route> route = wpr.lock();
2257 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2261 if (route->listening()) {
2263 if (Config->get_exclusive_solo()) {
2264 /* new listen: disable all other listen */
2265 shared_ptr<RouteList> r = routes.reader ();
2266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2270 (*i)->set_listen (false, this);
2276 } else if (_listen_cnt > 0) {
2282 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2284 boost::shared_ptr<Route> route = wpr.lock ();
2287 /* should not happen */
2288 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2292 bool send_changed = false;
2294 if (route->solo_isolated()) {
2295 if (_solo_isolated_cnt == 0) {
2296 send_changed = true;
2298 _solo_isolated_cnt++;
2299 } else if (_solo_isolated_cnt > 0) {
2300 _solo_isolated_cnt--;
2301 if (_solo_isolated_cnt == 0) {
2302 send_changed = true;
2307 IsolatedChanged (); /* EMIT SIGNAL */
2312 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2314 if (!self_solo_change) {
2315 // session doesn't care about changes to soloed-by-others
2319 if (solo_update_disabled) {
2324 boost::shared_ptr<Route> route = wpr.lock ();
2327 /* should not happen */
2328 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2332 shared_ptr<RouteList> r = routes.reader ();
2335 if (route->self_soloed()) {
2341 if (delta == 1 && Config->get_exclusive_solo()) {
2342 /* new solo: disable all other solos */
2343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2344 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2347 (*i)->set_solo (false, this);
2351 solo_update_disabled = true;
2353 RouteList uninvolved;
2355 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2356 bool via_sends_only;
2357 bool in_signal_flow;
2359 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2363 in_signal_flow = false;
2365 if ((*i)->feeds (route, &via_sends_only)) {
2366 if (!via_sends_only) {
2367 if (!route->soloed_by_others_upstream()) {
2368 (*i)->mod_solo_by_others_downstream (delta);
2370 in_signal_flow = true;
2374 if (route->feeds (*i, &via_sends_only)) {
2375 (*i)->mod_solo_by_others_upstream (delta);
2376 in_signal_flow = true;
2379 if (!in_signal_flow) {
2380 uninvolved.push_back (*i);
2384 solo_update_disabled = false;
2385 update_route_solo_state (r);
2387 /* now notify that the mute state of the routes not involved in the signal
2388 pathway of the just-solo-changed route may have altered.
2391 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2392 (*i)->mute_changed (this);
2395 SoloChanged (); /* EMIT SIGNAL */
2400 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2402 /* now figure out if anything that matters is soloed (or is "listening")*/
2404 bool something_soloed = false;
2405 uint32_t listeners = 0;
2406 uint32_t isolated = 0;
2409 r = routes.reader();
2412 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2413 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2414 something_soloed = true;
2417 if (!(*i)->is_hidden() && (*i)->listening()) {
2418 if (Config->get_solo_control_is_listen_control()) {
2421 (*i)->set_listen (false, this);
2425 if ((*i)->solo_isolated()) {
2430 if (something_soloed != _non_soloed_outs_muted) {
2431 _non_soloed_outs_muted = something_soloed;
2432 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2435 _listen_cnt = listeners;
2437 if (isolated != _solo_isolated_cnt) {
2438 _solo_isolated_cnt = isolated;
2439 IsolatedChanged (); /* EMIT SIGNAL */
2443 boost::shared_ptr<RouteList>
2444 Session::get_routes_with_internal_returns() const
2446 shared_ptr<RouteList> r = routes.reader ();
2447 boost::shared_ptr<RouteList> rl (new RouteList);
2449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2450 if ((*i)->internal_return ()) {
2458 Session::io_name_is_legal (const std::string& name)
2460 shared_ptr<RouteList> r = routes.reader ();
2462 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2463 if ((*i)->name() == name) {
2467 if ((*i)->has_io_processor_named (name)) {
2476 Session::route_by_name (string name)
2478 shared_ptr<RouteList> r = routes.reader ();
2480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2481 if ((*i)->name() == name) {
2486 return shared_ptr<Route> ((Route*) 0);
2490 Session::route_by_id (PBD::ID id)
2492 shared_ptr<RouteList> r = routes.reader ();
2494 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2495 if ((*i)->id() == id) {
2500 return shared_ptr<Route> ((Route*) 0);
2504 Session::route_by_remote_id (uint32_t id)
2506 shared_ptr<RouteList> r = routes.reader ();
2508 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2509 if ((*i)->remote_control_id() == id) {
2514 return shared_ptr<Route> ((Route*) 0);
2517 /** If either end of the session range location marker lies inside the current
2518 * session extent, move it to the corresponding session extent.
2521 Session::update_session_range_location_marker ()
2523 if (_state_of_the_state & Loading) {
2527 pair<framepos_t, framepos_t> const ext = get_extent ();
2529 if (_session_range_location == 0) {
2530 /* we don't have a session range yet; use this one (provided it is valid) */
2531 if (ext.first != max_framepos) {
2532 add_session_range_location (ext.first, ext.second);
2535 /* update the existing session range */
2536 if (ext.first < _session_range_location->start()) {
2537 _session_range_location->set_start (ext.first);
2541 if (ext.second > _session_range_location->end()) {
2542 _session_range_location->set_end (ext.second);
2549 /** @return Extent of the session's contents; if the session is empty, the first value of
2550 * the pair will equal max_framepos.
2552 pair<framepos_t, framepos_t>
2553 Session::get_extent () const
2555 pair<framepos_t, framepos_t> ext (max_framepos, 0);
2557 boost::shared_ptr<RouteList> rl = routes.reader ();
2558 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2559 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2560 if (!tr || tr->destructive()) {
2561 // ignore tape tracks when getting extents
2565 pair<framepos_t, framepos_t> e = tr->playlist()->get_extent ();
2566 if (e.first < ext.first) {
2567 ext.first = e.first;
2569 if (e.second > ext.second) {
2570 ext.second = e.second;
2577 /* Region management */
2579 boost::shared_ptr<Region>
2580 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2582 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2583 RegionFactory::RegionMap::const_iterator i;
2584 boost::shared_ptr<Region> region;
2586 Glib::Mutex::Lock lm (region_lock);
2588 for (i = regions.begin(); i != regions.end(); ++i) {
2592 if (region->whole_file()) {
2594 if (child->source_equivalent (region)) {
2600 return boost::shared_ptr<Region> ();
2604 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2606 set<boost::shared_ptr<Region> > relevant_regions;
2608 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2609 RegionFactory::get_regions_using_source (*s, relevant_regions);
2612 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2614 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2615 set<boost::shared_ptr<Region> >::iterator tmp;
2620 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2622 playlists->destroy_region (*r);
2623 RegionFactory::map_remove (*r);
2625 (*r)->drop_sources ();
2626 (*r)->drop_references ();
2628 cerr << "\tdone UC = " << (*r).use_count() << endl;
2630 relevant_regions.erase (r);
2635 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2638 Glib::Mutex::Lock ls (source_lock);
2639 /* remove from the main source list */
2640 sources.erase ((*s)->id());
2643 (*s)->mark_for_remove ();
2644 (*s)->drop_references ();
2653 Session::remove_last_capture ()
2655 list<boost::shared_ptr<Source> > srcs;
2657 boost::shared_ptr<RouteList> rl = routes.reader ();
2658 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2659 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2664 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2667 srcs.insert (srcs.end(), l.begin(), l.end());
2672 destroy_sources (srcs);
2674 save_state (_current_snapshot_name);
2679 /* Source Management */
2682 Session::add_source (boost::shared_ptr<Source> source)
2684 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2685 pair<SourceMap::iterator,bool> result;
2687 entry.first = source->id();
2688 entry.second = source;
2691 Glib::Mutex::Lock lm (source_lock);
2692 result = sources.insert (entry);
2695 if (result.second) {
2697 /* yay, new source */
2701 boost::shared_ptr<AudioFileSource> afs;
2703 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2704 if (Config->get_auto_analyse_audio()) {
2705 Analyser::queue_source_for_analysis (source, false);
2712 Session::remove_source (boost::weak_ptr<Source> src)
2714 SourceMap::iterator i;
2715 boost::shared_ptr<Source> source = src.lock();
2722 Glib::Mutex::Lock lm (source_lock);
2724 if ((i = sources.find (source->id())) != sources.end()) {
2725 cerr << "Removing source " << source->name() << endl;
2730 if (!_state_of_the_state & InCleanup) {
2732 /* save state so we don't end up with a session file
2733 referring to non-existent sources.
2736 save_state (_current_snapshot_name);
2740 boost::shared_ptr<Source>
2741 Session::source_by_id (const PBD::ID& id)
2743 Glib::Mutex::Lock lm (source_lock);
2744 SourceMap::iterator i;
2745 boost::shared_ptr<Source> source;
2747 if ((i = sources.find (id)) != sources.end()) {
2754 boost::shared_ptr<Source>
2755 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2757 Glib::Mutex::Lock lm (source_lock);
2759 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2760 boost::shared_ptr<AudioFileSource> afs
2761 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2763 if (afs && afs->path() == path && chn == afs->channel()) {
2767 return boost::shared_ptr<Source>();
2771 Session::count_sources_by_origin (const string& path)
2774 Glib::Mutex::Lock lm (source_lock);
2776 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2777 boost::shared_ptr<FileSource> fs
2778 = boost::dynamic_pointer_cast<FileSource>(i->second);
2780 if (fs && fs->origin() == path) {
2790 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2793 string old_basename = PBD::basename_nosuffix (oldname);
2794 string new_legalized = legalize_for_path (newname);
2796 /* note: we know (or assume) the old path is already valid */
2800 /* destructive file sources have a name of the form:
2802 /path/to/Tnnnn-NAME(%[LR])?.wav
2804 the task here is to replace NAME with the new name.
2809 string::size_type dash;
2811 dir = Glib::path_get_dirname (path);
2812 path = Glib::path_get_basename (path);
2814 /* '-' is not a legal character for the NAME part of the path */
2816 if ((dash = path.find_last_of ('-')) == string::npos) {
2820 prefix = path.substr (0, dash);
2824 path += new_legalized;
2825 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2826 path = Glib::build_filename (dir, path);
2830 /* non-destructive file sources have a name of the form:
2832 /path/to/NAME-nnnnn(%[LR])?.ext
2834 the task here is to replace NAME with the new name.
2839 string::size_type dash;
2840 string::size_type postfix;
2842 dir = Glib::path_get_dirname (path);
2843 path = Glib::path_get_basename (path);
2845 /* '-' is not a legal character for the NAME part of the path */
2847 if ((dash = path.find_last_of ('-')) == string::npos) {
2851 suffix = path.substr (dash+1);
2853 // Suffix is now everything after the dash. Now we need to eliminate
2854 // the nnnnn part, which is done by either finding a '%' or a '.'
2856 postfix = suffix.find_last_of ("%");
2857 if (postfix == string::npos) {
2858 postfix = suffix.find_last_of ('.');
2861 if (postfix != string::npos) {
2862 suffix = suffix.substr (postfix);
2864 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2868 const uint32_t limit = 10000;
2869 char buf[PATH_MAX+1];
2871 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2873 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2875 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2876 path = Glib::build_filename (dir, buf);
2884 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2893 /** Return the full path (in some session directory) for a new within-session source.
2894 * \a name must be a session-unique name that does not contain slashes
2895 * (e.g. as returned by new_*_source_name)
2898 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2900 assert(name.find("/") == string::npos);
2902 SessionDirectory sdir(get_best_session_directory_for_new_source());
2905 if (type == DataType::AUDIO) {
2906 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2907 } else if (type == DataType::MIDI) {
2908 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2910 error << "Unknown source type, unable to create file path" << endmsg;
2915 return p.to_string();
2919 Session::peak_path (string base) const
2921 sys::path peakfile_path(_session_dir->peak_path());
2922 peakfile_path /= base + peakfile_suffix;
2923 return peakfile_path.to_string();
2926 /** Return a unique name based on \a base for a new internal audio source */
2928 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2931 char buf[PATH_MAX+1];
2932 const uint32_t limit = 10000;
2934 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2937 legalized = legalize_for_path (base);
2939 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2940 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2942 vector<space_and_path>::iterator i;
2943 uint32_t existing = 0;
2945 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2950 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2951 cnt, legalized.c_str(), ext.c_str());
2952 } else if (nchan == 2) {
2954 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2955 cnt, legalized.c_str(), ext.c_str());
2957 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2958 cnt, legalized.c_str(), ext.c_str());
2960 } else if (nchan < 26) {
2961 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2962 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2964 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2965 cnt, legalized.c_str(), ext.c_str());
2971 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2972 } else if (nchan == 2) {
2974 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2976 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2978 } else if (nchan < 26) {
2979 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2981 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2985 SessionDirectory sdir((*i).path);
2987 string spath = sdir.sound_path().to_string();
2988 string spath_stubs = sdir.sound_stub_path().to_string();
2990 /* note that we search *without* the extension so that
2991 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2992 in the event that this new name is required for
2993 a file format change.
2996 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2997 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
3003 if (existing == 0) {
3008 error << string_compose(
3009 _("There are already %1 recordings for %2, which I consider too many."),
3010 limit, base) << endmsg;
3012 throw failed_constructor();
3016 return Glib::path_get_basename (buf);
3019 /** Create a new within-session audio source */
3020 boost::shared_ptr<AudioFileSource>
3021 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
3023 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3024 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
3026 return boost::dynamic_pointer_cast<AudioFileSource> (
3027 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3030 /** Return a unique name based on \a base for a new internal MIDI source */
3032 Session::new_midi_source_name (const string& base)
3035 char buf[PATH_MAX+1];
3036 const uint32_t limit = 10000;
3040 legalized = legalize_for_path (base);
3042 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3043 for (cnt = 1; cnt <= limit; ++cnt) {
3045 vector<space_and_path>::iterator i;
3046 uint32_t existing = 0;
3048 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3050 SessionDirectory sdir((*i).path);
3052 sys::path p = sdir.midi_path();
3055 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3057 if (sys::exists (buf)) {
3062 if (existing == 0) {
3067 error << string_compose(
3068 _("There are already %1 recordings for %2, which I consider too many."),
3069 limit, base) << endmsg;
3071 throw failed_constructor();
3075 return Glib::path_get_basename(buf);
3079 /** Create a new within-session MIDI source */
3080 boost::shared_ptr<MidiSource>
3081 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3083 /* try to use the existing write source for the track, to keep numbering sane
3087 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3091 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3094 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3095 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3099 const string name = new_midi_source_name (n);
3100 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3102 return boost::dynamic_pointer_cast<SMFSource> (
3103 SourceFactory::createWritable (
3104 DataType::MIDI, *this, path, string(), false, frame_rate()));
3109 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3111 if (playlist->hidden()) {
3115 playlists->add (playlist);
3118 playlist->release();
3125 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3127 if (_state_of_the_state & Deletion) {
3131 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3137 playlists->remove (playlist);
3143 Session::set_audition (boost::shared_ptr<Region> r)
3145 pending_audition_region = r;
3146 add_post_transport_work (PostTransportAudition);
3147 _butler->schedule_transport_work ();
3151 Session::audition_playlist ()
3153 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3154 ev->region.reset ();
3159 Session::non_realtime_set_audition ()
3161 if (!pending_audition_region) {
3162 auditioner->audition_current_playlist ();
3164 auditioner->audition_region (pending_audition_region);
3165 pending_audition_region.reset ();
3167 AuditionActive (true); /* EMIT SIGNAL */
3171 Session::audition_region (boost::shared_ptr<Region> r)
3173 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3179 Session::cancel_audition ()
3181 if (auditioner->auditioning()) {
3182 auditioner->cancel_audition ();
3183 AuditionActive (false); /* EMIT SIGNAL */
3188 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3190 if (a->is_monitor()) {
3193 if (b->is_monitor()) {
3196 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3200 Session::is_auditioning () const
3202 /* can be called before we have an auditioner object */
3204 return auditioner->auditioning();
3211 Session::graph_reordered ()
3213 /* don't do this stuff if we are setting up connections
3214 from a set_state() call or creating new tracks. Ditto for deletion.
3217 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3221 /* every track/bus asked for this to be handled but it was deferred because
3222 we were connecting. do it now.
3225 request_input_change_handling ();
3229 /* force all diskstreams to update their capture offset values to
3230 reflect any changes in latencies within the graph.
3233 boost::shared_ptr<RouteList> rl = routes.reader ();
3234 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3235 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3237 tr->set_capture_offset ();
3243 Session::available_capture_duration ()
3245 float sample_bytes_on_disk = 4.0; // keep gcc happy
3247 switch (config.get_native_file_data_format()) {
3249 sample_bytes_on_disk = 4.0;
3253 sample_bytes_on_disk = 3.0;
3257 sample_bytes_on_disk = 2.0;
3261 /* impossible, but keep some gcc versions happy */
3262 fatal << string_compose (_("programming error: %1"),
3263 X_("illegal native file data format"))
3268 double scale = 4096.0 / sample_bytes_on_disk;
3270 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3271 return max_framecnt;
3274 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3278 Session::add_bundle (shared_ptr<Bundle> bundle)
3281 RCUWriter<BundleList> writer (_bundles);
3282 boost::shared_ptr<BundleList> b = writer.get_copy ();
3283 b->push_back (bundle);
3286 BundleAdded (bundle); /* EMIT SIGNAL */
3292 Session::remove_bundle (shared_ptr<Bundle> bundle)
3294 bool removed = false;
3297 RCUWriter<BundleList> writer (_bundles);
3298 boost::shared_ptr<BundleList> b = writer.get_copy ();
3299 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3301 if (i != b->end()) {
3308 BundleRemoved (bundle); /* EMIT SIGNAL */
3315 Session::bundle_by_name (string name) const
3317 boost::shared_ptr<BundleList> b = _bundles.reader ();
3319 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3320 if ((*i)->name() == name) {
3325 return boost::shared_ptr<Bundle> ();
3329 Session::tempo_map_changed (const PropertyChange&)
3333 playlists->update_after_tempo_map_change ();
3335 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3341 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3343 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3344 (*i)->recompute_frames_from_bbt ();
3348 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3349 * the given count with the current block size.
3352 Session::ensure_buffers (ChanCount howmany)
3354 BufferManager::ensure_buffers (howmany);
3358 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3360 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3361 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3366 Session::next_insert_id ()
3368 /* this doesn't really loop forever. just think about it */
3371 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3372 if (!insert_bitset[n]) {
3373 insert_bitset[n] = true;
3379 /* none available, so resize and try again */
3381 insert_bitset.resize (insert_bitset.size() + 16, false);
3386 Session::next_send_id ()
3388 /* this doesn't really loop forever. just think about it */
3391 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3392 if (!send_bitset[n]) {
3393 send_bitset[n] = true;
3399 /* none available, so resize and try again */
3401 send_bitset.resize (send_bitset.size() + 16, false);
3406 Session::next_return_id ()
3408 /* this doesn't really loop forever. just think about it */
3411 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3412 if (!return_bitset[n]) {
3413 return_bitset[n] = true;
3419 /* none available, so resize and try again */
3421 return_bitset.resize (return_bitset.size() + 16, false);
3426 Session::mark_send_id (uint32_t id)
3428 if (id >= send_bitset.size()) {
3429 send_bitset.resize (id+16, false);
3431 if (send_bitset[id]) {
3432 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3434 send_bitset[id] = true;
3438 Session::mark_return_id (uint32_t id)
3440 if (id >= return_bitset.size()) {
3441 return_bitset.resize (id+16, false);
3443 if (return_bitset[id]) {
3444 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3446 return_bitset[id] = true;
3450 Session::mark_insert_id (uint32_t id)
3452 if (id >= insert_bitset.size()) {
3453 insert_bitset.resize (id+16, false);
3455 if (insert_bitset[id]) {
3456 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3458 insert_bitset[id] = true;
3462 Session::unmark_send_id (uint32_t id)
3464 if (id < send_bitset.size()) {
3465 send_bitset[id] = false;
3470 Session::unmark_return_id (uint32_t id)
3472 if (id < return_bitset.size()) {
3473 return_bitset[id] = false;
3478 Session::unmark_insert_id (uint32_t id)
3480 if (id < insert_bitset.size()) {
3481 insert_bitset[id] = false;
3486 /* Named Selection management */
3488 boost::shared_ptr<NamedSelection>
3489 Session::named_selection_by_name (string name)
3491 Glib::Mutex::Lock lm (named_selection_lock);
3492 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3493 if ((*i)->name == name) {
3497 return boost::shared_ptr<NamedSelection>();
3501 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3504 Glib::Mutex::Lock lm (named_selection_lock);
3505 named_selections.insert (named_selections.begin(), named_selection);
3510 NamedSelectionAdded (); /* EMIT SIGNAL */
3514 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3516 bool removed = false;
3519 Glib::Mutex::Lock lm (named_selection_lock);
3521 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3523 if (i != named_selections.end()) {
3524 named_selections.erase (i);
3531 NamedSelectionRemoved (); /* EMIT SIGNAL */
3536 Session::reset_native_file_format ()
3538 boost::shared_ptr<RouteList> rl = routes.reader ();
3539 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3540 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3542 /* don't save state as we do this, there's no point
3545 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3546 tr->reset_write_sources (false);
3547 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3553 Session::route_name_unique (string n) const
3555 shared_ptr<RouteList> r = routes.reader ();
3557 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3558 if ((*i)->name() == n) {
3567 Session::route_name_internal (string n) const
3569 if (auditioner && auditioner->name() == n) {
3573 if (_click_io && _click_io->name() == n) {
3581 Session::freeze_all (InterThreadInfo& itt)
3583 shared_ptr<RouteList> r = routes.reader ();
3585 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3587 boost::shared_ptr<Track> t;
3589 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3590 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3600 boost::shared_ptr<Region>
3601 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3602 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3603 InterThreadInfo& itt, bool enable_processing)
3605 boost::shared_ptr<Region> result;
3606 boost::shared_ptr<Playlist> playlist;
3607 boost::shared_ptr<AudioFileSource> fsource;
3609 char buf[PATH_MAX+1];
3610 ChanCount nchans(track.n_channels());
3611 framepos_t position;
3612 framecnt_t this_chunk;
3615 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3616 const string sound_dir = sdir.sound_path().to_string();
3617 framepos_t len = end - start;
3618 bool need_block_size_reset = false;
3622 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3623 end, start) << endmsg;
3627 const framecnt_t chunk_size = (256 * 1024)/4;
3629 // block all process callback handling
3631 block_processing ();
3633 /* call tree *MUST* hold route_lock */
3635 if ((playlist = track.playlist()) == 0) {
3639 /* external redirects will be a problem */
3641 if (track.has_external_redirects()) {
3645 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3647 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3649 for (x = 0; x < 99999; ++x) {
3650 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());
3651 if (access (buf, F_OK) != 0) {
3657 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3662 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3663 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3666 catch (failed_constructor& err) {
3667 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3671 srcs.push_back (fsource);
3674 /* tell redirects that care that we are about to use a much larger blocksize */
3676 need_block_size_reset = true;
3677 track.set_block_size (chunk_size);
3679 /* XXX need to flush all redirects */
3684 /* create a set of reasonably-sized buffers */
3685 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3686 buffers.set_count(nchans);
3688 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3689 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3691 afs->prepare_for_peakfile_writes ();
3694 while (to_do && !itt.cancel) {
3696 this_chunk = min (to_do, chunk_size);
3698 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3703 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3704 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3707 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3713 start += this_chunk;
3714 to_do -= this_chunk;
3716 itt.progress = (float) (1.0 - ((double) to_do / len));
3725 xnow = localtime (&now);
3727 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3728 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3731 afs->update_header (position, *xnow, now);
3732 afs->flush_header ();
3736 /* construct a region to represent the bounced material */
3740 plist.add (Properties::start, 0);
3741 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3742 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3744 result = RegionFactory::create (srcs, plist);
3750 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3751 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3754 afs->mark_for_remove ();
3757 (*src)->drop_references ();
3761 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3762 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3765 afs->done_with_peakfile_writes ();
3770 if (need_block_size_reset) {
3771 track.set_block_size (get_block_size());
3774 unblock_processing ();
3780 Session::gain_automation_buffer() const
3782 return ProcessThread::gain_automation_buffer ();
3786 Session::pan_automation_buffer() const
3788 return ProcessThread::pan_automation_buffer ();
3792 Session::get_silent_buffers (ChanCount count)
3794 return ProcessThread::get_silent_buffers (count);
3796 assert(_silent_buffers->available() >= count);
3797 _silent_buffers->set_count(count);
3799 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3800 for (size_t i= 0; i < count.get(*t); ++i) {
3801 _silent_buffers->get(*t, i).clear();
3805 return *_silent_buffers;
3810 Session::get_scratch_buffers (ChanCount count)
3812 return ProcessThread::get_scratch_buffers (count);
3814 if (count != ChanCount::ZERO) {
3815 assert(_scratch_buffers->available() >= count);
3816 _scratch_buffers->set_count(count);
3818 _scratch_buffers->set_count (_scratch_buffers->available());
3821 return *_scratch_buffers;
3826 Session::get_mix_buffers (ChanCount count)
3828 return ProcessThread::get_mix_buffers (count);
3830 assert(_mix_buffers->available() >= count);
3831 _mix_buffers->set_count(count);
3832 return *_mix_buffers;
3837 Session::ntracks () const
3840 shared_ptr<RouteList> r = routes.reader ();
3842 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3843 if (boost::dynamic_pointer_cast<Track> (*i)) {
3852 Session::nbusses () const
3855 shared_ptr<RouteList> r = routes.reader ();
3857 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3858 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3867 Session::add_automation_list(AutomationList *al)
3869 automation_lists[al->id()] = al;
3873 Session::sync_order_keys (std::string const & base)
3875 if (deletion_in_progress()) {
3879 if (!Config->get_sync_all_route_ordering()) {
3880 /* leave order keys as they are */
3884 boost::shared_ptr<RouteList> r = routes.reader ();
3886 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3887 (*i)->sync_order_keys (base);
3890 Route::SyncOrderKeys (base); // EMIT SIGNAL
3892 /* this might not do anything */
3894 set_remote_control_ids ();
3897 /** @return true if there is at least one record-enabled track, otherwise false */
3899 Session::have_rec_enabled_track () const
3901 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3904 /** Update the state of our rec-enabled tracks flag */
3906 Session::update_have_rec_enabled_track ()
3908 boost::shared_ptr<RouteList> rl = routes.reader ();
3909 RouteList::iterator i = rl->begin();
3910 while (i != rl->end ()) {
3912 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3913 if (tr && tr->record_enabled ()) {
3920 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3922 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3924 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3925 RecordStateChanged (); /* EMIT SIGNAL */
3930 Session::listen_position_changed ()
3934 switch (Config->get_listen_position()) {
3935 case AfterFaderListen:
3939 case PreFaderListen:
3944 boost::shared_ptr<RouteList> r = routes.reader ();
3946 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3947 (*i)->put_monitor_send_at (p);
3952 Session::solo_control_mode_changed ()
3954 /* cancel all solo or all listen when solo control mode changes */
3957 set_solo (get_routes(), false);
3958 } else if (listening()) {
3959 set_listen (get_routes(), false);
3963 /** Called when anything about any of our route groups changes (membership, state etc.) */
3965 Session::route_group_changed ()
3967 RouteGroupChanged (); /* EMIT SIGNAL */
3971 Session::get_available_sync_options () const
3973 vector<SyncSource> ret;
3975 ret.push_back (JACK);
3976 ret.push_back (MTC);
3977 ret.push_back (MIDIClock);
3982 boost::shared_ptr<RouteList>
3983 Session::get_routes_with_regions_at (framepos_t const p) const
3985 shared_ptr<RouteList> r = routes.reader ();
3986 shared_ptr<RouteList> rl (new RouteList);
3988 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3989 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3994 boost::shared_ptr<Playlist> pl = tr->playlist ();
3999 if (pl->has_region_at (p)) {
4008 Session::goto_end ()
4010 if (_session_range_location) {
4011 request_locate (_session_range_location->end(), false);
4013 request_locate (0, false);
4018 Session::goto_start ()
4020 if (_session_range_location) {
4021 request_locate (_session_range_location->start(), false);
4023 request_locate (0, false);
4028 Session::current_start_frame () const
4030 return _session_range_location ? _session_range_location->start() : 0;
4034 Session::current_end_frame () const
4036 return _session_range_location ? _session_range_location->end() : 0;
4040 Session::add_session_range_location (nframes_t start, nframes_t end)
4042 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4043 _locations->add (_session_range_location);
4046 /** Called when one of our routes' order keys has changed */
4048 Session::route_order_key_changed ()
4050 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4054 Session::step_edit_status_change (bool yn)
4060 send = (_step_editors == 0);
4065 send = (_step_editors == 1);
4068 if (_step_editors > 0) {
4074 StepEditStatusChange (val);
4080 Session::start_time_changed (framepos_t old)
4082 /* Update the auto loop range to match the session range
4083 (unless the auto loop range has been changed by the user)
4086 Location* s = _locations->session_range_location ();
4087 Location* l = _locations->auto_loop_location ();
4089 if (l->start() == old) {
4090 l->set_start (s->start(), true);
4095 Session::end_time_changed (framepos_t old)
4097 /* Update the auto loop range to match the session range
4098 (unless the auto loop range has been changed by the user)
4101 Location* s = _locations->session_range_location ();
4102 Location* l = _locations->auto_loop_location ();
4104 if (l->end() == old) {
4105 l->set_end (s->end(), true);
4110 Session::source_search_path (DataType type) const
4114 if (session_dirs.size() == 1) {
4116 case DataType::AUDIO:
4117 search_path = _session_dir->sound_path().to_string();
4119 case DataType::MIDI:
4120 search_path = _session_dir->midi_path().to_string();
4124 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4125 SessionDirectory sdir (i->path);
4126 if (!search_path.empty()) {
4130 case DataType::AUDIO:
4131 search_path += sdir.sound_path().to_string();
4133 case DataType::MIDI:
4134 search_path += sdir.midi_path().to_string();
4140 /* now add user-specified locations
4143 vector<string> dirs;
4146 case DataType::AUDIO:
4147 split (config.get_audio_search_path (), dirs, ':');
4149 case DataType::MIDI:
4150 split (config.get_midi_search_path (), dirs, ':');
4154 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4164 Session::ensure_search_path_includes (const string& path, DataType type)
4167 vector<string> dirs;
4174 case DataType::AUDIO:
4175 search_path = config.get_audio_search_path ();
4177 case DataType::MIDI:
4178 search_path = config.get_midi_search_path ();
4182 split (search_path, dirs, ':');
4184 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4190 if (!search_path.empty()) {
4194 search_path += path;
4197 case DataType::AUDIO:
4198 config.set_audio_search_path (search_path);
4200 case DataType::MIDI:
4201 config.set_midi_search_path (search_path);
4207 Session::get_speakers()
4210 _speakers = new Speakers;
4217 Session::unknown_processors () const
4221 boost::shared_ptr<RouteList> r = routes.reader ();
4222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4223 list<string> t = (*i)->unknown_processors ();
4224 copy (t.begin(), t.end(), back_inserter (p));