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.
20 #define __STDC_LIMIT_MACROS
28 #include <cstdio> /* sprintf(3) ... grrr */
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include <boost/algorithm/string/erase.hpp>
40 #include "pbd/error.h"
41 #include "pbd/boost_debug.h"
42 #include "pbd/pathscanner.h"
43 #include "pbd/stl_delete.h"
44 #include "pbd/basename.h"
45 #include "pbd/stacktrace.h"
46 #include "pbd/file_utils.h"
47 #include "pbd/convert.h"
49 #include "ardour/amp.h"
50 #include "ardour/analyser.h"
51 #include "ardour/audio_buffer.h"
52 #include "ardour/audio_diskstream.h"
53 #include "ardour/audio_port.h"
54 #include "ardour/audio_track.h"
55 #include "ardour/audioengine.h"
56 #include "ardour/audiofilesource.h"
57 #include "ardour/audioplaylist.h"
58 #include "ardour/audioregion.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/buffer_manager.h"
61 #include "ardour/buffer_set.h"
62 #include "ardour/bundle.h"
63 #include "ardour/butler.h"
64 #include "ardour/click.h"
65 #include "ardour/configuration.h"
66 #include "ardour/crossfade.h"
67 #include "ardour/cycle_timer.h"
68 #include "ardour/data_type.h"
69 #include "ardour/debug.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/internal_send.h"
72 #include "ardour/io_processor.h"
73 #include "ardour/midi_diskstream.h"
74 #include "ardour/midi_playlist.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/midi_track.h"
77 #include "ardour/midi_ui.h"
78 #include "ardour/named_selection.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/playlist.h"
81 #include "ardour/plugin_insert.h"
82 #include "ardour/port_insert.h"
83 #include "ardour/processor.h"
84 #include "ardour/rc_configuration.h"
85 #include "ardour/recent_sessions.h"
86 #include "ardour/region_factory.h"
87 #include "ardour/return.h"
88 #include "ardour/route_group.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_metadata.h"
94 #include "ardour/session_playlists.h"
95 #include "ardour/slave.h"
96 #include "ardour/smf_source.h"
97 #include "ardour/source_factory.h"
98 #include "ardour/tape_file_matcher.h"
99 #include "ardour/tempo.h"
100 #include "ardour/utils.h"
101 #include "ardour/graph.h"
103 #include "midi++/port.h"
104 #include "midi++/mmc.h"
105 #include "midi++/manager.h"
110 using namespace ARDOUR;
112 using boost::shared_ptr;
113 using boost::weak_ptr;
115 bool Session::_disable_all_loaded_plugins = false;
117 PBD::Signal1<void,std::string> Session::Dialog;
118 PBD::Signal0<int> Session::AskAboutPendingState;
119 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
120 PBD::Signal0<void> Session::SendFeedback;
122 PBD::Signal0<void> Session::TimecodeOffsetChanged;
123 PBD::Signal0<void> Session::StartTimeChanged;
124 PBD::Signal0<void> Session::EndTimeChanged;
125 PBD::Signal0<void> Session::AutoBindingOn;
126 PBD::Signal0<void> Session::AutoBindingOff;
127 PBD::Signal2<void,std::string, std::string> Session::Exported;
128 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
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 */
217 vector<void*> debug_pointers;
219 /* if we got to here, leaving pending capture state around
223 remove_pending_capture_state ();
225 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
227 _engine.remove_session ();
229 /* clear history so that no references to objects are held any more */
233 /* clear state tree so that no references to objects are held any more */
237 /* remove all stubfiles that might still be lurking */
239 cleanup_stubfiles ();
241 /* reset dynamic state version back to default */
243 Stateful::loading_state_version = 0;
245 _butler->drop_references ();
247 delete midi_control_ui;
248 delete _all_route_group;
250 if (click_data != default_click) {
251 delete [] click_data;
254 if (click_emphasis_data != default_click_emphasis) {
255 delete [] click_emphasis_data;
260 /* clear out any pending dead wood from RCU managed objects */
265 AudioDiskstream::free_working_buffers();
267 /* tell everyone who is still standing that we're about to die */
270 /* tell everyone to drop references and delete objects as we go */
272 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
273 named_selections.clear ();
275 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
276 RegionFactory::delete_all_regions ();
278 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
280 /* reset these three references to special routes before we do the usual route delete thing */
283 _master_out.reset ();
284 _monitor_out.reset ();
287 RCUWriter<RouteList> writer (routes);
288 boost::shared_ptr<RouteList> r = writer.get_copy ();
290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
291 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
292 (*i)->drop_references ();
296 /* writer goes out of scope and updates master */
300 boost::shared_ptr<RouteList> r = routes.reader ();
302 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
303 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
304 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
305 i->second->drop_references ();
310 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
311 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
316 Crossfade::set_buffer_size (0);
318 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
321 boost_debug_list_ptrs ();
325 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
329 Session::set_worst_io_latencies ()
331 _worst_output_latency = 0;
332 _worst_input_latency = 0;
334 if (!_engine.connected()) {
338 boost::shared_ptr<RouteList> r = routes.reader ();
340 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
341 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
342 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
347 Session::when_engine_running ()
349 string first_physical_output;
351 BootMessage (_("Set block size and sample rate"));
353 set_block_size (_engine.frames_per_cycle());
354 set_frame_rate (_engine.frame_rate());
356 BootMessage (_("Using configuration"));
358 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
359 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
361 Config->map_parameters (ff);
362 config.map_parameters (ft);
364 /* every time we reconnect, recompute worst case output latencies */
366 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
368 if (synced_to_jack()) {
369 _engine.transport_stop ();
372 if (config.get_jack_time_master()) {
373 _engine.transport_locate (_transport_frame);
381 _click_io.reset (new ClickIO (*this, "click"));
383 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
385 /* existing state for Click */
388 if (Stateful::loading_state_version < 3000) {
389 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
391 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
396 _clicking = Config->get_clicking ();
400 error << _("could not setup Click I/O") << endmsg;
407 /* default state for Click: dual-mono to first 2 physical outputs */
410 _engine.get_physical_outputs (DataType::AUDIO, outs);
412 for (uint32_t physport = 0; physport < 2; ++physport) {
413 if (outs.size() > physport) {
414 if (_click_io->add_port (outs[physport], this)) {
415 // relax, even though its an error
420 if (_click_io->n_ports () > ChanCount::ZERO) {
421 _clicking = Config->get_clicking ();
426 catch (failed_constructor& err) {
427 error << _("cannot setup Click I/O") << endmsg;
430 BootMessage (_("Compute I/O Latencies"));
432 set_worst_io_latencies ();
435 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
438 BootMessage (_("Set up standard connections"));
440 vector<string> inputs[DataType::num_types];
441 vector<string> outputs[DataType::num_types];
442 for (uint32_t i = 0; i < DataType::num_types; ++i) {
443 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
444 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
447 /* Create a set of Bundle objects that map
448 to the physical I/O currently available. We create both
449 mono and stereo bundles, so that the common cases of mono
450 and stereo tracks get bundles to put in their mixer strip
451 in / out menus. There may be a nicer way of achieving that;
452 it doesn't really scale that well to higher channel counts
455 /* mono output bundles */
457 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
459 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
461 shared_ptr<Bundle> c (new Bundle (buf, true));
462 c->add_channel (_("mono"), DataType::AUDIO);
463 c->set_port (0, outputs[DataType::AUDIO][np]);
468 /* stereo output bundles */
470 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
471 if (np + 1 < outputs[DataType::AUDIO].size()) {
473 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
474 shared_ptr<Bundle> c (new Bundle (buf, true));
475 c->add_channel (_("L"), DataType::AUDIO);
476 c->set_port (0, outputs[DataType::AUDIO][np]);
477 c->add_channel (_("R"), DataType::AUDIO);
478 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
484 /* mono input bundles */
486 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
488 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
490 shared_ptr<Bundle> c (new Bundle (buf, false));
491 c->add_channel (_("mono"), DataType::AUDIO);
492 c->set_port (0, inputs[DataType::AUDIO][np]);
497 /* stereo input bundles */
499 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
500 if (np + 1 < inputs[DataType::AUDIO].size()) {
502 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
504 shared_ptr<Bundle> c (new Bundle (buf, false));
505 c->add_channel (_("L"), DataType::AUDIO);
506 c->set_port (0, inputs[DataType::AUDIO][np]);
507 c->add_channel (_("R"), DataType::AUDIO);
508 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
514 /* MIDI input bundles */
516 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
517 string n = inputs[DataType::MIDI][np];
518 boost::erase_first (n, X_("alsa_pcm:"));
520 shared_ptr<Bundle> c (new Bundle (n, false));
521 c->add_channel ("", DataType::MIDI);
522 c->set_port (0, inputs[DataType::MIDI][np]);
526 /* MIDI output bundles */
528 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
529 string n = outputs[DataType::MIDI][np];
530 boost::erase_first (n, X_("alsa_pcm:"));
532 shared_ptr<Bundle> c (new Bundle (n, true));
533 c->add_channel ("", DataType::MIDI);
534 c->set_port (0, outputs[DataType::MIDI][np]);
538 BootMessage (_("Setup signal flow and plugins"));
542 if (_is_new && !no_auto_connect()) {
544 /* don't connect the master bus outputs if there is a monitor bus */
546 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
548 /* if requested auto-connect the outputs to the first N physical ports.
551 uint32_t limit = _master_out->n_outputs().n_total();
553 for (uint32_t n = 0; n < limit; ++n) {
554 Port* p = _master_out->output()->nth (n);
556 if (outputs[p->type()].size() > n) {
557 connect_to = outputs[p->type()][n];
560 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
561 if (_master_out->output()->connect (p, connect_to, this)) {
562 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
572 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
573 are undefined, at best.
576 /* control out listens to master bus (but ignores it
577 under some conditions)
580 uint32_t limit = _monitor_out->n_inputs().n_audio();
583 for (uint32_t n = 0; n < limit; ++n) {
584 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
585 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
588 string connect_to = o->name();
589 if (_monitor_out->input()->connect (p, connect_to, this)) {
590 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
598 /* if control out is not connected, connect control out to physical outs
601 if (!_monitor_out->output()->connected ()) {
603 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
605 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
608 _monitor_out->output()->connect_ports_to_bundle (b, this);
610 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
611 Config->get_monitor_bus_preferred_bundle())
617 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
618 uint32_t mod = n_physical_outputs.get (*t);
619 uint32_t limit = _monitor_out->n_outputs().get(*t);
621 for (uint32_t n = 0; n < limit; ++n) {
623 Port* p = _monitor_out->output()->ports().port(*t, n);
625 if (outputs[*t].size() > (n % mod)) {
626 connect_to = outputs[*t][n % mod];
629 if (!connect_to.empty()) {
630 if (_monitor_out->output()->connect (p, connect_to, this)) {
631 error << string_compose (
632 _("cannot connect control output %1 to %2"),
645 /* catch up on send+insert cnts */
647 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
649 /* hook us up to the engine */
651 BootMessage (_("Connect to engine"));
653 _engine.set_session (this);
657 Session::hookup_io ()
659 /* stop graph reordering notifications from
660 causing resorts, etc.
663 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
668 /* we delay creating the auditioner till now because
669 it makes its own connections to ports.
673 Auditioner* a = new Auditioner (*this);
676 throw failed_constructor();
678 a->use_new_diskstream ();
679 auditioner.reset (a);
682 catch (failed_constructor& err) {
683 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
687 /* load bundles, which we may have postponed earlier on */
688 if (_bundle_xml_node) {
689 load_bundles (*_bundle_xml_node);
690 delete _bundle_xml_node;
693 /* Tell all IO objects to connect themselves together */
695 IO::enable_connecting ();
696 MIDI::Port::MakeConnections ();
698 /* Now reset all panners */
700 Delivery::reset_panners ();
702 /* Connect tracks to monitor/listen bus if there is one.
703 Note that in an existing session, the internal sends will
704 already exist, but we want the routes to notice that
705 they connect to the control out specifically.
709 boost::shared_ptr<RouteList> r = routes.reader ();
710 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
712 if ((*x)->is_monitor()) {
716 } else if ((*x)->is_master()) {
722 (*x)->listen_via (_monitor_out,
723 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
729 /* Anyone who cares about input state, wake up and do something */
731 IOConnectionsComplete (); /* EMIT SIGNAL */
733 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
735 /* now handle the whole enchilada as if it was one
741 /* update the full solo state, which can't be
742 correctly determined on a per-route basis, but
743 needs the global overview that only the session
747 update_route_solo_state ();
751 Session::playlist_length_changed ()
753 update_session_range_location_marker ();
757 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
759 boost::shared_ptr<Track> track = wp.lock ();
764 boost::shared_ptr<Playlist> playlist;
766 if ((playlist = track->playlist()) != 0) {
767 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
770 update_session_range_location_marker ();
774 Session::record_enabling_legal () const
776 /* this used to be in here, but survey says.... we don't need to restrict it */
777 // if (record_status() == Recording) {
781 if (Config->get_all_safe()) {
788 Session::reset_input_monitor_state ()
790 if (transport_rolling()) {
792 boost::shared_ptr<RouteList> rl = routes.reader ();
793 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
794 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
795 if (tr && tr->record_enabled ()) {
796 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
797 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
803 boost::shared_ptr<RouteList> rl = routes.reader ();
804 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
805 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
806 if (tr && tr->record_enabled ()) {
807 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
808 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
815 Session::auto_punch_start_changed (Location* location)
817 replace_event (SessionEvent::PunchIn, location->start());
819 if (get_record_enabled() && config.get_punch_in()) {
820 /* capture start has been changed, so save new pending state */
821 save_state ("", true);
826 Session::auto_punch_end_changed (Location* location)
828 nframes_t when_to_stop = location->end();
829 // when_to_stop += _worst_output_latency + _worst_input_latency;
830 replace_event (SessionEvent::PunchOut, when_to_stop);
834 Session::auto_punch_changed (Location* location)
836 nframes_t when_to_stop = location->end();
838 replace_event (SessionEvent::PunchIn, location->start());
839 //when_to_stop += _worst_output_latency + _worst_input_latency;
840 replace_event (SessionEvent::PunchOut, when_to_stop);
844 Session::auto_loop_changed (Location* location)
846 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
848 if (transport_rolling() && play_loop) {
851 // if (_transport_frame > location->end()) {
853 if (_transport_frame < location->start() || _transport_frame > location->end()) {
854 // relocate to beginning of loop
855 clear_events (SessionEvent::LocateRoll);
857 request_locate (location->start(), true);
860 else if (Config->get_seamless_loop() && !loop_changing) {
862 // schedule a locate-roll to refill the diskstreams at the
864 loop_changing = true;
866 if (location->end() > last_loopend) {
867 clear_events (SessionEvent::LocateRoll);
868 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
875 last_loopend = location->end();
879 Session::set_auto_punch_location (Location* location)
883 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
884 punch_connections.drop_connections();
885 existing->set_auto_punch (false, this);
886 remove_event (existing->start(), SessionEvent::PunchIn);
887 clear_events (SessionEvent::PunchOut);
888 auto_punch_location_changed (0);
897 if (location->end() <= location->start()) {
898 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
902 punch_connections.drop_connections ();
904 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
905 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
906 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
908 location->set_auto_punch (true, this);
910 auto_punch_changed (location);
912 auto_punch_location_changed (location);
916 Session::set_auto_loop_location (Location* location)
920 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
921 loop_connections.drop_connections ();
922 existing->set_auto_loop (false, this);
923 remove_event (existing->end(), SessionEvent::AutoLoop);
924 auto_loop_location_changed (0);
933 if (location->end() <= location->start()) {
934 error << _("Session: you can't use a mark for auto loop") << endmsg;
938 last_loopend = location->end();
940 loop_connections.drop_connections ();
942 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
943 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
944 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
946 location->set_auto_loop (true, this);
948 /* take care of our stuff first */
950 auto_loop_changed (location);
952 /* now tell everyone else */
954 auto_loop_location_changed (location);
958 Session::locations_added (Location *)
964 Session::locations_changed ()
966 _locations->apply (*this, &Session::handle_locations_changed);
970 Session::handle_locations_changed (Locations::LocationList& locations)
972 Locations::LocationList::iterator i;
974 bool set_loop = false;
975 bool set_punch = false;
977 for (i = locations.begin(); i != locations.end(); ++i) {
981 if (location->is_auto_punch()) {
982 set_auto_punch_location (location);
985 if (location->is_auto_loop()) {
986 set_auto_loop_location (location);
990 if (location->is_session_range()) {
991 _session_range_location = location;
996 set_auto_loop_location (0);
999 set_auto_punch_location (0);
1006 Session::enable_record ()
1009 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1011 if (rs == Recording) {
1015 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1017 _last_record_location = _transport_frame;
1018 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1020 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1022 boost::shared_ptr<RouteList> rl = routes.reader ();
1023 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1024 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1025 if (tr && tr->record_enabled ()) {
1026 tr->monitor_input (true);
1031 RecordStateChanged ();
1038 Session::disable_record (bool rt_context, bool force)
1042 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1044 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1045 g_atomic_int_set (&_record_status, Disabled);
1046 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1048 if (rs == Recording) {
1049 g_atomic_int_set (&_record_status, Enabled);
1053 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1055 boost::shared_ptr<RouteList> rl = routes.reader ();
1056 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1057 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1058 if (tr && tr->record_enabled ()) {
1059 tr->monitor_input (false);
1064 RecordStateChanged (); /* emit signal */
1067 remove_pending_capture_state ();
1073 Session::step_back_from_record ()
1075 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1077 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1078 boost::shared_ptr<RouteList> rl = routes.reader ();
1079 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1080 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1081 if (tr && tr->record_enabled ()) {
1082 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1083 tr->monitor_input (false);
1091 Session::maybe_enable_record ()
1093 if (_step_editors > 0) {
1097 g_atomic_int_set (&_record_status, Enabled);
1099 /* this function is currently called from somewhere other than an RT thread.
1100 this save_state() call therefore doesn't impact anything.
1103 save_state ("", true);
1105 if (_transport_speed) {
1106 if (!config.get_punch_in()) {
1110 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1111 RecordStateChanged (); /* EMIT SIGNAL */
1118 Session::audible_frame () const
1124 /* the first of these two possible settings for "offset"
1125 mean that the audible frame is stationary until
1126 audio emerges from the latency compensation
1129 the second means that the audible frame is stationary
1130 until audio would emerge from a physical port
1131 in the absence of any plugin latency compensation
1134 offset = _worst_output_latency;
1136 if (offset > current_block_size) {
1137 offset -= current_block_size;
1139 /* XXX is this correct? if we have no external
1140 physical connections and everything is internal
1141 then surely this is zero? still, how
1142 likely is that anyway?
1144 offset = current_block_size;
1147 if (synced_to_jack()) {
1148 tf = _engine.transport_frame();
1150 tf = _transport_frame;
1155 if (!non_realtime_work_pending()) {
1159 /* Check to see if we have passed the first guaranteed
1160 audible frame past our last start position. if not,
1161 return that last start point because in terms
1162 of audible frames, we have not moved yet.
1164 `Start position' in this context means the time we last
1165 either started or changed transport direction.
1168 if (_transport_speed > 0.0f) {
1170 if (!play_loop || !have_looped) {
1171 if (tf < _last_roll_or_reversal_location + offset) {
1172 return _last_roll_or_reversal_location;
1180 } else if (_transport_speed < 0.0f) {
1182 /* XXX wot? no backward looping? */
1184 if (tf > _last_roll_or_reversal_location - offset) {
1185 return _last_roll_or_reversal_location;
1197 Session::set_frame_rate (nframes_t frames_per_second)
1199 /** \fn void Session::set_frame_size(nframes_t)
1200 the AudioEngine object that calls this guarantees
1201 that it will not be called while we are also in
1202 ::process(). Its fine to do things that block
1206 _base_frame_rate = frames_per_second;
1210 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1214 // XXX we need some equivalent to this, somehow
1215 // SndFileSource::setup_standard_crossfades (frames_per_second);
1219 /* XXX need to reset/reinstantiate all LADSPA plugins */
1223 Session::set_block_size (nframes_t nframes)
1225 /* the AudioEngine guarantees
1226 that it will not be called while we are also in
1227 ::process(). It is therefore fine to do things that block
1232 current_block_size = nframes;
1236 boost::shared_ptr<RouteList> r = routes.reader ();
1238 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1239 (*i)->set_block_size (nframes);
1242 boost::shared_ptr<RouteList> rl = routes.reader ();
1243 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1244 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1246 tr->set_block_size (nframes);
1250 set_worst_io_latencies ();
1255 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1258 nframes_t fade_frames;
1260 /* Don't allow fade of less 1 frame */
1262 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1269 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1273 default_fade_msecs = fade_msecs;
1274 default_fade_steepness = steepness;
1277 // jlc, WTF is this!
1278 Glib::RWLock::ReaderLock lm (route_lock);
1279 AudioRegion::set_default_fade (steepness, fade_frames);
1284 /* XXX have to do this at some point */
1285 /* foreach region using default fade, reset, then
1286 refill_all_diskstream_buffers ();
1291 struct RouteSorter {
1292 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1293 if (r2->feeds (r1)) {
1295 } else if (r1->feeds (r2)) {
1298 if (r1->not_fed ()) {
1299 if (r2->not_fed ()) {
1300 /* no ardour-based connections inbound to either route. just use signal order */
1301 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1303 /* r2 has connections, r1 does not; run r1 early */
1307 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1314 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1316 shared_ptr<Route> r2;
1318 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1319 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1323 /* make a copy of the existing list of routes that feed r1 */
1325 Route::FedBy existing (r1->fed_by());
1327 /* for each route that feeds r1, recurse, marking it as feeding
1331 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1332 if (!(r2 = i->r.lock ())) {
1333 /* (*i) went away, ignore it */
1337 /* r2 is a route that feeds r1 which somehow feeds base. mark
1338 base as being fed by r2
1341 rbase->add_fed_by (r2, i->sends_only);
1345 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1349 if (r1->feeds (r2) && r2->feeds (r1)) {
1353 /* now recurse, so that we can mark base as being fed by
1354 all routes that feed r2
1357 trace_terminal (r2, rbase);
1364 Session::resort_routes ()
1366 /* don't do anything here with signals emitted
1367 by Routes while we are being destroyed.
1370 if (_state_of_the_state & Deletion) {
1375 RCUWriter<RouteList> writer (routes);
1376 shared_ptr<RouteList> r = writer.get_copy ();
1377 resort_routes_using (r);
1378 /* writer goes out of scope and forces update */
1381 //route_graph->dump(1);
1384 boost::shared_ptr<RouteList> rl = routes.reader ();
1385 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1386 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1388 const Route::FedBy& fb ((*i)->fed_by());
1390 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1391 boost::shared_ptr<Route> sf = f->r.lock();
1393 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1401 Session::resort_routes_using (shared_ptr<RouteList> r)
1403 RouteList::iterator i, j;
1405 for (i = r->begin(); i != r->end(); ++i) {
1407 (*i)->clear_fed_by ();
1409 for (j = r->begin(); j != r->end(); ++j) {
1411 /* although routes can feed themselves, it will
1412 cause an endless recursive descent if we
1413 detect it. so don't bother checking for
1421 bool via_sends_only;
1423 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1424 (*i)->add_fed_by (*j, via_sends_only);
1429 for (i = r->begin(); i != r->end(); ++i) {
1430 trace_terminal (*i, *i);
1436 route_graph->rechain (r);
1439 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1440 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1441 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1442 (*i)->name(), (*i)->order_key ("signal")));
1448 /** Find the route name starting with \a base with the lowest \a id.
1450 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1451 * The available route name with the lowest ID will be used, and \a id
1452 * will be set to the ID.
1454 * \return false if a route name could not be found, and \a track_name
1455 * and \a id do not reflect a free route name.
1458 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1461 snprintf (name, name_len, "%s %" PRIu32, base, id);
1463 if (route_by_name (name) == 0) {
1469 } while (id < (UINT_MAX-1));
1474 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1476 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1478 in = ChanCount::ZERO;
1479 out = ChanCount::ZERO;
1480 shared_ptr<RouteList> r = routes.reader ();
1481 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1482 if (!(*i)->is_hidden()) {
1483 in += (*i)->n_inputs();
1484 out += (*i)->n_outputs();
1489 list<boost::shared_ptr<MidiTrack> >
1490 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1492 char track_name[32];
1493 uint32_t track_id = 0;
1494 ChanCount existing_inputs;
1495 ChanCount existing_outputs;
1497 RouteList new_routes;
1498 list<boost::shared_ptr<MidiTrack> > ret;
1499 uint32_t control_id;
1501 count_existing_route_channels (existing_inputs, existing_outputs);
1503 control_id = ntracks() + nbusses();
1506 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1507 error << "cannot find name for new midi track" << endmsg;
1511 shared_ptr<MidiTrack> track;
1514 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1521 mt->use_new_diskstream();
1523 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1524 track = boost::shared_ptr<MidiTrack>(mt);
1526 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1527 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1532 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1533 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1537 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1539 track->non_realtime_input_change();
1542 route_group->add (track);
1545 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1546 track->set_remote_control_id (control_id);
1548 new_routes.push_back (track);
1549 ret.push_back (track);
1552 catch (failed_constructor &err) {
1553 error << _("Session: could not create new midi track.") << endmsg;
1557 catch (AudioEngine::PortRegistrationFailure& pfe) {
1559 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;
1567 if (!new_routes.empty()) {
1568 add_routes (new_routes, false);
1569 save_state (_current_snapshot_name);
1575 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1576 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1577 * @param output_start As \a input_start, but for outputs.
1580 Session::auto_connect_route (
1581 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1584 /* If both inputs and outputs are auto-connected to physical ports,
1585 use the max of input and output offsets to ensure auto-connected
1586 port numbers always match up (e.g. the first audio input and the
1587 first audio output of the route will have the same physical
1588 port number). Otherwise just use the lowest input or output
1592 const bool in_out_physical =
1593 (Config->get_input_auto_connect() & AutoConnectPhysical)
1594 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1597 const ChanCount in_offset = in_out_physical
1598 ? ChanCount::max(existing_inputs, existing_outputs)
1601 const ChanCount out_offset = in_out_physical
1602 ? ChanCount::max(existing_inputs, existing_outputs)
1605 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1606 vector<string> physinputs;
1607 vector<string> physoutputs;
1609 _engine.get_physical_outputs (*t, physoutputs);
1610 _engine.get_physical_inputs (*t, physinputs);
1612 if (!physinputs.empty() && connect_inputs) {
1613 uint32_t nphysical_in = physinputs.size();
1614 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1617 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1618 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1621 if (!port.empty() && route->input()->connect (
1622 route->input()->ports().port(*t, i), port, this)) {
1628 if (!physoutputs.empty()) {
1629 uint32_t nphysical_out = physoutputs.size();
1630 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1633 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1634 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1635 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1636 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1637 port = _master_out->input()->ports().port(*t,
1638 i % _master_out->input()->n_ports().get(*t))->name();
1642 if (!port.empty() && route->output()->connect (
1643 route->output()->ports().port(*t, i), port, this)) {
1650 existing_inputs += route->n_inputs();
1651 existing_outputs += route->n_outputs();
1654 list< boost::shared_ptr<AudioTrack> >
1655 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1657 char track_name[32];
1658 uint32_t track_id = 0;
1659 ChanCount existing_inputs;
1660 ChanCount existing_outputs;
1662 RouteList new_routes;
1663 list<boost::shared_ptr<AudioTrack> > ret;
1664 uint32_t control_id;
1666 count_existing_route_channels (existing_inputs, existing_outputs);
1668 control_id = ntracks() + nbusses() + 1;
1671 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1672 error << "cannot find name for new audio track" << endmsg;
1676 shared_ptr<AudioTrack> track;
1679 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1686 at->use_new_diskstream();
1688 boost_debug_shared_ptr_mark_interesting (at, "Track");
1689 track = boost::shared_ptr<AudioTrack>(at);
1691 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1692 error << string_compose (
1693 _("cannot configure %1 in/%2 out configuration for new audio track"),
1694 input_channels, output_channels)
1699 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1700 error << string_compose (
1701 _("cannot configure %1 in/%2 out configuration for new audio track"),
1702 input_channels, output_channels)
1707 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1710 route_group->add (track);
1713 track->non_realtime_input_change();
1715 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1716 track->set_remote_control_id (control_id);
1719 new_routes.push_back (track);
1720 ret.push_back (track);
1723 catch (failed_constructor &err) {
1724 error << _("Session: could not create new audio track.") << endmsg;
1728 catch (AudioEngine::PortRegistrationFailure& pfe) {
1730 error << pfe.what() << endmsg;
1738 if (!new_routes.empty()) {
1739 add_routes (new_routes, true);
1746 Session::set_remote_control_ids ()
1748 RemoteModel m = Config->get_remote_model();
1749 bool emit_signal = false;
1751 shared_ptr<RouteList> r = routes.reader ();
1753 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1754 if (MixerOrdered == m) {
1755 int32_t order = (*i)->order_key(N_("signal"));
1756 (*i)->set_remote_control_id (order+1, false);
1758 } else if (EditorOrdered == m) {
1759 int32_t order = (*i)->order_key(N_("editor"));
1760 (*i)->set_remote_control_id (order+1, false);
1762 } else if (UserOrdered == m) {
1763 //do nothing ... only changes to remote id's are initiated by user
1768 Route::RemoteControlIDChange();
1774 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1777 uint32_t bus_id = 0;
1778 ChanCount existing_inputs;
1779 ChanCount existing_outputs;
1782 uint32_t control_id;
1784 count_existing_route_channels (existing_inputs, existing_outputs);
1786 control_id = ntracks() + nbusses() + 1;
1789 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1790 error << "cannot find name for new audio bus" << endmsg;
1795 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1802 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1803 shared_ptr<Route> bus (rt);
1805 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1806 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1807 input_channels, output_channels)
1813 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1814 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1815 input_channels, output_channels)
1820 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1823 route_group->add (bus);
1825 bus->set_remote_control_id (control_id);
1829 bus->add_internal_return ();
1832 ret.push_back (bus);
1836 catch (failed_constructor &err) {
1837 error << _("Session: could not create new audio route.") << endmsg;
1841 catch (AudioEngine::PortRegistrationFailure& pfe) {
1842 error << pfe.what() << endmsg;
1852 add_routes (ret, true);
1860 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1864 uint32_t control_id;
1866 uint32_t number = 0;
1868 if (!tree.read (template_path.c_str())) {
1872 XMLNode* node = tree.root();
1874 control_id = ntracks() + nbusses() + 1;
1878 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1880 std::string node_name = IO::name_from_state (*node_copy.children().front());
1882 /* generate a new name by adding a number to the end of the template name */
1883 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1884 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1888 /* set IO children to use the new name */
1889 XMLNodeList const & children = node_copy.children ();
1890 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1891 if ((*i)->name() == IO::state_node_name) {
1892 IO::set_name_in_state (**i, name);
1896 Track::zero_diskstream_id_in_xml (node_copy);
1899 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1902 error << _("Session: cannot create track/bus from template description") << endmsg;
1906 if (boost::dynamic_pointer_cast<Track>(route)) {
1907 /* force input/output change signals so that the new diskstream
1908 picks up the configuration of the route. During session
1909 loading this normally happens in a different way.
1911 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1912 change.after = route->input()->n_ports();
1913 route->input()->changed (change, this);
1914 change.after = route->output()->n_ports();
1915 route->output()->changed (change, this);
1918 route->set_remote_control_id (control_id);
1921 ret.push_back (route);
1924 catch (failed_constructor &err) {
1925 error << _("Session: could not create new route from template") << endmsg;
1929 catch (AudioEngine::PortRegistrationFailure& pfe) {
1930 error << pfe.what() << endmsg;
1939 add_routes (ret, true);
1946 Session::add_routes (RouteList& new_routes, bool save)
1949 RCUWriter<RouteList> writer (routes);
1950 shared_ptr<RouteList> r = writer.get_copy ();
1951 r->insert (r->end(), new_routes.begin(), new_routes.end());
1954 /* if there is no control out and we're not in the middle of loading,
1955 resort the graph here. if there is a control out, we will resort
1956 toward the end of this method. if we are in the middle of loading,
1957 we will resort when done.
1960 if (!_monitor_out && IO::connecting_legal) {
1961 resort_routes_using (r);
1965 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1967 boost::weak_ptr<Route> wpr (*x);
1968 boost::shared_ptr<Route> r (*x);
1970 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1971 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1972 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1973 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1974 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1975 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1976 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1978 if (r->is_master()) {
1982 if (r->is_monitor()) {
1986 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1988 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1989 track_playlist_changed (boost::weak_ptr<Track> (tr));
1990 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1992 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
1994 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
1999 if (_monitor_out && IO::connecting_legal) {
2001 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2002 if ((*x)->is_monitor()) {
2004 } else if ((*x)->is_master()) {
2007 (*x)->listen_via (_monitor_out,
2008 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2019 save_state (_current_snapshot_name);
2022 RouteAdded (new_routes); /* EMIT SIGNAL */
2023 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2027 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2029 boost::shared_ptr<RouteList> r = routes.reader ();
2030 boost::shared_ptr<Send> s;
2034 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2035 if (boost::dynamic_pointer_cast<Track>(*i)) {
2036 if ((s = (*i)->internal_send_for (dest)) != 0) {
2037 s->amp()->gain_control()->set_value (0.0);
2044 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2046 boost::shared_ptr<RouteList> r = routes.reader ();
2047 boost::shared_ptr<Send> s;
2051 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2052 if (boost::dynamic_pointer_cast<Track>(*i)) {
2053 if ((s = (*i)->internal_send_for (dest)) != 0) {
2054 s->amp()->gain_control()->set_value (1.0);
2061 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2063 boost::shared_ptr<RouteList> r = routes.reader ();
2064 boost::shared_ptr<Send> s;
2068 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2069 if (boost::dynamic_pointer_cast<Track>(*i)) {
2070 if ((s = (*i)->internal_send_for (dest)) != 0) {
2071 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2078 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2080 boost::shared_ptr<RouteList> r = routes.reader ();
2081 boost::shared_ptr<RouteList> t (new RouteList);
2083 /* only send tracks */
2085 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2086 if (boost::dynamic_pointer_cast<Track>(*i)) {
2091 add_internal_sends (dest, p, t);
2095 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2097 if (dest->is_monitor() || dest->is_master()) {
2101 if (!dest->internal_return()) {
2102 dest->add_internal_return();
2105 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2107 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2111 (*i)->listen_via (dest, p, true, true);
2118 Session::remove_route (shared_ptr<Route> route)
2120 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2124 route->set_solo (false, this);
2127 RCUWriter<RouteList> writer (routes);
2128 shared_ptr<RouteList> rs = writer.get_copy ();
2132 /* deleting the master out seems like a dumb
2133 idea, but its more of a UI policy issue
2137 if (route == _master_out) {
2138 _master_out = shared_ptr<Route> ();
2141 if (route == _monitor_out) {
2143 /* cancel control outs for all routes */
2145 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2146 (*r)->drop_listen (_monitor_out);
2149 _monitor_out.reset ();
2152 /* writer goes out of scope, forces route list update */
2155 update_route_solo_state ();
2156 update_session_range_location_marker ();
2158 // We need to disconnect the route's inputs and outputs
2160 route->input()->disconnect (0);
2161 route->output()->disconnect (0);
2163 /* if the route had internal sends sending to it, remove them */
2164 if (route->internal_return()) {
2166 boost::shared_ptr<RouteList> r = routes.reader ();
2167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2168 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2170 (*i)->remove_processor (s);
2175 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2176 if (mt && mt->step_editing()) {
2177 if (_step_editors > 0) {
2182 update_latency_compensation (false, false);
2185 /* Re-sort routes to remove the graph's current references to the one that is
2186 * going away, then flush old references out of the graph.
2190 route_graph->clear_other_chain ();
2192 /* get rid of it from the dead wood collection in the route list manager */
2194 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2198 /* try to cause everyone to drop their references */
2200 route->drop_references ();
2202 sync_order_keys (N_("session"));
2204 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2206 /* save the new state of the world */
2208 if (save_state (_current_snapshot_name)) {
2209 save_history (_current_snapshot_name);
2214 Session::route_mute_changed (void* /*src*/)
2220 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2222 boost::shared_ptr<Route> route = wpr.lock();
2224 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2228 if (route->listening()) {
2230 if (Config->get_exclusive_solo()) {
2231 /* new listen: disable all other listen */
2232 shared_ptr<RouteList> r = routes.reader ();
2233 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2234 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2237 (*i)->set_listen (false, this);
2243 } else if (_listen_cnt > 0) {
2249 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2251 boost::shared_ptr<Route> route = wpr.lock ();
2254 /* should not happen */
2255 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2259 bool send_changed = false;
2261 if (route->solo_isolated()) {
2262 if (_solo_isolated_cnt == 0) {
2263 send_changed = true;
2265 _solo_isolated_cnt++;
2266 } else if (_solo_isolated_cnt > 0) {
2267 _solo_isolated_cnt--;
2268 if (_solo_isolated_cnt == 0) {
2269 send_changed = true;
2274 IsolatedChanged (); /* EMIT SIGNAL */
2279 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2281 if (!self_solo_change) {
2282 // session doesn't care about changes to soloed-by-others
2286 if (solo_update_disabled) {
2291 boost::shared_ptr<Route> route = wpr.lock ();
2294 /* should not happen */
2295 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2299 shared_ptr<RouteList> r = routes.reader ();
2302 if (route->self_soloed()) {
2308 if (delta == 1 && Config->get_exclusive_solo()) {
2309 /* new solo: disable all other solos */
2310 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2311 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2314 (*i)->set_solo (false, this);
2318 solo_update_disabled = true;
2320 RouteList uninvolved;
2322 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2323 bool via_sends_only;
2324 bool in_signal_flow;
2326 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2330 in_signal_flow = false;
2332 if ((*i)->feeds (route, &via_sends_only)) {
2333 if (!via_sends_only) {
2334 if (!route->soloed_by_others_upstream()) {
2335 (*i)->mod_solo_by_others_downstream (delta);
2337 in_signal_flow = true;
2341 if (route->feeds (*i, &via_sends_only)) {
2342 (*i)->mod_solo_by_others_upstream (delta);
2343 in_signal_flow = true;
2346 if (!in_signal_flow) {
2347 uninvolved.push_back (*i);
2351 solo_update_disabled = false;
2352 update_route_solo_state (r);
2354 /* now notify that the mute state of the routes not involved in the signal
2355 pathway of the just-solo-changed route may have altered.
2358 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2359 (*i)->mute_changed (this);
2362 SoloChanged (); /* EMIT SIGNAL */
2367 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2369 /* now figure out if anything that matters is soloed (or is "listening")*/
2371 bool something_soloed = false;
2372 uint32_t listeners = 0;
2373 uint32_t isolated = 0;
2376 r = routes.reader();
2379 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2380 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2381 something_soloed = true;
2384 if (!(*i)->is_hidden() && (*i)->listening()) {
2385 if (Config->get_solo_control_is_listen_control()) {
2388 (*i)->set_listen (false, this);
2392 if ((*i)->solo_isolated()) {
2397 if (something_soloed != _non_soloed_outs_muted) {
2398 _non_soloed_outs_muted = something_soloed;
2399 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2402 _listen_cnt = listeners;
2404 if (isolated != _solo_isolated_cnt) {
2405 _solo_isolated_cnt = isolated;
2406 IsolatedChanged (); /* EMIT SIGNAL */
2410 boost::shared_ptr<RouteList>
2411 Session::get_routes_with_internal_returns() const
2413 shared_ptr<RouteList> r = routes.reader ();
2414 boost::shared_ptr<RouteList> rl (new RouteList);
2416 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2417 if ((*i)->internal_return ()) {
2425 Session::io_name_is_legal (const std::string& name)
2427 shared_ptr<RouteList> r = routes.reader ();
2429 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2430 if ((*i)->name() == name) {
2434 if ((*i)->has_io_processor_named (name)) {
2443 Session::route_by_name (string name)
2445 shared_ptr<RouteList> r = routes.reader ();
2447 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2448 if ((*i)->name() == name) {
2453 return shared_ptr<Route> ((Route*) 0);
2457 Session::route_by_id (PBD::ID id)
2459 shared_ptr<RouteList> r = routes.reader ();
2461 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2462 if ((*i)->id() == id) {
2467 return shared_ptr<Route> ((Route*) 0);
2471 Session::route_by_remote_id (uint32_t id)
2473 shared_ptr<RouteList> r = routes.reader ();
2475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2476 if ((*i)->remote_control_id() == id) {
2481 return shared_ptr<Route> ((Route*) 0);
2484 /** If either end of the session range location marker lies inside the current
2485 * session extent, move it to the corresponding session extent.
2488 Session::update_session_range_location_marker ()
2490 if (_state_of_the_state & Loading) {
2494 pair<nframes_t, nframes_t> const ext = get_extent ();
2496 if (_session_range_location == 0) {
2497 /* we don't have a session range yet; use this one (provided it is valid) */
2498 if (ext.first != max_frames) {
2499 add_session_range_location (ext.first, ext.second);
2502 /* update the existing session range */
2503 if (ext.first < _session_range_location->start()) {
2504 _session_range_location->set_start (ext.first);
2508 if (ext.second > _session_range_location->end()) {
2509 _session_range_location->set_end (ext.second);
2516 /** @return Extent of the session's contents; if the session is empty, the first value of
2517 * the pair will equal max_frames.
2519 pair<nframes_t, nframes_t>
2520 Session::get_extent () const
2522 pair<nframes_t, nframes_t> ext (max_frames, 0);
2524 boost::shared_ptr<RouteList> rl = routes.reader ();
2525 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2526 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2527 if (!tr || tr->destructive()) {
2528 // ignore tape tracks when getting extents
2532 pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
2533 if (e.first < ext.first) {
2534 ext.first = e.first;
2536 if (e.second > ext.second) {
2537 ext.second = e.second;
2544 /* Region management */
2546 boost::shared_ptr<Region>
2547 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2549 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2550 RegionFactory::RegionMap::const_iterator i;
2551 boost::shared_ptr<Region> region;
2553 Glib::Mutex::Lock lm (region_lock);
2555 for (i = regions.begin(); i != regions.end(); ++i) {
2559 if (region->whole_file()) {
2561 if (child->source_equivalent (region)) {
2567 return boost::shared_ptr<Region> ();
2571 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2573 set<boost::shared_ptr<Region> > relevant_regions;
2575 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2576 RegionFactory::get_regions_using_source (*s, relevant_regions);
2579 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2581 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2582 set<boost::shared_ptr<Region> >::iterator tmp;
2587 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2589 playlists->destroy_region (*r);
2590 RegionFactory::map_remove (*r);
2592 (*r)->drop_sources ();
2593 (*r)->drop_references ();
2595 cerr << "\tdone UC = " << (*r).use_count() << endl;
2597 relevant_regions.erase (r);
2602 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2605 Glib::Mutex::Lock ls (source_lock);
2606 /* remove from the main source list */
2607 sources.erase ((*s)->id());
2610 (*s)->mark_for_remove ();
2611 (*s)->drop_references ();
2620 Session::remove_last_capture ()
2622 list<boost::shared_ptr<Source> > srcs;
2624 boost::shared_ptr<RouteList> rl = routes.reader ();
2625 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2626 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2631 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2634 srcs.insert (srcs.end(), l.begin(), l.end());
2639 destroy_sources (srcs);
2641 save_state (_current_snapshot_name);
2646 /* Source Management */
2649 Session::add_source (boost::shared_ptr<Source> source)
2651 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2652 pair<SourceMap::iterator,bool> result;
2654 entry.first = source->id();
2655 entry.second = source;
2658 Glib::Mutex::Lock lm (source_lock);
2659 result = sources.insert (entry);
2662 if (result.second) {
2664 /* yay, new source */
2668 boost::shared_ptr<AudioFileSource> afs;
2670 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2671 if (Config->get_auto_analyse_audio()) {
2672 Analyser::queue_source_for_analysis (source, false);
2679 Session::remove_source (boost::weak_ptr<Source> src)
2681 SourceMap::iterator i;
2682 boost::shared_ptr<Source> source = src.lock();
2689 Glib::Mutex::Lock lm (source_lock);
2691 if ((i = sources.find (source->id())) != sources.end()) {
2692 cerr << "Removing source " << source->name() << endl;
2697 if (!_state_of_the_state & InCleanup) {
2699 /* save state so we don't end up with a session file
2700 referring to non-existent sources.
2703 save_state (_current_snapshot_name);
2707 boost::shared_ptr<Source>
2708 Session::source_by_id (const PBD::ID& id)
2710 Glib::Mutex::Lock lm (source_lock);
2711 SourceMap::iterator i;
2712 boost::shared_ptr<Source> source;
2714 if ((i = sources.find (id)) != sources.end()) {
2721 boost::shared_ptr<Source>
2722 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2724 Glib::Mutex::Lock lm (source_lock);
2726 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2727 boost::shared_ptr<AudioFileSource> afs
2728 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2730 if (afs && afs->path() == path && chn == afs->channel()) {
2734 return boost::shared_ptr<Source>();
2739 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2742 string old_basename = PBD::basename_nosuffix (oldname);
2743 string new_legalized = legalize_for_path (newname);
2745 /* note: we know (or assume) the old path is already valid */
2749 /* destructive file sources have a name of the form:
2751 /path/to/Tnnnn-NAME(%[LR])?.wav
2753 the task here is to replace NAME with the new name.
2758 string::size_type dash;
2760 dir = Glib::path_get_dirname (path);
2761 path = Glib::path_get_basename (path);
2763 /* '-' is not a legal character for the NAME part of the path */
2765 if ((dash = path.find_last_of ('-')) == string::npos) {
2769 prefix = path.substr (0, dash);
2773 path += new_legalized;
2774 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2776 path = Glib::build_filename (dir, path);
2780 /* non-destructive file sources have a name of the form:
2782 /path/to/NAME-nnnnn(%[LR])?.ext
2784 the task here is to replace NAME with the new name.
2789 string::size_type dash;
2790 string::size_type postfix;
2792 dir = Glib::path_get_dirname (path);
2793 path = Glib::path_get_basename (path);
2795 /* '-' is not a legal character for the NAME part of the path */
2797 if ((dash = path.find_last_of ('-')) == string::npos) {
2801 suffix = path.substr (dash+1);
2803 // Suffix is now everything after the dash. Now we need to eliminate
2804 // the nnnnn part, which is done by either finding a '%' or a '.'
2806 postfix = suffix.find_last_of ("%");
2807 if (postfix == string::npos) {
2808 postfix = suffix.find_last_of ('.');
2811 if (postfix != string::npos) {
2812 suffix = suffix.substr (postfix);
2814 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2818 const uint32_t limit = 10000;
2819 char buf[PATH_MAX+1];
2821 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2823 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2825 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2826 path = Glib::build_filename (dir, buf);
2834 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2843 /** Return the full path (in some session directory) for a new within-session source.
2844 * \a name must be a session-unique name that does not contain slashes
2845 * (e.g. as returned by new_*_source_name)
2848 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2850 assert(name.find("/") == string::npos);
2852 SessionDirectory sdir(get_best_session_directory_for_new_source());
2855 if (type == DataType::AUDIO) {
2856 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2857 } else if (type == DataType::MIDI) {
2858 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2860 error << "Unknown source type, unable to create file path" << endmsg;
2865 return p.to_string();
2869 Session::peak_path (Glib::ustring base) const
2871 sys::path peakfile_path(_session_dir->peak_path());
2872 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2873 return peakfile_path.to_string();
2876 /** Return a unique name based on \a base for a new internal audio source */
2878 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2881 char buf[PATH_MAX+1];
2882 const uint32_t limit = 10000;
2884 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2887 legalized = legalize_for_path (base);
2889 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2890 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2892 vector<space_and_path>::iterator i;
2893 uint32_t existing = 0;
2895 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2900 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2901 cnt, legalized.c_str(), ext.c_str());
2902 } else if (nchan == 2) {
2904 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2905 cnt, legalized.c_str(), ext.c_str());
2907 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2908 cnt, legalized.c_str(), ext.c_str());
2910 } else if (nchan < 26) {
2911 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2912 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2914 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2915 cnt, legalized.c_str(), ext.c_str());
2921 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2922 } else if (nchan == 2) {
2924 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2926 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2928 } else if (nchan < 26) {
2929 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2931 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2935 SessionDirectory sdir((*i).path);
2937 string spath = sdir.sound_path().to_string();
2938 string spath_stubs = sdir.sound_stub_path().to_string();
2940 /* note that we search *without* the extension so that
2941 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2942 in the event that this new name is required for
2943 a file format change.
2946 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2947 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
2953 if (existing == 0) {
2958 error << string_compose(
2959 _("There are already %1 recordings for %2, which I consider too many."),
2960 limit, base) << endmsg;
2962 throw failed_constructor();
2966 return Glib::path_get_basename (buf);
2969 /** Create a new within-session audio source */
2970 boost::shared_ptr<AudioFileSource>
2971 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
2973 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2974 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
2976 return boost::dynamic_pointer_cast<AudioFileSource> (
2977 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
2980 /** Return a unique name based on \a base for a new internal MIDI source */
2982 Session::new_midi_source_name (const string& base)
2985 char buf[PATH_MAX+1];
2986 const uint32_t limit = 10000;
2990 legalized = legalize_for_path (base);
2992 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2993 for (cnt = 1; cnt <= limit; ++cnt) {
2995 vector<space_and_path>::iterator i;
2996 uint32_t existing = 0;
2998 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3000 SessionDirectory sdir((*i).path);
3002 sys::path p = sdir.midi_path();
3005 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3007 if (sys::exists (buf)) {
3012 if (existing == 0) {
3017 error << string_compose(
3018 _("There are already %1 recordings for %2, which I consider too many."),
3019 limit, base) << endmsg;
3021 throw failed_constructor();
3025 return Glib::path_get_basename(buf);
3029 /** Create a new within-session MIDI source */
3030 boost::shared_ptr<MidiSource>
3031 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3033 /* try to use the existing write source for the track, to keep numbering sane
3037 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3041 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3044 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3045 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3049 const string name = new_midi_source_name (n);
3050 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3052 return boost::dynamic_pointer_cast<SMFSource> (
3053 SourceFactory::createWritable (
3054 DataType::MIDI, *this, path, false, frame_rate()));
3059 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3061 if (playlist->hidden()) {
3065 playlists->add (playlist);
3068 playlist->release();
3075 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3077 if (_state_of_the_state & Deletion) {
3081 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3087 playlists->remove (playlist);
3093 Session::set_audition (boost::shared_ptr<Region> r)
3095 pending_audition_region = r;
3096 add_post_transport_work (PostTransportAudition);
3097 _butler->schedule_transport_work ();
3101 Session::audition_playlist ()
3103 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3104 ev->region.reset ();
3109 Session::non_realtime_set_audition ()
3111 if (!pending_audition_region) {
3112 auditioner->audition_current_playlist ();
3114 auditioner->audition_region (pending_audition_region);
3115 pending_audition_region.reset ();
3117 AuditionActive (true); /* EMIT SIGNAL */
3121 Session::audition_region (boost::shared_ptr<Region> r)
3123 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3129 Session::cancel_audition ()
3131 if (auditioner->auditioning()) {
3132 auditioner->cancel_audition ();
3133 AuditionActive (false); /* EMIT SIGNAL */
3138 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3140 if (a->is_monitor()) {
3143 if (b->is_monitor()) {
3146 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3150 Session::is_auditioning () const
3152 /* can be called before we have an auditioner object */
3154 return auditioner->auditioning();
3161 Session::graph_reordered ()
3163 /* don't do this stuff if we are setting up connections
3164 from a set_state() call or creating new tracks. Ditto for deletion.
3167 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3171 /* every track/bus asked for this to be handled but it was deferred because
3172 we were connecting. do it now.
3175 request_input_change_handling ();
3179 /* force all diskstreams to update their capture offset values to
3180 reflect any changes in latencies within the graph.
3183 boost::shared_ptr<RouteList> rl = routes.reader ();
3184 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3185 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3187 tr->set_capture_offset ();
3193 Session::available_capture_duration ()
3195 float sample_bytes_on_disk = 4.0; // keep gcc happy
3197 switch (config.get_native_file_data_format()) {
3199 sample_bytes_on_disk = 4.0;
3203 sample_bytes_on_disk = 3.0;
3207 sample_bytes_on_disk = 2.0;
3211 /* impossible, but keep some gcc versions happy */
3212 fatal << string_compose (_("programming error: %1"),
3213 X_("illegal native file data format"))
3218 double scale = 4096.0 / sample_bytes_on_disk;
3220 if (_total_free_4k_blocks * scale > (double) max_frames) {
3224 return (nframes_t) floor (_total_free_4k_blocks * scale);
3228 Session::add_bundle (shared_ptr<Bundle> bundle)
3231 RCUWriter<BundleList> writer (_bundles);
3232 boost::shared_ptr<BundleList> b = writer.get_copy ();
3233 b->push_back (bundle);
3236 BundleAdded (bundle); /* EMIT SIGNAL */
3242 Session::remove_bundle (shared_ptr<Bundle> bundle)
3244 bool removed = false;
3247 RCUWriter<BundleList> writer (_bundles);
3248 boost::shared_ptr<BundleList> b = writer.get_copy ();
3249 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3251 if (i != b->end()) {
3258 BundleRemoved (bundle); /* EMIT SIGNAL */
3265 Session::bundle_by_name (string name) const
3267 boost::shared_ptr<BundleList> b = _bundles.reader ();
3269 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3270 if ((*i)->name() == name) {
3275 return boost::shared_ptr<Bundle> ();
3279 Session::tempo_map_changed (const PropertyChange&)
3283 playlists->update_after_tempo_map_change ();
3285 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3291 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3293 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3294 (*i)->recompute_frames_from_bbt ();
3298 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3299 * the given count with the current block size.
3302 Session::ensure_buffers (ChanCount howmany)
3304 BufferManager::ensure_buffers (howmany);
3308 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3310 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3311 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3316 Session::next_insert_id ()
3318 /* this doesn't really loop forever. just think about it */
3321 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3322 if (!insert_bitset[n]) {
3323 insert_bitset[n] = true;
3329 /* none available, so resize and try again */
3331 insert_bitset.resize (insert_bitset.size() + 16, false);
3336 Session::next_send_id ()
3338 /* this doesn't really loop forever. just think about it */
3341 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3342 if (!send_bitset[n]) {
3343 send_bitset[n] = true;
3349 /* none available, so resize and try again */
3351 send_bitset.resize (send_bitset.size() + 16, false);
3356 Session::next_return_id ()
3358 /* this doesn't really loop forever. just think about it */
3361 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3362 if (!return_bitset[n]) {
3363 return_bitset[n] = true;
3369 /* none available, so resize and try again */
3371 return_bitset.resize (return_bitset.size() + 16, false);
3376 Session::mark_send_id (uint32_t id)
3378 if (id >= send_bitset.size()) {
3379 send_bitset.resize (id+16, false);
3381 if (send_bitset[id]) {
3382 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3384 send_bitset[id] = true;
3388 Session::mark_return_id (uint32_t id)
3390 if (id >= return_bitset.size()) {
3391 return_bitset.resize (id+16, false);
3393 if (return_bitset[id]) {
3394 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3396 return_bitset[id] = true;
3400 Session::mark_insert_id (uint32_t id)
3402 if (id >= insert_bitset.size()) {
3403 insert_bitset.resize (id+16, false);
3405 if (insert_bitset[id]) {
3406 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3408 insert_bitset[id] = true;
3412 Session::unmark_send_id (uint32_t id)
3414 if (id < send_bitset.size()) {
3415 send_bitset[id] = false;
3420 Session::unmark_return_id (uint32_t id)
3422 if (id < return_bitset.size()) {
3423 return_bitset[id] = false;
3428 Session::unmark_insert_id (uint32_t id)
3430 if (id < insert_bitset.size()) {
3431 insert_bitset[id] = false;
3436 /* Named Selection management */
3438 boost::shared_ptr<NamedSelection>
3439 Session::named_selection_by_name (string name)
3441 Glib::Mutex::Lock lm (named_selection_lock);
3442 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3443 if ((*i)->name == name) {
3447 return boost::shared_ptr<NamedSelection>();
3451 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3454 Glib::Mutex::Lock lm (named_selection_lock);
3455 named_selections.insert (named_selections.begin(), named_selection);
3460 NamedSelectionAdded (); /* EMIT SIGNAL */
3464 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3466 bool removed = false;
3469 Glib::Mutex::Lock lm (named_selection_lock);
3471 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3473 if (i != named_selections.end()) {
3474 named_selections.erase (i);
3481 NamedSelectionRemoved (); /* EMIT SIGNAL */
3486 Session::reset_native_file_format ()
3488 boost::shared_ptr<RouteList> rl = routes.reader ();
3489 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3490 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3492 /* don't save state as we do this, there's no point
3495 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3496 tr->reset_write_sources (false);
3497 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3503 Session::route_name_unique (string n) const
3505 shared_ptr<RouteList> r = routes.reader ();
3507 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3508 if ((*i)->name() == n) {
3517 Session::route_name_internal (string n) const
3519 if (auditioner && auditioner->name() == n) {
3523 if (_click_io && _click_io->name() == n) {
3531 Session::freeze_all (InterThreadInfo& itt)
3533 shared_ptr<RouteList> r = routes.reader ();
3535 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3537 boost::shared_ptr<Track> t;
3539 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3540 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3550 boost::shared_ptr<Region>
3551 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3552 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3553 InterThreadInfo& itt, bool enable_processing)
3555 boost::shared_ptr<Region> result;
3556 boost::shared_ptr<Playlist> playlist;
3557 boost::shared_ptr<AudioFileSource> fsource;
3559 char buf[PATH_MAX+1];
3560 ChanCount nchans(track.n_channels());
3561 framepos_t position;
3562 framecnt_t this_chunk;
3565 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3566 const string sound_dir = sdir.sound_path().to_string();
3567 framepos_t len = end - start;
3568 bool need_block_size_reset = false;
3572 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3573 end, start) << endmsg;
3577 const framecnt_t chunk_size = (256 * 1024)/4;
3579 // block all process callback handling
3581 block_processing ();
3583 /* call tree *MUST* hold route_lock */
3585 if ((playlist = track.playlist()) == 0) {
3589 /* external redirects will be a problem */
3591 if (track.has_external_redirects()) {
3595 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3597 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3599 for (x = 0; x < 99999; ++x) {
3600 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());
3601 if (access (buf, F_OK) != 0) {
3607 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3612 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3613 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3616 catch (failed_constructor& err) {
3617 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3621 srcs.push_back (fsource);
3624 /* tell redirects that care that we are about to use a much larger blocksize */
3626 need_block_size_reset = true;
3627 track.set_block_size (chunk_size);
3629 /* XXX need to flush all redirects */
3634 /* create a set of reasonably-sized buffers */
3635 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3636 buffers.set_count(nchans);
3638 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3639 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3641 afs->prepare_for_peakfile_writes ();
3644 while (to_do && !itt.cancel) {
3646 this_chunk = min (to_do, chunk_size);
3648 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3653 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3654 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3657 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3663 start += this_chunk;
3664 to_do -= this_chunk;
3666 itt.progress = (float) (1.0 - ((double) to_do / len));
3675 xnow = localtime (&now);
3677 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3678 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3681 afs->update_header (position, *xnow, now);
3682 afs->flush_header ();
3686 /* construct a region to represent the bounced material */
3690 plist.add (Properties::start, 0);
3691 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3692 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3694 result = RegionFactory::create (srcs, plist);
3700 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3701 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3704 afs->mark_for_remove ();
3707 (*src)->drop_references ();
3711 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3712 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3715 afs->done_with_peakfile_writes ();
3720 if (need_block_size_reset) {
3721 track.set_block_size (get_block_size());
3724 unblock_processing ();
3730 Session::gain_automation_buffer() const
3732 return ProcessThread::gain_automation_buffer ();
3736 Session::pan_automation_buffer() const
3738 return ProcessThread::pan_automation_buffer ();
3742 Session::get_silent_buffers (ChanCount count)
3744 return ProcessThread::get_silent_buffers (count);
3746 assert(_silent_buffers->available() >= count);
3747 _silent_buffers->set_count(count);
3749 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3750 for (size_t i= 0; i < count.get(*t); ++i) {
3751 _silent_buffers->get(*t, i).clear();
3755 return *_silent_buffers;
3760 Session::get_scratch_buffers (ChanCount count)
3762 return ProcessThread::get_scratch_buffers (count);
3764 if (count != ChanCount::ZERO) {
3765 assert(_scratch_buffers->available() >= count);
3766 _scratch_buffers->set_count(count);
3768 _scratch_buffers->set_count (_scratch_buffers->available());
3771 return *_scratch_buffers;
3776 Session::get_mix_buffers (ChanCount count)
3778 return ProcessThread::get_mix_buffers (count);
3780 assert(_mix_buffers->available() >= count);
3781 _mix_buffers->set_count(count);
3782 return *_mix_buffers;
3787 Session::ntracks () const
3790 shared_ptr<RouteList> r = routes.reader ();
3792 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3793 if (boost::dynamic_pointer_cast<Track> (*i)) {
3802 Session::nbusses () const
3805 shared_ptr<RouteList> r = routes.reader ();
3807 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3808 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3817 Session::add_automation_list(AutomationList *al)
3819 automation_lists[al->id()] = al;
3823 Session::sync_order_keys (std::string const & base)
3825 if (deletion_in_progress()) {
3829 if (!Config->get_sync_all_route_ordering()) {
3830 /* leave order keys as they are */
3834 boost::shared_ptr<RouteList> r = routes.reader ();
3836 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3837 (*i)->sync_order_keys (base);
3840 Route::SyncOrderKeys (base); // EMIT SIGNAL
3842 /* this might not do anything */
3844 set_remote_control_ids ();
3847 /** @return true if there is at least one record-enabled track, otherwise false */
3849 Session::have_rec_enabled_track () const
3851 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3854 /** Update the state of our rec-enabled tracks flag */
3856 Session::update_have_rec_enabled_track ()
3858 boost::shared_ptr<RouteList> rl = routes.reader ();
3859 RouteList::iterator i = rl->begin();
3860 while (i != rl->end ()) {
3862 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3863 if (tr && tr->record_enabled ()) {
3870 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3872 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3874 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3875 RecordStateChanged (); /* EMIT SIGNAL */
3880 Session::listen_position_changed ()
3884 switch (Config->get_listen_position()) {
3885 case AfterFaderListen:
3889 case PreFaderListen:
3894 boost::shared_ptr<RouteList> r = routes.reader ();
3896 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3897 (*i)->put_monitor_send_at (p);
3902 Session::solo_control_mode_changed ()
3904 /* cancel all solo or all listen when solo control mode changes */
3907 set_solo (get_routes(), false);
3908 } else if (listening()) {
3909 set_listen (get_routes(), false);
3913 /** Called when anything about any of our route groups changes (membership, state etc.) */
3915 Session::route_group_changed ()
3917 RouteGroupChanged (); /* EMIT SIGNAL */
3921 Session::get_available_sync_options () const
3923 vector<SyncSource> ret;
3925 ret.push_back (JACK);
3926 ret.push_back (MTC);
3927 ret.push_back (MIDIClock);
3932 boost::shared_ptr<RouteList>
3933 Session::get_routes_with_regions_at (nframes64_t const p) const
3935 shared_ptr<RouteList> r = routes.reader ();
3936 shared_ptr<RouteList> rl (new RouteList);
3938 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3939 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3944 boost::shared_ptr<Playlist> pl = tr->playlist ();
3949 if (pl->has_region_at (p)) {
3958 Session::goto_end ()
3960 if (_session_range_location) {
3961 request_locate (_session_range_location->end(), false);
3963 request_locate (0, false);
3968 Session::goto_start ()
3970 if (_session_range_location) {
3971 request_locate (_session_range_location->start(), false);
3973 request_locate (0, false);
3978 Session::current_start_frame () const
3980 return _session_range_location ? _session_range_location->start() : 0;
3984 Session::current_end_frame () const
3986 return _session_range_location ? _session_range_location->end() : 0;
3990 Session::add_session_range_location (nframes_t start, nframes_t end)
3992 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
3993 _locations->add (_session_range_location);
3996 /** Called when one of our routes' order keys has changed */
3998 Session::route_order_key_changed ()
4000 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4004 Session::step_edit_status_change (bool yn)
4010 send = (_step_editors == 0);
4015 send = (_step_editors == 1);
4018 if (_step_editors > 0) {
4024 StepEditStatusChange (val);