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"
48 #include "ardour/amp.h"
49 #include "ardour/analyser.h"
50 #include "ardour/audio_buffer.h"
51 #include "ardour/audio_diskstream.h"
52 #include "ardour/audio_port.h"
53 #include "ardour/audio_track.h"
54 #include "ardour/audioengine.h"
55 #include "ardour/audiofilesource.h"
56 #include "ardour/audioplaylist.h"
57 #include "ardour/audioregion.h"
58 #include "ardour/auditioner.h"
59 #include "ardour/buffer_manager.h"
60 #include "ardour/buffer_set.h"
61 #include "ardour/bundle.h"
62 #include "ardour/butler.h"
63 #include "ardour/click.h"
64 #include "ardour/configuration.h"
65 #include "ardour/crossfade.h"
66 #include "ardour/cycle_timer.h"
67 #include "ardour/data_type.h"
68 #include "ardour/debug.h"
69 #include "ardour/filename_extensions.h"
70 #include "ardour/internal_send.h"
71 #include "ardour/io_processor.h"
72 #include "ardour/midi_diskstream.h"
73 #include "ardour/midi_playlist.h"
74 #include "ardour/midi_region.h"
75 #include "ardour/midi_track.h"
76 #include "ardour/midi_ui.h"
77 #include "ardour/named_selection.h"
78 #include "ardour/process_thread.h"
79 #include "ardour/playlist.h"
80 #include "ardour/plugin_insert.h"
81 #include "ardour/port_insert.h"
82 #include "ardour/processor.h"
83 #include "ardour/rc_configuration.h"
84 #include "ardour/recent_sessions.h"
85 #include "ardour/region_factory.h"
86 #include "ardour/return.h"
87 #include "ardour/route_group.h"
88 #include "ardour/send.h"
89 #include "ardour/session.h"
90 #include "ardour/session_directory.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_metadata.h"
93 #include "ardour/session_playlists.h"
94 #include "ardour/slave.h"
95 #include "ardour/smf_source.h"
96 #include "ardour/source_factory.h"
97 #include "ardour/tape_file_matcher.h"
98 #include "ardour/tempo.h"
99 #include "ardour/utils.h"
100 #include "ardour/graph.h"
102 #include "midi++/port.h"
103 #include "midi++/mmc.h"
104 #include "midi++/manager.h"
109 using namespace ARDOUR;
111 using boost::shared_ptr;
112 using boost::weak_ptr;
114 bool Session::_disable_all_loaded_plugins = false;
116 PBD::Signal1<void,std::string> Session::Dialog;
117 PBD::Signal0<int> Session::AskAboutPendingState;
118 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
119 PBD::Signal0<void> Session::SendFeedback;
121 PBD::Signal0<void> Session::TimecodeOffsetChanged;
122 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
123 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
124 PBD::Signal0<void> Session::AutoBindingOn;
125 PBD::Signal0<void> Session::AutoBindingOff;
126 PBD::Signal2<void,std::string, std::string> Session::Exported;
127 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
128 PBD::Signal0<void> Session::Quit;
130 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
131 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
133 Session::Session (AudioEngine &eng,
134 const string& fullpath,
135 const string& snapshot_name,
136 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)
154 , _click_io ((IO*) 0)
156 , click_emphasis_data (0)
158 , _metadata (new SessionMetadata())
159 , _have_rec_enabled_track (false)
160 , _suspend_timecode_transmission (0)
162 _locations = new Locations (*this);
164 playlists.reset (new SessionPlaylists);
166 _all_route_group->set_active (true, this);
168 interpolation.add_channel_to (0, 0);
170 if (!eng.connected()) {
171 throw failed_constructor();
174 n_physical_outputs = _engine.n_physical_outputs ();
175 n_physical_inputs = _engine.n_physical_inputs ();
177 first_stage_init (fullpath, snapshot_name);
179 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
182 if (create (mix_template, bus_profile)) {
184 throw failed_constructor ();
188 if (second_stage_init ()) {
190 throw failed_constructor ();
193 store_recent_sessions(_name, _path);
195 bool was_dirty = dirty();
197 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
199 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
200 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
203 DirtyChanged (); /* EMIT SIGNAL */
206 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
207 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
220 vector<void*> debug_pointers;
222 /* if we got to here, leaving pending capture state around
226 remove_pending_capture_state ();
228 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
230 _engine.remove_session ();
232 /* clear history so that no references to objects are held any more */
236 /* clear state tree so that no references to objects are held any more */
240 /* remove all stubfiles that might still be lurking */
242 cleanup_stubfiles ();
244 /* reset dynamic state version back to default */
246 Stateful::loading_state_version = 0;
248 _butler->drop_references ();
250 delete midi_control_ui;
251 delete _all_route_group;
253 if (click_data != default_click) {
254 delete [] click_data;
257 if (click_emphasis_data != default_click_emphasis) {
258 delete [] click_emphasis_data;
263 /* clear out any pending dead wood from RCU managed objects */
268 AudioDiskstream::free_working_buffers();
270 /* tell everyone who is still standing that we're about to die */
273 /* tell everyone to drop references and delete objects as we go */
275 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
276 named_selections.clear ();
278 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
279 RegionFactory::delete_all_regions ();
281 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
283 /* reset these three references to special routes before we do the usual route delete thing */
286 _master_out.reset ();
287 _monitor_out.reset ();
290 RCUWriter<RouteList> writer (routes);
291 boost::shared_ptr<RouteList> r = writer.get_copy ();
293 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
294 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
295 (*i)->drop_references ();
299 /* writer goes out of scope and updates master */
303 boost::shared_ptr<RouteList> r = routes.reader ();
305 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
306 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
307 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
308 i->second->drop_references ();
313 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
314 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
319 Crossfade::set_buffer_size (0);
321 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
324 boost_debug_list_ptrs ();
328 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
332 Session::set_worst_io_latencies ()
334 _worst_output_latency = 0;
335 _worst_input_latency = 0;
337 if (!_engine.connected()) {
341 boost::shared_ptr<RouteList> r = routes.reader ();
343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
344 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
345 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
350 Session::when_engine_running ()
352 string first_physical_output;
354 BootMessage (_("Set block size and sample rate"));
356 set_block_size (_engine.frames_per_cycle());
357 set_frame_rate (_engine.frame_rate());
359 BootMessage (_("Using configuration"));
361 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
362 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
364 Config->map_parameters (ff);
365 config.map_parameters (ft);
367 /* every time we reconnect, recompute worst case output latencies */
369 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
371 if (synced_to_jack()) {
372 _engine.transport_stop ();
375 if (config.get_jack_time_master()) {
376 _engine.transport_locate (_transport_frame);
384 _click_io.reset (new ClickIO (*this, "click"));
386 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
388 /* existing state for Click */
391 if (Stateful::loading_state_version < 3000) {
392 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
394 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
399 _clicking = Config->get_clicking ();
403 error << _("could not setup Click I/O") << endmsg;
410 /* default state for Click: dual-mono to first 2 physical outputs */
413 _engine.get_physical_outputs (DataType::AUDIO, outs);
415 for (uint32_t physport = 0; physport < 2; ++physport) {
416 if (outs.size() > physport) {
417 if (_click_io->add_port (outs[physport], this)) {
418 // relax, even though its an error
423 if (_click_io->n_ports () > ChanCount::ZERO) {
424 _clicking = Config->get_clicking ();
429 catch (failed_constructor& err) {
430 error << _("cannot setup Click I/O") << endmsg;
433 BootMessage (_("Compute I/O Latencies"));
435 set_worst_io_latencies ();
438 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
441 BootMessage (_("Set up standard connections"));
443 vector<string> inputs[DataType::num_types];
444 vector<string> outputs[DataType::num_types];
445 for (uint32_t i = 0; i < DataType::num_types; ++i) {
446 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
447 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
450 /* Create a set of Bundle objects that map
451 to the physical I/O currently available. We create both
452 mono and stereo bundles, so that the common cases of mono
453 and stereo tracks get bundles to put in their mixer strip
454 in / out menus. There may be a nicer way of achieving that;
455 it doesn't really scale that well to higher channel counts
458 /* mono output bundles */
460 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
462 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
464 shared_ptr<Bundle> c (new Bundle (buf, true));
465 c->add_channel (_("mono"), DataType::AUDIO);
466 c->set_port (0, outputs[DataType::AUDIO][np]);
471 /* stereo output bundles */
473 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
474 if (np + 1 < outputs[DataType::AUDIO].size()) {
476 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
477 shared_ptr<Bundle> c (new Bundle (buf, true));
478 c->add_channel (_("L"), DataType::AUDIO);
479 c->set_port (0, outputs[DataType::AUDIO][np]);
480 c->add_channel (_("R"), DataType::AUDIO);
481 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
487 /* mono input bundles */
489 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
491 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
493 shared_ptr<Bundle> c (new Bundle (buf, false));
494 c->add_channel (_("mono"), DataType::AUDIO);
495 c->set_port (0, inputs[DataType::AUDIO][np]);
500 /* stereo input bundles */
502 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
503 if (np + 1 < inputs[DataType::AUDIO].size()) {
505 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
507 shared_ptr<Bundle> c (new Bundle (buf, false));
508 c->add_channel (_("L"), DataType::AUDIO);
509 c->set_port (0, inputs[DataType::AUDIO][np]);
510 c->add_channel (_("R"), DataType::AUDIO);
511 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
517 /* MIDI input bundles */
519 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
520 string n = inputs[DataType::MIDI][np];
521 boost::erase_first (n, X_("alsa_pcm:"));
523 shared_ptr<Bundle> c (new Bundle (n, false));
524 c->add_channel ("", DataType::MIDI);
525 c->set_port (0, inputs[DataType::MIDI][np]);
529 /* MIDI output bundles */
531 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
532 string n = outputs[DataType::MIDI][np];
533 boost::erase_first (n, X_("alsa_pcm:"));
535 shared_ptr<Bundle> c (new Bundle (n, true));
536 c->add_channel ("", DataType::MIDI);
537 c->set_port (0, outputs[DataType::MIDI][np]);
541 BootMessage (_("Setup signal flow and plugins"));
545 if (_is_new && !no_auto_connect()) {
547 /* don't connect the master bus outputs if there is a monitor bus */
549 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
551 /* if requested auto-connect the outputs to the first N physical ports.
554 uint32_t limit = _master_out->n_outputs().n_total();
556 for (uint32_t n = 0; n < limit; ++n) {
557 Port* p = _master_out->output()->nth (n);
559 if (outputs[p->type()].size() > n) {
560 connect_to = outputs[p->type()][n];
563 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
564 if (_master_out->output()->connect (p, connect_to, this)) {
565 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
575 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
576 are undefined, at best.
579 /* control out listens to master bus (but ignores it
580 under some conditions)
583 uint32_t limit = _monitor_out->n_inputs().n_audio();
586 for (uint32_t n = 0; n < limit; ++n) {
587 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
588 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
591 string connect_to = o->name();
592 if (_monitor_out->input()->connect (p, connect_to, this)) {
593 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
601 /* if control out is not connected, connect control out to physical outs
604 if (!_monitor_out->output()->connected ()) {
606 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
608 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
611 _monitor_out->output()->connect_ports_to_bundle (b, this);
613 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
614 Config->get_monitor_bus_preferred_bundle())
620 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
621 uint32_t mod = n_physical_outputs.get (*t);
622 uint32_t limit = _monitor_out->n_outputs().get(*t);
624 for (uint32_t n = 0; n < limit; ++n) {
626 Port* p = _monitor_out->output()->ports().port(*t, n);
628 if (outputs[*t].size() > (n % mod)) {
629 connect_to = outputs[*t][n % mod];
632 if (!connect_to.empty()) {
633 if (_monitor_out->output()->connect (p, connect_to, this)) {
634 error << string_compose (
635 _("cannot connect control output %1 to %2"),
648 /* catch up on send+insert cnts */
650 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
652 /* hook us up to the engine */
654 BootMessage (_("Connect to engine"));
656 _engine.set_session (this);
660 Session::hookup_io ()
662 /* stop graph reordering notifications from
663 causing resorts, etc.
666 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
671 /* we delay creating the auditioner till now because
672 it makes its own connections to ports.
676 Auditioner* a = new Auditioner (*this);
679 throw failed_constructor();
681 a->use_new_diskstream ();
682 auditioner.reset (a);
685 catch (failed_constructor& err) {
686 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
690 /* load bundles, which we may have postponed earlier on */
691 if (_bundle_xml_node) {
692 load_bundles (*_bundle_xml_node);
693 delete _bundle_xml_node;
696 /* Tell all IO objects to connect themselves together */
698 IO::enable_connecting ();
699 MIDI::Port::MakeConnections ();
701 /* Now reset all panners */
703 Delivery::reset_panners ();
705 /* Connect tracks to monitor/listen bus if there is one.
706 Note that in an existing session, the internal sends will
707 already exist, but we want the routes to notice that
708 they connect to the control out specifically.
712 boost::shared_ptr<RouteList> r = routes.reader ();
713 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
715 if ((*x)->is_monitor()) {
719 } else if ((*x)->is_master()) {
725 (*x)->listen_via (_monitor_out,
726 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
732 /* Anyone who cares about input state, wake up and do something */
734 IOConnectionsComplete (); /* EMIT SIGNAL */
736 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
738 /* now handle the whole enchilada as if it was one
744 /* update the full solo state, which can't be
745 correctly determined on a per-route basis, but
746 needs the global overview that only the session
750 update_route_solo_state ();
754 Session::playlist_length_changed ()
756 update_session_range_location_marker ();
760 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
762 boost::shared_ptr<Track> track = wp.lock ();
767 boost::shared_ptr<Playlist> playlist;
769 if ((playlist = track->playlist()) != 0) {
770 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
773 update_session_range_location_marker ();
777 Session::record_enabling_legal () const
779 /* this used to be in here, but survey says.... we don't need to restrict it */
780 // if (record_status() == Recording) {
784 if (Config->get_all_safe()) {
791 Session::reset_input_monitor_state ()
793 if (transport_rolling()) {
795 boost::shared_ptr<RouteList> rl = routes.reader ();
796 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
797 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
798 if (tr && tr->record_enabled ()) {
799 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
800 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
806 boost::shared_ptr<RouteList> rl = routes.reader ();
807 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
808 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
809 if (tr && tr->record_enabled ()) {
810 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
811 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
818 Session::auto_punch_start_changed (Location* location)
820 replace_event (SessionEvent::PunchIn, location->start());
822 if (get_record_enabled() && config.get_punch_in()) {
823 /* capture start has been changed, so save new pending state */
824 save_state ("", true);
829 Session::auto_punch_end_changed (Location* location)
831 nframes_t when_to_stop = location->end();
832 // when_to_stop += _worst_output_latency + _worst_input_latency;
833 replace_event (SessionEvent::PunchOut, when_to_stop);
837 Session::auto_punch_changed (Location* location)
839 nframes_t when_to_stop = location->end();
841 replace_event (SessionEvent::PunchIn, location->start());
842 //when_to_stop += _worst_output_latency + _worst_input_latency;
843 replace_event (SessionEvent::PunchOut, when_to_stop);
847 Session::auto_loop_changed (Location* location)
849 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
851 if (transport_rolling() && play_loop) {
854 // if (_transport_frame > location->end()) {
856 if (_transport_frame < location->start() || _transport_frame > location->end()) {
857 // relocate to beginning of loop
858 clear_events (SessionEvent::LocateRoll);
860 request_locate (location->start(), true);
863 else if (Config->get_seamless_loop() && !loop_changing) {
865 // schedule a locate-roll to refill the diskstreams at the
867 loop_changing = true;
869 if (location->end() > last_loopend) {
870 clear_events (SessionEvent::LocateRoll);
871 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
878 last_loopend = location->end();
882 Session::set_auto_punch_location (Location* location)
886 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
887 punch_connections.drop_connections();
888 existing->set_auto_punch (false, this);
889 remove_event (existing->start(), SessionEvent::PunchIn);
890 clear_events (SessionEvent::PunchOut);
891 auto_punch_location_changed (0);
900 if (location->end() <= location->start()) {
901 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
905 punch_connections.drop_connections ();
907 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
908 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
909 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
911 location->set_auto_punch (true, this);
913 auto_punch_changed (location);
915 auto_punch_location_changed (location);
919 Session::set_auto_loop_location (Location* location)
923 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
924 loop_connections.drop_connections ();
925 existing->set_auto_loop (false, this);
926 remove_event (existing->end(), SessionEvent::AutoLoop);
927 auto_loop_location_changed (0);
936 if (location->end() <= location->start()) {
937 error << _("Session: you can't use a mark for auto loop") << endmsg;
941 last_loopend = location->end();
943 loop_connections.drop_connections ();
945 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
946 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
947 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
949 location->set_auto_loop (true, this);
951 /* take care of our stuff first */
953 auto_loop_changed (location);
955 /* now tell everyone else */
957 auto_loop_location_changed (location);
961 Session::locations_added (Location *)
967 Session::locations_changed ()
969 _locations->apply (*this, &Session::handle_locations_changed);
973 Session::handle_locations_changed (Locations::LocationList& locations)
975 Locations::LocationList::iterator i;
977 bool set_loop = false;
978 bool set_punch = false;
980 for (i = locations.begin(); i != locations.end(); ++i) {
984 if (location->is_auto_punch()) {
985 set_auto_punch_location (location);
988 if (location->is_auto_loop()) {
989 set_auto_loop_location (location);
993 if (location->is_session_range()) {
994 _session_range_location = location;
999 set_auto_loop_location (0);
1002 set_auto_punch_location (0);
1009 Session::enable_record ()
1012 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1014 if (rs == Recording) {
1018 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1020 _last_record_location = _transport_frame;
1021 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1023 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1025 boost::shared_ptr<RouteList> rl = routes.reader ();
1026 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1027 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1028 if (tr && tr->record_enabled ()) {
1029 tr->monitor_input (true);
1034 RecordStateChanged ();
1041 Session::disable_record (bool rt_context, bool force)
1045 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1047 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1048 g_atomic_int_set (&_record_status, Disabled);
1049 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1051 if (rs == Recording) {
1052 g_atomic_int_set (&_record_status, Enabled);
1056 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1058 boost::shared_ptr<RouteList> rl = routes.reader ();
1059 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1060 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1061 if (tr && tr->record_enabled ()) {
1062 tr->monitor_input (false);
1067 RecordStateChanged (); /* emit signal */
1070 remove_pending_capture_state ();
1076 Session::step_back_from_record ()
1078 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1080 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1081 boost::shared_ptr<RouteList> rl = routes.reader ();
1082 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1083 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1084 if (tr && tr->record_enabled ()) {
1085 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1086 tr->monitor_input (false);
1094 Session::maybe_enable_record ()
1096 if (_step_editors > 0) {
1100 g_atomic_int_set (&_record_status, Enabled);
1102 /* This function is currently called from somewhere other than an RT thread.
1103 This save_state() call therefore doesn't impact anything. Doing it here
1104 means that we save pending state of which sources the next record will use,
1105 which gives us some chance of recovering from a crash during the record.
1108 save_state ("", true);
1110 if (_transport_speed) {
1111 if (!config.get_punch_in()) {
1115 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1116 RecordStateChanged (); /* EMIT SIGNAL */
1123 Session::audible_frame () const
1129 /* the first of these two possible settings for "offset"
1130 mean that the audible frame is stationary until
1131 audio emerges from the latency compensation
1134 the second means that the audible frame is stationary
1135 until audio would emerge from a physical port
1136 in the absence of any plugin latency compensation
1139 offset = _worst_output_latency;
1141 if (offset > current_block_size) {
1142 offset -= current_block_size;
1144 /* XXX is this correct? if we have no external
1145 physical connections and everything is internal
1146 then surely this is zero? still, how
1147 likely is that anyway?
1149 offset = current_block_size;
1152 if (synced_to_jack()) {
1153 tf = _engine.transport_frame();
1155 tf = _transport_frame;
1160 if (!non_realtime_work_pending()) {
1164 /* Check to see if we have passed the first guaranteed
1165 audible frame past our last start position. if not,
1166 return that last start point because in terms
1167 of audible frames, we have not moved yet.
1169 `Start position' in this context means the time we last
1170 either started or changed transport direction.
1173 if (_transport_speed > 0.0f) {
1175 if (!play_loop || !have_looped) {
1176 if (tf < _last_roll_or_reversal_location + offset) {
1177 return _last_roll_or_reversal_location;
1185 } else if (_transport_speed < 0.0f) {
1187 /* XXX wot? no backward looping? */
1189 if (tf > _last_roll_or_reversal_location - offset) {
1190 return _last_roll_or_reversal_location;
1202 Session::set_frame_rate (nframes_t frames_per_second)
1204 /** \fn void Session::set_frame_size(nframes_t)
1205 the AudioEngine object that calls this guarantees
1206 that it will not be called while we are also in
1207 ::process(). Its fine to do things that block
1211 _base_frame_rate = frames_per_second;
1215 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1219 // XXX we need some equivalent to this, somehow
1220 // SndFileSource::setup_standard_crossfades (frames_per_second);
1224 /* XXX need to reset/reinstantiate all LADSPA plugins */
1228 Session::set_block_size (nframes_t nframes)
1230 /* the AudioEngine guarantees
1231 that it will not be called while we are also in
1232 ::process(). It is therefore fine to do things that block
1237 current_block_size = nframes;
1241 boost::shared_ptr<RouteList> r = routes.reader ();
1243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1244 (*i)->set_block_size (nframes);
1247 boost::shared_ptr<RouteList> rl = routes.reader ();
1248 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1249 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1251 tr->set_block_size (nframes);
1255 set_worst_io_latencies ();
1260 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1263 nframes_t fade_frames;
1265 /* Don't allow fade of less 1 frame */
1267 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1274 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1278 default_fade_msecs = fade_msecs;
1279 default_fade_steepness = steepness;
1282 // jlc, WTF is this!
1283 Glib::RWLock::ReaderLock lm (route_lock);
1284 AudioRegion::set_default_fade (steepness, fade_frames);
1289 /* XXX have to do this at some point */
1290 /* foreach region using default fade, reset, then
1291 refill_all_diskstream_buffers ();
1296 struct RouteSorter {
1297 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1298 if (r2->feeds (r1)) {
1300 } else if (r1->feeds (r2)) {
1303 if (r1->not_fed ()) {
1304 if (r2->not_fed ()) {
1305 /* no ardour-based connections inbound to either route. just use signal order */
1306 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1308 /* r2 has connections, r1 does not; run r1 early */
1312 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1319 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1321 shared_ptr<Route> r2;
1323 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1324 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1328 /* make a copy of the existing list of routes that feed r1 */
1330 Route::FedBy existing (r1->fed_by());
1332 /* for each route that feeds r1, recurse, marking it as feeding
1336 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1337 if (!(r2 = i->r.lock ())) {
1338 /* (*i) went away, ignore it */
1342 /* r2 is a route that feeds r1 which somehow feeds base. mark
1343 base as being fed by r2
1346 rbase->add_fed_by (r2, i->sends_only);
1350 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1354 if (r1->feeds (r2) && r2->feeds (r1)) {
1358 /* now recurse, so that we can mark base as being fed by
1359 all routes that feed r2
1362 trace_terminal (r2, rbase);
1369 Session::resort_routes ()
1371 /* don't do anything here with signals emitted
1372 by Routes while we are being destroyed.
1375 if (_state_of_the_state & Deletion) {
1380 RCUWriter<RouteList> writer (routes);
1381 shared_ptr<RouteList> r = writer.get_copy ();
1382 resort_routes_using (r);
1383 /* writer goes out of scope and forces update */
1386 //route_graph->dump(1);
1389 boost::shared_ptr<RouteList> rl = routes.reader ();
1390 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1391 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1393 const Route::FedBy& fb ((*i)->fed_by());
1395 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1396 boost::shared_ptr<Route> sf = f->r.lock();
1398 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1406 Session::resort_routes_using (shared_ptr<RouteList> r)
1408 RouteList::iterator i, j;
1410 for (i = r->begin(); i != r->end(); ++i) {
1412 (*i)->clear_fed_by ();
1414 for (j = r->begin(); j != r->end(); ++j) {
1416 /* although routes can feed themselves, it will
1417 cause an endless recursive descent if we
1418 detect it. so don't bother checking for
1426 bool via_sends_only;
1428 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1429 (*i)->add_fed_by (*j, via_sends_only);
1434 for (i = r->begin(); i != r->end(); ++i) {
1435 trace_terminal (*i, *i);
1441 route_graph->rechain (r);
1444 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1445 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1446 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1447 (*i)->name(), (*i)->order_key ("signal")));
1453 /** Find the route name starting with \a base with the lowest \a id.
1455 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1456 * The available route name with the lowest ID will be used, and \a id
1457 * will be set to the ID.
1459 * \return false if a route name could not be found, and \a track_name
1460 * and \a id do not reflect a free route name.
1463 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1466 snprintf (name, name_len, "%s %" PRIu32, base, id);
1468 if (route_by_name (name) == 0) {
1474 } while (id < (UINT_MAX-1));
1479 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1481 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1483 in = ChanCount::ZERO;
1484 out = ChanCount::ZERO;
1485 shared_ptr<RouteList> r = routes.reader ();
1486 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1487 if (!(*i)->is_hidden()) {
1488 in += (*i)->n_inputs();
1489 out += (*i)->n_outputs();
1494 list<boost::shared_ptr<MidiTrack> >
1495 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1497 char track_name[32];
1498 uint32_t track_id = 0;
1499 ChanCount existing_inputs;
1500 ChanCount existing_outputs;
1502 RouteList new_routes;
1503 list<boost::shared_ptr<MidiTrack> > ret;
1504 uint32_t control_id;
1506 count_existing_route_channels (existing_inputs, existing_outputs);
1508 control_id = ntracks() + nbusses();
1511 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1512 error << "cannot find name for new midi track" << endmsg;
1516 shared_ptr<MidiTrack> track;
1519 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1526 mt->use_new_diskstream();
1528 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1529 track = boost::shared_ptr<MidiTrack>(mt);
1531 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1532 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1537 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1538 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1542 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1544 track->non_realtime_input_change();
1547 route_group->add (track);
1550 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1551 track->set_remote_control_id (control_id);
1553 new_routes.push_back (track);
1554 ret.push_back (track);
1557 catch (failed_constructor &err) {
1558 error << _("Session: could not create new midi track.") << endmsg;
1562 catch (AudioEngine::PortRegistrationFailure& pfe) {
1564 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;
1572 if (!new_routes.empty()) {
1573 add_routes (new_routes, false);
1574 save_state (_current_snapshot_name);
1580 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1581 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1582 * @param output_start As \a input_start, but for outputs.
1585 Session::auto_connect_route (
1586 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1589 /* If both inputs and outputs are auto-connected to physical ports,
1590 use the max of input and output offsets to ensure auto-connected
1591 port numbers always match up (e.g. the first audio input and the
1592 first audio output of the route will have the same physical
1593 port number). Otherwise just use the lowest input or output
1597 const bool in_out_physical =
1598 (Config->get_input_auto_connect() & AutoConnectPhysical)
1599 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1602 const ChanCount in_offset = in_out_physical
1603 ? ChanCount::max(existing_inputs, existing_outputs)
1606 const ChanCount out_offset = in_out_physical
1607 ? ChanCount::max(existing_inputs, existing_outputs)
1610 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1611 vector<string> physinputs;
1612 vector<string> physoutputs;
1614 _engine.get_physical_outputs (*t, physoutputs);
1615 _engine.get_physical_inputs (*t, physinputs);
1617 if (!physinputs.empty() && connect_inputs) {
1618 uint32_t nphysical_in = physinputs.size();
1619 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1622 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1623 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1626 if (!port.empty() && route->input()->connect (
1627 route->input()->ports().port(*t, i), port, this)) {
1633 if (!physoutputs.empty()) {
1634 uint32_t nphysical_out = physoutputs.size();
1635 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1638 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1639 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1640 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1641 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1642 port = _master_out->input()->ports().port(*t,
1643 i % _master_out->input()->n_ports().get(*t))->name();
1647 if (!port.empty() && route->output()->connect (
1648 route->output()->ports().port(*t, i), port, this)) {
1655 existing_inputs += route->n_inputs();
1656 existing_outputs += route->n_outputs();
1659 list< boost::shared_ptr<AudioTrack> >
1660 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1662 char track_name[32];
1663 uint32_t track_id = 0;
1664 ChanCount existing_inputs;
1665 ChanCount existing_outputs;
1667 RouteList new_routes;
1668 list<boost::shared_ptr<AudioTrack> > ret;
1669 uint32_t control_id;
1671 count_existing_route_channels (existing_inputs, existing_outputs);
1673 control_id = ntracks() + nbusses() + 1;
1676 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1677 error << "cannot find name for new audio track" << endmsg;
1681 shared_ptr<AudioTrack> track;
1684 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1691 at->use_new_diskstream();
1693 boost_debug_shared_ptr_mark_interesting (at, "Track");
1694 track = boost::shared_ptr<AudioTrack>(at);
1696 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1697 error << string_compose (
1698 _("cannot configure %1 in/%2 out configuration for new audio track"),
1699 input_channels, output_channels)
1704 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1705 error << string_compose (
1706 _("cannot configure %1 in/%2 out configuration for new audio track"),
1707 input_channels, output_channels)
1712 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1715 route_group->add (track);
1718 track->non_realtime_input_change();
1720 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1721 track->set_remote_control_id (control_id);
1724 new_routes.push_back (track);
1725 ret.push_back (track);
1728 catch (failed_constructor &err) {
1729 error << _("Session: could not create new audio track.") << endmsg;
1733 catch (AudioEngine::PortRegistrationFailure& pfe) {
1735 error << pfe.what() << endmsg;
1743 if (!new_routes.empty()) {
1744 add_routes (new_routes, true);
1751 Session::set_remote_control_ids ()
1753 RemoteModel m = Config->get_remote_model();
1754 bool emit_signal = false;
1756 shared_ptr<RouteList> r = routes.reader ();
1758 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1759 if (MixerOrdered == m) {
1760 int32_t order = (*i)->order_key(N_("signal"));
1761 (*i)->set_remote_control_id (order+1, false);
1763 } else if (EditorOrdered == m) {
1764 int32_t order = (*i)->order_key(N_("editor"));
1765 (*i)->set_remote_control_id (order+1, false);
1767 } else if (UserOrdered == m) {
1768 //do nothing ... only changes to remote id's are initiated by user
1773 Route::RemoteControlIDChange();
1779 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1782 uint32_t bus_id = 0;
1783 ChanCount existing_inputs;
1784 ChanCount existing_outputs;
1787 uint32_t control_id;
1789 count_existing_route_channels (existing_inputs, existing_outputs);
1791 control_id = ntracks() + nbusses() + 1;
1794 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1795 error << "cannot find name for new audio bus" << endmsg;
1800 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1807 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1808 shared_ptr<Route> bus (rt);
1810 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1811 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1812 input_channels, output_channels)
1818 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1819 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1820 input_channels, output_channels)
1825 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1828 route_group->add (bus);
1830 bus->set_remote_control_id (control_id);
1834 bus->add_internal_return ();
1837 ret.push_back (bus);
1841 catch (failed_constructor &err) {
1842 error << _("Session: could not create new audio route.") << endmsg;
1846 catch (AudioEngine::PortRegistrationFailure& pfe) {
1847 error << pfe.what() << endmsg;
1857 add_routes (ret, true);
1865 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1869 uint32_t control_id;
1871 uint32_t number = 0;
1873 if (!tree.read (template_path.c_str())) {
1877 XMLNode* node = tree.root();
1879 control_id = ntracks() + nbusses() + 1;
1883 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1885 std::string node_name = IO::name_from_state (*node_copy.children().front());
1887 /* generate a new name by adding a number to the end of the template name */
1888 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1889 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1893 /* set IO children to use the new name */
1894 XMLNodeList const & children = node_copy.children ();
1895 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1896 if ((*i)->name() == IO::state_node_name) {
1897 IO::set_name_in_state (**i, name);
1901 Track::zero_diskstream_id_in_xml (node_copy);
1904 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1907 error << _("Session: cannot create track/bus from template description") << endmsg;
1911 if (boost::dynamic_pointer_cast<Track>(route)) {
1912 /* force input/output change signals so that the new diskstream
1913 picks up the configuration of the route. During session
1914 loading this normally happens in a different way.
1916 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1917 change.after = route->input()->n_ports();
1918 route->input()->changed (change, this);
1919 change.after = route->output()->n_ports();
1920 route->output()->changed (change, this);
1923 route->set_remote_control_id (control_id);
1926 ret.push_back (route);
1929 catch (failed_constructor &err) {
1930 error << _("Session: could not create new route from template") << endmsg;
1934 catch (AudioEngine::PortRegistrationFailure& pfe) {
1935 error << pfe.what() << endmsg;
1944 add_routes (ret, true);
1951 Session::add_routes (RouteList& new_routes, bool save)
1954 RCUWriter<RouteList> writer (routes);
1955 shared_ptr<RouteList> r = writer.get_copy ();
1956 r->insert (r->end(), new_routes.begin(), new_routes.end());
1959 /* if there is no control out and we're not in the middle of loading,
1960 resort the graph here. if there is a control out, we will resort
1961 toward the end of this method. if we are in the middle of loading,
1962 we will resort when done.
1965 if (!_monitor_out && IO::connecting_legal) {
1966 resort_routes_using (r);
1970 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1972 boost::weak_ptr<Route> wpr (*x);
1973 boost::shared_ptr<Route> r (*x);
1975 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1976 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1977 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1978 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1979 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1980 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1981 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1983 if (r->is_master()) {
1987 if (r->is_monitor()) {
1991 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1993 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1994 track_playlist_changed (boost::weak_ptr<Track> (tr));
1995 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1997 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
1999 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2004 if (_monitor_out && IO::connecting_legal) {
2006 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2007 if ((*x)->is_monitor()) {
2009 } else if ((*x)->is_master()) {
2012 (*x)->listen_via (_monitor_out,
2013 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2024 save_state (_current_snapshot_name);
2027 RouteAdded (new_routes); /* EMIT SIGNAL */
2028 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2032 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2034 boost::shared_ptr<RouteList> r = routes.reader ();
2035 boost::shared_ptr<Send> s;
2039 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2040 if (boost::dynamic_pointer_cast<Track>(*i)) {
2041 if ((s = (*i)->internal_send_for (dest)) != 0) {
2042 s->amp()->gain_control()->set_value (0.0);
2049 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2051 boost::shared_ptr<RouteList> r = routes.reader ();
2052 boost::shared_ptr<Send> s;
2056 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2057 if (boost::dynamic_pointer_cast<Track>(*i)) {
2058 if ((s = (*i)->internal_send_for (dest)) != 0) {
2059 s->amp()->gain_control()->set_value (1.0);
2066 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2068 boost::shared_ptr<RouteList> r = routes.reader ();
2069 boost::shared_ptr<Send> s;
2073 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2074 if (boost::dynamic_pointer_cast<Track>(*i)) {
2075 if ((s = (*i)->internal_send_for (dest)) != 0) {
2076 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2083 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2085 boost::shared_ptr<RouteList> r = routes.reader ();
2086 boost::shared_ptr<RouteList> t (new RouteList);
2088 /* only send tracks */
2090 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2091 if (boost::dynamic_pointer_cast<Track>(*i)) {
2096 add_internal_sends (dest, p, t);
2100 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2102 if (dest->is_monitor() || dest->is_master()) {
2106 if (!dest->internal_return()) {
2107 dest->add_internal_return();
2110 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2112 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2116 (*i)->listen_via (dest, p, true, true);
2123 Session::remove_route (shared_ptr<Route> route)
2125 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2129 route->set_solo (false, this);
2132 RCUWriter<RouteList> writer (routes);
2133 shared_ptr<RouteList> rs = writer.get_copy ();
2137 /* deleting the master out seems like a dumb
2138 idea, but its more of a UI policy issue
2142 if (route == _master_out) {
2143 _master_out = shared_ptr<Route> ();
2146 if (route == _monitor_out) {
2148 /* cancel control outs for all routes */
2150 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2151 (*r)->drop_listen (_monitor_out);
2154 _monitor_out.reset ();
2157 /* writer goes out of scope, forces route list update */
2160 update_route_solo_state ();
2161 update_session_range_location_marker ();
2163 // We need to disconnect the route's inputs and outputs
2165 route->input()->disconnect (0);
2166 route->output()->disconnect (0);
2168 /* if the route had internal sends sending to it, remove them */
2169 if (route->internal_return()) {
2171 boost::shared_ptr<RouteList> r = routes.reader ();
2172 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2173 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2175 (*i)->remove_processor (s);
2180 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2181 if (mt && mt->step_editing()) {
2182 if (_step_editors > 0) {
2187 update_latency_compensation (false, false);
2190 /* Re-sort routes to remove the graph's current references to the one that is
2191 * going away, then flush old references out of the graph.
2195 route_graph->clear_other_chain ();
2197 /* get rid of it from the dead wood collection in the route list manager */
2199 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2203 /* try to cause everyone to drop their references */
2205 route->drop_references ();
2207 sync_order_keys (N_("session"));
2209 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2211 /* save the new state of the world */
2213 if (save_state (_current_snapshot_name)) {
2214 save_history (_current_snapshot_name);
2219 Session::route_mute_changed (void* /*src*/)
2225 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2227 boost::shared_ptr<Route> route = wpr.lock();
2229 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2233 if (route->listening()) {
2235 if (Config->get_exclusive_solo()) {
2236 /* new listen: disable all other listen */
2237 shared_ptr<RouteList> r = routes.reader ();
2238 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2239 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2242 (*i)->set_listen (false, this);
2248 } else if (_listen_cnt > 0) {
2254 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2256 boost::shared_ptr<Route> route = wpr.lock ();
2259 /* should not happen */
2260 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2264 bool send_changed = false;
2266 if (route->solo_isolated()) {
2267 if (_solo_isolated_cnt == 0) {
2268 send_changed = true;
2270 _solo_isolated_cnt++;
2271 } else if (_solo_isolated_cnt > 0) {
2272 _solo_isolated_cnt--;
2273 if (_solo_isolated_cnt == 0) {
2274 send_changed = true;
2279 IsolatedChanged (); /* EMIT SIGNAL */
2284 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2286 if (!self_solo_change) {
2287 // session doesn't care about changes to soloed-by-others
2291 if (solo_update_disabled) {
2296 boost::shared_ptr<Route> route = wpr.lock ();
2299 /* should not happen */
2300 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2304 shared_ptr<RouteList> r = routes.reader ();
2307 if (route->self_soloed()) {
2313 if (delta == 1 && Config->get_exclusive_solo()) {
2314 /* new solo: disable all other solos */
2315 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2316 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2319 (*i)->set_solo (false, this);
2323 solo_update_disabled = true;
2325 RouteList uninvolved;
2327 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2328 bool via_sends_only;
2329 bool in_signal_flow;
2331 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2335 in_signal_flow = false;
2337 if ((*i)->feeds (route, &via_sends_only)) {
2338 if (!via_sends_only) {
2339 if (!route->soloed_by_others_upstream()) {
2340 (*i)->mod_solo_by_others_downstream (delta);
2342 in_signal_flow = true;
2346 if (route->feeds (*i, &via_sends_only)) {
2347 (*i)->mod_solo_by_others_upstream (delta);
2348 in_signal_flow = true;
2351 if (!in_signal_flow) {
2352 uninvolved.push_back (*i);
2356 solo_update_disabled = false;
2357 update_route_solo_state (r);
2359 /* now notify that the mute state of the routes not involved in the signal
2360 pathway of the just-solo-changed route may have altered.
2363 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2364 (*i)->mute_changed (this);
2367 SoloChanged (); /* EMIT SIGNAL */
2372 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2374 /* now figure out if anything that matters is soloed (or is "listening")*/
2376 bool something_soloed = false;
2377 uint32_t listeners = 0;
2378 uint32_t isolated = 0;
2381 r = routes.reader();
2384 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2385 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2386 something_soloed = true;
2389 if (!(*i)->is_hidden() && (*i)->listening()) {
2390 if (Config->get_solo_control_is_listen_control()) {
2393 (*i)->set_listen (false, this);
2397 if ((*i)->solo_isolated()) {
2402 if (something_soloed != _non_soloed_outs_muted) {
2403 _non_soloed_outs_muted = something_soloed;
2404 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2407 _listen_cnt = listeners;
2409 if (isolated != _solo_isolated_cnt) {
2410 _solo_isolated_cnt = isolated;
2411 IsolatedChanged (); /* EMIT SIGNAL */
2415 boost::shared_ptr<RouteList>
2416 Session::get_routes_with_internal_returns() const
2418 shared_ptr<RouteList> r = routes.reader ();
2419 boost::shared_ptr<RouteList> rl (new RouteList);
2421 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2422 if ((*i)->internal_return ()) {
2430 Session::io_name_is_legal (const std::string& name)
2432 shared_ptr<RouteList> r = routes.reader ();
2434 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2435 if ((*i)->name() == name) {
2439 if ((*i)->has_io_processor_named (name)) {
2448 Session::route_by_name (string name)
2450 shared_ptr<RouteList> r = routes.reader ();
2452 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2453 if ((*i)->name() == name) {
2458 return shared_ptr<Route> ((Route*) 0);
2462 Session::route_by_id (PBD::ID id)
2464 shared_ptr<RouteList> r = routes.reader ();
2466 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2467 if ((*i)->id() == id) {
2472 return shared_ptr<Route> ((Route*) 0);
2476 Session::route_by_remote_id (uint32_t id)
2478 shared_ptr<RouteList> r = routes.reader ();
2480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2481 if ((*i)->remote_control_id() == id) {
2486 return shared_ptr<Route> ((Route*) 0);
2489 /** If either end of the session range location marker lies inside the current
2490 * session extent, move it to the corresponding session extent.
2493 Session::update_session_range_location_marker ()
2495 if (_state_of_the_state & Loading) {
2499 pair<framepos_t, framepos_t> const ext = get_extent ();
2501 if (_session_range_location == 0) {
2502 /* we don't have a session range yet; use this one (provided it is valid) */
2503 if (ext.first != max_framepos) {
2504 add_session_range_location (ext.first, ext.second);
2507 /* update the existing session range */
2508 if (ext.first < _session_range_location->start()) {
2509 _session_range_location->set_start (ext.first);
2513 if (ext.second > _session_range_location->end()) {
2514 _session_range_location->set_end (ext.second);
2521 /** @return Extent of the session's contents; if the session is empty, the first value of
2522 * the pair will equal max_framepos.
2524 pair<framepos_t, framepos_t>
2525 Session::get_extent () const
2527 pair<framepos_t, framepos_t> ext (max_framepos, 0);
2529 boost::shared_ptr<RouteList> rl = routes.reader ();
2530 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2531 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2532 if (!tr || tr->destructive()) {
2533 // ignore tape tracks when getting extents
2537 pair<framepos_t, framepos_t> e = tr->playlist()->get_extent ();
2538 if (e.first < ext.first) {
2539 ext.first = e.first;
2541 if (e.second > ext.second) {
2542 ext.second = e.second;
2549 /* Region management */
2551 boost::shared_ptr<Region>
2552 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2554 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2555 RegionFactory::RegionMap::const_iterator i;
2556 boost::shared_ptr<Region> region;
2558 Glib::Mutex::Lock lm (region_lock);
2560 for (i = regions.begin(); i != regions.end(); ++i) {
2564 if (region->whole_file()) {
2566 if (child->source_equivalent (region)) {
2572 return boost::shared_ptr<Region> ();
2576 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2578 set<boost::shared_ptr<Region> > relevant_regions;
2580 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2581 RegionFactory::get_regions_using_source (*s, relevant_regions);
2584 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2586 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2587 set<boost::shared_ptr<Region> >::iterator tmp;
2592 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2594 playlists->destroy_region (*r);
2595 RegionFactory::map_remove (*r);
2597 (*r)->drop_sources ();
2598 (*r)->drop_references ();
2600 cerr << "\tdone UC = " << (*r).use_count() << endl;
2602 relevant_regions.erase (r);
2607 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2610 Glib::Mutex::Lock ls (source_lock);
2611 /* remove from the main source list */
2612 sources.erase ((*s)->id());
2615 (*s)->mark_for_remove ();
2616 (*s)->drop_references ();
2625 Session::remove_last_capture ()
2627 list<boost::shared_ptr<Source> > srcs;
2629 boost::shared_ptr<RouteList> rl = routes.reader ();
2630 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2631 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2636 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2639 srcs.insert (srcs.end(), l.begin(), l.end());
2644 destroy_sources (srcs);
2646 save_state (_current_snapshot_name);
2651 /* Source Management */
2654 Session::add_source (boost::shared_ptr<Source> source)
2656 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2657 pair<SourceMap::iterator,bool> result;
2659 entry.first = source->id();
2660 entry.second = source;
2663 Glib::Mutex::Lock lm (source_lock);
2664 result = sources.insert (entry);
2667 if (result.second) {
2669 /* yay, new source */
2673 boost::shared_ptr<AudioFileSource> afs;
2675 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2676 if (Config->get_auto_analyse_audio()) {
2677 Analyser::queue_source_for_analysis (source, false);
2684 Session::remove_source (boost::weak_ptr<Source> src)
2686 SourceMap::iterator i;
2687 boost::shared_ptr<Source> source = src.lock();
2694 Glib::Mutex::Lock lm (source_lock);
2696 if ((i = sources.find (source->id())) != sources.end()) {
2697 cerr << "Removing source " << source->name() << endl;
2702 if (!_state_of_the_state & InCleanup) {
2704 /* save state so we don't end up with a session file
2705 referring to non-existent sources.
2708 save_state (_current_snapshot_name);
2712 boost::shared_ptr<Source>
2713 Session::source_by_id (const PBD::ID& id)
2715 Glib::Mutex::Lock lm (source_lock);
2716 SourceMap::iterator i;
2717 boost::shared_ptr<Source> source;
2719 if ((i = sources.find (id)) != sources.end()) {
2726 boost::shared_ptr<Source>
2727 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2729 Glib::Mutex::Lock lm (source_lock);
2731 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2732 boost::shared_ptr<AudioFileSource> afs
2733 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2735 if (afs && afs->path() == path && chn == afs->channel()) {
2739 return boost::shared_ptr<Source>();
2744 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2747 string old_basename = PBD::basename_nosuffix (oldname);
2748 string new_legalized = legalize_for_path (newname);
2750 /* note: we know (or assume) the old path is already valid */
2754 /* destructive file sources have a name of the form:
2756 /path/to/Tnnnn-NAME(%[LR])?.wav
2758 the task here is to replace NAME with the new name.
2763 string::size_type dash;
2765 dir = Glib::path_get_dirname (path);
2766 path = Glib::path_get_basename (path);
2768 /* '-' is not a legal character for the NAME part of the path */
2770 if ((dash = path.find_last_of ('-')) == string::npos) {
2774 prefix = path.substr (0, dash);
2778 path += new_legalized;
2779 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2781 path = Glib::build_filename (dir, path);
2785 /* non-destructive file sources have a name of the form:
2787 /path/to/NAME-nnnnn(%[LR])?.ext
2789 the task here is to replace NAME with the new name.
2794 string::size_type dash;
2795 string::size_type postfix;
2797 dir = Glib::path_get_dirname (path);
2798 path = Glib::path_get_basename (path);
2800 /* '-' is not a legal character for the NAME part of the path */
2802 if ((dash = path.find_last_of ('-')) == string::npos) {
2806 suffix = path.substr (dash+1);
2808 // Suffix is now everything after the dash. Now we need to eliminate
2809 // the nnnnn part, which is done by either finding a '%' or a '.'
2811 postfix = suffix.find_last_of ("%");
2812 if (postfix == string::npos) {
2813 postfix = suffix.find_last_of ('.');
2816 if (postfix != string::npos) {
2817 suffix = suffix.substr (postfix);
2819 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2823 const uint32_t limit = 10000;
2824 char buf[PATH_MAX+1];
2826 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2828 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2830 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2831 path = Glib::build_filename (dir, buf);
2839 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2848 /** Return the full path (in some session directory) for a new within-session source.
2849 * \a name must be a session-unique name that does not contain slashes
2850 * (e.g. as returned by new_*_source_name)
2853 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2855 assert(name.find("/") == string::npos);
2857 SessionDirectory sdir(get_best_session_directory_for_new_source());
2860 if (type == DataType::AUDIO) {
2861 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2862 } else if (type == DataType::MIDI) {
2863 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2865 error << "Unknown source type, unable to create file path" << endmsg;
2870 return p.to_string();
2874 Session::peak_path (string base) const
2876 sys::path peakfile_path(_session_dir->peak_path());
2877 peakfile_path /= base + peakfile_suffix;
2878 return peakfile_path.to_string();
2881 /** Return a unique name based on \a base for a new internal audio source */
2883 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2886 char buf[PATH_MAX+1];
2887 const uint32_t limit = 10000;
2889 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2892 legalized = legalize_for_path (base);
2894 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2895 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2897 vector<space_and_path>::iterator i;
2898 uint32_t existing = 0;
2900 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2905 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2906 cnt, legalized.c_str(), ext.c_str());
2907 } else if (nchan == 2) {
2909 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2910 cnt, legalized.c_str(), ext.c_str());
2912 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2913 cnt, legalized.c_str(), ext.c_str());
2915 } else if (nchan < 26) {
2916 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2917 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2919 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2920 cnt, legalized.c_str(), ext.c_str());
2926 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2927 } else if (nchan == 2) {
2929 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2931 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2933 } else if (nchan < 26) {
2934 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2936 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2940 SessionDirectory sdir((*i).path);
2942 string spath = sdir.sound_path().to_string();
2943 string spath_stubs = sdir.sound_stub_path().to_string();
2945 /* note that we search *without* the extension so that
2946 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2947 in the event that this new name is required for
2948 a file format change.
2951 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2952 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
2958 if (existing == 0) {
2963 error << string_compose(
2964 _("There are already %1 recordings for %2, which I consider too many."),
2965 limit, base) << endmsg;
2967 throw failed_constructor();
2971 return Glib::path_get_basename (buf);
2974 /** Create a new within-session audio source */
2975 boost::shared_ptr<AudioFileSource>
2976 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
2978 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2979 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
2981 return boost::dynamic_pointer_cast<AudioFileSource> (
2982 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
2985 /** Return a unique name based on \a base for a new internal MIDI source */
2987 Session::new_midi_source_name (const string& base)
2990 char buf[PATH_MAX+1];
2991 const uint32_t limit = 10000;
2995 legalized = legalize_for_path (base);
2997 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2998 for (cnt = 1; cnt <= limit; ++cnt) {
3000 vector<space_and_path>::iterator i;
3001 uint32_t existing = 0;
3003 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3005 SessionDirectory sdir((*i).path);
3007 sys::path p = sdir.midi_path();
3010 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3012 if (sys::exists (buf)) {
3017 if (existing == 0) {
3022 error << string_compose(
3023 _("There are already %1 recordings for %2, which I consider too many."),
3024 limit, base) << endmsg;
3026 throw failed_constructor();
3030 return Glib::path_get_basename(buf);
3034 /** Create a new within-session MIDI source */
3035 boost::shared_ptr<MidiSource>
3036 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3038 /* try to use the existing write source for the track, to keep numbering sane
3042 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3046 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3049 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3050 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3054 const string name = new_midi_source_name (n);
3055 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3057 return boost::dynamic_pointer_cast<SMFSource> (
3058 SourceFactory::createWritable (
3059 DataType::MIDI, *this, path, false, frame_rate()));
3064 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3066 if (playlist->hidden()) {
3070 playlists->add (playlist);
3073 playlist->release();
3080 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3082 if (_state_of_the_state & Deletion) {
3086 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3092 playlists->remove (playlist);
3098 Session::set_audition (boost::shared_ptr<Region> r)
3100 pending_audition_region = r;
3101 add_post_transport_work (PostTransportAudition);
3102 _butler->schedule_transport_work ();
3106 Session::audition_playlist ()
3108 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3109 ev->region.reset ();
3114 Session::non_realtime_set_audition ()
3116 if (!pending_audition_region) {
3117 auditioner->audition_current_playlist ();
3119 auditioner->audition_region (pending_audition_region);
3120 pending_audition_region.reset ();
3122 AuditionActive (true); /* EMIT SIGNAL */
3126 Session::audition_region (boost::shared_ptr<Region> r)
3128 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3134 Session::cancel_audition ()
3136 if (auditioner->auditioning()) {
3137 auditioner->cancel_audition ();
3138 AuditionActive (false); /* EMIT SIGNAL */
3143 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3145 if (a->is_monitor()) {
3148 if (b->is_monitor()) {
3151 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3155 Session::is_auditioning () const
3157 /* can be called before we have an auditioner object */
3159 return auditioner->auditioning();
3166 Session::graph_reordered ()
3168 /* don't do this stuff if we are setting up connections
3169 from a set_state() call or creating new tracks. Ditto for deletion.
3172 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3176 /* every track/bus asked for this to be handled but it was deferred because
3177 we were connecting. do it now.
3180 request_input_change_handling ();
3184 /* force all diskstreams to update their capture offset values to
3185 reflect any changes in latencies within the graph.
3188 boost::shared_ptr<RouteList> rl = routes.reader ();
3189 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3190 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3192 tr->set_capture_offset ();
3198 Session::available_capture_duration ()
3200 float sample_bytes_on_disk = 4.0; // keep gcc happy
3202 switch (config.get_native_file_data_format()) {
3204 sample_bytes_on_disk = 4.0;
3208 sample_bytes_on_disk = 3.0;
3212 sample_bytes_on_disk = 2.0;
3216 /* impossible, but keep some gcc versions happy */
3217 fatal << string_compose (_("programming error: %1"),
3218 X_("illegal native file data format"))
3223 double scale = 4096.0 / sample_bytes_on_disk;
3225 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3226 return max_framecnt;
3229 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3233 Session::add_bundle (shared_ptr<Bundle> bundle)
3236 RCUWriter<BundleList> writer (_bundles);
3237 boost::shared_ptr<BundleList> b = writer.get_copy ();
3238 b->push_back (bundle);
3241 BundleAdded (bundle); /* EMIT SIGNAL */
3247 Session::remove_bundle (shared_ptr<Bundle> bundle)
3249 bool removed = false;
3252 RCUWriter<BundleList> writer (_bundles);
3253 boost::shared_ptr<BundleList> b = writer.get_copy ();
3254 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3256 if (i != b->end()) {
3263 BundleRemoved (bundle); /* EMIT SIGNAL */
3270 Session::bundle_by_name (string name) const
3272 boost::shared_ptr<BundleList> b = _bundles.reader ();
3274 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3275 if ((*i)->name() == name) {
3280 return boost::shared_ptr<Bundle> ();
3284 Session::tempo_map_changed (const PropertyChange&)
3288 playlists->update_after_tempo_map_change ();
3290 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3296 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3298 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3299 (*i)->recompute_frames_from_bbt ();
3303 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3304 * the given count with the current block size.
3307 Session::ensure_buffers (ChanCount howmany)
3309 BufferManager::ensure_buffers (howmany);
3313 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3315 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3316 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3321 Session::next_insert_id ()
3323 /* this doesn't really loop forever. just think about it */
3326 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3327 if (!insert_bitset[n]) {
3328 insert_bitset[n] = true;
3334 /* none available, so resize and try again */
3336 insert_bitset.resize (insert_bitset.size() + 16, false);
3341 Session::next_send_id ()
3343 /* this doesn't really loop forever. just think about it */
3346 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3347 if (!send_bitset[n]) {
3348 send_bitset[n] = true;
3354 /* none available, so resize and try again */
3356 send_bitset.resize (send_bitset.size() + 16, false);
3361 Session::next_return_id ()
3363 /* this doesn't really loop forever. just think about it */
3366 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3367 if (!return_bitset[n]) {
3368 return_bitset[n] = true;
3374 /* none available, so resize and try again */
3376 return_bitset.resize (return_bitset.size() + 16, false);
3381 Session::mark_send_id (uint32_t id)
3383 if (id >= send_bitset.size()) {
3384 send_bitset.resize (id+16, false);
3386 if (send_bitset[id]) {
3387 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3389 send_bitset[id] = true;
3393 Session::mark_return_id (uint32_t id)
3395 if (id >= return_bitset.size()) {
3396 return_bitset.resize (id+16, false);
3398 if (return_bitset[id]) {
3399 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3401 return_bitset[id] = true;
3405 Session::mark_insert_id (uint32_t id)
3407 if (id >= insert_bitset.size()) {
3408 insert_bitset.resize (id+16, false);
3410 if (insert_bitset[id]) {
3411 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3413 insert_bitset[id] = true;
3417 Session::unmark_send_id (uint32_t id)
3419 if (id < send_bitset.size()) {
3420 send_bitset[id] = false;
3425 Session::unmark_return_id (uint32_t id)
3427 if (id < return_bitset.size()) {
3428 return_bitset[id] = false;
3433 Session::unmark_insert_id (uint32_t id)
3435 if (id < insert_bitset.size()) {
3436 insert_bitset[id] = false;
3441 /* Named Selection management */
3443 boost::shared_ptr<NamedSelection>
3444 Session::named_selection_by_name (string name)
3446 Glib::Mutex::Lock lm (named_selection_lock);
3447 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3448 if ((*i)->name == name) {
3452 return boost::shared_ptr<NamedSelection>();
3456 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3459 Glib::Mutex::Lock lm (named_selection_lock);
3460 named_selections.insert (named_selections.begin(), named_selection);
3465 NamedSelectionAdded (); /* EMIT SIGNAL */
3469 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3471 bool removed = false;
3474 Glib::Mutex::Lock lm (named_selection_lock);
3476 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3478 if (i != named_selections.end()) {
3479 named_selections.erase (i);
3486 NamedSelectionRemoved (); /* EMIT SIGNAL */
3491 Session::reset_native_file_format ()
3493 boost::shared_ptr<RouteList> rl = routes.reader ();
3494 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3495 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3497 /* don't save state as we do this, there's no point
3500 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3501 tr->reset_write_sources (false);
3502 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3508 Session::route_name_unique (string n) const
3510 shared_ptr<RouteList> r = routes.reader ();
3512 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3513 if ((*i)->name() == n) {
3522 Session::route_name_internal (string n) const
3524 if (auditioner && auditioner->name() == n) {
3528 if (_click_io && _click_io->name() == n) {
3536 Session::freeze_all (InterThreadInfo& itt)
3538 shared_ptr<RouteList> r = routes.reader ();
3540 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3542 boost::shared_ptr<Track> t;
3544 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3545 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3555 boost::shared_ptr<Region>
3556 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3557 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3558 InterThreadInfo& itt, bool enable_processing)
3560 boost::shared_ptr<Region> result;
3561 boost::shared_ptr<Playlist> playlist;
3562 boost::shared_ptr<AudioFileSource> fsource;
3564 char buf[PATH_MAX+1];
3565 ChanCount nchans(track.n_channels());
3566 framepos_t position;
3567 framecnt_t this_chunk;
3570 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3571 const string sound_dir = sdir.sound_path().to_string();
3572 framepos_t len = end - start;
3573 bool need_block_size_reset = false;
3577 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3578 end, start) << endmsg;
3582 const framecnt_t chunk_size = (256 * 1024)/4;
3584 // block all process callback handling
3586 block_processing ();
3588 /* call tree *MUST* hold route_lock */
3590 if ((playlist = track.playlist()) == 0) {
3594 /* external redirects will be a problem */
3596 if (track.has_external_redirects()) {
3600 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3602 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3604 for (x = 0; x < 99999; ++x) {
3605 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());
3606 if (access (buf, F_OK) != 0) {
3612 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3617 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3618 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3621 catch (failed_constructor& err) {
3622 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3626 srcs.push_back (fsource);
3629 /* tell redirects that care that we are about to use a much larger blocksize */
3631 need_block_size_reset = true;
3632 track.set_block_size (chunk_size);
3634 /* XXX need to flush all redirects */
3639 /* create a set of reasonably-sized buffers */
3640 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3641 buffers.set_count(nchans);
3643 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3644 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3646 afs->prepare_for_peakfile_writes ();
3649 while (to_do && !itt.cancel) {
3651 this_chunk = min (to_do, chunk_size);
3653 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3658 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3659 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3662 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3668 start += this_chunk;
3669 to_do -= this_chunk;
3671 itt.progress = (float) (1.0 - ((double) to_do / len));
3680 xnow = localtime (&now);
3682 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3683 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3686 afs->update_header (position, *xnow, now);
3687 afs->flush_header ();
3691 /* construct a region to represent the bounced material */
3695 plist.add (Properties::start, 0);
3696 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3697 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3699 result = RegionFactory::create (srcs, plist);
3705 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3706 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3709 afs->mark_for_remove ();
3712 (*src)->drop_references ();
3716 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3717 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3720 afs->done_with_peakfile_writes ();
3725 if (need_block_size_reset) {
3726 track.set_block_size (get_block_size());
3729 unblock_processing ();
3735 Session::gain_automation_buffer() const
3737 return ProcessThread::gain_automation_buffer ();
3741 Session::pan_automation_buffer() const
3743 return ProcessThread::pan_automation_buffer ();
3747 Session::get_silent_buffers (ChanCount count)
3749 return ProcessThread::get_silent_buffers (count);
3751 assert(_silent_buffers->available() >= count);
3752 _silent_buffers->set_count(count);
3754 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3755 for (size_t i= 0; i < count.get(*t); ++i) {
3756 _silent_buffers->get(*t, i).clear();
3760 return *_silent_buffers;
3765 Session::get_scratch_buffers (ChanCount count)
3767 return ProcessThread::get_scratch_buffers (count);
3769 if (count != ChanCount::ZERO) {
3770 assert(_scratch_buffers->available() >= count);
3771 _scratch_buffers->set_count(count);
3773 _scratch_buffers->set_count (_scratch_buffers->available());
3776 return *_scratch_buffers;
3781 Session::get_mix_buffers (ChanCount count)
3783 return ProcessThread::get_mix_buffers (count);
3785 assert(_mix_buffers->available() >= count);
3786 _mix_buffers->set_count(count);
3787 return *_mix_buffers;
3792 Session::ntracks () const
3795 shared_ptr<RouteList> r = routes.reader ();
3797 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3798 if (boost::dynamic_pointer_cast<Track> (*i)) {
3807 Session::nbusses () const
3810 shared_ptr<RouteList> r = routes.reader ();
3812 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3813 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3822 Session::add_automation_list(AutomationList *al)
3824 automation_lists[al->id()] = al;
3828 Session::sync_order_keys (std::string const & base)
3830 if (deletion_in_progress()) {
3834 if (!Config->get_sync_all_route_ordering()) {
3835 /* leave order keys as they are */
3839 boost::shared_ptr<RouteList> r = routes.reader ();
3841 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3842 (*i)->sync_order_keys (base);
3845 Route::SyncOrderKeys (base); // EMIT SIGNAL
3847 /* this might not do anything */
3849 set_remote_control_ids ();
3852 /** @return true if there is at least one record-enabled track, otherwise false */
3854 Session::have_rec_enabled_track () const
3856 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3859 /** Update the state of our rec-enabled tracks flag */
3861 Session::update_have_rec_enabled_track ()
3863 boost::shared_ptr<RouteList> rl = routes.reader ();
3864 RouteList::iterator i = rl->begin();
3865 while (i != rl->end ()) {
3867 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3868 if (tr && tr->record_enabled ()) {
3875 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3877 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3879 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3880 RecordStateChanged (); /* EMIT SIGNAL */
3885 Session::listen_position_changed ()
3889 switch (Config->get_listen_position()) {
3890 case AfterFaderListen:
3894 case PreFaderListen:
3899 boost::shared_ptr<RouteList> r = routes.reader ();
3901 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3902 (*i)->put_monitor_send_at (p);
3907 Session::solo_control_mode_changed ()
3909 /* cancel all solo or all listen when solo control mode changes */
3912 set_solo (get_routes(), false);
3913 } else if (listening()) {
3914 set_listen (get_routes(), false);
3918 /** Called when anything about any of our route groups changes (membership, state etc.) */
3920 Session::route_group_changed ()
3922 RouteGroupChanged (); /* EMIT SIGNAL */
3926 Session::get_available_sync_options () const
3928 vector<SyncSource> ret;
3930 ret.push_back (JACK);
3931 ret.push_back (MTC);
3932 ret.push_back (MIDIClock);
3937 boost::shared_ptr<RouteList>
3938 Session::get_routes_with_regions_at (framepos_t const p) const
3940 shared_ptr<RouteList> r = routes.reader ();
3941 shared_ptr<RouteList> rl (new RouteList);
3943 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3944 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3949 boost::shared_ptr<Playlist> pl = tr->playlist ();
3954 if (pl->has_region_at (p)) {
3963 Session::goto_end ()
3965 if (_session_range_location) {
3966 request_locate (_session_range_location->end(), false);
3968 request_locate (0, false);
3973 Session::goto_start ()
3975 if (_session_range_location) {
3976 request_locate (_session_range_location->start(), false);
3978 request_locate (0, false);
3983 Session::current_start_frame () const
3985 return _session_range_location ? _session_range_location->start() : 0;
3989 Session::current_end_frame () const
3991 return _session_range_location ? _session_range_location->end() : 0;
3995 Session::add_session_range_location (nframes_t start, nframes_t end)
3997 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
3998 _locations->add (_session_range_location);
4001 /** Called when one of our routes' order keys has changed */
4003 Session::route_order_key_changed ()
4005 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4009 Session::step_edit_status_change (bool yn)
4015 send = (_step_editors == 0);
4020 send = (_step_editors == 1);
4023 if (_step_editors > 0) {
4029 StepEditStatusChange (val);
4035 Session::start_time_changed (framepos_t old)
4037 /* Update the auto loop range to match the session range
4038 (unless the auto loop range has been changed by the user)
4041 Location* s = _locations->session_range_location ();
4042 Location* l = _locations->auto_loop_location ();
4044 if (l->start() == old) {
4045 l->set_start (s->start(), true);
4050 Session::end_time_changed (framepos_t old)
4052 /* Update the auto loop range to match the session range
4053 (unless the auto loop range has been changed by the user)
4056 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);