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::Signal0<void> Session::StartTimeChanged;
123 PBD::Signal0<void> 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;
129 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
130 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
132 Session::Session (AudioEngine &eng,
133 const string& fullpath,
134 const string& snapshot_name,
135 BusProfile* bus_profile,
139 , _target_transport_speed (0.0)
140 , _requested_return_frame (-1)
141 , _session_dir (new SessionDirectory(fullpath))
143 , _state_of_the_state (Clean)
144 , _butler (new Butler (*this))
145 , _post_transport_work (0)
146 , _send_timecode_update (false)
147 , _all_route_group (new RouteGroup (*this, "all"))
148 , route_graph (new Graph(*this))
149 , routes (new RouteList)
150 , _total_free_4k_blocks (0)
151 , _bundles (new BundleList)
152 , _bundle_xml_node (0)
153 , _click_io ((IO*) 0)
155 , click_emphasis_data (0)
157 , _metadata (new SessionMetadata())
158 , _have_rec_enabled_track (false)
159 , _suspend_timecode_transmission (0)
161 _locations = new Locations (*this);
163 playlists.reset (new SessionPlaylists);
165 _all_route_group->set_active (true, this);
167 interpolation.add_channel_to (0, 0);
169 if (!eng.connected()) {
170 throw failed_constructor();
173 n_physical_outputs = _engine.n_physical_outputs ();
174 n_physical_inputs = _engine.n_physical_inputs ();
176 first_stage_init (fullpath, snapshot_name);
178 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
181 if (create (mix_template, bus_profile)) {
183 throw failed_constructor ();
187 if (second_stage_init ()) {
189 throw failed_constructor ();
192 store_recent_sessions(_name, _path);
194 bool was_dirty = dirty();
196 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
198 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
199 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
202 DirtyChanged (); /* EMIT SIGNAL */
216 vector<void*> debug_pointers;
218 /* if we got to here, leaving pending capture state around
222 remove_pending_capture_state ();
224 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
226 _engine.remove_session ();
228 /* clear history so that no references to objects are held any more */
232 /* clear state tree so that no references to objects are held any more */
236 /* remove all stubfiles that might still be lurking */
238 cleanup_stubfiles ();
240 /* reset dynamic state version back to default */
242 Stateful::loading_state_version = 0;
244 _butler->drop_references ();
246 delete midi_control_ui;
247 delete _all_route_group;
249 if (click_data != default_click) {
250 delete [] click_data;
253 if (click_emphasis_data != default_click_emphasis) {
254 delete [] click_emphasis_data;
259 /* clear out any pending dead wood from RCU managed objects */
264 AudioDiskstream::free_working_buffers();
266 /* tell everyone who is still standing that we're about to die */
269 /* tell everyone to drop references and delete objects as we go */
271 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
272 named_selections.clear ();
274 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
275 RegionFactory::delete_all_regions ();
277 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
279 /* reset these three references to special routes before we do the usual route delete thing */
282 _master_out.reset ();
283 _monitor_out.reset ();
286 RCUWriter<RouteList> writer (routes);
287 boost::shared_ptr<RouteList> r = writer.get_copy ();
289 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
290 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
291 (*i)->drop_references ();
295 /* writer goes out of scope and updates master */
299 boost::shared_ptr<RouteList> r = routes.reader ();
301 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
302 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
303 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
304 i->second->drop_references ();
309 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
310 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
315 Crossfade::set_buffer_size (0);
317 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
320 boost_debug_list_ptrs ();
324 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
328 Session::set_worst_io_latencies ()
330 _worst_output_latency = 0;
331 _worst_input_latency = 0;
333 if (!_engine.connected()) {
337 boost::shared_ptr<RouteList> r = routes.reader ();
339 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
340 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
341 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
346 Session::when_engine_running ()
348 string first_physical_output;
350 BootMessage (_("Set block size and sample rate"));
352 set_block_size (_engine.frames_per_cycle());
353 set_frame_rate (_engine.frame_rate());
355 BootMessage (_("Using configuration"));
357 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
358 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
360 Config->map_parameters (ff);
361 config.map_parameters (ft);
363 /* every time we reconnect, recompute worst case output latencies */
365 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
367 if (synced_to_jack()) {
368 _engine.transport_stop ();
371 if (config.get_jack_time_master()) {
372 _engine.transport_locate (_transport_frame);
380 _click_io.reset (new ClickIO (*this, "click"));
382 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
384 /* existing state for Click */
387 if (Stateful::loading_state_version < 3000) {
388 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
390 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
395 _clicking = Config->get_clicking ();
399 error << _("could not setup Click I/O") << endmsg;
406 /* default state for Click: dual-mono to first 2 physical outputs */
409 _engine.get_physical_outputs (DataType::AUDIO, outs);
411 for (uint32_t physport = 0; physport < 2; ++physport) {
412 if (outs.size() > physport) {
413 if (_click_io->add_port (outs[physport], this)) {
414 // relax, even though its an error
419 if (_click_io->n_ports () > ChanCount::ZERO) {
420 _clicking = Config->get_clicking ();
425 catch (failed_constructor& err) {
426 error << _("cannot setup Click I/O") << endmsg;
429 BootMessage (_("Compute I/O Latencies"));
431 set_worst_io_latencies ();
434 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
437 BootMessage (_("Set up standard connections"));
439 vector<string> inputs[DataType::num_types];
440 vector<string> outputs[DataType::num_types];
441 for (uint32_t i = 0; i < DataType::num_types; ++i) {
442 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
443 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
446 /* Create a set of Bundle objects that map
447 to the physical I/O currently available. We create both
448 mono and stereo bundles, so that the common cases of mono
449 and stereo tracks get bundles to put in their mixer strip
450 in / out menus. There may be a nicer way of achieving that;
451 it doesn't really scale that well to higher channel counts
454 /* mono output bundles */
456 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
458 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
460 shared_ptr<Bundle> c (new Bundle (buf, true));
461 c->add_channel (_("mono"), DataType::AUDIO);
462 c->set_port (0, outputs[DataType::AUDIO][np]);
467 /* stereo output bundles */
469 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
470 if (np + 1 < outputs[DataType::AUDIO].size()) {
472 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
473 shared_ptr<Bundle> c (new Bundle (buf, true));
474 c->add_channel (_("L"), DataType::AUDIO);
475 c->set_port (0, outputs[DataType::AUDIO][np]);
476 c->add_channel (_("R"), DataType::AUDIO);
477 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
483 /* mono input bundles */
485 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
487 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
489 shared_ptr<Bundle> c (new Bundle (buf, false));
490 c->add_channel (_("mono"), DataType::AUDIO);
491 c->set_port (0, inputs[DataType::AUDIO][np]);
496 /* stereo input bundles */
498 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
499 if (np + 1 < inputs[DataType::AUDIO].size()) {
501 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
503 shared_ptr<Bundle> c (new Bundle (buf, false));
504 c->add_channel (_("L"), DataType::AUDIO);
505 c->set_port (0, inputs[DataType::AUDIO][np]);
506 c->add_channel (_("R"), DataType::AUDIO);
507 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
513 /* MIDI input bundles */
515 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
516 string n = inputs[DataType::MIDI][np];
517 boost::erase_first (n, X_("alsa_pcm:"));
519 shared_ptr<Bundle> c (new Bundle (n, false));
520 c->add_channel ("", DataType::MIDI);
521 c->set_port (0, inputs[DataType::MIDI][np]);
525 /* MIDI output bundles */
527 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
528 string n = outputs[DataType::MIDI][np];
529 boost::erase_first (n, X_("alsa_pcm:"));
531 shared_ptr<Bundle> c (new Bundle (n, true));
532 c->add_channel ("", DataType::MIDI);
533 c->set_port (0, outputs[DataType::MIDI][np]);
537 BootMessage (_("Setup signal flow and plugins"));
541 if (_is_new && !no_auto_connect()) {
543 /* don't connect the master bus outputs if there is a monitor bus */
545 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
547 /* if requested auto-connect the outputs to the first N physical ports.
550 uint32_t limit = _master_out->n_outputs().n_total();
552 for (uint32_t n = 0; n < limit; ++n) {
553 Port* p = _master_out->output()->nth (n);
555 if (outputs[p->type()].size() > n) {
556 connect_to = outputs[p->type()][n];
559 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
560 if (_master_out->output()->connect (p, connect_to, this)) {
561 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
571 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
572 are undefined, at best.
575 /* control out listens to master bus (but ignores it
576 under some conditions)
579 uint32_t limit = _monitor_out->n_inputs().n_audio();
582 for (uint32_t n = 0; n < limit; ++n) {
583 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
584 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
587 string connect_to = o->name();
588 if (_monitor_out->input()->connect (p, connect_to, this)) {
589 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
597 /* if control out is not connected, connect control out to physical outs
600 if (!_monitor_out->output()->connected ()) {
602 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
604 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
607 _monitor_out->output()->connect_ports_to_bundle (b, this);
609 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
610 Config->get_monitor_bus_preferred_bundle())
616 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
617 uint32_t mod = n_physical_outputs.get (*t);
618 uint32_t limit = _monitor_out->n_outputs().get(*t);
620 for (uint32_t n = 0; n < limit; ++n) {
622 Port* p = _monitor_out->output()->ports().port(*t, n);
624 if (outputs[*t].size() > (n % mod)) {
625 connect_to = outputs[*t][n % mod];
628 if (!connect_to.empty()) {
629 if (_monitor_out->output()->connect (p, connect_to, this)) {
630 error << string_compose (
631 _("cannot connect control output %1 to %2"),
644 /* catch up on send+insert cnts */
646 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
648 /* hook us up to the engine */
650 BootMessage (_("Connect to engine"));
652 _engine.set_session (this);
656 Session::hookup_io ()
658 /* stop graph reordering notifications from
659 causing resorts, etc.
662 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
667 /* we delay creating the auditioner till now because
668 it makes its own connections to ports.
672 Auditioner* a = new Auditioner (*this);
675 throw failed_constructor();
677 a->use_new_diskstream ();
678 auditioner.reset (a);
681 catch (failed_constructor& err) {
682 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
686 /* load bundles, which we may have postponed earlier on */
687 if (_bundle_xml_node) {
688 load_bundles (*_bundle_xml_node);
689 delete _bundle_xml_node;
692 /* Tell all IO objects to connect themselves together */
694 IO::enable_connecting ();
695 MIDI::Port::MakeConnections ();
697 /* Now reset all panners */
699 Delivery::reset_panners ();
701 /* Connect tracks to monitor/listen bus if there is one.
702 Note that in an existing session, the internal sends will
703 already exist, but we want the routes to notice that
704 they connect to the control out specifically.
708 boost::shared_ptr<RouteList> r = routes.reader ();
709 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
711 if ((*x)->is_monitor()) {
715 } else if ((*x)->is_master()) {
721 (*x)->listen_via (_monitor_out,
722 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
728 /* Anyone who cares about input state, wake up and do something */
730 IOConnectionsComplete (); /* EMIT SIGNAL */
732 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
734 /* now handle the whole enchilada as if it was one
740 /* update the full solo state, which can't be
741 correctly determined on a per-route basis, but
742 needs the global overview that only the session
746 update_route_solo_state ();
750 Session::playlist_length_changed ()
752 update_session_range_location_marker ();
756 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
758 boost::shared_ptr<Track> track = wp.lock ();
763 boost::shared_ptr<Playlist> playlist;
765 if ((playlist = track->playlist()) != 0) {
766 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
769 update_session_range_location_marker ();
773 Session::record_enabling_legal () const
775 /* this used to be in here, but survey says.... we don't need to restrict it */
776 // if (record_status() == Recording) {
780 if (Config->get_all_safe()) {
787 Session::reset_input_monitor_state ()
789 if (transport_rolling()) {
791 boost::shared_ptr<RouteList> rl = routes.reader ();
792 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
793 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
794 if (tr && tr->record_enabled ()) {
795 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
796 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
802 boost::shared_ptr<RouteList> rl = routes.reader ();
803 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
804 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
805 if (tr && tr->record_enabled ()) {
806 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
807 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
814 Session::auto_punch_start_changed (Location* location)
816 replace_event (SessionEvent::PunchIn, location->start());
818 if (get_record_enabled() && config.get_punch_in()) {
819 /* capture start has been changed, so save new pending state */
820 save_state ("", true);
825 Session::auto_punch_end_changed (Location* location)
827 nframes_t when_to_stop = location->end();
828 // when_to_stop += _worst_output_latency + _worst_input_latency;
829 replace_event (SessionEvent::PunchOut, when_to_stop);
833 Session::auto_punch_changed (Location* location)
835 nframes_t when_to_stop = location->end();
837 replace_event (SessionEvent::PunchIn, location->start());
838 //when_to_stop += _worst_output_latency + _worst_input_latency;
839 replace_event (SessionEvent::PunchOut, when_to_stop);
843 Session::auto_loop_changed (Location* location)
845 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
847 if (transport_rolling() && play_loop) {
850 // if (_transport_frame > location->end()) {
852 if (_transport_frame < location->start() || _transport_frame > location->end()) {
853 // relocate to beginning of loop
854 clear_events (SessionEvent::LocateRoll);
856 request_locate (location->start(), true);
859 else if (Config->get_seamless_loop() && !loop_changing) {
861 // schedule a locate-roll to refill the diskstreams at the
863 loop_changing = true;
865 if (location->end() > last_loopend) {
866 clear_events (SessionEvent::LocateRoll);
867 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
874 last_loopend = location->end();
878 Session::set_auto_punch_location (Location* location)
882 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
883 punch_connections.drop_connections();
884 existing->set_auto_punch (false, this);
885 remove_event (existing->start(), SessionEvent::PunchIn);
886 clear_events (SessionEvent::PunchOut);
887 auto_punch_location_changed (0);
896 if (location->end() <= location->start()) {
897 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
901 punch_connections.drop_connections ();
903 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
904 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
905 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
907 location->set_auto_punch (true, this);
909 auto_punch_changed (location);
911 auto_punch_location_changed (location);
915 Session::set_auto_loop_location (Location* location)
919 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
920 loop_connections.drop_connections ();
921 existing->set_auto_loop (false, this);
922 remove_event (existing->end(), SessionEvent::AutoLoop);
923 auto_loop_location_changed (0);
932 if (location->end() <= location->start()) {
933 error << _("Session: you can't use a mark for auto loop") << endmsg;
937 last_loopend = location->end();
939 loop_connections.drop_connections ();
941 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
942 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
943 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
945 location->set_auto_loop (true, this);
947 /* take care of our stuff first */
949 auto_loop_changed (location);
951 /* now tell everyone else */
953 auto_loop_location_changed (location);
957 Session::locations_added (Location *)
963 Session::locations_changed ()
965 _locations->apply (*this, &Session::handle_locations_changed);
969 Session::handle_locations_changed (Locations::LocationList& locations)
971 Locations::LocationList::iterator i;
973 bool set_loop = false;
974 bool set_punch = false;
976 for (i = locations.begin(); i != locations.end(); ++i) {
980 if (location->is_auto_punch()) {
981 set_auto_punch_location (location);
984 if (location->is_auto_loop()) {
985 set_auto_loop_location (location);
989 if (location->is_session_range()) {
990 _session_range_location = location;
995 set_auto_loop_location (0);
998 set_auto_punch_location (0);
1005 Session::enable_record ()
1008 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1010 if (rs == Recording) {
1014 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1016 _last_record_location = _transport_frame;
1017 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1019 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1021 boost::shared_ptr<RouteList> rl = routes.reader ();
1022 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1023 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1024 if (tr && tr->record_enabled ()) {
1025 tr->monitor_input (true);
1030 RecordStateChanged ();
1037 Session::disable_record (bool rt_context, bool force)
1041 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1043 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1044 g_atomic_int_set (&_record_status, Disabled);
1045 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1047 if (rs == Recording) {
1048 g_atomic_int_set (&_record_status, Enabled);
1052 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1054 boost::shared_ptr<RouteList> rl = routes.reader ();
1055 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1056 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1057 if (tr && tr->record_enabled ()) {
1058 tr->monitor_input (false);
1063 RecordStateChanged (); /* emit signal */
1066 remove_pending_capture_state ();
1072 Session::step_back_from_record ()
1074 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1076 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1077 boost::shared_ptr<RouteList> rl = routes.reader ();
1078 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1079 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1080 if (tr && tr->record_enabled ()) {
1081 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1082 tr->monitor_input (false);
1090 Session::maybe_enable_record ()
1092 if (_step_editors > 0) {
1096 g_atomic_int_set (&_record_status, Enabled);
1098 /* this function is currently called from somewhere other than an RT thread.
1099 this save_state() call therefore doesn't impact anything.
1102 save_state ("", true);
1104 if (_transport_speed) {
1105 if (!config.get_punch_in()) {
1109 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1110 RecordStateChanged (); /* EMIT SIGNAL */
1117 Session::audible_frame () const
1123 /* the first of these two possible settings for "offset"
1124 mean that the audible frame is stationary until
1125 audio emerges from the latency compensation
1128 the second means that the audible frame is stationary
1129 until audio would emerge from a physical port
1130 in the absence of any plugin latency compensation
1133 offset = _worst_output_latency;
1135 if (offset > current_block_size) {
1136 offset -= current_block_size;
1138 /* XXX is this correct? if we have no external
1139 physical connections and everything is internal
1140 then surely this is zero? still, how
1141 likely is that anyway?
1143 offset = current_block_size;
1146 if (synced_to_jack()) {
1147 tf = _engine.transport_frame();
1149 tf = _transport_frame;
1154 if (!non_realtime_work_pending()) {
1158 /* Check to see if we have passed the first guaranteed
1159 audible frame past our last start position. if not,
1160 return that last start point because in terms
1161 of audible frames, we have not moved yet.
1163 `Start position' in this context means the time we last
1164 either started or changed transport direction.
1167 if (_transport_speed > 0.0f) {
1169 if (!play_loop || !have_looped) {
1170 if (tf < _last_roll_or_reversal_location + offset) {
1171 return _last_roll_or_reversal_location;
1179 } else if (_transport_speed < 0.0f) {
1181 /* XXX wot? no backward looping? */
1183 if (tf > _last_roll_or_reversal_location - offset) {
1184 return _last_roll_or_reversal_location;
1196 Session::set_frame_rate (nframes_t frames_per_second)
1198 /** \fn void Session::set_frame_size(nframes_t)
1199 the AudioEngine object that calls this guarantees
1200 that it will not be called while we are also in
1201 ::process(). Its fine to do things that block
1205 _base_frame_rate = frames_per_second;
1209 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1213 // XXX we need some equivalent to this, somehow
1214 // SndFileSource::setup_standard_crossfades (frames_per_second);
1218 /* XXX need to reset/reinstantiate all LADSPA plugins */
1222 Session::set_block_size (nframes_t nframes)
1224 /* the AudioEngine guarantees
1225 that it will not be called while we are also in
1226 ::process(). It is therefore fine to do things that block
1231 current_block_size = nframes;
1235 boost::shared_ptr<RouteList> r = routes.reader ();
1237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1238 (*i)->set_block_size (nframes);
1241 boost::shared_ptr<RouteList> rl = routes.reader ();
1242 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1243 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1245 tr->set_block_size (nframes);
1249 set_worst_io_latencies ();
1254 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1257 nframes_t fade_frames;
1259 /* Don't allow fade of less 1 frame */
1261 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1268 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1272 default_fade_msecs = fade_msecs;
1273 default_fade_steepness = steepness;
1276 // jlc, WTF is this!
1277 Glib::RWLock::ReaderLock lm (route_lock);
1278 AudioRegion::set_default_fade (steepness, fade_frames);
1283 /* XXX have to do this at some point */
1284 /* foreach region using default fade, reset, then
1285 refill_all_diskstream_buffers ();
1290 struct RouteSorter {
1291 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1292 if (r2->feeds (r1)) {
1294 } else if (r1->feeds (r2)) {
1297 if (r1->not_fed ()) {
1298 if (r2->not_fed ()) {
1299 /* no ardour-based connections inbound to either route. just use signal order */
1300 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1302 /* r2 has connections, r1 does not; run r1 early */
1306 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1313 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1315 shared_ptr<Route> r2;
1317 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1318 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1322 /* make a copy of the existing list of routes that feed r1 */
1324 Route::FedBy existing (r1->fed_by());
1326 /* for each route that feeds r1, recurse, marking it as feeding
1330 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1331 if (!(r2 = i->r.lock ())) {
1332 /* (*i) went away, ignore it */
1336 /* r2 is a route that feeds r1 which somehow feeds base. mark
1337 base as being fed by r2
1340 rbase->add_fed_by (r2, i->sends_only);
1344 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1348 if (r1->feeds (r2) && r2->feeds (r1)) {
1352 /* now recurse, so that we can mark base as being fed by
1353 all routes that feed r2
1356 trace_terminal (r2, rbase);
1363 Session::resort_routes ()
1365 /* don't do anything here with signals emitted
1366 by Routes while we are being destroyed.
1369 if (_state_of_the_state & Deletion) {
1374 RCUWriter<RouteList> writer (routes);
1375 shared_ptr<RouteList> r = writer.get_copy ();
1376 resort_routes_using (r);
1377 /* writer goes out of scope and forces update */
1380 //route_graph->dump(1);
1383 boost::shared_ptr<RouteList> rl = routes.reader ();
1384 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1385 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1387 const Route::FedBy& fb ((*i)->fed_by());
1389 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1390 boost::shared_ptr<Route> sf = f->r.lock();
1392 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1400 Session::resort_routes_using (shared_ptr<RouteList> r)
1402 RouteList::iterator i, j;
1404 for (i = r->begin(); i != r->end(); ++i) {
1406 (*i)->clear_fed_by ();
1408 for (j = r->begin(); j != r->end(); ++j) {
1410 /* although routes can feed themselves, it will
1411 cause an endless recursive descent if we
1412 detect it. so don't bother checking for
1420 bool via_sends_only;
1422 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1423 (*i)->add_fed_by (*j, via_sends_only);
1428 for (i = r->begin(); i != r->end(); ++i) {
1429 trace_terminal (*i, *i);
1435 route_graph->rechain (r);
1438 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1440 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1441 (*i)->name(), (*i)->order_key ("signal")));
1447 /** Find the route name starting with \a base with the lowest \a id.
1449 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1450 * The available route name with the lowest ID will be used, and \a id
1451 * will be set to the ID.
1453 * \return false if a route name could not be found, and \a track_name
1454 * and \a id do not reflect a free route name.
1457 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1460 snprintf (name, name_len, "%s %" PRIu32, base, id);
1462 if (route_by_name (name) == 0) {
1468 } while (id < (UINT_MAX-1));
1473 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1475 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1477 in = ChanCount::ZERO;
1478 out = ChanCount::ZERO;
1479 shared_ptr<RouteList> r = routes.reader ();
1480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1481 if (!(*i)->is_hidden()) {
1482 in += (*i)->n_inputs();
1483 out += (*i)->n_outputs();
1488 list<boost::shared_ptr<MidiTrack> >
1489 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1491 char track_name[32];
1492 uint32_t track_id = 0;
1493 ChanCount existing_inputs;
1494 ChanCount existing_outputs;
1496 RouteList new_routes;
1497 list<boost::shared_ptr<MidiTrack> > ret;
1498 uint32_t control_id;
1500 count_existing_route_channels (existing_inputs, existing_outputs);
1502 control_id = ntracks() + nbusses();
1505 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1506 error << "cannot find name for new midi track" << endmsg;
1510 shared_ptr<MidiTrack> track;
1513 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1520 mt->use_new_diskstream();
1522 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1523 track = boost::shared_ptr<MidiTrack>(mt);
1525 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1526 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1531 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1532 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1536 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1538 track->non_realtime_input_change();
1541 route_group->add (track);
1544 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1545 track->set_remote_control_id (control_id);
1547 new_routes.push_back (track);
1548 ret.push_back (track);
1551 catch (failed_constructor &err) {
1552 error << _("Session: could not create new midi track.") << endmsg;
1556 catch (AudioEngine::PortRegistrationFailure& pfe) {
1558 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;
1566 if (!new_routes.empty()) {
1567 add_routes (new_routes, false);
1568 save_state (_current_snapshot_name);
1574 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1575 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1576 * @param output_start As \a input_start, but for outputs.
1579 Session::auto_connect_route (
1580 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1583 /* If both inputs and outputs are auto-connected to physical ports,
1584 use the max of input and output offsets to ensure auto-connected
1585 port numbers always match up (e.g. the first audio input and the
1586 first audio output of the route will have the same physical
1587 port number). Otherwise just use the lowest input or output
1591 const bool in_out_physical =
1592 (Config->get_input_auto_connect() & AutoConnectPhysical)
1593 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1596 const ChanCount in_offset = in_out_physical
1597 ? ChanCount::max(existing_inputs, existing_outputs)
1600 const ChanCount out_offset = in_out_physical
1601 ? ChanCount::max(existing_inputs, existing_outputs)
1604 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1605 vector<string> physinputs;
1606 vector<string> physoutputs;
1608 _engine.get_physical_outputs (*t, physoutputs);
1609 _engine.get_physical_inputs (*t, physinputs);
1611 if (!physinputs.empty() && connect_inputs) {
1612 uint32_t nphysical_in = physinputs.size();
1613 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1616 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1617 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1620 if (!port.empty() && route->input()->connect (
1621 route->input()->ports().port(*t, i), port, this)) {
1627 if (!physoutputs.empty()) {
1628 uint32_t nphysical_out = physoutputs.size();
1629 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1632 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1633 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1634 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1635 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1636 port = _master_out->input()->ports().port(*t,
1637 i % _master_out->input()->n_ports().get(*t))->name();
1641 if (!port.empty() && route->output()->connect (
1642 route->output()->ports().port(*t, i), port, this)) {
1649 existing_inputs += route->n_inputs();
1650 existing_outputs += route->n_outputs();
1653 list< boost::shared_ptr<AudioTrack> >
1654 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1656 char track_name[32];
1657 uint32_t track_id = 0;
1658 ChanCount existing_inputs;
1659 ChanCount existing_outputs;
1661 RouteList new_routes;
1662 list<boost::shared_ptr<AudioTrack> > ret;
1663 uint32_t control_id;
1665 count_existing_route_channels (existing_inputs, existing_outputs);
1667 control_id = ntracks() + nbusses() + 1;
1670 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1671 error << "cannot find name for new audio track" << endmsg;
1675 shared_ptr<AudioTrack> track;
1678 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1685 at->use_new_diskstream();
1687 boost_debug_shared_ptr_mark_interesting (at, "Track");
1688 track = boost::shared_ptr<AudioTrack>(at);
1690 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1691 error << string_compose (
1692 _("cannot configure %1 in/%2 out configuration for new audio track"),
1693 input_channels, output_channels)
1698 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1699 error << string_compose (
1700 _("cannot configure %1 in/%2 out configuration for new audio track"),
1701 input_channels, output_channels)
1706 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1709 route_group->add (track);
1712 track->non_realtime_input_change();
1714 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1715 track->set_remote_control_id (control_id);
1718 new_routes.push_back (track);
1719 ret.push_back (track);
1722 catch (failed_constructor &err) {
1723 error << _("Session: could not create new audio track.") << endmsg;
1727 catch (AudioEngine::PortRegistrationFailure& pfe) {
1729 error << pfe.what() << endmsg;
1737 if (!new_routes.empty()) {
1738 add_routes (new_routes, true);
1745 Session::set_remote_control_ids ()
1747 RemoteModel m = Config->get_remote_model();
1748 bool emit_signal = false;
1750 shared_ptr<RouteList> r = routes.reader ();
1752 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1753 if (MixerOrdered == m) {
1754 int32_t order = (*i)->order_key(N_("signal"));
1755 (*i)->set_remote_control_id (order+1, false);
1757 } else if (EditorOrdered == m) {
1758 int32_t order = (*i)->order_key(N_("editor"));
1759 (*i)->set_remote_control_id (order+1, false);
1761 } else if (UserOrdered == m) {
1762 //do nothing ... only changes to remote id's are initiated by user
1767 Route::RemoteControlIDChange();
1773 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1776 uint32_t bus_id = 0;
1777 ChanCount existing_inputs;
1778 ChanCount existing_outputs;
1781 uint32_t control_id;
1783 count_existing_route_channels (existing_inputs, existing_outputs);
1785 control_id = ntracks() + nbusses() + 1;
1788 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1789 error << "cannot find name for new audio bus" << endmsg;
1794 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1801 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1802 shared_ptr<Route> bus (rt);
1804 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1805 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1806 input_channels, output_channels)
1812 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1813 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1814 input_channels, output_channels)
1819 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1822 route_group->add (bus);
1824 bus->set_remote_control_id (control_id);
1828 bus->add_internal_return ();
1831 ret.push_back (bus);
1835 catch (failed_constructor &err) {
1836 error << _("Session: could not create new audio route.") << endmsg;
1840 catch (AudioEngine::PortRegistrationFailure& pfe) {
1841 error << pfe.what() << endmsg;
1851 add_routes (ret, true);
1859 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1863 uint32_t control_id;
1865 uint32_t number = 0;
1867 if (!tree.read (template_path.c_str())) {
1871 XMLNode* node = tree.root();
1873 control_id = ntracks() + nbusses() + 1;
1877 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1879 std::string node_name = IO::name_from_state (*node_copy.children().front());
1881 /* generate a new name by adding a number to the end of the template name */
1882 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1883 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1887 /* set IO children to use the new name */
1888 XMLNodeList const & children = node_copy.children ();
1889 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1890 if ((*i)->name() == IO::state_node_name) {
1891 IO::set_name_in_state (**i, name);
1895 Track::zero_diskstream_id_in_xml (node_copy);
1898 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1901 error << _("Session: cannot create track/bus from template description") << endmsg;
1905 if (boost::dynamic_pointer_cast<Track>(route)) {
1906 /* force input/output change signals so that the new diskstream
1907 picks up the configuration of the route. During session
1908 loading this normally happens in a different way.
1910 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1911 change.after = route->input()->n_ports();
1912 route->input()->changed (change, this);
1913 change.after = route->output()->n_ports();
1914 route->output()->changed (change, this);
1917 route->set_remote_control_id (control_id);
1920 ret.push_back (route);
1923 catch (failed_constructor &err) {
1924 error << _("Session: could not create new route from template") << endmsg;
1928 catch (AudioEngine::PortRegistrationFailure& pfe) {
1929 error << pfe.what() << endmsg;
1938 add_routes (ret, true);
1945 Session::add_routes (RouteList& new_routes, bool save)
1948 RCUWriter<RouteList> writer (routes);
1949 shared_ptr<RouteList> r = writer.get_copy ();
1950 r->insert (r->end(), new_routes.begin(), new_routes.end());
1953 /* if there is no control out and we're not in the middle of loading,
1954 resort the graph here. if there is a control out, we will resort
1955 toward the end of this method. if we are in the middle of loading,
1956 we will resort when done.
1959 if (!_monitor_out && IO::connecting_legal) {
1960 resort_routes_using (r);
1964 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1966 boost::weak_ptr<Route> wpr (*x);
1967 boost::shared_ptr<Route> r (*x);
1969 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1970 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1971 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1972 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1973 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1974 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1975 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1977 if (r->is_master()) {
1981 if (r->is_monitor()) {
1985 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1987 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1988 track_playlist_changed (boost::weak_ptr<Track> (tr));
1989 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1991 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
1993 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
1998 if (_monitor_out && IO::connecting_legal) {
2000 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2001 if ((*x)->is_monitor()) {
2003 } else if ((*x)->is_master()) {
2006 (*x)->listen_via (_monitor_out,
2007 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2018 save_state (_current_snapshot_name);
2021 RouteAdded (new_routes); /* EMIT SIGNAL */
2022 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2026 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2028 boost::shared_ptr<RouteList> r = routes.reader ();
2029 boost::shared_ptr<Send> s;
2033 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2034 if (boost::dynamic_pointer_cast<Track>(*i)) {
2035 if ((s = (*i)->internal_send_for (dest)) != 0) {
2036 s->amp()->gain_control()->set_value (0.0);
2043 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2045 boost::shared_ptr<RouteList> r = routes.reader ();
2046 boost::shared_ptr<Send> s;
2050 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2051 if (boost::dynamic_pointer_cast<Track>(*i)) {
2052 if ((s = (*i)->internal_send_for (dest)) != 0) {
2053 s->amp()->gain_control()->set_value (1.0);
2060 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2062 boost::shared_ptr<RouteList> r = routes.reader ();
2063 boost::shared_ptr<Send> s;
2067 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2068 if (boost::dynamic_pointer_cast<Track>(*i)) {
2069 if ((s = (*i)->internal_send_for (dest)) != 0) {
2070 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2077 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2079 boost::shared_ptr<RouteList> r = routes.reader ();
2080 boost::shared_ptr<RouteList> t (new RouteList);
2082 /* only send tracks */
2084 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2085 if (boost::dynamic_pointer_cast<Track>(*i)) {
2090 add_internal_sends (dest, p, t);
2094 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2096 if (dest->is_monitor() || dest->is_master()) {
2100 if (!dest->internal_return()) {
2101 dest->add_internal_return();
2104 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2106 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2110 (*i)->listen_via (dest, p, true, true);
2117 Session::remove_route (shared_ptr<Route> route)
2119 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2123 route->set_solo (false, this);
2126 RCUWriter<RouteList> writer (routes);
2127 shared_ptr<RouteList> rs = writer.get_copy ();
2131 /* deleting the master out seems like a dumb
2132 idea, but its more of a UI policy issue
2136 if (route == _master_out) {
2137 _master_out = shared_ptr<Route> ();
2140 if (route == _monitor_out) {
2142 /* cancel control outs for all routes */
2144 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2145 (*r)->drop_listen (_monitor_out);
2148 _monitor_out.reset ();
2151 /* writer goes out of scope, forces route list update */
2154 update_route_solo_state ();
2155 update_session_range_location_marker ();
2157 // We need to disconnect the route's inputs and outputs
2159 route->input()->disconnect (0);
2160 route->output()->disconnect (0);
2162 /* if the route had internal sends sending to it, remove them */
2163 if (route->internal_return()) {
2165 boost::shared_ptr<RouteList> r = routes.reader ();
2166 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2167 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2169 (*i)->remove_processor (s);
2174 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2175 if (mt && mt->step_editing()) {
2176 if (_step_editors > 0) {
2181 update_latency_compensation (false, false);
2184 /* Re-sort routes to remove the graph's current references to the one that is
2185 * going away, then flush old references out of the graph.
2189 route_graph->clear_other_chain ();
2191 /* get rid of it from the dead wood collection in the route list manager */
2193 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2197 /* try to cause everyone to drop their references */
2199 route->drop_references ();
2201 sync_order_keys (N_("session"));
2203 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2205 /* save the new state of the world */
2207 if (save_state (_current_snapshot_name)) {
2208 save_history (_current_snapshot_name);
2213 Session::route_mute_changed (void* /*src*/)
2219 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2221 boost::shared_ptr<Route> route = wpr.lock();
2223 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2227 if (route->listening()) {
2229 if (Config->get_exclusive_solo()) {
2230 /* new listen: disable all other listen */
2231 shared_ptr<RouteList> r = routes.reader ();
2232 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2233 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2236 (*i)->set_listen (false, this);
2242 } else if (_listen_cnt > 0) {
2248 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2250 boost::shared_ptr<Route> route = wpr.lock ();
2253 /* should not happen */
2254 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2258 bool send_changed = false;
2260 if (route->solo_isolated()) {
2261 if (_solo_isolated_cnt == 0) {
2262 send_changed = true;
2264 _solo_isolated_cnt++;
2265 } else if (_solo_isolated_cnt > 0) {
2266 _solo_isolated_cnt--;
2267 if (_solo_isolated_cnt == 0) {
2268 send_changed = true;
2273 IsolatedChanged (); /* EMIT SIGNAL */
2278 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2280 if (!self_solo_change) {
2281 // session doesn't care about changes to soloed-by-others
2285 if (solo_update_disabled) {
2290 boost::shared_ptr<Route> route = wpr.lock ();
2293 /* should not happen */
2294 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2298 shared_ptr<RouteList> r = routes.reader ();
2301 if (route->self_soloed()) {
2307 if (delta == 1 && Config->get_exclusive_solo()) {
2308 /* new solo: disable all other solos */
2309 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2310 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2313 (*i)->set_solo (false, this);
2317 solo_update_disabled = true;
2319 RouteList uninvolved;
2321 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2322 bool via_sends_only;
2323 bool in_signal_flow;
2325 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2329 in_signal_flow = false;
2331 if ((*i)->feeds (route, &via_sends_only)) {
2332 if (!via_sends_only) {
2333 if (!route->soloed_by_others_upstream()) {
2334 (*i)->mod_solo_by_others_downstream (delta);
2336 in_signal_flow = true;
2340 if (route->feeds (*i, &via_sends_only)) {
2341 (*i)->mod_solo_by_others_upstream (delta);
2342 in_signal_flow = true;
2345 if (!in_signal_flow) {
2346 uninvolved.push_back (*i);
2350 solo_update_disabled = false;
2351 update_route_solo_state (r);
2353 /* now notify that the mute state of the routes not involved in the signal
2354 pathway of the just-solo-changed route may have altered.
2357 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2358 (*i)->mute_changed (this);
2361 SoloChanged (); /* EMIT SIGNAL */
2366 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2368 /* now figure out if anything that matters is soloed (or is "listening")*/
2370 bool something_soloed = false;
2371 uint32_t listeners = 0;
2372 uint32_t isolated = 0;
2375 r = routes.reader();
2378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2379 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2380 something_soloed = true;
2383 if (!(*i)->is_hidden() && (*i)->listening()) {
2384 if (Config->get_solo_control_is_listen_control()) {
2387 (*i)->set_listen (false, this);
2391 if ((*i)->solo_isolated()) {
2396 if (something_soloed != _non_soloed_outs_muted) {
2397 _non_soloed_outs_muted = something_soloed;
2398 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2401 _listen_cnt = listeners;
2403 if (isolated != _solo_isolated_cnt) {
2404 _solo_isolated_cnt = isolated;
2405 IsolatedChanged (); /* EMIT SIGNAL */
2409 boost::shared_ptr<RouteList>
2410 Session::get_routes_with_internal_returns() const
2412 shared_ptr<RouteList> r = routes.reader ();
2413 boost::shared_ptr<RouteList> rl (new RouteList);
2415 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2416 if ((*i)->internal_return ()) {
2424 Session::io_name_is_legal (const std::string& name)
2426 shared_ptr<RouteList> r = routes.reader ();
2428 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2429 if ((*i)->name() == name) {
2433 if ((*i)->has_io_processor_named (name)) {
2442 Session::route_by_name (string name)
2444 shared_ptr<RouteList> r = routes.reader ();
2446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2447 if ((*i)->name() == name) {
2452 return shared_ptr<Route> ((Route*) 0);
2456 Session::route_by_id (PBD::ID id)
2458 shared_ptr<RouteList> r = routes.reader ();
2460 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2461 if ((*i)->id() == id) {
2466 return shared_ptr<Route> ((Route*) 0);
2470 Session::route_by_remote_id (uint32_t id)
2472 shared_ptr<RouteList> r = routes.reader ();
2474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2475 if ((*i)->remote_control_id() == id) {
2480 return shared_ptr<Route> ((Route*) 0);
2483 /** If either end of the session range location marker lies inside the current
2484 * session extent, move it to the corresponding session extent.
2487 Session::update_session_range_location_marker ()
2489 if (_state_of_the_state & Loading) {
2493 pair<framepos_t, framepos_t> const ext = get_extent ();
2495 if (_session_range_location == 0) {
2496 /* we don't have a session range yet; use this one (provided it is valid) */
2497 if (ext.first != max_framepos) {
2498 add_session_range_location (ext.first, ext.second);
2501 /* update the existing session range */
2502 if (ext.first < _session_range_location->start()) {
2503 _session_range_location->set_start (ext.first);
2507 if (ext.second > _session_range_location->end()) {
2508 _session_range_location->set_end (ext.second);
2515 /** @return Extent of the session's contents; if the session is empty, the first value of
2516 * the pair will equal max_framepos.
2518 pair<framepos_t, framepos_t>
2519 Session::get_extent () const
2521 pair<framepos_t, framepos_t> ext (max_framepos, 0);
2523 boost::shared_ptr<RouteList> rl = routes.reader ();
2524 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2525 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2526 if (!tr || tr->destructive()) {
2527 // ignore tape tracks when getting extents
2531 pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
2532 if (e.first < ext.first) {
2533 ext.first = e.first;
2535 if (e.second > ext.second) {
2536 ext.second = e.second;
2543 /* Region management */
2545 boost::shared_ptr<Region>
2546 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2548 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2549 RegionFactory::RegionMap::const_iterator i;
2550 boost::shared_ptr<Region> region;
2552 Glib::Mutex::Lock lm (region_lock);
2554 for (i = regions.begin(); i != regions.end(); ++i) {
2558 if (region->whole_file()) {
2560 if (child->source_equivalent (region)) {
2566 return boost::shared_ptr<Region> ();
2570 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2572 set<boost::shared_ptr<Region> > relevant_regions;
2574 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2575 RegionFactory::get_regions_using_source (*s, relevant_regions);
2578 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2580 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2581 set<boost::shared_ptr<Region> >::iterator tmp;
2586 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2588 playlists->destroy_region (*r);
2589 RegionFactory::map_remove (*r);
2591 (*r)->drop_sources ();
2592 (*r)->drop_references ();
2594 cerr << "\tdone UC = " << (*r).use_count() << endl;
2596 relevant_regions.erase (r);
2601 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2604 Glib::Mutex::Lock ls (source_lock);
2605 /* remove from the main source list */
2606 sources.erase ((*s)->id());
2609 (*s)->mark_for_remove ();
2610 (*s)->drop_references ();
2619 Session::remove_last_capture ()
2621 list<boost::shared_ptr<Source> > srcs;
2623 boost::shared_ptr<RouteList> rl = routes.reader ();
2624 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2625 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2630 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2633 srcs.insert (srcs.end(), l.begin(), l.end());
2638 destroy_sources (srcs);
2640 save_state (_current_snapshot_name);
2645 /* Source Management */
2648 Session::add_source (boost::shared_ptr<Source> source)
2650 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2651 pair<SourceMap::iterator,bool> result;
2653 entry.first = source->id();
2654 entry.second = source;
2657 Glib::Mutex::Lock lm (source_lock);
2658 result = sources.insert (entry);
2661 if (result.second) {
2663 /* yay, new source */
2667 boost::shared_ptr<AudioFileSource> afs;
2669 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2670 if (Config->get_auto_analyse_audio()) {
2671 Analyser::queue_source_for_analysis (source, false);
2678 Session::remove_source (boost::weak_ptr<Source> src)
2680 SourceMap::iterator i;
2681 boost::shared_ptr<Source> source = src.lock();
2688 Glib::Mutex::Lock lm (source_lock);
2690 if ((i = sources.find (source->id())) != sources.end()) {
2691 cerr << "Removing source " << source->name() << endl;
2696 if (!_state_of_the_state & InCleanup) {
2698 /* save state so we don't end up with a session file
2699 referring to non-existent sources.
2702 save_state (_current_snapshot_name);
2706 boost::shared_ptr<Source>
2707 Session::source_by_id (const PBD::ID& id)
2709 Glib::Mutex::Lock lm (source_lock);
2710 SourceMap::iterator i;
2711 boost::shared_ptr<Source> source;
2713 if ((i = sources.find (id)) != sources.end()) {
2720 boost::shared_ptr<Source>
2721 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2723 Glib::Mutex::Lock lm (source_lock);
2725 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2726 boost::shared_ptr<AudioFileSource> afs
2727 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2729 if (afs && afs->path() == path && chn == afs->channel()) {
2733 return boost::shared_ptr<Source>();
2738 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2741 string old_basename = PBD::basename_nosuffix (oldname);
2742 string new_legalized = legalize_for_path (newname);
2744 /* note: we know (or assume) the old path is already valid */
2748 /* destructive file sources have a name of the form:
2750 /path/to/Tnnnn-NAME(%[LR])?.wav
2752 the task here is to replace NAME with the new name.
2757 string::size_type dash;
2759 dir = Glib::path_get_dirname (path);
2760 path = Glib::path_get_basename (path);
2762 /* '-' is not a legal character for the NAME part of the path */
2764 if ((dash = path.find_last_of ('-')) == string::npos) {
2768 prefix = path.substr (0, dash);
2772 path += new_legalized;
2773 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2775 path = Glib::build_filename (dir, path);
2779 /* non-destructive file sources have a name of the form:
2781 /path/to/NAME-nnnnn(%[LR])?.ext
2783 the task here is to replace NAME with the new name.
2788 string::size_type dash;
2789 string::size_type postfix;
2791 dir = Glib::path_get_dirname (path);
2792 path = Glib::path_get_basename (path);
2794 /* '-' is not a legal character for the NAME part of the path */
2796 if ((dash = path.find_last_of ('-')) == string::npos) {
2800 suffix = path.substr (dash+1);
2802 // Suffix is now everything after the dash. Now we need to eliminate
2803 // the nnnnn part, which is done by either finding a '%' or a '.'
2805 postfix = suffix.find_last_of ("%");
2806 if (postfix == string::npos) {
2807 postfix = suffix.find_last_of ('.');
2810 if (postfix != string::npos) {
2811 suffix = suffix.substr (postfix);
2813 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2817 const uint32_t limit = 10000;
2818 char buf[PATH_MAX+1];
2820 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2822 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2824 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2825 path = Glib::build_filename (dir, buf);
2833 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2842 /** Return the full path (in some session directory) for a new within-session source.
2843 * \a name must be a session-unique name that does not contain slashes
2844 * (e.g. as returned by new_*_source_name)
2847 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2849 assert(name.find("/") == string::npos);
2851 SessionDirectory sdir(get_best_session_directory_for_new_source());
2854 if (type == DataType::AUDIO) {
2855 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2856 } else if (type == DataType::MIDI) {
2857 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2859 error << "Unknown source type, unable to create file path" << endmsg;
2864 return p.to_string();
2868 Session::peak_path (string base) const
2870 sys::path peakfile_path(_session_dir->peak_path());
2871 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2872 return peakfile_path.to_string();
2875 /** Return a unique name based on \a base for a new internal audio source */
2877 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2880 char buf[PATH_MAX+1];
2881 const uint32_t limit = 10000;
2883 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2886 legalized = legalize_for_path (base);
2888 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2889 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2891 vector<space_and_path>::iterator i;
2892 uint32_t existing = 0;
2894 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2899 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2900 cnt, legalized.c_str(), ext.c_str());
2901 } else if (nchan == 2) {
2903 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2904 cnt, legalized.c_str(), ext.c_str());
2906 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2907 cnt, legalized.c_str(), ext.c_str());
2909 } else if (nchan < 26) {
2910 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2911 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2913 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2914 cnt, legalized.c_str(), ext.c_str());
2920 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2921 } else if (nchan == 2) {
2923 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2925 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2927 } else if (nchan < 26) {
2928 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2930 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2934 SessionDirectory sdir((*i).path);
2936 string spath = sdir.sound_path().to_string();
2937 string spath_stubs = sdir.sound_stub_path().to_string();
2939 /* note that we search *without* the extension so that
2940 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2941 in the event that this new name is required for
2942 a file format change.
2945 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2946 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
2952 if (existing == 0) {
2957 error << string_compose(
2958 _("There are already %1 recordings for %2, which I consider too many."),
2959 limit, base) << endmsg;
2961 throw failed_constructor();
2965 return Glib::path_get_basename (buf);
2968 /** Create a new within-session audio source */
2969 boost::shared_ptr<AudioFileSource>
2970 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
2972 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2973 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
2975 return boost::dynamic_pointer_cast<AudioFileSource> (
2976 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
2979 /** Return a unique name based on \a base for a new internal MIDI source */
2981 Session::new_midi_source_name (const string& base)
2984 char buf[PATH_MAX+1];
2985 const uint32_t limit = 10000;
2989 legalized = legalize_for_path (base);
2991 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2992 for (cnt = 1; cnt <= limit; ++cnt) {
2994 vector<space_and_path>::iterator i;
2995 uint32_t existing = 0;
2997 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2999 SessionDirectory sdir((*i).path);
3001 sys::path p = sdir.midi_path();
3004 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3006 if (sys::exists (buf)) {
3011 if (existing == 0) {
3016 error << string_compose(
3017 _("There are already %1 recordings for %2, which I consider too many."),
3018 limit, base) << endmsg;
3020 throw failed_constructor();
3024 return Glib::path_get_basename(buf);
3028 /** Create a new within-session MIDI source */
3029 boost::shared_ptr<MidiSource>
3030 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3032 /* try to use the existing write source for the track, to keep numbering sane
3036 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3040 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3043 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3044 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3048 const string name = new_midi_source_name (n);
3049 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3051 return boost::dynamic_pointer_cast<SMFSource> (
3052 SourceFactory::createWritable (
3053 DataType::MIDI, *this, path, false, frame_rate()));
3058 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3060 if (playlist->hidden()) {
3064 playlists->add (playlist);
3067 playlist->release();
3074 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3076 if (_state_of_the_state & Deletion) {
3080 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3086 playlists->remove (playlist);
3092 Session::set_audition (boost::shared_ptr<Region> r)
3094 pending_audition_region = r;
3095 add_post_transport_work (PostTransportAudition);
3096 _butler->schedule_transport_work ();
3100 Session::audition_playlist ()
3102 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3103 ev->region.reset ();
3108 Session::non_realtime_set_audition ()
3110 if (!pending_audition_region) {
3111 auditioner->audition_current_playlist ();
3113 auditioner->audition_region (pending_audition_region);
3114 pending_audition_region.reset ();
3116 AuditionActive (true); /* EMIT SIGNAL */
3120 Session::audition_region (boost::shared_ptr<Region> r)
3122 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3128 Session::cancel_audition ()
3130 if (auditioner->auditioning()) {
3131 auditioner->cancel_audition ();
3132 AuditionActive (false); /* EMIT SIGNAL */
3137 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3139 if (a->is_monitor()) {
3142 if (b->is_monitor()) {
3145 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3149 Session::is_auditioning () const
3151 /* can be called before we have an auditioner object */
3153 return auditioner->auditioning();
3160 Session::graph_reordered ()
3162 /* don't do this stuff if we are setting up connections
3163 from a set_state() call or creating new tracks. Ditto for deletion.
3166 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3170 /* every track/bus asked for this to be handled but it was deferred because
3171 we were connecting. do it now.
3174 request_input_change_handling ();
3178 /* force all diskstreams to update their capture offset values to
3179 reflect any changes in latencies within the graph.
3182 boost::shared_ptr<RouteList> rl = routes.reader ();
3183 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3184 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3186 tr->set_capture_offset ();
3192 Session::available_capture_duration ()
3194 float sample_bytes_on_disk = 4.0; // keep gcc happy
3196 switch (config.get_native_file_data_format()) {
3198 sample_bytes_on_disk = 4.0;
3202 sample_bytes_on_disk = 3.0;
3206 sample_bytes_on_disk = 2.0;
3210 /* impossible, but keep some gcc versions happy */
3211 fatal << string_compose (_("programming error: %1"),
3212 X_("illegal native file data format"))
3217 double scale = 4096.0 / sample_bytes_on_disk;
3219 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3220 return max_framecnt;
3223 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3227 Session::add_bundle (shared_ptr<Bundle> bundle)
3230 RCUWriter<BundleList> writer (_bundles);
3231 boost::shared_ptr<BundleList> b = writer.get_copy ();
3232 b->push_back (bundle);
3235 BundleAdded (bundle); /* EMIT SIGNAL */
3241 Session::remove_bundle (shared_ptr<Bundle> bundle)
3243 bool removed = false;
3246 RCUWriter<BundleList> writer (_bundles);
3247 boost::shared_ptr<BundleList> b = writer.get_copy ();
3248 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3250 if (i != b->end()) {
3257 BundleRemoved (bundle); /* EMIT SIGNAL */
3264 Session::bundle_by_name (string name) const
3266 boost::shared_ptr<BundleList> b = _bundles.reader ();
3268 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3269 if ((*i)->name() == name) {
3274 return boost::shared_ptr<Bundle> ();
3278 Session::tempo_map_changed (const PropertyChange&)
3282 playlists->update_after_tempo_map_change ();
3284 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3290 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3292 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3293 (*i)->recompute_frames_from_bbt ();
3297 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3298 * the given count with the current block size.
3301 Session::ensure_buffers (ChanCount howmany)
3303 BufferManager::ensure_buffers (howmany);
3307 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3309 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3310 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3315 Session::next_insert_id ()
3317 /* this doesn't really loop forever. just think about it */
3320 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3321 if (!insert_bitset[n]) {
3322 insert_bitset[n] = true;
3328 /* none available, so resize and try again */
3330 insert_bitset.resize (insert_bitset.size() + 16, false);
3335 Session::next_send_id ()
3337 /* this doesn't really loop forever. just think about it */
3340 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3341 if (!send_bitset[n]) {
3342 send_bitset[n] = true;
3348 /* none available, so resize and try again */
3350 send_bitset.resize (send_bitset.size() + 16, false);
3355 Session::next_return_id ()
3357 /* this doesn't really loop forever. just think about it */
3360 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3361 if (!return_bitset[n]) {
3362 return_bitset[n] = true;
3368 /* none available, so resize and try again */
3370 return_bitset.resize (return_bitset.size() + 16, false);
3375 Session::mark_send_id (uint32_t id)
3377 if (id >= send_bitset.size()) {
3378 send_bitset.resize (id+16, false);
3380 if (send_bitset[id]) {
3381 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3383 send_bitset[id] = true;
3387 Session::mark_return_id (uint32_t id)
3389 if (id >= return_bitset.size()) {
3390 return_bitset.resize (id+16, false);
3392 if (return_bitset[id]) {
3393 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3395 return_bitset[id] = true;
3399 Session::mark_insert_id (uint32_t id)
3401 if (id >= insert_bitset.size()) {
3402 insert_bitset.resize (id+16, false);
3404 if (insert_bitset[id]) {
3405 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3407 insert_bitset[id] = true;
3411 Session::unmark_send_id (uint32_t id)
3413 if (id < send_bitset.size()) {
3414 send_bitset[id] = false;
3419 Session::unmark_return_id (uint32_t id)
3421 if (id < return_bitset.size()) {
3422 return_bitset[id] = false;
3427 Session::unmark_insert_id (uint32_t id)
3429 if (id < insert_bitset.size()) {
3430 insert_bitset[id] = false;
3435 /* Named Selection management */
3437 boost::shared_ptr<NamedSelection>
3438 Session::named_selection_by_name (string name)
3440 Glib::Mutex::Lock lm (named_selection_lock);
3441 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3442 if ((*i)->name == name) {
3446 return boost::shared_ptr<NamedSelection>();
3450 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3453 Glib::Mutex::Lock lm (named_selection_lock);
3454 named_selections.insert (named_selections.begin(), named_selection);
3459 NamedSelectionAdded (); /* EMIT SIGNAL */
3463 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3465 bool removed = false;
3468 Glib::Mutex::Lock lm (named_selection_lock);
3470 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3472 if (i != named_selections.end()) {
3473 named_selections.erase (i);
3480 NamedSelectionRemoved (); /* EMIT SIGNAL */
3485 Session::reset_native_file_format ()
3487 boost::shared_ptr<RouteList> rl = routes.reader ();
3488 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3489 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3491 /* don't save state as we do this, there's no point
3494 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3495 tr->reset_write_sources (false);
3496 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3502 Session::route_name_unique (string n) const
3504 shared_ptr<RouteList> r = routes.reader ();
3506 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3507 if ((*i)->name() == n) {
3516 Session::route_name_internal (string n) const
3518 if (auditioner && auditioner->name() == n) {
3522 if (_click_io && _click_io->name() == n) {
3530 Session::freeze_all (InterThreadInfo& itt)
3532 shared_ptr<RouteList> r = routes.reader ();
3534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3536 boost::shared_ptr<Track> t;
3538 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3539 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3549 boost::shared_ptr<Region>
3550 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3551 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3552 InterThreadInfo& itt, bool enable_processing)
3554 boost::shared_ptr<Region> result;
3555 boost::shared_ptr<Playlist> playlist;
3556 boost::shared_ptr<AudioFileSource> fsource;
3558 char buf[PATH_MAX+1];
3559 ChanCount nchans(track.n_channels());
3560 framepos_t position;
3561 framecnt_t this_chunk;
3564 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3565 const string sound_dir = sdir.sound_path().to_string();
3566 framepos_t len = end - start;
3567 bool need_block_size_reset = false;
3571 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3572 end, start) << endmsg;
3576 const framecnt_t chunk_size = (256 * 1024)/4;
3578 // block all process callback handling
3580 block_processing ();
3582 /* call tree *MUST* hold route_lock */
3584 if ((playlist = track.playlist()) == 0) {
3588 /* external redirects will be a problem */
3590 if (track.has_external_redirects()) {
3594 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3596 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3598 for (x = 0; x < 99999; ++x) {
3599 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());
3600 if (access (buf, F_OK) != 0) {
3606 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3611 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3612 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3615 catch (failed_constructor& err) {
3616 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3620 srcs.push_back (fsource);
3623 /* tell redirects that care that we are about to use a much larger blocksize */
3625 need_block_size_reset = true;
3626 track.set_block_size (chunk_size);
3628 /* XXX need to flush all redirects */
3633 /* create a set of reasonably-sized buffers */
3634 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3635 buffers.set_count(nchans);
3637 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3638 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3640 afs->prepare_for_peakfile_writes ();
3643 while (to_do && !itt.cancel) {
3645 this_chunk = min (to_do, chunk_size);
3647 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3652 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3653 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3656 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3662 start += this_chunk;
3663 to_do -= this_chunk;
3665 itt.progress = (float) (1.0 - ((double) to_do / len));
3674 xnow = localtime (&now);
3676 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3677 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3680 afs->update_header (position, *xnow, now);
3681 afs->flush_header ();
3685 /* construct a region to represent the bounced material */
3689 plist.add (Properties::start, 0);
3690 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3691 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3693 result = RegionFactory::create (srcs, plist);
3699 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3700 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3703 afs->mark_for_remove ();
3706 (*src)->drop_references ();
3710 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3711 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3714 afs->done_with_peakfile_writes ();
3719 if (need_block_size_reset) {
3720 track.set_block_size (get_block_size());
3723 unblock_processing ();
3729 Session::gain_automation_buffer() const
3731 return ProcessThread::gain_automation_buffer ();
3735 Session::pan_automation_buffer() const
3737 return ProcessThread::pan_automation_buffer ();
3741 Session::get_silent_buffers (ChanCount count)
3743 return ProcessThread::get_silent_buffers (count);
3745 assert(_silent_buffers->available() >= count);
3746 _silent_buffers->set_count(count);
3748 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3749 for (size_t i= 0; i < count.get(*t); ++i) {
3750 _silent_buffers->get(*t, i).clear();
3754 return *_silent_buffers;
3759 Session::get_scratch_buffers (ChanCount count)
3761 return ProcessThread::get_scratch_buffers (count);
3763 if (count != ChanCount::ZERO) {
3764 assert(_scratch_buffers->available() >= count);
3765 _scratch_buffers->set_count(count);
3767 _scratch_buffers->set_count (_scratch_buffers->available());
3770 return *_scratch_buffers;
3775 Session::get_mix_buffers (ChanCount count)
3777 return ProcessThread::get_mix_buffers (count);
3779 assert(_mix_buffers->available() >= count);
3780 _mix_buffers->set_count(count);
3781 return *_mix_buffers;
3786 Session::ntracks () const
3789 shared_ptr<RouteList> r = routes.reader ();
3791 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3792 if (boost::dynamic_pointer_cast<Track> (*i)) {
3801 Session::nbusses () const
3804 shared_ptr<RouteList> r = routes.reader ();
3806 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3807 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3816 Session::add_automation_list(AutomationList *al)
3818 automation_lists[al->id()] = al;
3822 Session::sync_order_keys (std::string const & base)
3824 if (deletion_in_progress()) {
3828 if (!Config->get_sync_all_route_ordering()) {
3829 /* leave order keys as they are */
3833 boost::shared_ptr<RouteList> r = routes.reader ();
3835 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3836 (*i)->sync_order_keys (base);
3839 Route::SyncOrderKeys (base); // EMIT SIGNAL
3841 /* this might not do anything */
3843 set_remote_control_ids ();
3846 /** @return true if there is at least one record-enabled track, otherwise false */
3848 Session::have_rec_enabled_track () const
3850 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3853 /** Update the state of our rec-enabled tracks flag */
3855 Session::update_have_rec_enabled_track ()
3857 boost::shared_ptr<RouteList> rl = routes.reader ();
3858 RouteList::iterator i = rl->begin();
3859 while (i != rl->end ()) {
3861 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3862 if (tr && tr->record_enabled ()) {
3869 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3871 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3873 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3874 RecordStateChanged (); /* EMIT SIGNAL */
3879 Session::listen_position_changed ()
3883 switch (Config->get_listen_position()) {
3884 case AfterFaderListen:
3888 case PreFaderListen:
3893 boost::shared_ptr<RouteList> r = routes.reader ();
3895 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3896 (*i)->put_monitor_send_at (p);
3901 Session::solo_control_mode_changed ()
3903 /* cancel all solo or all listen when solo control mode changes */
3906 set_solo (get_routes(), false);
3907 } else if (listening()) {
3908 set_listen (get_routes(), false);
3912 /** Called when anything about any of our route groups changes (membership, state etc.) */
3914 Session::route_group_changed ()
3916 RouteGroupChanged (); /* EMIT SIGNAL */
3920 Session::get_available_sync_options () const
3922 vector<SyncSource> ret;
3924 ret.push_back (JACK);
3925 ret.push_back (MTC);
3926 ret.push_back (MIDIClock);
3931 boost::shared_ptr<RouteList>
3932 Session::get_routes_with_regions_at (framepos_t const p) const
3934 shared_ptr<RouteList> r = routes.reader ();
3935 shared_ptr<RouteList> rl (new RouteList);
3937 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3938 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3943 boost::shared_ptr<Playlist> pl = tr->playlist ();
3948 if (pl->has_region_at (p)) {
3957 Session::goto_end ()
3959 if (_session_range_location) {
3960 request_locate (_session_range_location->end(), false);
3962 request_locate (0, false);
3967 Session::goto_start ()
3969 if (_session_range_location) {
3970 request_locate (_session_range_location->start(), false);
3972 request_locate (0, false);
3977 Session::current_start_frame () const
3979 return _session_range_location ? _session_range_location->start() : 0;
3983 Session::current_end_frame () const
3985 return _session_range_location ? _session_range_location->end() : 0;
3989 Session::add_session_range_location (nframes_t start, nframes_t end)
3991 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
3992 _locations->add (_session_range_location);
3995 /** Called when one of our routes' order keys has changed */
3997 Session::route_order_key_changed ()
3999 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4003 Session::step_edit_status_change (bool yn)
4009 send = (_step_editors == 0);
4014 send = (_step_editors == 1);
4017 if (_step_editors > 0) {
4023 StepEditStatusChange (val);