2 Copyright (C) 1999-2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/thread.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/error.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
49 #include "ardour/amp.h"
50 #include "ardour/analyser.h"
51 #include "ardour/audio_buffer.h"
52 #include "ardour/audio_diskstream.h"
53 #include "ardour/audio_port.h"
54 #include "ardour/audio_track.h"
55 #include "ardour/audioengine.h"
56 #include "ardour/audiofilesource.h"
57 #include "ardour/audioplaylist.h"
58 #include "ardour/audioregion.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/buffer_manager.h"
61 #include "ardour/buffer_set.h"
62 #include "ardour/bundle.h"
63 #include "ardour/butler.h"
64 #include "ardour/click.h"
65 #include "ardour/configuration.h"
66 #include "ardour/crossfade.h"
67 #include "ardour/cycle_timer.h"
68 #include "ardour/data_type.h"
69 #include "ardour/debug.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/internal_send.h"
72 #include "ardour/io_processor.h"
73 #include "ardour/midi_diskstream.h"
74 #include "ardour/midi_playlist.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/midi_track.h"
77 #include "ardour/midi_ui.h"
78 #include "ardour/named_selection.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/playlist.h"
81 #include "ardour/plugin_insert.h"
82 #include "ardour/port_insert.h"
83 #include "ardour/processor.h"
84 #include "ardour/rc_configuration.h"
85 #include "ardour/recent_sessions.h"
86 #include "ardour/region_factory.h"
87 #include "ardour/return.h"
88 #include "ardour/route_group.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_metadata.h"
94 #include "ardour/session_playlists.h"
95 #include "ardour/slave.h"
96 #include "ardour/smf_source.h"
97 #include "ardour/source_factory.h"
98 #include "ardour/tape_file_matcher.h"
99 #include "ardour/tempo.h"
100 #include "ardour/utils.h"
101 #include "ardour/graph.h"
102 #include "ardour/speakers.h"
103 #include "ardour/operations.h"
105 #include "midi++/port.h"
106 #include "midi++/mmc.h"
107 #include "midi++/manager.h"
112 using namespace ARDOUR;
115 bool Session::_disable_all_loaded_plugins = false;
117 PBD::Signal1<void,std::string> Session::Dialog;
118 PBD::Signal0<int> Session::AskAboutPendingState;
119 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
120 PBD::Signal0<void> Session::SendFeedback;
121 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
123 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
124 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
125 PBD::Signal0<void> Session::AutoBindingOn;
126 PBD::Signal0<void> Session::AutoBindingOff;
127 PBD::Signal2<void,std::string, std::string> Session::Exported;
128 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
129 PBD::Signal0<void> Session::Quit;
131 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
132 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
134 Session::Session (AudioEngine &eng,
135 const string& fullpath,
136 const string& snapshot_name,
137 BusProfile* bus_profile,
140 , _target_transport_speed (0.0)
141 , _requested_return_frame (-1)
142 , _session_dir (new SessionDirectory(fullpath))
144 , _state_of_the_state (Clean)
145 , _butler (new Butler (*this))
146 , _post_transport_work (0)
147 , _send_timecode_update (false)
148 , _all_route_group (new RouteGroup (*this, "all"))
149 , route_graph (new Graph(*this))
150 , routes (new RouteList)
151 , _total_free_4k_blocks (0)
152 , _bundles (new BundleList)
153 , _bundle_xml_node (0)
155 , _click_io ((IO*) 0)
157 , click_emphasis_data (0)
159 , _metadata (new SessionMetadata())
160 , _have_rec_enabled_track (false)
161 , _suspend_timecode_transmission (0)
163 _locations = new Locations (*this);
165 playlists.reset (new SessionPlaylists);
167 _all_route_group->set_active (true, this);
169 interpolation.add_channel_to (0, 0);
171 if (!eng.connected()) {
172 throw failed_constructor();
175 n_physical_outputs = _engine.n_physical_outputs ();
176 n_physical_inputs = _engine.n_physical_inputs ();
178 first_stage_init (fullpath, snapshot_name);
180 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
183 if (create (mix_template, bus_profile)) {
185 throw failed_constructor ();
189 if (second_stage_init ()) {
191 throw failed_constructor ();
194 store_recent_sessions(_name, _path);
196 bool was_dirty = dirty();
198 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
200 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
201 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
204 DirtyChanged (); /* EMIT SIGNAL */
207 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
208 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
221 vector<void*> debug_pointers;
223 /* if we got to here, leaving pending capture state around
227 remove_pending_capture_state ();
229 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
231 _engine.remove_session ();
233 /* clear history so that no references to objects are held any more */
237 /* clear state tree so that no references to objects are held any more */
241 /* remove all stubfiles that might still be lurking */
243 cleanup_stubfiles ();
245 /* reset dynamic state version back to default */
247 Stateful::loading_state_version = 0;
249 _butler->drop_references ();
251 delete midi_control_ui;
252 delete _all_route_group;
254 if (click_data != default_click) {
255 delete [] click_data;
258 if (click_emphasis_data != default_click_emphasis) {
259 delete [] click_emphasis_data;
264 /* clear out any pending dead wood from RCU managed objects */
269 AudioDiskstream::free_working_buffers();
271 /* tell everyone who is still standing that we're about to die */
274 /* tell everyone to drop references and delete objects as we go */
276 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
277 named_selections.clear ();
279 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
280 RegionFactory::delete_all_regions ();
282 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
284 /* reset these three references to special routes before we do the usual route delete thing */
287 _master_out.reset ();
288 _monitor_out.reset ();
291 RCUWriter<RouteList> writer (routes);
292 boost::shared_ptr<RouteList> r = writer.get_copy ();
294 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
295 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
296 (*i)->drop_references ();
300 /* writer goes out of scope and updates master */
304 boost::shared_ptr<RouteList> r = routes.reader ();
306 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
307 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
308 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
309 i->second->drop_references ();
314 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
315 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
320 Crossfade::set_buffer_size (0);
322 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
327 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
329 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
330 boost_debug_list_ptrs ();
335 Session::set_worst_io_latencies ()
337 _worst_output_latency = 0;
338 _worst_input_latency = 0;
340 if (!_engine.connected()) {
344 boost::shared_ptr<RouteList> r = routes.reader ();
346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
347 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
348 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
353 Session::when_engine_running ()
355 string first_physical_output;
357 BootMessage (_("Set block size and sample rate"));
359 set_block_size (_engine.frames_per_cycle());
360 set_frame_rate (_engine.frame_rate());
362 BootMessage (_("Using configuration"));
364 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
365 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
367 Config->map_parameters (ff);
368 config.map_parameters (ft);
370 /* every time we reconnect, recompute worst case output latencies */
372 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
374 if (synced_to_jack()) {
375 _engine.transport_stop ();
378 if (config.get_jack_time_master()) {
379 _engine.transport_locate (_transport_frame);
387 _click_io.reset (new ClickIO (*this, "click"));
389 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
391 /* existing state for Click */
394 if (Stateful::loading_state_version < 3000) {
395 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
397 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
402 _clicking = Config->get_clicking ();
406 error << _("could not setup Click I/O") << endmsg;
413 /* default state for Click: dual-mono to first 2 physical outputs */
416 _engine.get_physical_outputs (DataType::AUDIO, outs);
418 for (uint32_t physport = 0; physport < 2; ++physport) {
419 if (outs.size() > physport) {
420 if (_click_io->add_port (outs[physport], this)) {
421 // relax, even though its an error
426 if (_click_io->n_ports () > ChanCount::ZERO) {
427 _clicking = Config->get_clicking ();
432 catch (failed_constructor& err) {
433 error << _("cannot setup Click I/O") << endmsg;
436 BootMessage (_("Compute I/O Latencies"));
438 set_worst_io_latencies ();
441 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
444 BootMessage (_("Set up standard connections"));
446 vector<string> inputs[DataType::num_types];
447 vector<string> outputs[DataType::num_types];
448 for (uint32_t i = 0; i < DataType::num_types; ++i) {
449 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
450 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
453 /* Create a set of Bundle objects that map
454 to the physical I/O currently available. We create both
455 mono and stereo bundles, so that the common cases of mono
456 and stereo tracks get bundles to put in their mixer strip
457 in / out menus. There may be a nicer way of achieving that;
458 it doesn't really scale that well to higher channel counts
461 /* mono output bundles */
463 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
465 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
467 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
468 c->add_channel (_("mono"), DataType::AUDIO);
469 c->set_port (0, outputs[DataType::AUDIO][np]);
474 /* stereo output bundles */
476 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
477 if (np + 1 < outputs[DataType::AUDIO].size()) {
479 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
480 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
481 c->add_channel (_("L"), DataType::AUDIO);
482 c->set_port (0, outputs[DataType::AUDIO][np]);
483 c->add_channel (_("R"), DataType::AUDIO);
484 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
490 /* mono input bundles */
492 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
494 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
496 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
497 c->add_channel (_("mono"), DataType::AUDIO);
498 c->set_port (0, inputs[DataType::AUDIO][np]);
503 /* stereo input bundles */
505 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
506 if (np + 1 < inputs[DataType::AUDIO].size()) {
508 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
510 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
511 c->add_channel (_("L"), DataType::AUDIO);
512 c->set_port (0, inputs[DataType::AUDIO][np]);
513 c->add_channel (_("R"), DataType::AUDIO);
514 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
520 /* MIDI input bundles */
522 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
523 string n = inputs[DataType::MIDI][np];
524 boost::erase_first (n, X_("alsa_pcm:"));
526 boost::shared_ptr<Bundle> c (new Bundle (n, false));
527 c->add_channel ("", DataType::MIDI);
528 c->set_port (0, inputs[DataType::MIDI][np]);
532 /* MIDI output bundles */
534 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
535 string n = outputs[DataType::MIDI][np];
536 boost::erase_first (n, X_("alsa_pcm:"));
538 boost::shared_ptr<Bundle> c (new Bundle (n, true));
539 c->add_channel ("", DataType::MIDI);
540 c->set_port (0, outputs[DataType::MIDI][np]);
544 BootMessage (_("Setup signal flow and plugins"));
548 if (_is_new && !no_auto_connect()) {
550 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
552 /* don't connect the master bus outputs if there is a monitor bus */
554 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
556 /* if requested auto-connect the outputs to the first N physical ports.
559 uint32_t limit = _master_out->n_outputs().n_total();
561 for (uint32_t n = 0; n < limit; ++n) {
562 Port* p = _master_out->output()->nth (n);
564 if (outputs[p->type()].size() > n) {
565 connect_to = outputs[p->type()][n];
568 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
569 if (_master_out->output()->connect (p, connect_to, this)) {
570 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
580 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
581 are undefined, at best.
584 /* control out listens to master bus (but ignores it
585 under some conditions)
588 uint32_t limit = _monitor_out->n_inputs().n_audio();
591 for (uint32_t n = 0; n < limit; ++n) {
592 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
593 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
596 string connect_to = o->name();
597 if (_monitor_out->input()->connect (p, connect_to, this)) {
598 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
606 /* if control out is not connected, connect control out to physical outs
609 if (!_monitor_out->output()->connected ()) {
611 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
613 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
616 _monitor_out->output()->connect_ports_to_bundle (b, this);
618 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
619 Config->get_monitor_bus_preferred_bundle())
625 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
626 uint32_t mod = n_physical_outputs.get (*t);
627 uint32_t limit = _monitor_out->n_outputs().get(*t);
629 for (uint32_t n = 0; n < limit; ++n) {
631 Port* p = _monitor_out->output()->ports().port(*t, n);
633 if (outputs[*t].size() > (n % mod)) {
634 connect_to = outputs[*t][n % mod];
637 if (!connect_to.empty()) {
638 if (_monitor_out->output()->connect (p, connect_to, this)) {
639 error << string_compose (
640 _("cannot connect control output %1 to %2"),
653 /* catch up on send+insert cnts */
655 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
657 /* hook us up to the engine */
659 BootMessage (_("Connect to engine"));
661 _engine.set_session (this);
662 _engine.update_total_latencies ();
666 Session::hookup_io ()
668 /* stop graph reordering notifications from
669 causing resorts, etc.
672 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
677 /* we delay creating the auditioner till now because
678 it makes its own connections to ports.
682 Auditioner* a = new Auditioner (*this);
685 throw failed_constructor();
687 a->use_new_diskstream ();
688 auditioner.reset (a);
691 catch (failed_constructor& err) {
692 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
696 /* load bundles, which we may have postponed earlier on */
697 if (_bundle_xml_node) {
698 load_bundles (*_bundle_xml_node);
699 delete _bundle_xml_node;
702 /* Tell all IO objects to connect themselves together */
704 IO::enable_connecting ();
705 MIDI::Port::MakeConnections ();
707 /* Now reset all panners */
709 Delivery::reset_panners ();
711 /* Connect tracks to monitor/listen bus if there is one.
712 Note that in an existing session, the internal sends will
713 already exist, but we want the routes to notice that
714 they connect to the control out specifically.
718 boost::shared_ptr<RouteList> r = routes.reader ();
719 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
721 if ((*x)->is_monitor()) {
725 } else if ((*x)->is_master()) {
731 (*x)->listen_via_monitor ();
736 /* Anyone who cares about input state, wake up and do something */
738 IOConnectionsComplete (); /* EMIT SIGNAL */
740 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
742 /* now handle the whole enchilada as if it was one
748 /* update the full solo state, which can't be
749 correctly determined on a per-route basis, but
750 needs the global overview that only the session
754 update_route_solo_state ();
758 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
760 boost::shared_ptr<Track> track = wp.lock ();
765 boost::shared_ptr<Playlist> playlist;
767 if ((playlist = track->playlist()) != 0) {
768 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
769 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
774 Session::record_enabling_legal () const
776 /* this used to be in here, but survey says.... we don't need to restrict it */
777 // if (record_status() == Recording) {
781 if (Config->get_all_safe()) {
788 Session::reset_input_monitor_state ()
790 if (transport_rolling()) {
792 boost::shared_ptr<RouteList> rl = routes.reader ();
793 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
794 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
795 if (tr && tr->record_enabled ()) {
796 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
797 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
803 boost::shared_ptr<RouteList> rl = routes.reader ();
804 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
805 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
806 if (tr && tr->record_enabled ()) {
807 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
808 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
815 Session::auto_punch_start_changed (Location* location)
817 replace_event (SessionEvent::PunchIn, location->start());
819 if (get_record_enabled() && config.get_punch_in()) {
820 /* capture start has been changed, so save new pending state */
821 save_state ("", true);
826 Session::auto_punch_end_changed (Location* location)
828 framepos_t when_to_stop = location->end();
829 // when_to_stop += _worst_output_latency + _worst_input_latency;
830 replace_event (SessionEvent::PunchOut, when_to_stop);
834 Session::auto_punch_changed (Location* location)
836 framepos_t when_to_stop = location->end();
838 replace_event (SessionEvent::PunchIn, location->start());
839 //when_to_stop += _worst_output_latency + _worst_input_latency;
840 replace_event (SessionEvent::PunchOut, when_to_stop);
844 Session::auto_loop_changed (Location* location)
846 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
848 if (transport_rolling() && play_loop) {
851 // if (_transport_frame > location->end()) {
853 if (_transport_frame < location->start() || _transport_frame > location->end()) {
854 // relocate to beginning of loop
855 clear_events (SessionEvent::LocateRoll);
857 request_locate (location->start(), true);
860 else if (Config->get_seamless_loop() && !loop_changing) {
862 // schedule a locate-roll to refill the diskstreams at the
864 loop_changing = true;
866 if (location->end() > last_loopend) {
867 clear_events (SessionEvent::LocateRoll);
868 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
875 last_loopend = location->end();
879 Session::set_auto_punch_location (Location* location)
883 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
884 punch_connections.drop_connections();
885 existing->set_auto_punch (false, this);
886 remove_event (existing->start(), SessionEvent::PunchIn);
887 clear_events (SessionEvent::PunchOut);
888 auto_punch_location_changed (0);
897 if (location->end() <= location->start()) {
898 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
902 punch_connections.drop_connections ();
904 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
905 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
906 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
908 location->set_auto_punch (true, this);
910 auto_punch_changed (location);
912 auto_punch_location_changed (location);
916 Session::set_auto_loop_location (Location* location)
920 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
921 loop_connections.drop_connections ();
922 existing->set_auto_loop (false, this);
923 remove_event (existing->end(), SessionEvent::AutoLoop);
924 auto_loop_location_changed (0);
933 if (location->end() <= location->start()) {
934 error << _("Session: you can't use a mark for auto loop") << endmsg;
938 last_loopend = location->end();
940 loop_connections.drop_connections ();
942 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
943 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
944 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
946 location->set_auto_loop (true, this);
948 /* take care of our stuff first */
950 auto_loop_changed (location);
952 /* now tell everyone else */
954 auto_loop_location_changed (location);
958 Session::locations_added (Location *)
964 Session::locations_changed ()
966 _locations->apply (*this, &Session::handle_locations_changed);
970 Session::handle_locations_changed (Locations::LocationList& locations)
972 Locations::LocationList::iterator i;
974 bool set_loop = false;
975 bool set_punch = false;
977 for (i = locations.begin(); i != locations.end(); ++i) {
981 if (location->is_auto_punch()) {
982 set_auto_punch_location (location);
985 if (location->is_auto_loop()) {
986 set_auto_loop_location (location);
990 if (location->is_session_range()) {
991 _session_range_location = location;
996 set_auto_loop_location (0);
999 set_auto_punch_location (0);
1006 Session::enable_record ()
1009 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1011 if (rs == Recording) {
1015 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1017 _last_record_location = _transport_frame;
1018 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1020 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1022 boost::shared_ptr<RouteList> rl = routes.reader ();
1023 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1024 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1025 if (tr && tr->record_enabled ()) {
1026 tr->monitor_input (true);
1031 RecordStateChanged ();
1038 Session::disable_record (bool rt_context, bool force)
1042 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1044 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1045 g_atomic_int_set (&_record_status, Disabled);
1046 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1048 if (rs == Recording) {
1049 g_atomic_int_set (&_record_status, Enabled);
1053 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1055 boost::shared_ptr<RouteList> rl = routes.reader ();
1056 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1057 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1058 if (tr && tr->record_enabled ()) {
1059 tr->monitor_input (false);
1064 RecordStateChanged (); /* emit signal */
1067 remove_pending_capture_state ();
1073 Session::step_back_from_record ()
1075 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1077 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1078 boost::shared_ptr<RouteList> rl = routes.reader ();
1079 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1080 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1081 if (tr && tr->record_enabled ()) {
1082 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1083 tr->monitor_input (false);
1091 Session::maybe_enable_record ()
1093 if (_step_editors > 0) {
1097 g_atomic_int_set (&_record_status, Enabled);
1099 /* This function is currently called from somewhere other than an RT thread.
1100 This save_state() call therefore doesn't impact anything. Doing it here
1101 means that we save pending state of which sources the next record will use,
1102 which gives us some chance of recovering from a crash during the record.
1105 save_state ("", true);
1107 if (_transport_speed) {
1108 if (!config.get_punch_in()) {
1112 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1113 RecordStateChanged (); /* EMIT SIGNAL */
1120 Session::audible_frame () const
1126 /* the first of these two possible settings for "offset"
1127 mean that the audible frame is stationary until
1128 audio emerges from the latency compensation
1131 the second means that the audible frame is stationary
1132 until audio would emerge from a physical port
1133 in the absence of any plugin latency compensation
1136 offset = _worst_output_latency;
1138 if (offset > current_block_size) {
1139 offset -= current_block_size;
1141 /* XXX is this correct? if we have no external
1142 physical connections and everything is internal
1143 then surely this is zero? still, how
1144 likely is that anyway?
1146 offset = current_block_size;
1149 if (synced_to_jack()) {
1150 tf = _engine.transport_frame();
1152 tf = _transport_frame;
1157 if (!non_realtime_work_pending()) {
1161 /* Check to see if we have passed the first guaranteed
1162 audible frame past our last start position. if not,
1163 return that last start point because in terms
1164 of audible frames, we have not moved yet.
1166 `Start position' in this context means the time we last
1167 either started or changed transport direction.
1170 if (_transport_speed > 0.0f) {
1172 if (!play_loop || !have_looped) {
1173 if (tf < _last_roll_or_reversal_location + offset) {
1174 return _last_roll_or_reversal_location;
1182 } else if (_transport_speed < 0.0f) {
1184 /* XXX wot? no backward looping? */
1186 if (tf > _last_roll_or_reversal_location - offset) {
1187 return _last_roll_or_reversal_location;
1199 Session::set_frame_rate (framecnt_t frames_per_second)
1201 /** \fn void Session::set_frame_size(framecnt_t)
1202 the AudioEngine object that calls this guarantees
1203 that it will not be called while we are also in
1204 ::process(). Its fine to do things that block
1208 _base_frame_rate = frames_per_second;
1212 Automatable::set_automation_interval (ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1216 // XXX we need some equivalent to this, somehow
1217 // SndFileSource::setup_standard_crossfades (frames_per_second);
1221 /* XXX need to reset/reinstantiate all LADSPA plugins */
1225 Session::set_block_size (pframes_t nframes)
1227 /* the AudioEngine guarantees
1228 that it will not be called while we are also in
1229 ::process(). It is therefore fine to do things that block
1234 current_block_size = nframes;
1238 boost::shared_ptr<RouteList> r = routes.reader ();
1240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1241 (*i)->set_block_size (nframes);
1244 boost::shared_ptr<RouteList> rl = routes.reader ();
1245 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1246 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1248 tr->set_block_size (nframes);
1252 set_worst_io_latencies ();
1256 struct RouteSorter {
1257 /** @return true to run r1 before r2, otherwise false */
1258 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1259 if (r2->feeds (r1)) {
1260 /* r1 fed by r2; run r2 early */
1262 } else if (r1->feeds (r2)) {
1263 /* r2 fed by r1; run r1 early */
1266 if (r1->not_fed ()) {
1267 if (r2->not_fed ()) {
1268 /* no ardour-based connections inbound to either route. just use signal order */
1269 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1271 /* r2 has connections, r1 does not; run r1 early */
1275 if (r2->not_fed()) {
1276 /* r1 has connections, r2 does not; run r2 early */
1279 /* both r1 and r2 have connections, but not to each other. just use signal order */
1280 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1288 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1290 boost::shared_ptr<Route> r2;
1292 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1293 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1297 /* make a copy of the existing list of routes that feed r1 */
1299 Route::FedBy existing (r1->fed_by());
1301 /* for each route that feeds r1, recurse, marking it as feeding
1305 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1306 if (!(r2 = i->r.lock ())) {
1307 /* (*i) went away, ignore it */
1311 /* r2 is a route that feeds r1 which somehow feeds base. mark
1312 base as being fed by r2
1315 rbase->add_fed_by (r2, i->sends_only);
1319 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1323 if (r1->feeds (r2) && r2->feeds (r1)) {
1327 /* now recurse, so that we can mark base as being fed by
1328 all routes that feed r2
1331 trace_terminal (r2, rbase);
1338 Session::resort_routes ()
1340 /* don't do anything here with signals emitted
1341 by Routes while we are being destroyed.
1344 if (_state_of_the_state & Deletion) {
1349 RCUWriter<RouteList> writer (routes);
1350 boost::shared_ptr<RouteList> r = writer.get_copy ();
1351 resort_routes_using (r);
1352 /* writer goes out of scope and forces update */
1355 //route_graph->dump(1);
1358 boost::shared_ptr<RouteList> rl = routes.reader ();
1359 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1360 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1362 const Route::FedBy& fb ((*i)->fed_by());
1364 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1365 boost::shared_ptr<Route> sf = f->r.lock();
1367 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1375 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1377 RouteList::iterator i, j;
1379 for (i = r->begin(); i != r->end(); ++i) {
1381 (*i)->clear_fed_by ();
1383 for (j = r->begin(); j != r->end(); ++j) {
1385 /* although routes can feed themselves, it will
1386 cause an endless recursive descent if we
1387 detect it. so don't bother checking for
1395 bool via_sends_only;
1397 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1398 (*i)->add_fed_by (*j, via_sends_only);
1403 for (i = r->begin(); i != r->end(); ++i) {
1404 trace_terminal (*i, *i);
1410 route_graph->rechain (r);
1413 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1414 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1415 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1416 (*i)->name(), (*i)->order_key ("signal")));
1422 /** Find the route name starting with \a base with the lowest \a id.
1424 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1425 * The available route name with the lowest ID will be used, and \a id
1426 * will be set to the ID.
1428 * \return false if a route name could not be found, and \a track_name
1429 * and \a id do not reflect a free route name.
1432 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1435 snprintf (name, name_len, "%s %" PRIu32, base, id);
1437 if (route_by_name (name) == 0) {
1443 } while (id < (UINT_MAX-1));
1448 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1450 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1452 in = ChanCount::ZERO;
1453 out = ChanCount::ZERO;
1454 boost::shared_ptr<RouteList> r = routes.reader ();
1455 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1456 if (!(*i)->is_hidden()) {
1457 in += (*i)->n_inputs();
1458 out += (*i)->n_outputs();
1463 /** Caller must not hold process lock */
1464 list<boost::shared_ptr<MidiTrack> >
1465 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1467 char track_name[32];
1468 uint32_t track_id = 0;
1469 ChanCount existing_inputs;
1470 ChanCount existing_outputs;
1472 RouteList new_routes;
1473 list<boost::shared_ptr<MidiTrack> > ret;
1474 uint32_t control_id;
1476 count_existing_route_channels (existing_inputs, existing_outputs);
1478 control_id = ntracks() + nbusses();
1481 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1482 error << "cannot find name for new midi track" << endmsg;
1486 boost::shared_ptr<MidiTrack> track;
1489 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1496 mt->use_new_diskstream();
1498 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1499 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1501 track = boost::shared_ptr<MidiTrack>(mt);
1504 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1505 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1506 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1510 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1511 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1516 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1518 track->non_realtime_input_change();
1521 route_group->add (track);
1524 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1525 track->set_remote_control_id (control_id);
1527 new_routes.push_back (track);
1528 ret.push_back (track);
1531 catch (failed_constructor &err) {
1532 error << _("Session: could not create new midi track.") << endmsg;
1536 catch (AudioEngine::PortRegistrationFailure& pfe) {
1538 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;
1546 if (!new_routes.empty()) {
1547 add_routes (new_routes, false);
1548 save_state (_current_snapshot_name);
1554 /** Caller must hold process lock.
1555 * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1556 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1557 * @param output_start As \a input_start, but for outputs.
1560 Session::auto_connect_route (
1561 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1564 /* If both inputs and outputs are auto-connected to physical ports,
1565 use the max of input and output offsets to ensure auto-connected
1566 port numbers always match up (e.g. the first audio input and the
1567 first audio output of the route will have the same physical
1568 port number). Otherwise just use the lowest input or output
1572 const bool in_out_physical =
1573 (Config->get_input_auto_connect() & AutoConnectPhysical)
1574 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1577 const ChanCount in_offset = in_out_physical
1578 ? ChanCount::max(existing_inputs, existing_outputs)
1581 const ChanCount out_offset = in_out_physical
1582 ? ChanCount::max(existing_inputs, existing_outputs)
1585 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1586 vector<string> physinputs;
1587 vector<string> physoutputs;
1589 _engine.get_physical_outputs (*t, physoutputs);
1590 _engine.get_physical_inputs (*t, physinputs);
1592 if (!physinputs.empty() && connect_inputs) {
1593 uint32_t nphysical_in = physinputs.size();
1594 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1597 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1598 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1601 if (!port.empty() && route->input()->connect (
1602 route->input()->ports().port(*t, i), port, this)) {
1608 if (!physoutputs.empty()) {
1609 uint32_t nphysical_out = physoutputs.size();
1610 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1613 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1614 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1615 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1616 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1617 port = _master_out->input()->ports().port(*t,
1618 i % _master_out->input()->n_ports().get(*t))->name();
1622 if (!port.empty() && route->output()->connect (
1623 route->output()->ports().port(*t, i), port, this)) {
1630 existing_inputs += route->n_inputs();
1631 existing_outputs += route->n_outputs();
1634 /** Caller must not hold process lock */
1635 list< boost::shared_ptr<AudioTrack> >
1636 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1638 char track_name[32];
1639 uint32_t track_id = 0;
1640 ChanCount existing_inputs;
1641 ChanCount existing_outputs;
1643 RouteList new_routes;
1644 list<boost::shared_ptr<AudioTrack> > ret;
1645 uint32_t control_id;
1647 count_existing_route_channels (existing_inputs, existing_outputs);
1649 control_id = ntracks() + nbusses() + 1;
1652 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1653 error << "cannot find name for new audio track" << endmsg;
1657 boost::shared_ptr<AudioTrack> track;
1660 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1667 at->use_new_diskstream();
1669 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1670 boost_debug_shared_ptr_mark_interesting (at, "Track");
1672 track = boost::shared_ptr<AudioTrack>(at);
1675 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1677 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1678 error << string_compose (
1679 _("cannot configure %1 in/%2 out configuration for new audio track"),
1680 input_channels, output_channels)
1685 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1686 error << string_compose (
1687 _("cannot configure %1 in/%2 out configuration for new audio track"),
1688 input_channels, output_channels)
1693 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1697 route_group->add (track);
1700 track->non_realtime_input_change();
1702 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1703 track->set_remote_control_id (control_id);
1706 new_routes.push_back (track);
1707 ret.push_back (track);
1710 catch (failed_constructor &err) {
1711 error << _("Session: could not create new audio track.") << endmsg;
1715 catch (AudioEngine::PortRegistrationFailure& pfe) {
1717 error << pfe.what() << endmsg;
1725 if (!new_routes.empty()) {
1726 add_routes (new_routes, true);
1733 Session::set_remote_control_ids ()
1735 RemoteModel m = Config->get_remote_model();
1736 bool emit_signal = false;
1738 boost::shared_ptr<RouteList> r = routes.reader ();
1740 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1741 if (MixerOrdered == m) {
1742 int32_t order = (*i)->order_key(N_("signal"));
1743 (*i)->set_remote_control_id (order+1, false);
1745 } else if (EditorOrdered == m) {
1746 int32_t order = (*i)->order_key(N_("editor"));
1747 (*i)->set_remote_control_id (order+1, false);
1749 } else if (UserOrdered == m) {
1750 //do nothing ... only changes to remote id's are initiated by user
1755 Route::RemoteControlIDChange();
1759 /** Caller must not hold process lock */
1761 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1764 uint32_t bus_id = 0;
1765 ChanCount existing_inputs;
1766 ChanCount existing_outputs;
1769 uint32_t control_id;
1771 count_existing_route_channels (existing_inputs, existing_outputs);
1773 control_id = ntracks() + nbusses() + 1;
1776 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1777 error << "cannot find name for new audio bus" << endmsg;
1782 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1789 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1790 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1792 boost::shared_ptr<Route> bus (rt);
1795 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1797 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1798 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1799 input_channels, output_channels)
1805 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1806 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1807 input_channels, output_channels)
1812 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1816 route_group->add (bus);
1818 bus->set_remote_control_id (control_id);
1821 bus->add_internal_return ();
1823 ret.push_back (bus);
1827 catch (failed_constructor &err) {
1828 error << _("Session: could not create new audio route.") << endmsg;
1832 catch (AudioEngine::PortRegistrationFailure& pfe) {
1833 error << pfe.what() << endmsg;
1843 add_routes (ret, true);
1851 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1855 uint32_t control_id;
1857 uint32_t number = 0;
1859 if (!tree.read (template_path.c_str())) {
1863 XMLNode* node = tree.root();
1865 control_id = ntracks() + nbusses() + 1;
1869 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1871 std::string node_name = IO::name_from_state (*node_copy.children().front());
1873 /* generate a new name by adding a number to the end of the template name */
1874 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1875 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1879 /* set IO children to use the new name */
1880 XMLNodeList const & children = node_copy.children ();
1881 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1882 if ((*i)->name() == IO::state_node_name) {
1883 IO::set_name_in_state (**i, name);
1887 Track::zero_diskstream_id_in_xml (node_copy);
1890 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1893 error << _("Session: cannot create track/bus from template description") << endmsg;
1897 if (boost::dynamic_pointer_cast<Track>(route)) {
1898 /* force input/output change signals so that the new diskstream
1899 picks up the configuration of the route. During session
1900 loading this normally happens in a different way.
1903 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1905 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1906 change.after = route->input()->n_ports();
1907 route->input()->changed (change, this);
1908 change.after = route->output()->n_ports();
1909 route->output()->changed (change, this);
1912 route->set_remote_control_id (control_id);
1915 ret.push_back (route);
1918 catch (failed_constructor &err) {
1919 error << _("Session: could not create new route from template") << endmsg;
1923 catch (AudioEngine::PortRegistrationFailure& pfe) {
1924 error << pfe.what() << endmsg;
1933 add_routes (ret, true);
1940 Session::add_routes (RouteList& new_routes, bool save)
1943 RCUWriter<RouteList> writer (routes);
1944 boost::shared_ptr<RouteList> r = writer.get_copy ();
1945 r->insert (r->end(), new_routes.begin(), new_routes.end());
1948 /* if there is no control out and we're not in the middle of loading,
1949 resort the graph here. if there is a control out, we will resort
1950 toward the end of this method. if we are in the middle of loading,
1951 we will resort when done.
1954 if (!_monitor_out && IO::connecting_legal) {
1955 resort_routes_using (r);
1959 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1961 boost::weak_ptr<Route> wpr (*x);
1962 boost::shared_ptr<Route> r (*x);
1964 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1965 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1966 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1967 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1968 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1969 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1970 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1972 if (r->is_master()) {
1976 if (r->is_monitor()) {
1980 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1982 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1983 track_playlist_changed (boost::weak_ptr<Track> (tr));
1984 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1986 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
1988 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
1993 if (_monitor_out && IO::connecting_legal) {
1995 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1996 if ((*x)->is_monitor()) {
1998 } else if ((*x)->is_master()) {
2001 (*x)->listen_via_monitor ();
2011 save_state (_current_snapshot_name);
2014 RouteAdded (new_routes); /* EMIT SIGNAL */
2015 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2019 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2021 boost::shared_ptr<RouteList> r = routes.reader ();
2022 boost::shared_ptr<Send> s;
2024 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2025 if ((s = (*i)->internal_send_for (dest)) != 0) {
2026 s->amp()->gain_control()->set_value (0.0);
2032 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2034 boost::shared_ptr<RouteList> r = routes.reader ();
2035 boost::shared_ptr<Send> s;
2037 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2038 if ((s = (*i)->internal_send_for (dest)) != 0) {
2039 s->amp()->gain_control()->set_value (1.0);
2045 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2047 boost::shared_ptr<RouteList> r = routes.reader ();
2048 boost::shared_ptr<Send> s;
2050 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2051 if ((s = (*i)->internal_send_for (dest)) != 0) {
2052 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2057 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2059 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2061 boost::shared_ptr<RouteList> r = routes.reader ();
2062 boost::shared_ptr<RouteList> t (new RouteList);
2064 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2065 if (include_buses || boost::dynamic_pointer_cast<Track>(*i)) {
2070 add_internal_sends (dest, p, t);
2074 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2076 if (dest->is_monitor() || dest->is_master()) {
2080 if (!dest->internal_return()) {
2081 dest->add_internal_return();
2084 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2086 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2090 (*i)->listen_via (dest, p);
2097 Session::remove_route (boost::shared_ptr<Route> route)
2099 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2103 route->set_solo (false, this);
2106 RCUWriter<RouteList> writer (routes);
2107 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2111 /* deleting the master out seems like a dumb
2112 idea, but its more of a UI policy issue
2116 if (route == _master_out) {
2117 _master_out = boost::shared_ptr<Route> ();
2120 if (route == _monitor_out) {
2122 /* cancel control outs for all routes */
2124 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2125 (*r)->drop_listen (_monitor_out);
2128 _monitor_out.reset ();
2131 /* writer goes out of scope, forces route list update */
2134 update_route_solo_state ();
2136 // We need to disconnect the route's inputs and outputs
2138 route->input()->disconnect (0);
2139 route->output()->disconnect (0);
2141 /* if the route had internal sends sending to it, remove them */
2142 if (route->internal_return()) {
2144 boost::shared_ptr<RouteList> r = routes.reader ();
2145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2146 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2148 (*i)->remove_processor (s);
2153 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2154 if (mt && mt->step_editing()) {
2155 if (_step_editors > 0) {
2160 update_latency_compensation (false, false);
2163 /* Re-sort routes to remove the graph's current references to the one that is
2164 * going away, then flush old references out of the graph.
2168 route_graph->clear_other_chain ();
2170 /* get rid of it from the dead wood collection in the route list manager */
2172 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2176 /* try to cause everyone to drop their references */
2178 route->drop_references ();
2180 sync_order_keys (N_("session"));
2182 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2184 /* save the new state of the world */
2186 if (save_state (_current_snapshot_name)) {
2187 save_history (_current_snapshot_name);
2192 Session::route_mute_changed (void* /*src*/)
2198 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2200 boost::shared_ptr<Route> route = wpr.lock();
2202 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2206 if (route->listening_via_monitor ()) {
2208 if (Config->get_exclusive_solo()) {
2209 /* new listen: disable all other listen */
2210 boost::shared_ptr<RouteList> r = routes.reader ();
2211 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2212 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2215 (*i)->set_listen (false, this);
2221 } else if (_listen_cnt > 0) {
2227 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2229 boost::shared_ptr<Route> route = wpr.lock ();
2232 /* should not happen */
2233 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2237 bool send_changed = false;
2239 if (route->solo_isolated()) {
2240 if (_solo_isolated_cnt == 0) {
2241 send_changed = true;
2243 _solo_isolated_cnt++;
2244 } else if (_solo_isolated_cnt > 0) {
2245 _solo_isolated_cnt--;
2246 if (_solo_isolated_cnt == 0) {
2247 send_changed = true;
2252 IsolatedChanged (); /* EMIT SIGNAL */
2257 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2259 if (!self_solo_change) {
2260 // session doesn't care about changes to soloed-by-others
2264 if (solo_update_disabled) {
2269 boost::shared_ptr<Route> route = wpr.lock ();
2272 /* should not happen */
2273 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2277 boost::shared_ptr<RouteList> r = routes.reader ();
2280 if (route->self_soloed()) {
2286 if (delta == 1 && Config->get_exclusive_solo()) {
2287 /* new solo: disable all other solos */
2288 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2292 (*i)->set_solo (false, this);
2296 solo_update_disabled = true;
2298 RouteList uninvolved;
2300 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2301 bool via_sends_only;
2302 bool in_signal_flow;
2304 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2308 in_signal_flow = false;
2310 if ((*i)->feeds (route, &via_sends_only)) {
2311 if (!via_sends_only) {
2312 if (!route->soloed_by_others_upstream()) {
2313 (*i)->mod_solo_by_others_downstream (delta);
2315 in_signal_flow = true;
2319 if (route->feeds (*i, &via_sends_only)) {
2320 (*i)->mod_solo_by_others_upstream (delta);
2321 in_signal_flow = true;
2324 if (!in_signal_flow) {
2325 uninvolved.push_back (*i);
2329 solo_update_disabled = false;
2330 update_route_solo_state (r);
2332 /* now notify that the mute state of the routes not involved in the signal
2333 pathway of the just-solo-changed route may have altered.
2336 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2337 (*i)->mute_changed (this);
2340 SoloChanged (); /* EMIT SIGNAL */
2345 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2347 /* now figure out if anything that matters is soloed (or is "listening")*/
2349 bool something_soloed = false;
2350 uint32_t listeners = 0;
2351 uint32_t isolated = 0;
2354 r = routes.reader();
2357 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2358 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2359 something_soloed = true;
2362 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2363 if (Config->get_solo_control_is_listen_control()) {
2366 (*i)->set_listen (false, this);
2370 if ((*i)->solo_isolated()) {
2375 if (something_soloed != _non_soloed_outs_muted) {
2376 _non_soloed_outs_muted = something_soloed;
2377 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2380 _listen_cnt = listeners;
2382 if (isolated != _solo_isolated_cnt) {
2383 _solo_isolated_cnt = isolated;
2384 IsolatedChanged (); /* EMIT SIGNAL */
2388 boost::shared_ptr<RouteList>
2389 Session::get_routes_with_internal_returns() const
2391 boost::shared_ptr<RouteList> r = routes.reader ();
2392 boost::shared_ptr<RouteList> rl (new RouteList);
2394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2395 if ((*i)->internal_return ()) {
2403 Session::io_name_is_legal (const std::string& name)
2405 boost::shared_ptr<RouteList> r = routes.reader ();
2407 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2408 if ((*i)->name() == name) {
2412 if ((*i)->has_io_processor_named (name)) {
2420 boost::shared_ptr<Route>
2421 Session::route_by_name (string name)
2423 boost::shared_ptr<RouteList> r = routes.reader ();
2425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2426 if ((*i)->name() == name) {
2431 return boost::shared_ptr<Route> ((Route*) 0);
2434 boost::shared_ptr<Route>
2435 Session::route_by_id (PBD::ID id)
2437 boost::shared_ptr<RouteList> r = routes.reader ();
2439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2440 if ((*i)->id() == id) {
2445 return boost::shared_ptr<Route> ((Route*) 0);
2448 boost::shared_ptr<Route>
2449 Session::route_by_remote_id (uint32_t id)
2451 boost::shared_ptr<RouteList> r = routes.reader ();
2453 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2454 if ((*i)->remote_control_id() == id) {
2459 return boost::shared_ptr<Route> ((Route*) 0);
2463 Session::playlist_region_added (boost::weak_ptr<Region> w)
2465 boost::shared_ptr<Region> r = w.lock ();
2470 /* These are the operations that are currently in progress... */
2471 list<GQuark> curr = _current_trans_quarks;
2474 /* ...and these are the operations during which we want to update
2475 the session range location markers.
2478 ops.push_back (Operations::capture);
2479 ops.push_back (Operations::paste);
2480 ops.push_back (Operations::duplicate_region);
2481 ops.push_back (Operations::insert_file);
2482 ops.push_back (Operations::insert_region);
2483 ops.push_back (Operations::drag_region_brush);
2484 ops.push_back (Operations::region_drag);
2485 ops.push_back (Operations::selection_grab);
2486 ops.push_back (Operations::region_fill);
2487 ops.push_back (Operations::fill_selection);
2488 ops.push_back (Operations::create_region);
2491 /* See if any of the current operations match the ones that we want */
2493 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2495 /* If so, update the session range markers */
2497 maybe_update_session_range (r->position (), r->last_frame ());
2501 /** Update the session range markers if a is before the current start or
2502 * b is after the current end.
2505 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2507 if (_state_of_the_state & Loading) {
2511 if (_session_range_location == 0) {
2513 add_session_range_location (a, b);
2517 if (a < _session_range_location->start()) {
2518 _session_range_location->set_start (a);
2521 if (b > _session_range_location->end()) {
2522 _session_range_location->set_end (b);
2528 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2530 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2531 maybe_update_session_range (i->to, i->to + i->length);
2535 /* Region management */
2537 boost::shared_ptr<Region>
2538 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2540 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2541 RegionFactory::RegionMap::const_iterator i;
2542 boost::shared_ptr<Region> region;
2544 Glib::Mutex::Lock lm (region_lock);
2546 for (i = regions.begin(); i != regions.end(); ++i) {
2550 if (region->whole_file()) {
2552 if (child->source_equivalent (region)) {
2558 return boost::shared_ptr<Region> ();
2562 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2564 set<boost::shared_ptr<Region> > relevant_regions;
2566 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2567 RegionFactory::get_regions_using_source (*s, relevant_regions);
2570 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2572 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2573 set<boost::shared_ptr<Region> >::iterator tmp;
2578 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2580 playlists->destroy_region (*r);
2581 RegionFactory::map_remove (*r);
2583 (*r)->drop_sources ();
2584 (*r)->drop_references ();
2586 cerr << "\tdone UC = " << (*r).use_count() << endl;
2588 relevant_regions.erase (r);
2593 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2596 Glib::Mutex::Lock ls (source_lock);
2597 /* remove from the main source list */
2598 sources.erase ((*s)->id());
2601 (*s)->mark_for_remove ();
2602 (*s)->drop_references ();
2611 Session::remove_last_capture ()
2613 list<boost::shared_ptr<Source> > srcs;
2615 boost::shared_ptr<RouteList> rl = routes.reader ();
2616 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2617 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2622 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2625 srcs.insert (srcs.end(), l.begin(), l.end());
2630 destroy_sources (srcs);
2632 save_state (_current_snapshot_name);
2637 /* Source Management */
2640 Session::add_source (boost::shared_ptr<Source> source)
2642 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2643 pair<SourceMap::iterator,bool> result;
2645 entry.first = source->id();
2646 entry.second = source;
2649 Glib::Mutex::Lock lm (source_lock);
2650 result = sources.insert (entry);
2653 if (result.second) {
2655 /* yay, new source */
2659 boost::shared_ptr<AudioFileSource> afs;
2661 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2662 if (Config->get_auto_analyse_audio()) {
2663 Analyser::queue_source_for_analysis (source, false);
2670 Session::remove_source (boost::weak_ptr<Source> src)
2672 SourceMap::iterator i;
2673 boost::shared_ptr<Source> source = src.lock();
2680 Glib::Mutex::Lock lm (source_lock);
2682 if ((i = sources.find (source->id())) != sources.end()) {
2683 cerr << "Removing source " << source->name() << endl;
2688 if (!_state_of_the_state & InCleanup) {
2690 /* save state so we don't end up with a session file
2691 referring to non-existent sources.
2694 save_state (_current_snapshot_name);
2698 boost::shared_ptr<Source>
2699 Session::source_by_id (const PBD::ID& id)
2701 Glib::Mutex::Lock lm (source_lock);
2702 SourceMap::iterator i;
2703 boost::shared_ptr<Source> source;
2705 if ((i = sources.find (id)) != sources.end()) {
2712 boost::shared_ptr<Source>
2713 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2715 Glib::Mutex::Lock lm (source_lock);
2717 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2718 boost::shared_ptr<AudioFileSource> afs
2719 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2721 if (afs && afs->path() == path && chn == afs->channel()) {
2725 return boost::shared_ptr<Source>();
2729 Session::count_sources_by_origin (const string& path)
2732 Glib::Mutex::Lock lm (source_lock);
2734 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2735 boost::shared_ptr<FileSource> fs
2736 = boost::dynamic_pointer_cast<FileSource>(i->second);
2738 if (fs && fs->origin() == path) {
2748 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2751 string old_basename = PBD::basename_nosuffix (oldname);
2752 string new_legalized = legalize_for_path (newname);
2754 /* note: we know (or assume) the old path is already valid */
2758 /* destructive file sources have a name of the form:
2760 /path/to/Tnnnn-NAME(%[LR])?.wav
2762 the task here is to replace NAME with the new name.
2767 string::size_type dash;
2769 dir = Glib::path_get_dirname (path);
2770 path = Glib::path_get_basename (path);
2772 /* '-' is not a legal character for the NAME part of the path */
2774 if ((dash = path.find_last_of ('-')) == string::npos) {
2778 prefix = path.substr (0, dash);
2782 path += new_legalized;
2783 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2784 path = Glib::build_filename (dir, path);
2788 /* non-destructive file sources have a name of the form:
2790 /path/to/NAME-nnnnn(%[LR])?.ext
2792 the task here is to replace NAME with the new name.
2797 string::size_type dash;
2798 string::size_type postfix;
2800 dir = Glib::path_get_dirname (path);
2801 path = Glib::path_get_basename (path);
2803 /* '-' is not a legal character for the NAME part of the path */
2805 if ((dash = path.find_last_of ('-')) == string::npos) {
2809 suffix = path.substr (dash+1);
2811 // Suffix is now everything after the dash. Now we need to eliminate
2812 // the nnnnn part, which is done by either finding a '%' or a '.'
2814 postfix = suffix.find_last_of ("%");
2815 if (postfix == string::npos) {
2816 postfix = suffix.find_last_of ('.');
2819 if (postfix != string::npos) {
2820 suffix = suffix.substr (postfix);
2822 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2826 const uint32_t limit = 10000;
2827 char buf[PATH_MAX+1];
2829 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2831 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2833 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2834 path = Glib::build_filename (dir, buf);
2842 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2851 /** Return the full path (in some session directory) for a new within-session source.
2852 * \a name must be a session-unique name that does not contain slashes
2853 * (e.g. as returned by new_*_source_name)
2856 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2858 assert(name.find("/") == string::npos);
2860 SessionDirectory sdir(get_best_session_directory_for_new_source());
2863 if (type == DataType::AUDIO) {
2864 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2865 } else if (type == DataType::MIDI) {
2866 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2868 error << "Unknown source type, unable to create file path" << endmsg;
2873 return p.to_string();
2877 Session::peak_path (string base) const
2879 sys::path peakfile_path(_session_dir->peak_path());
2880 peakfile_path /= base + peakfile_suffix;
2881 return peakfile_path.to_string();
2884 /** Return a unique name based on \a base for a new internal audio source */
2886 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2889 char buf[PATH_MAX+1];
2890 const uint32_t limit = 10000;
2892 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2895 legalized = legalize_for_path (base);
2897 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2898 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2900 vector<space_and_path>::iterator i;
2901 uint32_t existing = 0;
2903 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2908 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2909 cnt, legalized.c_str(), ext.c_str());
2910 } else if (nchan == 2) {
2912 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2913 cnt, legalized.c_str(), ext.c_str());
2915 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2916 cnt, legalized.c_str(), ext.c_str());
2918 } else if (nchan < 26) {
2919 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2920 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2922 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2923 cnt, legalized.c_str(), ext.c_str());
2929 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2930 } else if (nchan == 2) {
2932 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2934 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2936 } else if (nchan < 26) {
2937 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2939 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2943 SessionDirectory sdir((*i).path);
2945 string spath = sdir.sound_path().to_string();
2946 string spath_stubs = sdir.sound_stub_path().to_string();
2948 /* note that we search *without* the extension so that
2949 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2950 in the event that this new name is required for
2951 a file format change.
2954 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2955 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
2961 if (existing == 0) {
2966 error << string_compose(
2967 _("There are already %1 recordings for %2, which I consider too many."),
2968 limit, base) << endmsg;
2970 throw failed_constructor();
2974 return Glib::path_get_basename (buf);
2977 /** Create a new within-session audio source */
2978 boost::shared_ptr<AudioFileSource>
2979 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
2981 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2982 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
2984 return boost::dynamic_pointer_cast<AudioFileSource> (
2985 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
2988 /** Return a unique name based on \a base for a new internal MIDI source */
2990 Session::new_midi_source_name (const string& base)
2993 char buf[PATH_MAX+1];
2994 const uint32_t limit = 10000;
2998 legalized = legalize_for_path (base);
3000 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3001 for (cnt = 1; cnt <= limit; ++cnt) {
3003 vector<space_and_path>::iterator i;
3004 uint32_t existing = 0;
3006 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3008 SessionDirectory sdir((*i).path);
3010 sys::path p = sdir.midi_path();
3013 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3015 if (sys::exists (buf)) {
3020 if (existing == 0) {
3025 error << string_compose(
3026 _("There are already %1 recordings for %2, which I consider too many."),
3027 limit, base) << endmsg;
3029 throw failed_constructor();
3033 return Glib::path_get_basename(buf);
3037 /** Create a new within-session MIDI source */
3038 boost::shared_ptr<MidiSource>
3039 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3041 /* try to use the existing write source for the track, to keep numbering sane
3045 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3049 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3052 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3053 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3057 const string name = new_midi_source_name (n);
3058 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3060 return boost::dynamic_pointer_cast<SMFSource> (
3061 SourceFactory::createWritable (
3062 DataType::MIDI, *this, path, string(), false, frame_rate()));
3067 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3069 if (playlist->hidden()) {
3073 playlists->add (playlist);
3076 playlist->release();
3083 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3085 if (_state_of_the_state & Deletion) {
3089 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3095 playlists->remove (playlist);
3101 Session::set_audition (boost::shared_ptr<Region> r)
3103 pending_audition_region = r;
3104 add_post_transport_work (PostTransportAudition);
3105 _butler->schedule_transport_work ();
3109 Session::audition_playlist ()
3111 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3112 ev->region.reset ();
3117 Session::non_realtime_set_audition ()
3119 if (!pending_audition_region) {
3120 auditioner->audition_current_playlist ();
3122 auditioner->audition_region (pending_audition_region);
3123 pending_audition_region.reset ();
3125 AuditionActive (true); /* EMIT SIGNAL */
3129 Session::audition_region (boost::shared_ptr<Region> r)
3131 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3137 Session::cancel_audition ()
3139 if (auditioner->auditioning()) {
3140 auditioner->cancel_audition ();
3141 AuditionActive (false); /* EMIT SIGNAL */
3146 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3148 if (a->is_monitor()) {
3151 if (b->is_monitor()) {
3154 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3158 Session::is_auditioning () const
3160 /* can be called before we have an auditioner object */
3162 return auditioner->auditioning();
3169 Session::graph_reordered ()
3171 /* don't do this stuff if we are setting up connections
3172 from a set_state() call or creating new tracks. Ditto for deletion.
3175 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3179 /* every track/bus asked for this to be handled but it was deferred because
3180 we were connecting. do it now.
3183 request_input_change_handling ();
3187 /* force all diskstreams to update their capture offset values to
3188 reflect any changes in latencies within the graph.
3191 boost::shared_ptr<RouteList> rl = routes.reader ();
3192 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3193 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3195 tr->set_capture_offset ();
3201 Session::available_capture_duration ()
3203 float sample_bytes_on_disk = 4.0; // keep gcc happy
3205 switch (config.get_native_file_data_format()) {
3207 sample_bytes_on_disk = 4.0;
3211 sample_bytes_on_disk = 3.0;
3215 sample_bytes_on_disk = 2.0;
3219 /* impossible, but keep some gcc versions happy */
3220 fatal << string_compose (_("programming error: %1"),
3221 X_("illegal native file data format"))
3226 double scale = 4096.0 / sample_bytes_on_disk;
3228 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3229 return max_framecnt;
3232 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3236 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3239 RCUWriter<BundleList> writer (_bundles);
3240 boost::shared_ptr<BundleList> b = writer.get_copy ();
3241 b->push_back (bundle);
3244 BundleAdded (bundle); /* EMIT SIGNAL */
3250 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3252 bool removed = false;
3255 RCUWriter<BundleList> writer (_bundles);
3256 boost::shared_ptr<BundleList> b = writer.get_copy ();
3257 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3259 if (i != b->end()) {
3266 BundleRemoved (bundle); /* EMIT SIGNAL */
3272 boost::shared_ptr<Bundle>
3273 Session::bundle_by_name (string name) const
3275 boost::shared_ptr<BundleList> b = _bundles.reader ();
3277 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3278 if ((*i)->name() == name) {
3283 return boost::shared_ptr<Bundle> ();
3287 Session::tempo_map_changed (const PropertyChange&)
3291 playlists->update_after_tempo_map_change ();
3293 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3299 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3301 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3302 (*i)->recompute_frames_from_bbt ();
3306 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3307 * the given count with the current block size.
3310 Session::ensure_buffers (ChanCount howmany)
3312 BufferManager::ensure_buffers (howmany);
3316 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3318 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3319 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3324 Session::next_insert_id ()
3326 /* this doesn't really loop forever. just think about it */
3329 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3330 if (!insert_bitset[n]) {
3331 insert_bitset[n] = true;
3337 /* none available, so resize and try again */
3339 insert_bitset.resize (insert_bitset.size() + 16, false);
3344 Session::next_send_id ()
3346 /* this doesn't really loop forever. just think about it */
3349 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3350 if (!send_bitset[n]) {
3351 send_bitset[n] = true;
3357 /* none available, so resize and try again */
3359 send_bitset.resize (send_bitset.size() + 16, false);
3364 Session::next_return_id ()
3366 /* this doesn't really loop forever. just think about it */
3369 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3370 if (!return_bitset[n]) {
3371 return_bitset[n] = true;
3377 /* none available, so resize and try again */
3379 return_bitset.resize (return_bitset.size() + 16, false);
3384 Session::mark_send_id (uint32_t id)
3386 if (id >= send_bitset.size()) {
3387 send_bitset.resize (id+16, false);
3389 if (send_bitset[id]) {
3390 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3392 send_bitset[id] = true;
3396 Session::mark_return_id (uint32_t id)
3398 if (id >= return_bitset.size()) {
3399 return_bitset.resize (id+16, false);
3401 if (return_bitset[id]) {
3402 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3404 return_bitset[id] = true;
3408 Session::mark_insert_id (uint32_t id)
3410 if (id >= insert_bitset.size()) {
3411 insert_bitset.resize (id+16, false);
3413 if (insert_bitset[id]) {
3414 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3416 insert_bitset[id] = true;
3420 Session::unmark_send_id (uint32_t id)
3422 if (id < send_bitset.size()) {
3423 send_bitset[id] = false;
3428 Session::unmark_return_id (uint32_t id)
3430 if (id < return_bitset.size()) {
3431 return_bitset[id] = false;
3436 Session::unmark_insert_id (uint32_t id)
3438 if (id < insert_bitset.size()) {
3439 insert_bitset[id] = false;
3444 /* Named Selection management */
3446 boost::shared_ptr<NamedSelection>
3447 Session::named_selection_by_name (string name)
3449 Glib::Mutex::Lock lm (named_selection_lock);
3450 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3451 if ((*i)->name == name) {
3455 return boost::shared_ptr<NamedSelection>();
3459 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3462 Glib::Mutex::Lock lm (named_selection_lock);
3463 named_selections.insert (named_selections.begin(), named_selection);
3468 NamedSelectionAdded (); /* EMIT SIGNAL */
3472 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3474 bool removed = false;
3477 Glib::Mutex::Lock lm (named_selection_lock);
3479 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3481 if (i != named_selections.end()) {
3482 named_selections.erase (i);
3489 NamedSelectionRemoved (); /* EMIT SIGNAL */
3494 Session::reset_native_file_format ()
3496 boost::shared_ptr<RouteList> rl = routes.reader ();
3497 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3498 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3500 /* don't save state as we do this, there's no point
3503 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3504 tr->reset_write_sources (false);
3505 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3511 Session::route_name_unique (string n) const
3513 boost::shared_ptr<RouteList> r = routes.reader ();
3515 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3516 if ((*i)->name() == n) {
3525 Session::route_name_internal (string n) const
3527 if (auditioner && auditioner->name() == n) {
3531 if (_click_io && _click_io->name() == n) {
3539 Session::freeze_all (InterThreadInfo& itt)
3541 boost::shared_ptr<RouteList> r = routes.reader ();
3543 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3545 boost::shared_ptr<Track> t;
3547 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3548 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3558 boost::shared_ptr<Region>
3559 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3560 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3561 InterThreadInfo& itt, bool enable_processing)
3563 boost::shared_ptr<Region> result;
3564 boost::shared_ptr<Playlist> playlist;
3565 boost::shared_ptr<AudioFileSource> fsource;
3567 char buf[PATH_MAX+1];
3568 ChanCount diskstream_channels (track.n_channels());
3569 framepos_t position;
3570 framecnt_t this_chunk;
3573 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3574 const string sound_dir = sdir.sound_path().to_string();
3575 framepos_t len = end - start;
3576 bool need_block_size_reset = false;
3578 ChanCount const max_proc = track.max_processor_streams ();
3581 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3582 end, start) << endmsg;
3586 const framecnt_t chunk_size = (256 * 1024)/4;
3588 // block all process callback handling
3590 block_processing ();
3592 /* call tree *MUST* hold route_lock */
3594 if ((playlist = track.playlist()) == 0) {
3598 /* external redirects will be a problem */
3600 if (track.has_external_redirects()) {
3604 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3606 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3608 for (x = 0; x < 99999; ++x) {
3609 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());
3610 if (access (buf, F_OK) != 0) {
3616 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3621 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3622 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3625 catch (failed_constructor& err) {
3626 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3630 srcs.push_back (fsource);
3633 /* tell redirects that care that we are about to use a much larger blocksize */
3635 need_block_size_reset = true;
3636 track.set_block_size (chunk_size);
3638 /* XXX need to flush all redirects */
3643 /* create a set of reasonably-sized buffers */
3644 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
3645 buffers.set_count (max_proc);
3647 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3648 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3650 afs->prepare_for_peakfile_writes ();
3653 while (to_do && !itt.cancel) {
3655 this_chunk = min (to_do, chunk_size);
3657 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3662 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3663 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3666 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3672 start += this_chunk;
3673 to_do -= this_chunk;
3675 itt.progress = (float) (1.0 - ((double) to_do / len));
3684 xnow = localtime (&now);
3686 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3687 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3690 afs->update_header (position, *xnow, now);
3691 afs->flush_header ();
3695 /* construct a region to represent the bounced material */
3699 plist.add (Properties::start, 0);
3700 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3701 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3703 result = RegionFactory::create (srcs, plist);
3709 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3710 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3713 afs->mark_for_remove ();
3716 (*src)->drop_references ();
3720 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3721 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3724 afs->done_with_peakfile_writes ();
3729 if (need_block_size_reset) {
3730 track.set_block_size (get_block_size());
3733 unblock_processing ();
3739 Session::gain_automation_buffer() const
3741 return ProcessThread::gain_automation_buffer ();
3745 Session::pan_automation_buffer() const
3747 return ProcessThread::pan_automation_buffer ();
3751 Session::get_silent_buffers (ChanCount count)
3753 return ProcessThread::get_silent_buffers (count);
3755 assert(_silent_buffers->available() >= count);
3756 _silent_buffers->set_count(count);
3758 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3759 for (size_t i= 0; i < count.get(*t); ++i) {
3760 _silent_buffers->get(*t, i).clear();
3764 return *_silent_buffers;
3769 Session::get_scratch_buffers (ChanCount count)
3771 return ProcessThread::get_scratch_buffers (count);
3773 if (count != ChanCount::ZERO) {
3774 assert(_scratch_buffers->available() >= count);
3775 _scratch_buffers->set_count(count);
3777 _scratch_buffers->set_count (_scratch_buffers->available());
3780 return *_scratch_buffers;
3785 Session::get_mix_buffers (ChanCount count)
3787 return ProcessThread::get_mix_buffers (count);
3789 assert(_mix_buffers->available() >= count);
3790 _mix_buffers->set_count(count);
3791 return *_mix_buffers;
3796 Session::ntracks () const
3799 boost::shared_ptr<RouteList> r = routes.reader ();
3801 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3802 if (boost::dynamic_pointer_cast<Track> (*i)) {
3811 Session::nbusses () const
3814 boost::shared_ptr<RouteList> r = routes.reader ();
3816 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3817 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3826 Session::add_automation_list(AutomationList *al)
3828 automation_lists[al->id()] = al;
3832 Session::sync_order_keys (std::string const & base)
3834 if (deletion_in_progress()) {
3838 if (!Config->get_sync_all_route_ordering()) {
3839 /* leave order keys as they are */
3843 boost::shared_ptr<RouteList> r = routes.reader ();
3845 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3846 (*i)->sync_order_keys (base);
3849 Route::SyncOrderKeys (base); // EMIT SIGNAL
3851 /* this might not do anything */
3853 set_remote_control_ids ();
3856 /** @return true if there is at least one record-enabled track, otherwise false */
3858 Session::have_rec_enabled_track () const
3860 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3863 /** Update the state of our rec-enabled tracks flag */
3865 Session::update_have_rec_enabled_track ()
3867 boost::shared_ptr<RouteList> rl = routes.reader ();
3868 RouteList::iterator i = rl->begin();
3869 while (i != rl->end ()) {
3871 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3872 if (tr && tr->record_enabled ()) {
3879 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3881 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3883 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3884 RecordStateChanged (); /* EMIT SIGNAL */
3889 Session::listen_position_changed ()
3891 boost::shared_ptr<RouteList> r = routes.reader ();
3893 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3894 (*i)->listen_position_changed ();
3899 Session::solo_control_mode_changed ()
3901 /* cancel all solo or all listen when solo control mode changes */
3904 set_solo (get_routes(), false);
3905 } else if (listening()) {
3906 set_listen (get_routes(), false);
3910 /** Called when anything about any of our route groups changes (membership, state etc.) */
3912 Session::route_group_changed ()
3914 RouteGroupChanged (); /* EMIT SIGNAL */
3918 Session::get_available_sync_options () const
3920 vector<SyncSource> ret;
3922 ret.push_back (JACK);
3923 ret.push_back (MTC);
3924 ret.push_back (MIDIClock);
3929 boost::shared_ptr<RouteList>
3930 Session::get_routes_with_regions_at (framepos_t const p) const
3932 boost::shared_ptr<RouteList> r = routes.reader ();
3933 boost::shared_ptr<RouteList> rl (new RouteList);
3935 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3936 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3941 boost::shared_ptr<Playlist> pl = tr->playlist ();
3946 if (pl->has_region_at (p)) {
3955 Session::goto_end ()
3957 if (_session_range_location) {
3958 request_locate (_session_range_location->end(), false);
3960 request_locate (0, false);
3965 Session::goto_start ()
3967 if (_session_range_location) {
3968 request_locate (_session_range_location->start(), false);
3970 request_locate (0, false);
3975 Session::current_start_frame () const
3977 return _session_range_location ? _session_range_location->start() : 0;
3981 Session::current_end_frame () const
3983 return _session_range_location ? _session_range_location->end() : 0;
3987 Session::add_session_range_location (framepos_t start, framepos_t end)
3989 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
3990 _locations->add (_session_range_location);
3993 /** Called when one of our routes' order keys has changed */
3995 Session::route_order_key_changed ()
3997 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4001 Session::step_edit_status_change (bool yn)
4007 send = (_step_editors == 0);
4012 send = (_step_editors == 1);
4015 if (_step_editors > 0) {
4021 StepEditStatusChange (val);
4027 Session::start_time_changed (framepos_t old)
4029 /* Update the auto loop range to match the session range
4030 (unless the auto loop range has been changed by the user)
4033 Location* s = _locations->session_range_location ();
4038 Location* l = _locations->auto_loop_location ();
4040 if (l->start() == old) {
4041 l->set_start (s->start(), true);
4046 Session::end_time_changed (framepos_t old)
4048 /* Update the auto loop range to match the session range
4049 (unless the auto loop range has been changed by the user)
4052 Location* s = _locations->session_range_location ();
4057 Location* l = _locations->auto_loop_location ();
4059 if (l->end() == old) {
4060 l->set_end (s->end(), true);
4065 Session::source_search_path (DataType type) const
4069 if (session_dirs.size() == 1) {
4071 case DataType::AUDIO:
4072 search_path = _session_dir->sound_path().to_string();
4074 case DataType::MIDI:
4075 search_path = _session_dir->midi_path().to_string();
4079 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4080 SessionDirectory sdir (i->path);
4081 if (!search_path.empty()) {
4085 case DataType::AUDIO:
4086 search_path += sdir.sound_path().to_string();
4088 case DataType::MIDI:
4089 search_path += sdir.midi_path().to_string();
4095 /* now add user-specified locations
4098 vector<string> dirs;
4101 case DataType::AUDIO:
4102 split (config.get_audio_search_path (), dirs, ':');
4104 case DataType::MIDI:
4105 split (config.get_midi_search_path (), dirs, ':');
4109 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4119 Session::ensure_search_path_includes (const string& path, DataType type)
4122 vector<string> dirs;
4129 case DataType::AUDIO:
4130 search_path = config.get_audio_search_path ();
4132 case DataType::MIDI:
4133 search_path = config.get_midi_search_path ();
4137 split (search_path, dirs, ':');
4139 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4145 if (!search_path.empty()) {
4149 search_path += path;
4152 case DataType::AUDIO:
4153 config.set_audio_search_path (search_path);
4155 case DataType::MIDI:
4156 config.set_midi_search_path (search_path);
4161 boost::shared_ptr<Speakers>
4162 Session::get_speakers()
4168 Session::unknown_processors () const
4172 boost::shared_ptr<RouteList> r = routes.reader ();
4173 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4174 list<string> t = (*i)->unknown_processors ();
4175 copy (t.begin(), t.end(), back_inserter (p));
4184 #ifdef HAVE_JACK_NEW_LATENCY
4186 Session::update_latency (bool playback)
4188 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback\n");
4190 boost::shared_ptr<RouteList> r = routes.reader ();
4193 /* reverse the list so that we work backwards from the last route to run to the first */
4194 reverse (r->begin(), r->end());
4197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4198 DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Working on latency for %1\n", (*i)->name()));
4199 (*i)->set_latency_ranges (playback);
4200 DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Done working on latency for %1\n\n", (*i)->name()));