2 Copyright (C) 1999-2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/thread.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/error.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
49 #include "ardour/amp.h"
50 #include "ardour/analyser.h"
51 #include "ardour/audio_buffer.h"
52 #include "ardour/audio_diskstream.h"
53 #include "ardour/audio_port.h"
54 #include "ardour/audio_track.h"
55 #include "ardour/audioengine.h"
56 #include "ardour/audiofilesource.h"
57 #include "ardour/audioplaylist.h"
58 #include "ardour/audioregion.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/buffer_manager.h"
61 #include "ardour/buffer_set.h"
62 #include "ardour/bundle.h"
63 #include "ardour/butler.h"
64 #include "ardour/click.h"
65 #include "ardour/configuration.h"
66 #include "ardour/crossfade.h"
67 #include "ardour/cycle_timer.h"
68 #include "ardour/data_type.h"
69 #include "ardour/debug.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/internal_send.h"
72 #include "ardour/io_processor.h"
73 #include "ardour/midi_diskstream.h"
74 #include "ardour/midi_playlist.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/midi_track.h"
77 #include "ardour/midi_ui.h"
78 #include "ardour/named_selection.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/playlist.h"
81 #include "ardour/plugin_insert.h"
82 #include "ardour/port_insert.h"
83 #include "ardour/processor.h"
84 #include "ardour/rc_configuration.h"
85 #include "ardour/recent_sessions.h"
86 #include "ardour/region_factory.h"
87 #include "ardour/return.h"
88 #include "ardour/route_group.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_metadata.h"
94 #include "ardour/session_playlists.h"
95 #include "ardour/slave.h"
96 #include "ardour/smf_source.h"
97 #include "ardour/source_factory.h"
98 #include "ardour/tape_file_matcher.h"
99 #include "ardour/tempo.h"
100 #include "ardour/utils.h"
101 #include "ardour/graph.h"
102 #include "ardour/speakers.h"
103 #include "ardour/operations.h"
105 #include "midi++/port.h"
106 #include "midi++/mmc.h"
107 #include "midi++/manager.h"
112 using namespace ARDOUR;
115 bool Session::_disable_all_loaded_plugins = false;
117 PBD::Signal1<void,std::string> Session::Dialog;
118 PBD::Signal0<int> Session::AskAboutPendingState;
119 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
120 PBD::Signal0<void> Session::SendFeedback;
121 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
123 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
124 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
125 PBD::Signal0<void> Session::AutoBindingOn;
126 PBD::Signal0<void> Session::AutoBindingOff;
127 PBD::Signal2<void,std::string, std::string> Session::Exported;
128 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
129 PBD::Signal0<void> Session::Quit;
131 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
132 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
134 Session::Session (AudioEngine &eng,
135 const string& fullpath,
136 const string& snapshot_name,
137 BusProfile* bus_profile,
141 , _target_transport_speed (0.0)
142 , _requested_return_frame (-1)
143 , _session_dir (new SessionDirectory(fullpath))
145 , _state_of_the_state (Clean)
146 , _butler (new Butler (*this))
147 , _post_transport_work (0)
148 , _send_timecode_update (false)
149 , _all_route_group (new RouteGroup (*this, "all"))
150 , route_graph (new Graph(*this))
151 , routes (new RouteList)
152 , _total_free_4k_blocks (0)
153 , _bundles (new BundleList)
154 , _bundle_xml_node (0)
156 , _click_io ((IO*) 0)
158 , click_emphasis_data (0)
160 , _metadata (new SessionMetadata())
161 , _have_rec_enabled_track (false)
162 , _suspend_timecode_transmission (0)
164 _locations = new Locations (*this);
166 playlists.reset (new SessionPlaylists);
168 _all_route_group->set_active (true, this);
170 interpolation.add_channel_to (0, 0);
172 if (!eng.connected()) {
173 throw failed_constructor();
176 n_physical_outputs = _engine.n_physical_outputs ();
177 n_physical_inputs = _engine.n_physical_inputs ();
179 first_stage_init (fullpath, snapshot_name);
181 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
184 if (create (mix_template, bus_profile)) {
186 throw failed_constructor ();
190 if (second_stage_init ()) {
192 throw failed_constructor ();
195 store_recent_sessions(_name, _path);
197 bool was_dirty = dirty();
199 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
201 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
202 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
205 DirtyChanged (); /* EMIT SIGNAL */
208 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
209 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
222 vector<void*> debug_pointers;
224 /* if we got to here, leaving pending capture state around
228 remove_pending_capture_state ();
230 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
232 _engine.remove_session ();
234 /* clear history so that no references to objects are held any more */
238 /* clear state tree so that no references to objects are held any more */
242 /* remove all stubfiles that might still be lurking */
244 cleanup_stubfiles ();
246 /* reset dynamic state version back to default */
248 Stateful::loading_state_version = 0;
250 _butler->drop_references ();
252 delete midi_control_ui;
253 delete _all_route_group;
255 if (click_data != default_click) {
256 delete [] click_data;
259 if (click_emphasis_data != default_click_emphasis) {
260 delete [] click_emphasis_data;
265 /* clear out any pending dead wood from RCU managed objects */
270 AudioDiskstream::free_working_buffers();
272 /* tell everyone who is still standing that we're about to die */
275 /* tell everyone to drop references and delete objects as we go */
277 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
278 named_selections.clear ();
280 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
281 RegionFactory::delete_all_regions ();
283 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
285 /* reset these three references to special routes before we do the usual route delete thing */
288 _master_out.reset ();
289 _monitor_out.reset ();
292 RCUWriter<RouteList> writer (routes);
293 boost::shared_ptr<RouteList> r = writer.get_copy ();
295 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
296 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
297 (*i)->drop_references ();
301 /* writer goes out of scope and updates master */
305 boost::shared_ptr<RouteList> r = routes.reader ();
307 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
308 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
309 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
310 i->second->drop_references ();
315 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
316 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
321 Crossfade::set_buffer_size (0);
323 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
329 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
331 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
332 boost_debug_list_ptrs ();
337 Session::set_worst_io_latencies ()
339 _worst_output_latency = 0;
340 _worst_input_latency = 0;
342 if (!_engine.connected()) {
346 boost::shared_ptr<RouteList> r = routes.reader ();
348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
349 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
350 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
355 Session::when_engine_running ()
357 string first_physical_output;
359 BootMessage (_("Set block size and sample rate"));
361 set_block_size (_engine.frames_per_cycle());
362 set_frame_rate (_engine.frame_rate());
364 BootMessage (_("Using configuration"));
366 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
367 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
369 Config->map_parameters (ff);
370 config.map_parameters (ft);
372 /* every time we reconnect, recompute worst case output latencies */
374 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
376 if (synced_to_jack()) {
377 _engine.transport_stop ();
380 if (config.get_jack_time_master()) {
381 _engine.transport_locate (_transport_frame);
389 _click_io.reset (new ClickIO (*this, "click"));
391 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
393 /* existing state for Click */
396 if (Stateful::loading_state_version < 3000) {
397 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
399 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
404 _clicking = Config->get_clicking ();
408 error << _("could not setup Click I/O") << endmsg;
415 /* default state for Click: dual-mono to first 2 physical outputs */
418 _engine.get_physical_outputs (DataType::AUDIO, outs);
420 for (uint32_t physport = 0; physport < 2; ++physport) {
421 if (outs.size() > physport) {
422 if (_click_io->add_port (outs[physport], this)) {
423 // relax, even though its an error
428 if (_click_io->n_ports () > ChanCount::ZERO) {
429 _clicking = Config->get_clicking ();
434 catch (failed_constructor& err) {
435 error << _("cannot setup Click I/O") << endmsg;
438 BootMessage (_("Compute I/O Latencies"));
440 set_worst_io_latencies ();
443 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
446 BootMessage (_("Set up standard connections"));
448 vector<string> inputs[DataType::num_types];
449 vector<string> outputs[DataType::num_types];
450 for (uint32_t i = 0; i < DataType::num_types; ++i) {
451 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
452 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
455 /* Create a set of Bundle objects that map
456 to the physical I/O currently available. We create both
457 mono and stereo bundles, so that the common cases of mono
458 and stereo tracks get bundles to put in their mixer strip
459 in / out menus. There may be a nicer way of achieving that;
460 it doesn't really scale that well to higher channel counts
463 /* mono output bundles */
465 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
467 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
469 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
470 c->add_channel (_("mono"), DataType::AUDIO);
471 c->set_port (0, outputs[DataType::AUDIO][np]);
476 /* stereo output bundles */
478 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
479 if (np + 1 < outputs[DataType::AUDIO].size()) {
481 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
482 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
483 c->add_channel (_("L"), DataType::AUDIO);
484 c->set_port (0, outputs[DataType::AUDIO][np]);
485 c->add_channel (_("R"), DataType::AUDIO);
486 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
492 /* mono input bundles */
494 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
496 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
498 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
499 c->add_channel (_("mono"), DataType::AUDIO);
500 c->set_port (0, inputs[DataType::AUDIO][np]);
505 /* stereo input bundles */
507 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
508 if (np + 1 < inputs[DataType::AUDIO].size()) {
510 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
512 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
513 c->add_channel (_("L"), DataType::AUDIO);
514 c->set_port (0, inputs[DataType::AUDIO][np]);
515 c->add_channel (_("R"), DataType::AUDIO);
516 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
522 /* MIDI input bundles */
524 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
525 string n = inputs[DataType::MIDI][np];
526 boost::erase_first (n, X_("alsa_pcm:"));
528 boost::shared_ptr<Bundle> c (new Bundle (n, false));
529 c->add_channel ("", DataType::MIDI);
530 c->set_port (0, inputs[DataType::MIDI][np]);
534 /* MIDI output bundles */
536 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
537 string n = outputs[DataType::MIDI][np];
538 boost::erase_first (n, X_("alsa_pcm:"));
540 boost::shared_ptr<Bundle> c (new Bundle (n, true));
541 c->add_channel ("", DataType::MIDI);
542 c->set_port (0, outputs[DataType::MIDI][np]);
546 BootMessage (_("Setup signal flow and plugins"));
550 if (_is_new && !no_auto_connect()) {
552 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
554 /* don't connect the master bus outputs if there is a monitor bus */
556 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
558 /* if requested auto-connect the outputs to the first N physical ports.
561 uint32_t limit = _master_out->n_outputs().n_total();
563 for (uint32_t n = 0; n < limit; ++n) {
564 Port* p = _master_out->output()->nth (n);
566 if (outputs[p->type()].size() > n) {
567 connect_to = outputs[p->type()][n];
570 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
571 if (_master_out->output()->connect (p, connect_to, this)) {
572 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
582 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
583 are undefined, at best.
586 /* control out listens to master bus (but ignores it
587 under some conditions)
590 uint32_t limit = _monitor_out->n_inputs().n_audio();
593 for (uint32_t n = 0; n < limit; ++n) {
594 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
595 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
598 string connect_to = o->name();
599 if (_monitor_out->input()->connect (p, connect_to, this)) {
600 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
608 /* if control out is not connected, connect control out to physical outs
611 if (!_monitor_out->output()->connected ()) {
613 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
615 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
618 _monitor_out->output()->connect_ports_to_bundle (b, this);
620 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
621 Config->get_monitor_bus_preferred_bundle())
627 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
628 uint32_t mod = n_physical_outputs.get (*t);
629 uint32_t limit = _monitor_out->n_outputs().get(*t);
631 for (uint32_t n = 0; n < limit; ++n) {
633 Port* p = _monitor_out->output()->ports().port(*t, n);
635 if (outputs[*t].size() > (n % mod)) {
636 connect_to = outputs[*t][n % mod];
639 if (!connect_to.empty()) {
640 if (_monitor_out->output()->connect (p, connect_to, this)) {
641 error << string_compose (
642 _("cannot connect control output %1 to %2"),
655 /* catch up on send+insert cnts */
657 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
659 /* hook us up to the engine */
661 BootMessage (_("Connect to engine"));
663 _engine.set_session (this);
667 Session::hookup_io ()
669 /* stop graph reordering notifications from
670 causing resorts, etc.
673 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
678 /* we delay creating the auditioner till now because
679 it makes its own connections to ports.
683 Auditioner* a = new Auditioner (*this);
686 throw failed_constructor();
688 a->use_new_diskstream ();
689 auditioner.reset (a);
692 catch (failed_constructor& err) {
693 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
697 /* load bundles, which we may have postponed earlier on */
698 if (_bundle_xml_node) {
699 load_bundles (*_bundle_xml_node);
700 delete _bundle_xml_node;
703 /* Tell all IO objects to connect themselves together */
705 IO::enable_connecting ();
706 MIDI::Port::MakeConnections ();
708 /* Now reset all panners */
710 Delivery::reset_panners ();
712 /* Connect tracks to monitor/listen bus if there is one.
713 Note that in an existing session, the internal sends will
714 already exist, but we want the routes to notice that
715 they connect to the control out specifically.
719 boost::shared_ptr<RouteList> r = routes.reader ();
720 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
722 if ((*x)->is_monitor()) {
726 } else if ((*x)->is_master()) {
732 (*x)->listen_via (_monitor_out,
733 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
739 /* Anyone who cares about input state, wake up and do something */
741 IOConnectionsComplete (); /* EMIT SIGNAL */
743 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
745 /* now handle the whole enchilada as if it was one
751 /* update the full solo state, which can't be
752 correctly determined on a per-route basis, but
753 needs the global overview that only the session
757 update_route_solo_state ();
761 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
763 boost::shared_ptr<Track> track = wp.lock ();
768 boost::shared_ptr<Playlist> playlist;
770 if ((playlist = track->playlist()) != 0) {
771 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
772 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
777 Session::record_enabling_legal () const
779 /* this used to be in here, but survey says.... we don't need to restrict it */
780 // if (record_status() == Recording) {
784 if (Config->get_all_safe()) {
791 Session::reset_input_monitor_state ()
793 if (transport_rolling()) {
795 boost::shared_ptr<RouteList> rl = routes.reader ();
796 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
797 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
798 if (tr && tr->record_enabled ()) {
799 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
800 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
806 boost::shared_ptr<RouteList> rl = routes.reader ();
807 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
808 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
809 if (tr && tr->record_enabled ()) {
810 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
811 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
818 Session::auto_punch_start_changed (Location* location)
820 replace_event (SessionEvent::PunchIn, location->start());
822 if (get_record_enabled() && config.get_punch_in()) {
823 /* capture start has been changed, so save new pending state */
824 save_state ("", true);
829 Session::auto_punch_end_changed (Location* location)
831 framepos_t when_to_stop = location->end();
832 // when_to_stop += _worst_output_latency + _worst_input_latency;
833 replace_event (SessionEvent::PunchOut, when_to_stop);
837 Session::auto_punch_changed (Location* location)
839 framepos_t when_to_stop = location->end();
841 replace_event (SessionEvent::PunchIn, location->start());
842 //when_to_stop += _worst_output_latency + _worst_input_latency;
843 replace_event (SessionEvent::PunchOut, when_to_stop);
847 Session::auto_loop_changed (Location* location)
849 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
851 if (transport_rolling() && play_loop) {
854 // if (_transport_frame > location->end()) {
856 if (_transport_frame < location->start() || _transport_frame > location->end()) {
857 // relocate to beginning of loop
858 clear_events (SessionEvent::LocateRoll);
860 request_locate (location->start(), true);
863 else if (Config->get_seamless_loop() && !loop_changing) {
865 // schedule a locate-roll to refill the diskstreams at the
867 loop_changing = true;
869 if (location->end() > last_loopend) {
870 clear_events (SessionEvent::LocateRoll);
871 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
878 last_loopend = location->end();
882 Session::set_auto_punch_location (Location* location)
886 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
887 punch_connections.drop_connections();
888 existing->set_auto_punch (false, this);
889 remove_event (existing->start(), SessionEvent::PunchIn);
890 clear_events (SessionEvent::PunchOut);
891 auto_punch_location_changed (0);
900 if (location->end() <= location->start()) {
901 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
905 punch_connections.drop_connections ();
907 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
908 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
909 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
911 location->set_auto_punch (true, this);
913 auto_punch_changed (location);
915 auto_punch_location_changed (location);
919 Session::set_auto_loop_location (Location* location)
923 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
924 loop_connections.drop_connections ();
925 existing->set_auto_loop (false, this);
926 remove_event (existing->end(), SessionEvent::AutoLoop);
927 auto_loop_location_changed (0);
936 if (location->end() <= location->start()) {
937 error << _("Session: you can't use a mark for auto loop") << endmsg;
941 last_loopend = location->end();
943 loop_connections.drop_connections ();
945 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
946 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
947 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
949 location->set_auto_loop (true, this);
951 /* take care of our stuff first */
953 auto_loop_changed (location);
955 /* now tell everyone else */
957 auto_loop_location_changed (location);
961 Session::locations_added (Location *)
967 Session::locations_changed ()
969 _locations->apply (*this, &Session::handle_locations_changed);
973 Session::handle_locations_changed (Locations::LocationList& locations)
975 Locations::LocationList::iterator i;
977 bool set_loop = false;
978 bool set_punch = false;
980 for (i = locations.begin(); i != locations.end(); ++i) {
984 if (location->is_auto_punch()) {
985 set_auto_punch_location (location);
988 if (location->is_auto_loop()) {
989 set_auto_loop_location (location);
993 if (location->is_session_range()) {
994 _session_range_location = location;
999 set_auto_loop_location (0);
1002 set_auto_punch_location (0);
1009 Session::enable_record ()
1012 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1014 if (rs == Recording) {
1018 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1020 _last_record_location = _transport_frame;
1021 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1023 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1025 boost::shared_ptr<RouteList> rl = routes.reader ();
1026 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1027 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1028 if (tr && tr->record_enabled ()) {
1029 tr->monitor_input (true);
1034 RecordStateChanged ();
1041 Session::disable_record (bool rt_context, bool force)
1045 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1047 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1048 g_atomic_int_set (&_record_status, Disabled);
1049 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1051 if (rs == Recording) {
1052 g_atomic_int_set (&_record_status, Enabled);
1056 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1058 boost::shared_ptr<RouteList> rl = routes.reader ();
1059 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1060 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1061 if (tr && tr->record_enabled ()) {
1062 tr->monitor_input (false);
1067 RecordStateChanged (); /* emit signal */
1070 remove_pending_capture_state ();
1076 Session::step_back_from_record ()
1078 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1080 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1081 boost::shared_ptr<RouteList> rl = routes.reader ();
1082 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1083 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1084 if (tr && tr->record_enabled ()) {
1085 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1086 tr->monitor_input (false);
1094 Session::maybe_enable_record ()
1096 if (_step_editors > 0) {
1100 g_atomic_int_set (&_record_status, Enabled);
1102 /* This function is currently called from somewhere other than an RT thread.
1103 This save_state() call therefore doesn't impact anything. Doing it here
1104 means that we save pending state of which sources the next record will use,
1105 which gives us some chance of recovering from a crash during the record.
1108 save_state ("", true);
1110 if (_transport_speed) {
1111 if (!config.get_punch_in()) {
1115 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1116 RecordStateChanged (); /* EMIT SIGNAL */
1123 Session::audible_frame () const
1129 /* the first of these two possible settings for "offset"
1130 mean that the audible frame is stationary until
1131 audio emerges from the latency compensation
1134 the second means that the audible frame is stationary
1135 until audio would emerge from a physical port
1136 in the absence of any plugin latency compensation
1139 offset = _worst_output_latency;
1141 if (offset > current_block_size) {
1142 offset -= current_block_size;
1144 /* XXX is this correct? if we have no external
1145 physical connections and everything is internal
1146 then surely this is zero? still, how
1147 likely is that anyway?
1149 offset = current_block_size;
1152 if (synced_to_jack()) {
1153 tf = _engine.transport_frame();
1155 tf = _transport_frame;
1160 if (!non_realtime_work_pending()) {
1164 /* Check to see if we have passed the first guaranteed
1165 audible frame past our last start position. if not,
1166 return that last start point because in terms
1167 of audible frames, we have not moved yet.
1169 `Start position' in this context means the time we last
1170 either started or changed transport direction.
1173 if (_transport_speed > 0.0f) {
1175 if (!play_loop || !have_looped) {
1176 if (tf < _last_roll_or_reversal_location + offset) {
1177 return _last_roll_or_reversal_location;
1185 } else if (_transport_speed < 0.0f) {
1187 /* XXX wot? no backward looping? */
1189 if (tf > _last_roll_or_reversal_location - offset) {
1190 return _last_roll_or_reversal_location;
1202 Session::set_frame_rate (framecnt_t frames_per_second)
1204 /** \fn void Session::set_frame_size(framecnt_t)
1205 the AudioEngine object that calls this guarantees
1206 that it will not be called while we are also in
1207 ::process(). Its fine to do things that block
1211 _base_frame_rate = frames_per_second;
1215 Automatable::set_automation_interval (ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1219 // XXX we need some equivalent to this, somehow
1220 // SndFileSource::setup_standard_crossfades (frames_per_second);
1224 /* XXX need to reset/reinstantiate all LADSPA plugins */
1228 Session::set_block_size (pframes_t nframes)
1230 /* the AudioEngine guarantees
1231 that it will not be called while we are also in
1232 ::process(). It is therefore fine to do things that block
1237 current_block_size = nframes;
1241 boost::shared_ptr<RouteList> r = routes.reader ();
1243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1244 (*i)->set_block_size (nframes);
1247 boost::shared_ptr<RouteList> rl = routes.reader ();
1248 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1249 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1251 tr->set_block_size (nframes);
1255 set_worst_io_latencies ();
1260 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1263 framecnt_t fade_frames;
1265 /* Don't allow fade of less 1 frame */
1267 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1274 fade_frames = (framecnt_t) floor (fade_msecs * _current_frame_rate * 0.001);
1278 default_fade_msecs = fade_msecs;
1279 default_fade_steepness = steepness;
1282 // jlc, WTF is this!
1283 Glib::RWLock::ReaderLock lm (route_lock);
1284 AudioRegion::set_default_fade (steepness, fade_frames);
1289 /* XXX have to do this at some point */
1290 /* foreach region using default fade, reset, then
1291 refill_all_diskstream_buffers ();
1296 struct RouteSorter {
1297 /** @return true to run r1 before r2, otherwise false */
1298 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1299 if (r2->feeds (r1)) {
1300 /* r1 fed by r2; run r2 early */
1302 } else if (r1->feeds (r2)) {
1303 /* r2 fed by r1; run r1 early */
1306 if (r1->not_fed ()) {
1307 if (r2->not_fed ()) {
1308 /* no ardour-based connections inbound to either route. just use signal order */
1309 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1311 /* r2 has connections, r1 does not; run r1 early */
1315 if (r2->not_fed()) {
1316 /* r1 has connections, r2 does not; run r2 early */
1319 /* both r1 and r2 have connections, but not to each other. just use signal order */
1320 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1328 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1330 boost::shared_ptr<Route> r2;
1332 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1333 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1337 /* make a copy of the existing list of routes that feed r1 */
1339 Route::FedBy existing (r1->fed_by());
1341 /* for each route that feeds r1, recurse, marking it as feeding
1345 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1346 if (!(r2 = i->r.lock ())) {
1347 /* (*i) went away, ignore it */
1351 /* r2 is a route that feeds r1 which somehow feeds base. mark
1352 base as being fed by r2
1355 rbase->add_fed_by (r2, i->sends_only);
1359 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1363 if (r1->feeds (r2) && r2->feeds (r1)) {
1367 /* now recurse, so that we can mark base as being fed by
1368 all routes that feed r2
1371 trace_terminal (r2, rbase);
1378 Session::resort_routes ()
1380 /* don't do anything here with signals emitted
1381 by Routes while we are being destroyed.
1384 if (_state_of_the_state & Deletion) {
1389 RCUWriter<RouteList> writer (routes);
1390 boost::shared_ptr<RouteList> r = writer.get_copy ();
1391 resort_routes_using (r);
1392 /* writer goes out of scope and forces update */
1395 //route_graph->dump(1);
1398 boost::shared_ptr<RouteList> rl = routes.reader ();
1399 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1400 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1402 const Route::FedBy& fb ((*i)->fed_by());
1404 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1405 boost::shared_ptr<Route> sf = f->r.lock();
1407 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1415 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1417 RouteList::iterator i, j;
1419 for (i = r->begin(); i != r->end(); ++i) {
1421 (*i)->clear_fed_by ();
1423 for (j = r->begin(); j != r->end(); ++j) {
1425 /* although routes can feed themselves, it will
1426 cause an endless recursive descent if we
1427 detect it. so don't bother checking for
1435 bool via_sends_only;
1437 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1438 (*i)->add_fed_by (*j, via_sends_only);
1443 for (i = r->begin(); i != r->end(); ++i) {
1444 trace_terminal (*i, *i);
1450 route_graph->rechain (r);
1453 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1454 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1455 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1456 (*i)->name(), (*i)->order_key ("signal")));
1462 /** Find the route name starting with \a base with the lowest \a id.
1464 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1465 * The available route name with the lowest ID will be used, and \a id
1466 * will be set to the ID.
1468 * \return false if a route name could not be found, and \a track_name
1469 * and \a id do not reflect a free route name.
1472 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1475 snprintf (name, name_len, "%s %" PRIu32, base, id);
1477 if (route_by_name (name) == 0) {
1483 } while (id < (UINT_MAX-1));
1488 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1490 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1492 in = ChanCount::ZERO;
1493 out = ChanCount::ZERO;
1494 boost::shared_ptr<RouteList> r = routes.reader ();
1495 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1496 if (!(*i)->is_hidden()) {
1497 in += (*i)->n_inputs();
1498 out += (*i)->n_outputs();
1503 /** Caller must not hold process lock */
1504 list<boost::shared_ptr<MidiTrack> >
1505 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1507 char track_name[32];
1508 uint32_t track_id = 0;
1509 ChanCount existing_inputs;
1510 ChanCount existing_outputs;
1512 RouteList new_routes;
1513 list<boost::shared_ptr<MidiTrack> > ret;
1514 uint32_t control_id;
1516 count_existing_route_channels (existing_inputs, existing_outputs);
1518 control_id = ntracks() + nbusses();
1521 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1522 error << "cannot find name for new midi track" << endmsg;
1526 boost::shared_ptr<MidiTrack> track;
1529 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1536 mt->use_new_diskstream();
1538 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1539 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1541 track = boost::shared_ptr<MidiTrack>(mt);
1544 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1545 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1546 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1550 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1551 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1556 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1558 track->non_realtime_input_change();
1561 route_group->add (track);
1564 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1565 track->set_remote_control_id (control_id);
1567 new_routes.push_back (track);
1568 ret.push_back (track);
1571 catch (failed_constructor &err) {
1572 error << _("Session: could not create new midi track.") << endmsg;
1576 catch (AudioEngine::PortRegistrationFailure& pfe) {
1578 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;
1586 if (!new_routes.empty()) {
1587 add_routes (new_routes, false);
1588 save_state (_current_snapshot_name);
1594 /** Caller must hold process lock.
1595 * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1596 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1597 * @param output_start As \a input_start, but for outputs.
1600 Session::auto_connect_route (
1601 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1604 /* If both inputs and outputs are auto-connected to physical ports,
1605 use the max of input and output offsets to ensure auto-connected
1606 port numbers always match up (e.g. the first audio input and the
1607 first audio output of the route will have the same physical
1608 port number). Otherwise just use the lowest input or output
1612 const bool in_out_physical =
1613 (Config->get_input_auto_connect() & AutoConnectPhysical)
1614 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1617 const ChanCount in_offset = in_out_physical
1618 ? ChanCount::max(existing_inputs, existing_outputs)
1621 const ChanCount out_offset = in_out_physical
1622 ? ChanCount::max(existing_inputs, existing_outputs)
1625 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1626 vector<string> physinputs;
1627 vector<string> physoutputs;
1629 _engine.get_physical_outputs (*t, physoutputs);
1630 _engine.get_physical_inputs (*t, physinputs);
1632 if (!physinputs.empty() && connect_inputs) {
1633 uint32_t nphysical_in = physinputs.size();
1634 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1637 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1638 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1641 if (!port.empty() && route->input()->connect (
1642 route->input()->ports().port(*t, i), port, this)) {
1648 if (!physoutputs.empty()) {
1649 uint32_t nphysical_out = physoutputs.size();
1650 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1653 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1654 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1655 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1656 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1657 port = _master_out->input()->ports().port(*t,
1658 i % _master_out->input()->n_ports().get(*t))->name();
1662 if (!port.empty() && route->output()->connect (
1663 route->output()->ports().port(*t, i), port, this)) {
1670 existing_inputs += route->n_inputs();
1671 existing_outputs += route->n_outputs();
1674 /** Caller must not hold process lock */
1675 list< boost::shared_ptr<AudioTrack> >
1676 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1678 char track_name[32];
1679 uint32_t track_id = 0;
1680 ChanCount existing_inputs;
1681 ChanCount existing_outputs;
1683 RouteList new_routes;
1684 list<boost::shared_ptr<AudioTrack> > ret;
1685 uint32_t control_id;
1687 count_existing_route_channels (existing_inputs, existing_outputs);
1689 control_id = ntracks() + nbusses() + 1;
1692 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1693 error << "cannot find name for new audio track" << endmsg;
1697 boost::shared_ptr<AudioTrack> track;
1700 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1707 at->use_new_diskstream();
1709 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1710 boost_debug_shared_ptr_mark_interesting (at, "Track");
1712 track = boost::shared_ptr<AudioTrack>(at);
1715 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1717 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1718 error << string_compose (
1719 _("cannot configure %1 in/%2 out configuration for new audio track"),
1720 input_channels, output_channels)
1725 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1726 error << string_compose (
1727 _("cannot configure %1 in/%2 out configuration for new audio track"),
1728 input_channels, output_channels)
1733 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1737 route_group->add (track);
1740 track->non_realtime_input_change();
1742 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1743 track->set_remote_control_id (control_id);
1746 new_routes.push_back (track);
1747 ret.push_back (track);
1750 catch (failed_constructor &err) {
1751 error << _("Session: could not create new audio track.") << endmsg;
1755 catch (AudioEngine::PortRegistrationFailure& pfe) {
1757 error << pfe.what() << endmsg;
1765 if (!new_routes.empty()) {
1766 add_routes (new_routes, true);
1773 Session::set_remote_control_ids ()
1775 RemoteModel m = Config->get_remote_model();
1776 bool emit_signal = false;
1778 boost::shared_ptr<RouteList> r = routes.reader ();
1780 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1781 if (MixerOrdered == m) {
1782 int32_t order = (*i)->order_key(N_("signal"));
1783 (*i)->set_remote_control_id (order+1, false);
1785 } else if (EditorOrdered == m) {
1786 int32_t order = (*i)->order_key(N_("editor"));
1787 (*i)->set_remote_control_id (order+1, false);
1789 } else if (UserOrdered == m) {
1790 //do nothing ... only changes to remote id's are initiated by user
1795 Route::RemoteControlIDChange();
1799 /** Caller must not hold process lock */
1801 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1804 uint32_t bus_id = 0;
1805 ChanCount existing_inputs;
1806 ChanCount existing_outputs;
1809 uint32_t control_id;
1811 count_existing_route_channels (existing_inputs, existing_outputs);
1813 control_id = ntracks() + nbusses() + 1;
1816 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1817 error << "cannot find name for new audio bus" << endmsg;
1822 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1829 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1830 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1832 boost::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);
1861 bus->add_internal_return ();
1863 ret.push_back (bus);
1867 catch (failed_constructor &err) {
1868 error << _("Session: could not create new audio route.") << endmsg;
1872 catch (AudioEngine::PortRegistrationFailure& pfe) {
1873 error << pfe.what() << endmsg;
1883 add_routes (ret, true);
1891 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1895 uint32_t control_id;
1897 uint32_t number = 0;
1899 if (!tree.read (template_path.c_str())) {
1903 XMLNode* node = tree.root();
1905 control_id = ntracks() + nbusses() + 1;
1909 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1911 std::string node_name = IO::name_from_state (*node_copy.children().front());
1913 /* generate a new name by adding a number to the end of the template name */
1914 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1915 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1919 /* set IO children to use the new name */
1920 XMLNodeList const & children = node_copy.children ();
1921 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1922 if ((*i)->name() == IO::state_node_name) {
1923 IO::set_name_in_state (**i, name);
1927 Track::zero_diskstream_id_in_xml (node_copy);
1930 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1933 error << _("Session: cannot create track/bus from template description") << endmsg;
1937 if (boost::dynamic_pointer_cast<Track>(route)) {
1938 /* force input/output change signals so that the new diskstream
1939 picks up the configuration of the route. During session
1940 loading this normally happens in a different way.
1943 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1945 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1946 change.after = route->input()->n_ports();
1947 route->input()->changed (change, this);
1948 change.after = route->output()->n_ports();
1949 route->output()->changed (change, this);
1952 route->set_remote_control_id (control_id);
1955 ret.push_back (route);
1958 catch (failed_constructor &err) {
1959 error << _("Session: could not create new route from template") << endmsg;
1963 catch (AudioEngine::PortRegistrationFailure& pfe) {
1964 error << pfe.what() << endmsg;
1973 add_routes (ret, true);
1980 Session::add_routes (RouteList& new_routes, bool save)
1983 RCUWriter<RouteList> writer (routes);
1984 boost::shared_ptr<RouteList> r = writer.get_copy ();
1985 r->insert (r->end(), new_routes.begin(), new_routes.end());
1988 /* if there is no control out and we're not in the middle of loading,
1989 resort the graph here. if there is a control out, we will resort
1990 toward the end of this method. if we are in the middle of loading,
1991 we will resort when done.
1994 if (!_monitor_out && IO::connecting_legal) {
1995 resort_routes_using (r);
1999 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2001 boost::weak_ptr<Route> wpr (*x);
2002 boost::shared_ptr<Route> r (*x);
2004 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2005 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
2006 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
2007 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2008 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2009 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2010 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
2012 if (r->is_master()) {
2016 if (r->is_monitor()) {
2020 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
2022 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
2023 track_playlist_changed (boost::weak_ptr<Track> (tr));
2024 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
2026 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2028 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2033 if (_monitor_out && IO::connecting_legal) {
2035 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2036 if ((*x)->is_monitor()) {
2038 } else if ((*x)->is_master()) {
2041 (*x)->listen_via (_monitor_out,
2042 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2053 save_state (_current_snapshot_name);
2056 RouteAdded (new_routes); /* EMIT SIGNAL */
2057 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2061 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2063 boost::shared_ptr<RouteList> r = routes.reader ();
2064 boost::shared_ptr<Send> s;
2066 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2067 if ((s = (*i)->internal_send_for (dest)) != 0) {
2068 s->amp()->gain_control()->set_value (0.0);
2074 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2076 boost::shared_ptr<RouteList> r = routes.reader ();
2077 boost::shared_ptr<Send> s;
2079 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2080 if ((s = (*i)->internal_send_for (dest)) != 0) {
2081 s->amp()->gain_control()->set_value (1.0);
2087 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2089 boost::shared_ptr<RouteList> r = routes.reader ();
2090 boost::shared_ptr<Send> s;
2092 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2093 if ((s = (*i)->internal_send_for (dest)) != 0) {
2094 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2099 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2101 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2103 boost::shared_ptr<RouteList> r = routes.reader ();
2104 boost::shared_ptr<RouteList> t (new RouteList);
2106 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2107 if (include_buses || boost::dynamic_pointer_cast<Track>(*i)) {
2112 add_internal_sends (dest, p, t);
2116 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2118 if (dest->is_monitor() || dest->is_master()) {
2122 if (!dest->internal_return()) {
2123 dest->add_internal_return();
2126 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2128 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2132 (*i)->listen_via (dest, p, true, true);
2139 Session::remove_route (boost::shared_ptr<Route> route)
2141 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2145 route->set_solo (false, this);
2148 RCUWriter<RouteList> writer (routes);
2149 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2153 /* deleting the master out seems like a dumb
2154 idea, but its more of a UI policy issue
2158 if (route == _master_out) {
2159 _master_out = boost::shared_ptr<Route> ();
2162 if (route == _monitor_out) {
2164 /* cancel control outs for all routes */
2166 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2167 (*r)->drop_listen (_monitor_out);
2170 _monitor_out.reset ();
2173 /* writer goes out of scope, forces route list update */
2176 update_route_solo_state ();
2178 // We need to disconnect the route's inputs and outputs
2180 route->input()->disconnect (0);
2181 route->output()->disconnect (0);
2183 /* if the route had internal sends sending to it, remove them */
2184 if (route->internal_return()) {
2186 boost::shared_ptr<RouteList> r = routes.reader ();
2187 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2188 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2190 (*i)->remove_processor (s);
2195 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2196 if (mt && mt->step_editing()) {
2197 if (_step_editors > 0) {
2202 update_latency_compensation (false, false);
2205 /* Re-sort routes to remove the graph's current references to the one that is
2206 * going away, then flush old references out of the graph.
2210 route_graph->clear_other_chain ();
2212 /* get rid of it from the dead wood collection in the route list manager */
2214 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2218 /* try to cause everyone to drop their references */
2220 route->drop_references ();
2222 sync_order_keys (N_("session"));
2224 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2226 /* save the new state of the world */
2228 if (save_state (_current_snapshot_name)) {
2229 save_history (_current_snapshot_name);
2234 Session::route_mute_changed (void* /*src*/)
2240 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2242 boost::shared_ptr<Route> route = wpr.lock();
2244 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2248 if (route->listening()) {
2250 if (Config->get_exclusive_solo()) {
2251 /* new listen: disable all other listen */
2252 boost::shared_ptr<RouteList> r = routes.reader ();
2253 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2254 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2257 (*i)->set_listen (false, this);
2263 } else if (_listen_cnt > 0) {
2269 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2271 boost::shared_ptr<Route> route = wpr.lock ();
2274 /* should not happen */
2275 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2279 bool send_changed = false;
2281 if (route->solo_isolated()) {
2282 if (_solo_isolated_cnt == 0) {
2283 send_changed = true;
2285 _solo_isolated_cnt++;
2286 } else if (_solo_isolated_cnt > 0) {
2287 _solo_isolated_cnt--;
2288 if (_solo_isolated_cnt == 0) {
2289 send_changed = true;
2294 IsolatedChanged (); /* EMIT SIGNAL */
2299 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2301 if (!self_solo_change) {
2302 // session doesn't care about changes to soloed-by-others
2306 if (solo_update_disabled) {
2311 boost::shared_ptr<Route> route = wpr.lock ();
2314 /* should not happen */
2315 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2319 boost::shared_ptr<RouteList> r = routes.reader ();
2322 if (route->self_soloed()) {
2328 if (delta == 1 && Config->get_exclusive_solo()) {
2329 /* new solo: disable all other solos */
2330 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2331 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2334 (*i)->set_solo (false, this);
2338 solo_update_disabled = true;
2340 RouteList uninvolved;
2342 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2343 bool via_sends_only;
2344 bool in_signal_flow;
2346 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2350 in_signal_flow = false;
2352 if ((*i)->feeds (route, &via_sends_only)) {
2353 if (!via_sends_only) {
2354 if (!route->soloed_by_others_upstream()) {
2355 (*i)->mod_solo_by_others_downstream (delta);
2357 in_signal_flow = true;
2361 if (route->feeds (*i, &via_sends_only)) {
2362 (*i)->mod_solo_by_others_upstream (delta);
2363 in_signal_flow = true;
2366 if (!in_signal_flow) {
2367 uninvolved.push_back (*i);
2371 solo_update_disabled = false;
2372 update_route_solo_state (r);
2374 /* now notify that the mute state of the routes not involved in the signal
2375 pathway of the just-solo-changed route may have altered.
2378 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2379 (*i)->mute_changed (this);
2382 SoloChanged (); /* EMIT SIGNAL */
2387 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2389 /* now figure out if anything that matters is soloed (or is "listening")*/
2391 bool something_soloed = false;
2392 uint32_t listeners = 0;
2393 uint32_t isolated = 0;
2396 r = routes.reader();
2399 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2400 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2401 something_soloed = true;
2404 if (!(*i)->is_hidden() && (*i)->listening()) {
2405 if (Config->get_solo_control_is_listen_control()) {
2408 (*i)->set_listen (false, this);
2412 if ((*i)->solo_isolated()) {
2417 if (something_soloed != _non_soloed_outs_muted) {
2418 _non_soloed_outs_muted = something_soloed;
2419 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2422 _listen_cnt = listeners;
2424 if (isolated != _solo_isolated_cnt) {
2425 _solo_isolated_cnt = isolated;
2426 IsolatedChanged (); /* EMIT SIGNAL */
2430 boost::shared_ptr<RouteList>
2431 Session::get_routes_with_internal_returns() const
2433 boost::shared_ptr<RouteList> r = routes.reader ();
2434 boost::shared_ptr<RouteList> rl (new RouteList);
2436 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2437 if ((*i)->internal_return ()) {
2445 Session::io_name_is_legal (const std::string& name)
2447 boost::shared_ptr<RouteList> r = routes.reader ();
2449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2450 if ((*i)->name() == name) {
2454 if ((*i)->has_io_processor_named (name)) {
2462 boost::shared_ptr<Route>
2463 Session::route_by_name (string name)
2465 boost::shared_ptr<RouteList> r = routes.reader ();
2467 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2468 if ((*i)->name() == name) {
2473 return boost::shared_ptr<Route> ((Route*) 0);
2476 boost::shared_ptr<Route>
2477 Session::route_by_id (PBD::ID id)
2479 boost::shared_ptr<RouteList> r = routes.reader ();
2481 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2482 if ((*i)->id() == id) {
2487 return boost::shared_ptr<Route> ((Route*) 0);
2490 boost::shared_ptr<Route>
2491 Session::route_by_remote_id (uint32_t id)
2493 boost::shared_ptr<RouteList> r = routes.reader ();
2495 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2496 if ((*i)->remote_control_id() == id) {
2501 return boost::shared_ptr<Route> ((Route*) 0);
2505 Session::playlist_region_added (boost::weak_ptr<Region> w)
2507 boost::shared_ptr<Region> r = w.lock ();
2512 /* These are the operations that are currently in progress... */
2513 list<GQuark> curr = _current_trans_quarks;
2516 /* ...and these are the operations during which we want to update
2517 the session range location markers.
2520 ops.push_back (Operations::capture);
2521 ops.push_back (Operations::paste);
2522 ops.push_back (Operations::duplicate_region);
2523 ops.push_back (Operations::insert_file);
2524 ops.push_back (Operations::insert_region);
2525 ops.push_back (Operations::drag_region_brush);
2526 ops.push_back (Operations::region_drag);
2527 ops.push_back (Operations::selection_grab);
2528 ops.push_back (Operations::region_fill);
2529 ops.push_back (Operations::fill_selection);
2530 ops.push_back (Operations::create_region);
2533 /* See if any of the current operations match the ones that we want */
2535 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2537 /* If so, update the session range markers */
2539 maybe_update_session_range (r->position (), r->last_frame ());
2543 /** Update the session range markers if a is before the current start or
2544 * b is after the current end.
2547 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2549 if (_state_of_the_state & Loading) {
2553 if (_session_range_location == 0) {
2555 add_session_range_location (a, b);
2559 if (a < _session_range_location->start()) {
2560 _session_range_location->set_start (a);
2563 if (b > _session_range_location->end()) {
2564 _session_range_location->set_end (b);
2570 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2572 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2573 maybe_update_session_range (i->to, i->to + i->length);
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 (boost::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 (boost::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 */
3314 boost::shared_ptr<Bundle>
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 boost::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 boost::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 diskstream_channels (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;
3620 ChanCount const max_proc = track.max_processor_streams ();
3623 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3624 end, start) << endmsg;
3628 const framecnt_t chunk_size = (256 * 1024)/4;
3630 // block all process callback handling
3632 block_processing ();
3634 /* call tree *MUST* hold route_lock */
3636 if ((playlist = track.playlist()) == 0) {
3640 /* external redirects will be a problem */
3642 if (track.has_external_redirects()) {
3646 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3648 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3650 for (x = 0; x < 99999; ++x) {
3651 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());
3652 if (access (buf, F_OK) != 0) {
3658 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3663 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3664 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3667 catch (failed_constructor& err) {
3668 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3672 srcs.push_back (fsource);
3675 /* tell redirects that care that we are about to use a much larger blocksize */
3677 need_block_size_reset = true;
3678 track.set_block_size (chunk_size);
3680 /* XXX need to flush all redirects */
3685 /* create a set of reasonably-sized buffers */
3686 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
3687 buffers.set_count (max_proc);
3689 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3690 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3692 afs->prepare_for_peakfile_writes ();
3695 while (to_do && !itt.cancel) {
3697 this_chunk = min (to_do, chunk_size);
3699 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3704 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3705 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3708 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3714 start += this_chunk;
3715 to_do -= this_chunk;
3717 itt.progress = (float) (1.0 - ((double) to_do / len));
3726 xnow = localtime (&now);
3728 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3729 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3732 afs->update_header (position, *xnow, now);
3733 afs->flush_header ();
3737 /* construct a region to represent the bounced material */
3741 plist.add (Properties::start, 0);
3742 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3743 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3745 result = RegionFactory::create (srcs, plist);
3751 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3752 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3755 afs->mark_for_remove ();
3758 (*src)->drop_references ();
3762 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3763 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3766 afs->done_with_peakfile_writes ();
3771 if (need_block_size_reset) {
3772 track.set_block_size (get_block_size());
3775 unblock_processing ();
3781 Session::gain_automation_buffer() const
3783 return ProcessThread::gain_automation_buffer ();
3787 Session::pan_automation_buffer() const
3789 return ProcessThread::pan_automation_buffer ();
3793 Session::get_silent_buffers (ChanCount count)
3795 return ProcessThread::get_silent_buffers (count);
3797 assert(_silent_buffers->available() >= count);
3798 _silent_buffers->set_count(count);
3800 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3801 for (size_t i= 0; i < count.get(*t); ++i) {
3802 _silent_buffers->get(*t, i).clear();
3806 return *_silent_buffers;
3811 Session::get_scratch_buffers (ChanCount count)
3813 return ProcessThread::get_scratch_buffers (count);
3815 if (count != ChanCount::ZERO) {
3816 assert(_scratch_buffers->available() >= count);
3817 _scratch_buffers->set_count(count);
3819 _scratch_buffers->set_count (_scratch_buffers->available());
3822 return *_scratch_buffers;
3827 Session::get_mix_buffers (ChanCount count)
3829 return ProcessThread::get_mix_buffers (count);
3831 assert(_mix_buffers->available() >= count);
3832 _mix_buffers->set_count(count);
3833 return *_mix_buffers;
3838 Session::ntracks () const
3841 boost::shared_ptr<RouteList> r = routes.reader ();
3843 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3844 if (boost::dynamic_pointer_cast<Track> (*i)) {
3853 Session::nbusses () const
3856 boost::shared_ptr<RouteList> r = routes.reader ();
3858 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3859 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3868 Session::add_automation_list(AutomationList *al)
3870 automation_lists[al->id()] = al;
3874 Session::sync_order_keys (std::string const & base)
3876 if (deletion_in_progress()) {
3880 if (!Config->get_sync_all_route_ordering()) {
3881 /* leave order keys as they are */
3885 boost::shared_ptr<RouteList> r = routes.reader ();
3887 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3888 (*i)->sync_order_keys (base);
3891 Route::SyncOrderKeys (base); // EMIT SIGNAL
3893 /* this might not do anything */
3895 set_remote_control_ids ();
3898 /** @return true if there is at least one record-enabled track, otherwise false */
3900 Session::have_rec_enabled_track () const
3902 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3905 /** Update the state of our rec-enabled tracks flag */
3907 Session::update_have_rec_enabled_track ()
3909 boost::shared_ptr<RouteList> rl = routes.reader ();
3910 RouteList::iterator i = rl->begin();
3911 while (i != rl->end ()) {
3913 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3914 if (tr && tr->record_enabled ()) {
3921 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3923 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3925 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3926 RecordStateChanged (); /* EMIT SIGNAL */
3931 Session::listen_position_changed ()
3935 switch (Config->get_listen_position()) {
3936 case AfterFaderListen:
3940 case PreFaderListen:
3945 boost::shared_ptr<RouteList> r = routes.reader ();
3947 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3948 (*i)->put_monitor_send_at (p);
3953 Session::solo_control_mode_changed ()
3955 /* cancel all solo or all listen when solo control mode changes */
3958 set_solo (get_routes(), false);
3959 } else if (listening()) {
3960 set_listen (get_routes(), false);
3964 /** Called when anything about any of our route groups changes (membership, state etc.) */
3966 Session::route_group_changed ()
3968 RouteGroupChanged (); /* EMIT SIGNAL */
3972 Session::get_available_sync_options () const
3974 vector<SyncSource> ret;
3976 ret.push_back (JACK);
3977 ret.push_back (MTC);
3978 ret.push_back (MIDIClock);
3983 boost::shared_ptr<RouteList>
3984 Session::get_routes_with_regions_at (framepos_t const p) const
3986 boost::shared_ptr<RouteList> r = routes.reader ();
3987 boost::shared_ptr<RouteList> rl (new RouteList);
3989 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3990 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3995 boost::shared_ptr<Playlist> pl = tr->playlist ();
4000 if (pl->has_region_at (p)) {
4009 Session::goto_end ()
4011 if (_session_range_location) {
4012 request_locate (_session_range_location->end(), false);
4014 request_locate (0, false);
4019 Session::goto_start ()
4021 if (_session_range_location) {
4022 request_locate (_session_range_location->start(), false);
4024 request_locate (0, false);
4029 Session::current_start_frame () const
4031 return _session_range_location ? _session_range_location->start() : 0;
4035 Session::current_end_frame () const
4037 return _session_range_location ? _session_range_location->end() : 0;
4041 Session::add_session_range_location (framepos_t start, framepos_t end)
4043 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4044 _locations->add (_session_range_location);
4047 /** Called when one of our routes' order keys has changed */
4049 Session::route_order_key_changed ()
4051 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4055 Session::step_edit_status_change (bool yn)
4061 send = (_step_editors == 0);
4066 send = (_step_editors == 1);
4069 if (_step_editors > 0) {
4075 StepEditStatusChange (val);
4081 Session::start_time_changed (framepos_t old)
4083 /* Update the auto loop range to match the session range
4084 (unless the auto loop range has been changed by the user)
4087 Location* s = _locations->session_range_location ();
4092 Location* l = _locations->auto_loop_location ();
4094 if (l->start() == old) {
4095 l->set_start (s->start(), true);
4100 Session::end_time_changed (framepos_t old)
4102 /* Update the auto loop range to match the session range
4103 (unless the auto loop range has been changed by the user)
4106 Location* s = _locations->session_range_location ();
4111 Location* l = _locations->auto_loop_location ();
4113 if (l->end() == old) {
4114 l->set_end (s->end(), true);
4119 Session::source_search_path (DataType type) const
4123 if (session_dirs.size() == 1) {
4125 case DataType::AUDIO:
4126 search_path = _session_dir->sound_path().to_string();
4128 case DataType::MIDI:
4129 search_path = _session_dir->midi_path().to_string();
4133 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4134 SessionDirectory sdir (i->path);
4135 if (!search_path.empty()) {
4139 case DataType::AUDIO:
4140 search_path += sdir.sound_path().to_string();
4142 case DataType::MIDI:
4143 search_path += sdir.midi_path().to_string();
4149 /* now add user-specified locations
4152 vector<string> dirs;
4155 case DataType::AUDIO:
4156 split (config.get_audio_search_path (), dirs, ':');
4158 case DataType::MIDI:
4159 split (config.get_midi_search_path (), dirs, ':');
4163 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4173 Session::ensure_search_path_includes (const string& path, DataType type)
4176 vector<string> dirs;
4183 case DataType::AUDIO:
4184 search_path = config.get_audio_search_path ();
4186 case DataType::MIDI:
4187 search_path = config.get_midi_search_path ();
4191 split (search_path, dirs, ':');
4193 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4199 if (!search_path.empty()) {
4203 search_path += path;
4206 case DataType::AUDIO:
4207 config.set_audio_search_path (search_path);
4209 case DataType::MIDI:
4210 config.set_midi_search_path (search_path);
4216 Session::get_speakers()
4222 Session::unknown_processors () const
4226 boost::shared_ptr<RouteList> r = routes.reader ();
4227 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4228 list<string> t = (*i)->unknown_processors ();
4229 copy (t.begin(), t.end(), back_inserter (p));