2 Copyright (C) 1999-2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/thread.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/error.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
49 #include "ardour/amp.h"
50 #include "ardour/analyser.h"
51 #include "ardour/audio_buffer.h"
52 #include "ardour/audio_diskstream.h"
53 #include "ardour/audio_port.h"
54 #include "ardour/audio_track.h"
55 #include "ardour/audioengine.h"
56 #include "ardour/audiofilesource.h"
57 #include "ardour/audioplaylist.h"
58 #include "ardour/audioregion.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/buffer_manager.h"
61 #include "ardour/buffer_set.h"
62 #include "ardour/bundle.h"
63 #include "ardour/butler.h"
64 #include "ardour/click.h"
65 #include "ardour/configuration.h"
66 #include "ardour/crossfade.h"
67 #include "ardour/cycle_timer.h"
68 #include "ardour/data_type.h"
69 #include "ardour/debug.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/internal_send.h"
72 #include "ardour/io_processor.h"
73 #include "ardour/midi_diskstream.h"
74 #include "ardour/midi_playlist.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/midi_track.h"
77 #include "ardour/midi_ui.h"
78 #include "ardour/named_selection.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/playlist.h"
81 #include "ardour/plugin_insert.h"
82 #include "ardour/port_insert.h"
83 #include "ardour/processor.h"
84 #include "ardour/rc_configuration.h"
85 #include "ardour/recent_sessions.h"
86 #include "ardour/region_factory.h"
87 #include "ardour/return.h"
88 #include "ardour/route_group.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_metadata.h"
94 #include "ardour/session_playlists.h"
95 #include "ardour/slave.h"
96 #include "ardour/smf_source.h"
97 #include "ardour/source_factory.h"
98 #include "ardour/tape_file_matcher.h"
99 #include "ardour/tempo.h"
100 #include "ardour/utils.h"
101 #include "ardour/graph.h"
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;
121 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
123 PBD::Signal0<void> Session::TimecodeOffsetChanged;
124 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
125 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
126 PBD::Signal0<void> Session::AutoBindingOn;
127 PBD::Signal0<void> Session::AutoBindingOff;
128 PBD::Signal2<void,std::string, std::string> Session::Exported;
129 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
130 PBD::Signal0<void> Session::Quit;
132 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
133 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
135 Session::Session (AudioEngine &eng,
136 const string& fullpath,
137 const string& snapshot_name,
138 BusProfile* bus_profile,
142 , _target_transport_speed (0.0)
143 , _requested_return_frame (-1)
144 , _session_dir (new SessionDirectory(fullpath))
146 , _state_of_the_state (Clean)
147 , _butler (new Butler (*this))
148 , _post_transport_work (0)
149 , _send_timecode_update (false)
150 , _all_route_group (new RouteGroup (*this, "all"))
151 , route_graph (new Graph(*this))
152 , routes (new RouteList)
153 , _total_free_4k_blocks (0)
154 , _bundles (new BundleList)
155 , _bundle_xml_node (0)
156 , _click_io ((IO*) 0)
158 , click_emphasis_data (0)
160 , _metadata (new SessionMetadata())
161 , _have_rec_enabled_track (false)
162 , _suspend_timecode_transmission (0)
164 _locations = new Locations (*this);
166 playlists.reset (new SessionPlaylists);
168 _all_route_group->set_active (true, this);
170 interpolation.add_channel_to (0, 0);
172 if (!eng.connected()) {
173 throw failed_constructor();
176 n_physical_outputs = _engine.n_physical_outputs ();
177 n_physical_inputs = _engine.n_physical_inputs ();
179 first_stage_init (fullpath, snapshot_name);
181 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
184 if (create (mix_template, bus_profile)) {
186 throw failed_constructor ();
190 if (second_stage_init ()) {
192 throw failed_constructor ();
195 store_recent_sessions(_name, _path);
197 bool was_dirty = dirty();
199 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
201 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
202 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
205 DirtyChanged (); /* EMIT SIGNAL */
208 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
209 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
222 vector<void*> debug_pointers;
224 /* if we got to here, leaving pending capture state around
228 remove_pending_capture_state ();
230 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
232 _engine.remove_session ();
234 /* clear history so that no references to objects are held any more */
238 /* clear state tree so that no references to objects are held any more */
242 /* remove all stubfiles that might still be lurking */
244 cleanup_stubfiles ();
246 /* reset dynamic state version back to default */
248 Stateful::loading_state_version = 0;
250 _butler->drop_references ();
252 delete midi_control_ui;
253 delete _all_route_group;
255 if (click_data != default_click) {
256 delete [] click_data;
259 if (click_emphasis_data != default_click_emphasis) {
260 delete [] click_emphasis_data;
265 /* clear out any pending dead wood from RCU managed objects */
270 AudioDiskstream::free_working_buffers();
272 /* tell everyone who is still standing that we're about to die */
275 /* tell everyone to drop references and delete objects as we go */
277 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
278 named_selections.clear ();
280 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
281 RegionFactory::delete_all_regions ();
283 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
285 /* reset these three references to special routes before we do the usual route delete thing */
288 _master_out.reset ();
289 _monitor_out.reset ();
292 RCUWriter<RouteList> writer (routes);
293 boost::shared_ptr<RouteList> r = writer.get_copy ();
295 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
296 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
297 (*i)->drop_references ();
301 /* writer goes out of scope and updates master */
305 boost::shared_ptr<RouteList> r = routes.reader ();
307 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
308 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
309 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
310 i->second->drop_references ();
315 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
316 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
321 Crossfade::set_buffer_size (0);
323 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
326 boost_debug_list_ptrs ();
330 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
334 Session::set_worst_io_latencies ()
336 _worst_output_latency = 0;
337 _worst_input_latency = 0;
339 if (!_engine.connected()) {
343 boost::shared_ptr<RouteList> r = routes.reader ();
345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
346 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
347 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
352 Session::when_engine_running ()
354 string first_physical_output;
356 BootMessage (_("Set block size and sample rate"));
358 set_block_size (_engine.frames_per_cycle());
359 set_frame_rate (_engine.frame_rate());
361 BootMessage (_("Using configuration"));
363 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
364 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
366 Config->map_parameters (ff);
367 config.map_parameters (ft);
369 /* every time we reconnect, recompute worst case output latencies */
371 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
373 if (synced_to_jack()) {
374 _engine.transport_stop ();
377 if (config.get_jack_time_master()) {
378 _engine.transport_locate (_transport_frame);
386 _click_io.reset (new ClickIO (*this, "click"));
388 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
390 /* existing state for Click */
393 if (Stateful::loading_state_version < 3000) {
394 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
396 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
401 _clicking = Config->get_clicking ();
405 error << _("could not setup Click I/O") << endmsg;
412 /* default state for Click: dual-mono to first 2 physical outputs */
415 _engine.get_physical_outputs (DataType::AUDIO, outs);
417 for (uint32_t physport = 0; physport < 2; ++physport) {
418 if (outs.size() > physport) {
419 if (_click_io->add_port (outs[physport], this)) {
420 // relax, even though its an error
425 if (_click_io->n_ports () > ChanCount::ZERO) {
426 _clicking = Config->get_clicking ();
431 catch (failed_constructor& err) {
432 error << _("cannot setup Click I/O") << endmsg;
435 BootMessage (_("Compute I/O Latencies"));
437 set_worst_io_latencies ();
440 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
443 BootMessage (_("Set up standard connections"));
445 vector<string> inputs[DataType::num_types];
446 vector<string> outputs[DataType::num_types];
447 for (uint32_t i = 0; i < DataType::num_types; ++i) {
448 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
449 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
452 /* Create a set of Bundle objects that map
453 to the physical I/O currently available. We create both
454 mono and stereo bundles, so that the common cases of mono
455 and stereo tracks get bundles to put in their mixer strip
456 in / out menus. There may be a nicer way of achieving that;
457 it doesn't really scale that well to higher channel counts
460 /* mono output bundles */
462 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
464 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
466 shared_ptr<Bundle> c (new Bundle (buf, true));
467 c->add_channel (_("mono"), DataType::AUDIO);
468 c->set_port (0, outputs[DataType::AUDIO][np]);
473 /* stereo output bundles */
475 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
476 if (np + 1 < outputs[DataType::AUDIO].size()) {
478 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
479 shared_ptr<Bundle> c (new Bundle (buf, true));
480 c->add_channel (_("L"), DataType::AUDIO);
481 c->set_port (0, outputs[DataType::AUDIO][np]);
482 c->add_channel (_("R"), DataType::AUDIO);
483 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
489 /* mono input bundles */
491 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
493 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
495 shared_ptr<Bundle> c (new Bundle (buf, false));
496 c->add_channel (_("mono"), DataType::AUDIO);
497 c->set_port (0, inputs[DataType::AUDIO][np]);
502 /* stereo input bundles */
504 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
505 if (np + 1 < inputs[DataType::AUDIO].size()) {
507 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
509 shared_ptr<Bundle> c (new Bundle (buf, false));
510 c->add_channel (_("L"), DataType::AUDIO);
511 c->set_port (0, inputs[DataType::AUDIO][np]);
512 c->add_channel (_("R"), DataType::AUDIO);
513 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
519 /* MIDI input bundles */
521 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
522 string n = inputs[DataType::MIDI][np];
523 boost::erase_first (n, X_("alsa_pcm:"));
525 shared_ptr<Bundle> c (new Bundle (n, false));
526 c->add_channel ("", DataType::MIDI);
527 c->set_port (0, inputs[DataType::MIDI][np]);
531 /* MIDI output bundles */
533 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
534 string n = outputs[DataType::MIDI][np];
535 boost::erase_first (n, X_("alsa_pcm:"));
537 shared_ptr<Bundle> c (new Bundle (n, true));
538 c->add_channel ("", DataType::MIDI);
539 c->set_port (0, outputs[DataType::MIDI][np]);
543 BootMessage (_("Setup signal flow and plugins"));
547 if (_is_new && !no_auto_connect()) {
549 /* don't connect the master bus outputs if there is a monitor bus */
551 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
553 /* if requested auto-connect the outputs to the first N physical ports.
556 uint32_t limit = _master_out->n_outputs().n_total();
558 for (uint32_t n = 0; n < limit; ++n) {
559 Port* p = _master_out->output()->nth (n);
561 if (outputs[p->type()].size() > n) {
562 connect_to = outputs[p->type()][n];
565 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
566 if (_master_out->output()->connect (p, connect_to, this)) {
567 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
577 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
578 are undefined, at best.
581 /* control out listens to master bus (but ignores it
582 under some conditions)
585 uint32_t limit = _monitor_out->n_inputs().n_audio();
588 for (uint32_t n = 0; n < limit; ++n) {
589 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
590 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
593 string connect_to = o->name();
594 if (_monitor_out->input()->connect (p, connect_to, this)) {
595 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
603 /* if control out is not connected, connect control out to physical outs
606 if (!_monitor_out->output()->connected ()) {
608 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
610 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
613 _monitor_out->output()->connect_ports_to_bundle (b, this);
615 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
616 Config->get_monitor_bus_preferred_bundle())
622 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
623 uint32_t mod = n_physical_outputs.get (*t);
624 uint32_t limit = _monitor_out->n_outputs().get(*t);
626 for (uint32_t n = 0; n < limit; ++n) {
628 Port* p = _monitor_out->output()->ports().port(*t, n);
630 if (outputs[*t].size() > (n % mod)) {
631 connect_to = outputs[*t][n % mod];
634 if (!connect_to.empty()) {
635 if (_monitor_out->output()->connect (p, connect_to, this)) {
636 error << string_compose (
637 _("cannot connect control output %1 to %2"),
650 /* catch up on send+insert cnts */
652 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
654 /* hook us up to the engine */
656 BootMessage (_("Connect to engine"));
658 _engine.set_session (this);
662 Session::hookup_io ()
664 /* stop graph reordering notifications from
665 causing resorts, etc.
668 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
673 /* we delay creating the auditioner till now because
674 it makes its own connections to ports.
678 Auditioner* a = new Auditioner (*this);
681 throw failed_constructor();
683 a->use_new_diskstream ();
684 auditioner.reset (a);
687 catch (failed_constructor& err) {
688 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
692 /* load bundles, which we may have postponed earlier on */
693 if (_bundle_xml_node) {
694 load_bundles (*_bundle_xml_node);
695 delete _bundle_xml_node;
698 /* Tell all IO objects to connect themselves together */
700 IO::enable_connecting ();
701 MIDI::Port::MakeConnections ();
703 /* Now reset all panners */
705 Delivery::reset_panners ();
707 /* Connect tracks to monitor/listen bus if there is one.
708 Note that in an existing session, the internal sends will
709 already exist, but we want the routes to notice that
710 they connect to the control out specifically.
714 boost::shared_ptr<RouteList> r = routes.reader ();
715 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
717 if ((*x)->is_monitor()) {
721 } else if ((*x)->is_master()) {
727 (*x)->listen_via (_monitor_out,
728 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
734 /* Anyone who cares about input state, wake up and do something */
736 IOConnectionsComplete (); /* EMIT SIGNAL */
738 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
740 /* now handle the whole enchilada as if it was one
746 /* update the full solo state, which can't be
747 correctly determined on a per-route basis, but
748 needs the global overview that only the session
752 update_route_solo_state ();
756 Session::playlist_length_changed ()
758 update_session_range_location_marker ();
762 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
764 boost::shared_ptr<Track> track = wp.lock ();
769 boost::shared_ptr<Playlist> playlist;
771 if ((playlist = track->playlist()) != 0) {
772 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
775 update_session_range_location_marker ();
779 Session::record_enabling_legal () const
781 /* this used to be in here, but survey says.... we don't need to restrict it */
782 // if (record_status() == Recording) {
786 if (Config->get_all_safe()) {
793 Session::reset_input_monitor_state ()
795 if (transport_rolling()) {
797 boost::shared_ptr<RouteList> rl = routes.reader ();
798 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
799 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
800 if (tr && tr->record_enabled ()) {
801 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
802 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
808 boost::shared_ptr<RouteList> rl = routes.reader ();
809 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
810 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
811 if (tr && tr->record_enabled ()) {
812 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
813 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
820 Session::auto_punch_start_changed (Location* location)
822 replace_event (SessionEvent::PunchIn, location->start());
824 if (get_record_enabled() && config.get_punch_in()) {
825 /* capture start has been changed, so save new pending state */
826 save_state ("", true);
831 Session::auto_punch_end_changed (Location* location)
833 nframes_t when_to_stop = location->end();
834 // when_to_stop += _worst_output_latency + _worst_input_latency;
835 replace_event (SessionEvent::PunchOut, when_to_stop);
839 Session::auto_punch_changed (Location* location)
841 nframes_t when_to_stop = location->end();
843 replace_event (SessionEvent::PunchIn, location->start());
844 //when_to_stop += _worst_output_latency + _worst_input_latency;
845 replace_event (SessionEvent::PunchOut, when_to_stop);
849 Session::auto_loop_changed (Location* location)
851 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
853 if (transport_rolling() && play_loop) {
856 // if (_transport_frame > location->end()) {
858 if (_transport_frame < location->start() || _transport_frame > location->end()) {
859 // relocate to beginning of loop
860 clear_events (SessionEvent::LocateRoll);
862 request_locate (location->start(), true);
865 else if (Config->get_seamless_loop() && !loop_changing) {
867 // schedule a locate-roll to refill the diskstreams at the
869 loop_changing = true;
871 if (location->end() > last_loopend) {
872 clear_events (SessionEvent::LocateRoll);
873 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
880 last_loopend = location->end();
884 Session::set_auto_punch_location (Location* location)
888 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
889 punch_connections.drop_connections();
890 existing->set_auto_punch (false, this);
891 remove_event (existing->start(), SessionEvent::PunchIn);
892 clear_events (SessionEvent::PunchOut);
893 auto_punch_location_changed (0);
902 if (location->end() <= location->start()) {
903 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
907 punch_connections.drop_connections ();
909 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
910 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
911 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
913 location->set_auto_punch (true, this);
915 auto_punch_changed (location);
917 auto_punch_location_changed (location);
921 Session::set_auto_loop_location (Location* location)
925 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
926 loop_connections.drop_connections ();
927 existing->set_auto_loop (false, this);
928 remove_event (existing->end(), SessionEvent::AutoLoop);
929 auto_loop_location_changed (0);
938 if (location->end() <= location->start()) {
939 error << _("Session: you can't use a mark for auto loop") << endmsg;
943 last_loopend = location->end();
945 loop_connections.drop_connections ();
947 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
948 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
949 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
951 location->set_auto_loop (true, this);
953 /* take care of our stuff first */
955 auto_loop_changed (location);
957 /* now tell everyone else */
959 auto_loop_location_changed (location);
963 Session::locations_added (Location *)
969 Session::locations_changed ()
971 _locations->apply (*this, &Session::handle_locations_changed);
975 Session::handle_locations_changed (Locations::LocationList& locations)
977 Locations::LocationList::iterator i;
979 bool set_loop = false;
980 bool set_punch = false;
982 for (i = locations.begin(); i != locations.end(); ++i) {
986 if (location->is_auto_punch()) {
987 set_auto_punch_location (location);
990 if (location->is_auto_loop()) {
991 set_auto_loop_location (location);
995 if (location->is_session_range()) {
996 _session_range_location = location;
1001 set_auto_loop_location (0);
1004 set_auto_punch_location (0);
1011 Session::enable_record ()
1014 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1016 if (rs == Recording) {
1020 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1022 _last_record_location = _transport_frame;
1023 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1025 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1027 boost::shared_ptr<RouteList> rl = routes.reader ();
1028 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1029 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1030 if (tr && tr->record_enabled ()) {
1031 tr->monitor_input (true);
1036 RecordStateChanged ();
1043 Session::disable_record (bool rt_context, bool force)
1047 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1049 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1050 g_atomic_int_set (&_record_status, Disabled);
1051 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1053 if (rs == Recording) {
1054 g_atomic_int_set (&_record_status, Enabled);
1058 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1060 boost::shared_ptr<RouteList> rl = routes.reader ();
1061 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1062 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1063 if (tr && tr->record_enabled ()) {
1064 tr->monitor_input (false);
1069 RecordStateChanged (); /* emit signal */
1072 remove_pending_capture_state ();
1078 Session::step_back_from_record ()
1080 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1082 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1083 boost::shared_ptr<RouteList> rl = routes.reader ();
1084 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1085 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1086 if (tr && tr->record_enabled ()) {
1087 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1088 tr->monitor_input (false);
1096 Session::maybe_enable_record ()
1098 if (_step_editors > 0) {
1102 g_atomic_int_set (&_record_status, Enabled);
1104 /* This function is currently called from somewhere other than an RT thread.
1105 This save_state() call therefore doesn't impact anything. Doing it here
1106 means that we save pending state of which sources the next record will use,
1107 which gives us some chance of recovering from a crash during the record.
1110 save_state ("", true);
1112 if (_transport_speed) {
1113 if (!config.get_punch_in()) {
1117 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1118 RecordStateChanged (); /* EMIT SIGNAL */
1125 Session::audible_frame () const
1131 /* the first of these two possible settings for "offset"
1132 mean that the audible frame is stationary until
1133 audio emerges from the latency compensation
1136 the second means that the audible frame is stationary
1137 until audio would emerge from a physical port
1138 in the absence of any plugin latency compensation
1141 offset = _worst_output_latency;
1143 if (offset > current_block_size) {
1144 offset -= current_block_size;
1146 /* XXX is this correct? if we have no external
1147 physical connections and everything is internal
1148 then surely this is zero? still, how
1149 likely is that anyway?
1151 offset = current_block_size;
1154 if (synced_to_jack()) {
1155 tf = _engine.transport_frame();
1157 tf = _transport_frame;
1162 if (!non_realtime_work_pending()) {
1166 /* Check to see if we have passed the first guaranteed
1167 audible frame past our last start position. if not,
1168 return that last start point because in terms
1169 of audible frames, we have not moved yet.
1171 `Start position' in this context means the time we last
1172 either started or changed transport direction.
1175 if (_transport_speed > 0.0f) {
1177 if (!play_loop || !have_looped) {
1178 if (tf < _last_roll_or_reversal_location + offset) {
1179 return _last_roll_or_reversal_location;
1187 } else if (_transport_speed < 0.0f) {
1189 /* XXX wot? no backward looping? */
1191 if (tf > _last_roll_or_reversal_location - offset) {
1192 return _last_roll_or_reversal_location;
1204 Session::set_frame_rate (nframes_t frames_per_second)
1206 /** \fn void Session::set_frame_size(nframes_t)
1207 the AudioEngine object that calls this guarantees
1208 that it will not be called while we are also in
1209 ::process(). Its fine to do things that block
1213 _base_frame_rate = frames_per_second;
1217 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1221 // XXX we need some equivalent to this, somehow
1222 // SndFileSource::setup_standard_crossfades (frames_per_second);
1226 /* XXX need to reset/reinstantiate all LADSPA plugins */
1230 Session::set_block_size (nframes_t nframes)
1232 /* the AudioEngine guarantees
1233 that it will not be called while we are also in
1234 ::process(). It is therefore fine to do things that block
1239 current_block_size = nframes;
1243 boost::shared_ptr<RouteList> r = routes.reader ();
1245 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1246 (*i)->set_block_size (nframes);
1249 boost::shared_ptr<RouteList> rl = routes.reader ();
1250 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1251 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1253 tr->set_block_size (nframes);
1257 set_worst_io_latencies ();
1262 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1265 nframes_t fade_frames;
1267 /* Don't allow fade of less 1 frame */
1269 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1276 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1280 default_fade_msecs = fade_msecs;
1281 default_fade_steepness = steepness;
1284 // jlc, WTF is this!
1285 Glib::RWLock::ReaderLock lm (route_lock);
1286 AudioRegion::set_default_fade (steepness, fade_frames);
1291 /* XXX have to do this at some point */
1292 /* foreach region using default fade, reset, then
1293 refill_all_diskstream_buffers ();
1298 struct RouteSorter {
1299 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1300 if (r2->feeds (r1)) {
1302 } else if (r1->feeds (r2)) {
1305 if (r1->not_fed ()) {
1306 if (r2->not_fed ()) {
1307 /* no ardour-based connections inbound to either route. just use signal order */
1308 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1310 /* r2 has connections, r1 does not; run r1 early */
1314 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1321 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1323 shared_ptr<Route> r2;
1325 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1326 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1330 /* make a copy of the existing list of routes that feed r1 */
1332 Route::FedBy existing (r1->fed_by());
1334 /* for each route that feeds r1, recurse, marking it as feeding
1338 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1339 if (!(r2 = i->r.lock ())) {
1340 /* (*i) went away, ignore it */
1344 /* r2 is a route that feeds r1 which somehow feeds base. mark
1345 base as being fed by r2
1348 rbase->add_fed_by (r2, i->sends_only);
1352 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1356 if (r1->feeds (r2) && r2->feeds (r1)) {
1360 /* now recurse, so that we can mark base as being fed by
1361 all routes that feed r2
1364 trace_terminal (r2, rbase);
1371 Session::resort_routes ()
1373 /* don't do anything here with signals emitted
1374 by Routes while we are being destroyed.
1377 if (_state_of_the_state & Deletion) {
1382 RCUWriter<RouteList> writer (routes);
1383 shared_ptr<RouteList> r = writer.get_copy ();
1384 resort_routes_using (r);
1385 /* writer goes out of scope and forces update */
1388 //route_graph->dump(1);
1391 boost::shared_ptr<RouteList> rl = routes.reader ();
1392 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1393 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1395 const Route::FedBy& fb ((*i)->fed_by());
1397 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1398 boost::shared_ptr<Route> sf = f->r.lock();
1400 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1408 Session::resort_routes_using (shared_ptr<RouteList> r)
1410 RouteList::iterator i, j;
1412 for (i = r->begin(); i != r->end(); ++i) {
1414 (*i)->clear_fed_by ();
1416 for (j = r->begin(); j != r->end(); ++j) {
1418 /* although routes can feed themselves, it will
1419 cause an endless recursive descent if we
1420 detect it. so don't bother checking for
1428 bool via_sends_only;
1430 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1431 (*i)->add_fed_by (*j, via_sends_only);
1436 for (i = r->begin(); i != r->end(); ++i) {
1437 trace_terminal (*i, *i);
1443 route_graph->rechain (r);
1446 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1447 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1448 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1449 (*i)->name(), (*i)->order_key ("signal")));
1455 /** Find the route name starting with \a base with the lowest \a id.
1457 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1458 * The available route name with the lowest ID will be used, and \a id
1459 * will be set to the ID.
1461 * \return false if a route name could not be found, and \a track_name
1462 * and \a id do not reflect a free route name.
1465 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1468 snprintf (name, name_len, "%s %" PRIu32, base, id);
1470 if (route_by_name (name) == 0) {
1476 } while (id < (UINT_MAX-1));
1481 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1483 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1485 in = ChanCount::ZERO;
1486 out = ChanCount::ZERO;
1487 shared_ptr<RouteList> r = routes.reader ();
1488 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1489 if (!(*i)->is_hidden()) {
1490 in += (*i)->n_inputs();
1491 out += (*i)->n_outputs();
1496 list<boost::shared_ptr<MidiTrack> >
1497 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1499 char track_name[32];
1500 uint32_t track_id = 0;
1501 ChanCount existing_inputs;
1502 ChanCount existing_outputs;
1504 RouteList new_routes;
1505 list<boost::shared_ptr<MidiTrack> > ret;
1506 uint32_t control_id;
1508 count_existing_route_channels (existing_inputs, existing_outputs);
1510 control_id = ntracks() + nbusses();
1513 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1514 error << "cannot find name for new midi track" << endmsg;
1518 shared_ptr<MidiTrack> track;
1521 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1528 mt->use_new_diskstream();
1530 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1531 track = boost::shared_ptr<MidiTrack>(mt);
1533 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1534 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1539 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1540 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1544 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1546 track->non_realtime_input_change();
1549 route_group->add (track);
1552 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1553 track->set_remote_control_id (control_id);
1555 new_routes.push_back (track);
1556 ret.push_back (track);
1559 catch (failed_constructor &err) {
1560 error << _("Session: could not create new midi track.") << endmsg;
1564 catch (AudioEngine::PortRegistrationFailure& pfe) {
1566 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;
1574 if (!new_routes.empty()) {
1575 add_routes (new_routes, false);
1576 save_state (_current_snapshot_name);
1582 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1583 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1584 * @param output_start As \a input_start, but for outputs.
1587 Session::auto_connect_route (
1588 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1591 /* If both inputs and outputs are auto-connected to physical ports,
1592 use the max of input and output offsets to ensure auto-connected
1593 port numbers always match up (e.g. the first audio input and the
1594 first audio output of the route will have the same physical
1595 port number). Otherwise just use the lowest input or output
1599 const bool in_out_physical =
1600 (Config->get_input_auto_connect() & AutoConnectPhysical)
1601 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1604 const ChanCount in_offset = in_out_physical
1605 ? ChanCount::max(existing_inputs, existing_outputs)
1608 const ChanCount out_offset = in_out_physical
1609 ? ChanCount::max(existing_inputs, existing_outputs)
1612 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1613 vector<string> physinputs;
1614 vector<string> physoutputs;
1616 _engine.get_physical_outputs (*t, physoutputs);
1617 _engine.get_physical_inputs (*t, physinputs);
1619 if (!physinputs.empty() && connect_inputs) {
1620 uint32_t nphysical_in = physinputs.size();
1621 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1624 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1625 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1628 if (!port.empty() && route->input()->connect (
1629 route->input()->ports().port(*t, i), port, this)) {
1635 if (!physoutputs.empty()) {
1636 uint32_t nphysical_out = physoutputs.size();
1637 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1640 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1641 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1642 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1643 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1644 port = _master_out->input()->ports().port(*t,
1645 i % _master_out->input()->n_ports().get(*t))->name();
1649 if (!port.empty() && route->output()->connect (
1650 route->output()->ports().port(*t, i), port, this)) {
1657 existing_inputs += route->n_inputs();
1658 existing_outputs += route->n_outputs();
1661 list< boost::shared_ptr<AudioTrack> >
1662 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1664 char track_name[32];
1665 uint32_t track_id = 0;
1666 ChanCount existing_inputs;
1667 ChanCount existing_outputs;
1669 RouteList new_routes;
1670 list<boost::shared_ptr<AudioTrack> > ret;
1671 uint32_t control_id;
1673 count_existing_route_channels (existing_inputs, existing_outputs);
1675 control_id = ntracks() + nbusses() + 1;
1678 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1679 error << "cannot find name for new audio track" << endmsg;
1683 shared_ptr<AudioTrack> track;
1686 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1693 at->use_new_diskstream();
1695 boost_debug_shared_ptr_mark_interesting (at, "Track");
1696 track = boost::shared_ptr<AudioTrack>(at);
1698 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_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 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1707 error << string_compose (
1708 _("cannot configure %1 in/%2 out configuration for new audio track"),
1709 input_channels, output_channels)
1714 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1717 route_group->add (track);
1720 track->non_realtime_input_change();
1722 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1723 track->set_remote_control_id (control_id);
1726 new_routes.push_back (track);
1727 ret.push_back (track);
1730 catch (failed_constructor &err) {
1731 error << _("Session: could not create new audio track.") << endmsg;
1735 catch (AudioEngine::PortRegistrationFailure& pfe) {
1737 error << pfe.what() << endmsg;
1745 if (!new_routes.empty()) {
1746 add_routes (new_routes, true);
1753 Session::set_remote_control_ids ()
1755 RemoteModel m = Config->get_remote_model();
1756 bool emit_signal = false;
1758 shared_ptr<RouteList> r = routes.reader ();
1760 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1761 if (MixerOrdered == m) {
1762 int32_t order = (*i)->order_key(N_("signal"));
1763 (*i)->set_remote_control_id (order+1, false);
1765 } else if (EditorOrdered == m) {
1766 int32_t order = (*i)->order_key(N_("editor"));
1767 (*i)->set_remote_control_id (order+1, false);
1769 } else if (UserOrdered == m) {
1770 //do nothing ... only changes to remote id's are initiated by user
1775 Route::RemoteControlIDChange();
1781 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1784 uint32_t bus_id = 0;
1785 ChanCount existing_inputs;
1786 ChanCount existing_outputs;
1789 uint32_t control_id;
1791 count_existing_route_channels (existing_inputs, existing_outputs);
1793 control_id = ntracks() + nbusses() + 1;
1796 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1797 error << "cannot find name for new audio bus" << endmsg;
1802 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1809 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1810 shared_ptr<Route> bus (rt);
1812 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1813 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1814 input_channels, output_channels)
1820 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1821 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1822 input_channels, output_channels)
1827 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1830 route_group->add (bus);
1832 bus->set_remote_control_id (control_id);
1836 bus->add_internal_return ();
1839 ret.push_back (bus);
1843 catch (failed_constructor &err) {
1844 error << _("Session: could not create new audio route.") << endmsg;
1848 catch (AudioEngine::PortRegistrationFailure& pfe) {
1849 error << pfe.what() << endmsg;
1859 add_routes (ret, true);
1867 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1871 uint32_t control_id;
1873 uint32_t number = 0;
1875 if (!tree.read (template_path.c_str())) {
1879 XMLNode* node = tree.root();
1881 control_id = ntracks() + nbusses() + 1;
1885 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1887 std::string node_name = IO::name_from_state (*node_copy.children().front());
1889 /* generate a new name by adding a number to the end of the template name */
1890 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1891 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1895 /* set IO children to use the new name */
1896 XMLNodeList const & children = node_copy.children ();
1897 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1898 if ((*i)->name() == IO::state_node_name) {
1899 IO::set_name_in_state (**i, name);
1903 Track::zero_diskstream_id_in_xml (node_copy);
1906 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1909 error << _("Session: cannot create track/bus from template description") << endmsg;
1913 if (boost::dynamic_pointer_cast<Track>(route)) {
1914 /* force input/output change signals so that the new diskstream
1915 picks up the configuration of the route. During session
1916 loading this normally happens in a different way.
1918 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1919 change.after = route->input()->n_ports();
1920 route->input()->changed (change, this);
1921 change.after = route->output()->n_ports();
1922 route->output()->changed (change, this);
1925 route->set_remote_control_id (control_id);
1928 ret.push_back (route);
1931 catch (failed_constructor &err) {
1932 error << _("Session: could not create new route from template") << endmsg;
1936 catch (AudioEngine::PortRegistrationFailure& pfe) {
1937 error << pfe.what() << endmsg;
1946 add_routes (ret, true);
1953 Session::add_routes (RouteList& new_routes, bool save)
1956 RCUWriter<RouteList> writer (routes);
1957 shared_ptr<RouteList> r = writer.get_copy ();
1958 r->insert (r->end(), new_routes.begin(), new_routes.end());
1961 /* if there is no control out and we're not in the middle of loading,
1962 resort the graph here. if there is a control out, we will resort
1963 toward the end of this method. if we are in the middle of loading,
1964 we will resort when done.
1967 if (!_monitor_out && IO::connecting_legal) {
1968 resort_routes_using (r);
1972 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1974 boost::weak_ptr<Route> wpr (*x);
1975 boost::shared_ptr<Route> r (*x);
1977 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1978 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1979 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1980 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1981 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1982 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1983 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1985 if (r->is_master()) {
1989 if (r->is_monitor()) {
1993 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1995 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1996 track_playlist_changed (boost::weak_ptr<Track> (tr));
1997 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1999 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
2001 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
2006 if (_monitor_out && IO::connecting_legal) {
2008 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2009 if ((*x)->is_monitor()) {
2011 } else if ((*x)->is_master()) {
2014 (*x)->listen_via (_monitor_out,
2015 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2026 save_state (_current_snapshot_name);
2029 RouteAdded (new_routes); /* EMIT SIGNAL */
2030 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2034 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2036 boost::shared_ptr<RouteList> r = routes.reader ();
2037 boost::shared_ptr<Send> s;
2041 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2042 if (boost::dynamic_pointer_cast<Track>(*i)) {
2043 if ((s = (*i)->internal_send_for (dest)) != 0) {
2044 s->amp()->gain_control()->set_value (0.0);
2051 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2053 boost::shared_ptr<RouteList> r = routes.reader ();
2054 boost::shared_ptr<Send> s;
2058 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2059 if (boost::dynamic_pointer_cast<Track>(*i)) {
2060 if ((s = (*i)->internal_send_for (dest)) != 0) {
2061 s->amp()->gain_control()->set_value (1.0);
2068 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2070 boost::shared_ptr<RouteList> r = routes.reader ();
2071 boost::shared_ptr<Send> s;
2075 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2076 if (boost::dynamic_pointer_cast<Track>(*i)) {
2077 if ((s = (*i)->internal_send_for (dest)) != 0) {
2078 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2085 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2087 boost::shared_ptr<RouteList> r = routes.reader ();
2088 boost::shared_ptr<RouteList> t (new RouteList);
2090 /* only send tracks */
2092 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2093 if (boost::dynamic_pointer_cast<Track>(*i)) {
2098 add_internal_sends (dest, p, t);
2102 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2104 if (dest->is_monitor() || dest->is_master()) {
2108 if (!dest->internal_return()) {
2109 dest->add_internal_return();
2112 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2114 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2118 (*i)->listen_via (dest, p, true, true);
2125 Session::remove_route (shared_ptr<Route> route)
2127 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2131 route->set_solo (false, this);
2134 RCUWriter<RouteList> writer (routes);
2135 shared_ptr<RouteList> rs = writer.get_copy ();
2139 /* deleting the master out seems like a dumb
2140 idea, but its more of a UI policy issue
2144 if (route == _master_out) {
2145 _master_out = shared_ptr<Route> ();
2148 if (route == _monitor_out) {
2150 /* cancel control outs for all routes */
2152 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2153 (*r)->drop_listen (_monitor_out);
2156 _monitor_out.reset ();
2159 /* writer goes out of scope, forces route list update */
2162 update_route_solo_state ();
2163 update_session_range_location_marker ();
2165 // We need to disconnect the route's inputs and outputs
2167 route->input()->disconnect (0);
2168 route->output()->disconnect (0);
2170 /* if the route had internal sends sending to it, remove them */
2171 if (route->internal_return()) {
2173 boost::shared_ptr<RouteList> r = routes.reader ();
2174 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2175 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2177 (*i)->remove_processor (s);
2182 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2183 if (mt && mt->step_editing()) {
2184 if (_step_editors > 0) {
2189 update_latency_compensation (false, false);
2192 /* Re-sort routes to remove the graph's current references to the one that is
2193 * going away, then flush old references out of the graph.
2197 route_graph->clear_other_chain ();
2199 /* get rid of it from the dead wood collection in the route list manager */
2201 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2205 /* try to cause everyone to drop their references */
2207 route->drop_references ();
2209 sync_order_keys (N_("session"));
2211 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2213 /* save the new state of the world */
2215 if (save_state (_current_snapshot_name)) {
2216 save_history (_current_snapshot_name);
2221 Session::route_mute_changed (void* /*src*/)
2227 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2229 boost::shared_ptr<Route> route = wpr.lock();
2231 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2235 if (route->listening()) {
2237 if (Config->get_exclusive_solo()) {
2238 /* new listen: disable all other listen */
2239 shared_ptr<RouteList> r = routes.reader ();
2240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2241 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2244 (*i)->set_listen (false, this);
2250 } else if (_listen_cnt > 0) {
2256 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2258 boost::shared_ptr<Route> route = wpr.lock ();
2261 /* should not happen */
2262 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2266 bool send_changed = false;
2268 if (route->solo_isolated()) {
2269 if (_solo_isolated_cnt == 0) {
2270 send_changed = true;
2272 _solo_isolated_cnt++;
2273 } else if (_solo_isolated_cnt > 0) {
2274 _solo_isolated_cnt--;
2275 if (_solo_isolated_cnt == 0) {
2276 send_changed = true;
2281 IsolatedChanged (); /* EMIT SIGNAL */
2286 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2288 if (!self_solo_change) {
2289 // session doesn't care about changes to soloed-by-others
2293 if (solo_update_disabled) {
2298 boost::shared_ptr<Route> route = wpr.lock ();
2301 /* should not happen */
2302 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2306 shared_ptr<RouteList> r = routes.reader ();
2309 if (route->self_soloed()) {
2315 if (delta == 1 && Config->get_exclusive_solo()) {
2316 /* new solo: disable all other solos */
2317 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2318 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2321 (*i)->set_solo (false, this);
2325 solo_update_disabled = true;
2327 RouteList uninvolved;
2329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2330 bool via_sends_only;
2331 bool in_signal_flow;
2333 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2337 in_signal_flow = false;
2339 if ((*i)->feeds (route, &via_sends_only)) {
2340 if (!via_sends_only) {
2341 if (!route->soloed_by_others_upstream()) {
2342 (*i)->mod_solo_by_others_downstream (delta);
2344 in_signal_flow = true;
2348 if (route->feeds (*i, &via_sends_only)) {
2349 (*i)->mod_solo_by_others_upstream (delta);
2350 in_signal_flow = true;
2353 if (!in_signal_flow) {
2354 uninvolved.push_back (*i);
2358 solo_update_disabled = false;
2359 update_route_solo_state (r);
2361 /* now notify that the mute state of the routes not involved in the signal
2362 pathway of the just-solo-changed route may have altered.
2365 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2366 (*i)->mute_changed (this);
2369 SoloChanged (); /* EMIT SIGNAL */
2374 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2376 /* now figure out if anything that matters is soloed (or is "listening")*/
2378 bool something_soloed = false;
2379 uint32_t listeners = 0;
2380 uint32_t isolated = 0;
2383 r = routes.reader();
2386 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2387 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2388 something_soloed = true;
2391 if (!(*i)->is_hidden() && (*i)->listening()) {
2392 if (Config->get_solo_control_is_listen_control()) {
2395 (*i)->set_listen (false, this);
2399 if ((*i)->solo_isolated()) {
2404 if (something_soloed != _non_soloed_outs_muted) {
2405 _non_soloed_outs_muted = something_soloed;
2406 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2409 _listen_cnt = listeners;
2411 if (isolated != _solo_isolated_cnt) {
2412 _solo_isolated_cnt = isolated;
2413 IsolatedChanged (); /* EMIT SIGNAL */
2417 boost::shared_ptr<RouteList>
2418 Session::get_routes_with_internal_returns() const
2420 shared_ptr<RouteList> r = routes.reader ();
2421 boost::shared_ptr<RouteList> rl (new RouteList);
2423 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2424 if ((*i)->internal_return ()) {
2432 Session::io_name_is_legal (const std::string& name)
2434 shared_ptr<RouteList> r = routes.reader ();
2436 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2437 if ((*i)->name() == name) {
2441 if ((*i)->has_io_processor_named (name)) {
2450 Session::route_by_name (string name)
2452 shared_ptr<RouteList> r = routes.reader ();
2454 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2455 if ((*i)->name() == name) {
2460 return shared_ptr<Route> ((Route*) 0);
2464 Session::route_by_id (PBD::ID id)
2466 shared_ptr<RouteList> r = routes.reader ();
2468 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2469 if ((*i)->id() == id) {
2474 return shared_ptr<Route> ((Route*) 0);
2478 Session::route_by_remote_id (uint32_t id)
2480 shared_ptr<RouteList> r = routes.reader ();
2482 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2483 if ((*i)->remote_control_id() == id) {
2488 return shared_ptr<Route> ((Route*) 0);
2491 /** If either end of the session range location marker lies inside the current
2492 * session extent, move it to the corresponding session extent.
2495 Session::update_session_range_location_marker ()
2497 if (_state_of_the_state & Loading) {
2501 pair<framepos_t, framepos_t> const ext = get_extent ();
2503 if (_session_range_location == 0) {
2504 /* we don't have a session range yet; use this one (provided it is valid) */
2505 if (ext.first != max_framepos) {
2506 add_session_range_location (ext.first, ext.second);
2509 /* update the existing session range */
2510 if (ext.first < _session_range_location->start()) {
2511 _session_range_location->set_start (ext.first);
2515 if (ext.second > _session_range_location->end()) {
2516 _session_range_location->set_end (ext.second);
2523 /** @return Extent of the session's contents; if the session is empty, the first value of
2524 * the pair will equal max_framepos.
2526 pair<framepos_t, framepos_t>
2527 Session::get_extent () const
2529 pair<framepos_t, framepos_t> ext (max_framepos, 0);
2531 boost::shared_ptr<RouteList> rl = routes.reader ();
2532 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2533 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2534 if (!tr || tr->destructive()) {
2535 // ignore tape tracks when getting extents
2539 pair<framepos_t, framepos_t> e = tr->playlist()->get_extent ();
2540 if (e.first < ext.first) {
2541 ext.first = e.first;
2543 if (e.second > ext.second) {
2544 ext.second = e.second;
2551 /* Region management */
2553 boost::shared_ptr<Region>
2554 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2556 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2557 RegionFactory::RegionMap::const_iterator i;
2558 boost::shared_ptr<Region> region;
2560 Glib::Mutex::Lock lm (region_lock);
2562 for (i = regions.begin(); i != regions.end(); ++i) {
2566 if (region->whole_file()) {
2568 if (child->source_equivalent (region)) {
2574 return boost::shared_ptr<Region> ();
2578 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2580 set<boost::shared_ptr<Region> > relevant_regions;
2582 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2583 RegionFactory::get_regions_using_source (*s, relevant_regions);
2586 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2588 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2589 set<boost::shared_ptr<Region> >::iterator tmp;
2594 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2596 playlists->destroy_region (*r);
2597 RegionFactory::map_remove (*r);
2599 (*r)->drop_sources ();
2600 (*r)->drop_references ();
2602 cerr << "\tdone UC = " << (*r).use_count() << endl;
2604 relevant_regions.erase (r);
2609 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2612 Glib::Mutex::Lock ls (source_lock);
2613 /* remove from the main source list */
2614 sources.erase ((*s)->id());
2617 (*s)->mark_for_remove ();
2618 (*s)->drop_references ();
2627 Session::remove_last_capture ()
2629 list<boost::shared_ptr<Source> > srcs;
2631 boost::shared_ptr<RouteList> rl = routes.reader ();
2632 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2633 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2638 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2641 srcs.insert (srcs.end(), l.begin(), l.end());
2646 destroy_sources (srcs);
2648 save_state (_current_snapshot_name);
2653 /* Source Management */
2656 Session::add_source (boost::shared_ptr<Source> source)
2658 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2659 pair<SourceMap::iterator,bool> result;
2661 entry.first = source->id();
2662 entry.second = source;
2665 Glib::Mutex::Lock lm (source_lock);
2666 result = sources.insert (entry);
2669 if (result.second) {
2671 /* yay, new source */
2675 boost::shared_ptr<AudioFileSource> afs;
2677 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2678 if (Config->get_auto_analyse_audio()) {
2679 Analyser::queue_source_for_analysis (source, false);
2686 Session::remove_source (boost::weak_ptr<Source> src)
2688 SourceMap::iterator i;
2689 boost::shared_ptr<Source> source = src.lock();
2696 Glib::Mutex::Lock lm (source_lock);
2698 if ((i = sources.find (source->id())) != sources.end()) {
2699 cerr << "Removing source " << source->name() << endl;
2704 if (!_state_of_the_state & InCleanup) {
2706 /* save state so we don't end up with a session file
2707 referring to non-existent sources.
2710 save_state (_current_snapshot_name);
2714 boost::shared_ptr<Source>
2715 Session::source_by_id (const PBD::ID& id)
2717 Glib::Mutex::Lock lm (source_lock);
2718 SourceMap::iterator i;
2719 boost::shared_ptr<Source> source;
2721 if ((i = sources.find (id)) != sources.end()) {
2728 boost::shared_ptr<Source>
2729 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2731 Glib::Mutex::Lock lm (source_lock);
2733 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2734 boost::shared_ptr<AudioFileSource> afs
2735 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2737 if (afs && afs->path() == path && chn == afs->channel()) {
2741 return boost::shared_ptr<Source>();
2746 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2749 string old_basename = PBD::basename_nosuffix (oldname);
2750 string new_legalized = legalize_for_path (newname);
2752 /* note: we know (or assume) the old path is already valid */
2756 /* destructive file sources have a name of the form:
2758 /path/to/Tnnnn-NAME(%[LR])?.wav
2760 the task here is to replace NAME with the new name.
2765 string::size_type dash;
2767 dir = Glib::path_get_dirname (path);
2768 path = Glib::path_get_basename (path);
2770 /* '-' is not a legal character for the NAME part of the path */
2772 if ((dash = path.find_last_of ('-')) == string::npos) {
2776 prefix = path.substr (0, dash);
2780 path += new_legalized;
2781 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2783 path = Glib::build_filename (dir, path);
2787 /* non-destructive file sources have a name of the form:
2789 /path/to/NAME-nnnnn(%[LR])?.ext
2791 the task here is to replace NAME with the new name.
2796 string::size_type dash;
2797 string::size_type postfix;
2799 dir = Glib::path_get_dirname (path);
2800 path = Glib::path_get_basename (path);
2802 /* '-' is not a legal character for the NAME part of the path */
2804 if ((dash = path.find_last_of ('-')) == string::npos) {
2808 suffix = path.substr (dash+1);
2810 // Suffix is now everything after the dash. Now we need to eliminate
2811 // the nnnnn part, which is done by either finding a '%' or a '.'
2813 postfix = suffix.find_last_of ("%");
2814 if (postfix == string::npos) {
2815 postfix = suffix.find_last_of ('.');
2818 if (postfix != string::npos) {
2819 suffix = suffix.substr (postfix);
2821 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2825 const uint32_t limit = 10000;
2826 char buf[PATH_MAX+1];
2828 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2830 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2832 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2833 path = Glib::build_filename (dir, buf);
2841 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2850 /** Return the full path (in some session directory) for a new within-session source.
2851 * \a name must be a session-unique name that does not contain slashes
2852 * (e.g. as returned by new_*_source_name)
2855 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2857 assert(name.find("/") == string::npos);
2859 SessionDirectory sdir(get_best_session_directory_for_new_source());
2862 if (type == DataType::AUDIO) {
2863 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2864 } else if (type == DataType::MIDI) {
2865 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2867 error << "Unknown source type, unable to create file path" << endmsg;
2872 return p.to_string();
2876 Session::peak_path (string base) const
2878 sys::path peakfile_path(_session_dir->peak_path());
2879 peakfile_path /= base + peakfile_suffix;
2880 return peakfile_path.to_string();
2883 /** Return a unique name based on \a base for a new internal audio source */
2885 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2888 char buf[PATH_MAX+1];
2889 const uint32_t limit = 10000;
2891 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2894 legalized = legalize_for_path (base);
2896 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2897 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2899 vector<space_and_path>::iterator i;
2900 uint32_t existing = 0;
2902 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2907 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2908 cnt, legalized.c_str(), ext.c_str());
2909 } else if (nchan == 2) {
2911 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2912 cnt, legalized.c_str(), ext.c_str());
2914 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2915 cnt, legalized.c_str(), ext.c_str());
2917 } else if (nchan < 26) {
2918 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2919 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2921 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2922 cnt, legalized.c_str(), ext.c_str());
2928 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2929 } else if (nchan == 2) {
2931 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2933 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2935 } else if (nchan < 26) {
2936 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2938 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2942 SessionDirectory sdir((*i).path);
2944 string spath = sdir.sound_path().to_string();
2945 string spath_stubs = sdir.sound_stub_path().to_string();
2947 /* note that we search *without* the extension so that
2948 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2949 in the event that this new name is required for
2950 a file format change.
2953 if (matching_unsuffixed_filename_exists_in (spath, buf) ||
2954 matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
2960 if (existing == 0) {
2965 error << string_compose(
2966 _("There are already %1 recordings for %2, which I consider too many."),
2967 limit, base) << endmsg;
2969 throw failed_constructor();
2973 return Glib::path_get_basename (buf);
2976 /** Create a new within-session audio source */
2977 boost::shared_ptr<AudioFileSource>
2978 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
2980 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2981 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
2983 return boost::dynamic_pointer_cast<AudioFileSource> (
2984 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
2987 /** Return a unique name based on \a base for a new internal MIDI source */
2989 Session::new_midi_source_name (const string& base)
2992 char buf[PATH_MAX+1];
2993 const uint32_t limit = 10000;
2997 legalized = legalize_for_path (base);
2999 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3000 for (cnt = 1; cnt <= limit; ++cnt) {
3002 vector<space_and_path>::iterator i;
3003 uint32_t existing = 0;
3005 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3007 SessionDirectory sdir((*i).path);
3009 sys::path p = sdir.midi_path();
3012 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3014 if (sys::exists (buf)) {
3019 if (existing == 0) {
3024 error << string_compose(
3025 _("There are already %1 recordings for %2, which I consider too many."),
3026 limit, base) << endmsg;
3028 throw failed_constructor();
3032 return Glib::path_get_basename(buf);
3036 /** Create a new within-session MIDI source */
3037 boost::shared_ptr<MidiSource>
3038 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
3040 /* try to use the existing write source for the track, to keep numbering sane
3044 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3048 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3051 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3052 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3056 const string name = new_midi_source_name (n);
3057 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
3059 return boost::dynamic_pointer_cast<SMFSource> (
3060 SourceFactory::createWritable (
3061 DataType::MIDI, *this, path, string(), false, frame_rate()));
3066 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3068 if (playlist->hidden()) {
3072 playlists->add (playlist);
3075 playlist->release();
3082 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3084 if (_state_of_the_state & Deletion) {
3088 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3094 playlists->remove (playlist);
3100 Session::set_audition (boost::shared_ptr<Region> r)
3102 pending_audition_region = r;
3103 add_post_transport_work (PostTransportAudition);
3104 _butler->schedule_transport_work ();
3108 Session::audition_playlist ()
3110 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3111 ev->region.reset ();
3116 Session::non_realtime_set_audition ()
3118 if (!pending_audition_region) {
3119 auditioner->audition_current_playlist ();
3121 auditioner->audition_region (pending_audition_region);
3122 pending_audition_region.reset ();
3124 AuditionActive (true); /* EMIT SIGNAL */
3128 Session::audition_region (boost::shared_ptr<Region> r)
3130 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3136 Session::cancel_audition ()
3138 if (auditioner->auditioning()) {
3139 auditioner->cancel_audition ();
3140 AuditionActive (false); /* EMIT SIGNAL */
3145 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3147 if (a->is_monitor()) {
3150 if (b->is_monitor()) {
3153 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3157 Session::is_auditioning () const
3159 /* can be called before we have an auditioner object */
3161 return auditioner->auditioning();
3168 Session::graph_reordered ()
3170 /* don't do this stuff if we are setting up connections
3171 from a set_state() call or creating new tracks. Ditto for deletion.
3174 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3178 /* every track/bus asked for this to be handled but it was deferred because
3179 we were connecting. do it now.
3182 request_input_change_handling ();
3186 /* force all diskstreams to update their capture offset values to
3187 reflect any changes in latencies within the graph.
3190 boost::shared_ptr<RouteList> rl = routes.reader ();
3191 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3192 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3194 tr->set_capture_offset ();
3200 Session::available_capture_duration ()
3202 float sample_bytes_on_disk = 4.0; // keep gcc happy
3204 switch (config.get_native_file_data_format()) {
3206 sample_bytes_on_disk = 4.0;
3210 sample_bytes_on_disk = 3.0;
3214 sample_bytes_on_disk = 2.0;
3218 /* impossible, but keep some gcc versions happy */
3219 fatal << string_compose (_("programming error: %1"),
3220 X_("illegal native file data format"))
3225 double scale = 4096.0 / sample_bytes_on_disk;
3227 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3228 return max_framecnt;
3231 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3235 Session::add_bundle (shared_ptr<Bundle> bundle)
3238 RCUWriter<BundleList> writer (_bundles);
3239 boost::shared_ptr<BundleList> b = writer.get_copy ();
3240 b->push_back (bundle);
3243 BundleAdded (bundle); /* EMIT SIGNAL */
3249 Session::remove_bundle (shared_ptr<Bundle> bundle)
3251 bool removed = false;
3254 RCUWriter<BundleList> writer (_bundles);
3255 boost::shared_ptr<BundleList> b = writer.get_copy ();
3256 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3258 if (i != b->end()) {
3265 BundleRemoved (bundle); /* EMIT SIGNAL */
3272 Session::bundle_by_name (string name) const
3274 boost::shared_ptr<BundleList> b = _bundles.reader ();
3276 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3277 if ((*i)->name() == name) {
3282 return boost::shared_ptr<Bundle> ();
3286 Session::tempo_map_changed (const PropertyChange&)
3290 playlists->update_after_tempo_map_change ();
3292 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3298 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3300 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3301 (*i)->recompute_frames_from_bbt ();
3305 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3306 * the given count with the current block size.
3309 Session::ensure_buffers (ChanCount howmany)
3311 BufferManager::ensure_buffers (howmany);
3315 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3317 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3318 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3323 Session::next_insert_id ()
3325 /* this doesn't really loop forever. just think about it */
3328 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3329 if (!insert_bitset[n]) {
3330 insert_bitset[n] = true;
3336 /* none available, so resize and try again */
3338 insert_bitset.resize (insert_bitset.size() + 16, false);
3343 Session::next_send_id ()
3345 /* this doesn't really loop forever. just think about it */
3348 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3349 if (!send_bitset[n]) {
3350 send_bitset[n] = true;
3356 /* none available, so resize and try again */
3358 send_bitset.resize (send_bitset.size() + 16, false);
3363 Session::next_return_id ()
3365 /* this doesn't really loop forever. just think about it */
3368 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3369 if (!return_bitset[n]) {
3370 return_bitset[n] = true;
3376 /* none available, so resize and try again */
3378 return_bitset.resize (return_bitset.size() + 16, false);
3383 Session::mark_send_id (uint32_t id)
3385 if (id >= send_bitset.size()) {
3386 send_bitset.resize (id+16, false);
3388 if (send_bitset[id]) {
3389 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3391 send_bitset[id] = true;
3395 Session::mark_return_id (uint32_t id)
3397 if (id >= return_bitset.size()) {
3398 return_bitset.resize (id+16, false);
3400 if (return_bitset[id]) {
3401 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3403 return_bitset[id] = true;
3407 Session::mark_insert_id (uint32_t id)
3409 if (id >= insert_bitset.size()) {
3410 insert_bitset.resize (id+16, false);
3412 if (insert_bitset[id]) {
3413 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3415 insert_bitset[id] = true;
3419 Session::unmark_send_id (uint32_t id)
3421 if (id < send_bitset.size()) {
3422 send_bitset[id] = false;
3427 Session::unmark_return_id (uint32_t id)
3429 if (id < return_bitset.size()) {
3430 return_bitset[id] = false;
3435 Session::unmark_insert_id (uint32_t id)
3437 if (id < insert_bitset.size()) {
3438 insert_bitset[id] = false;
3443 /* Named Selection management */
3445 boost::shared_ptr<NamedSelection>
3446 Session::named_selection_by_name (string name)
3448 Glib::Mutex::Lock lm (named_selection_lock);
3449 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3450 if ((*i)->name == name) {
3454 return boost::shared_ptr<NamedSelection>();
3458 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3461 Glib::Mutex::Lock lm (named_selection_lock);
3462 named_selections.insert (named_selections.begin(), named_selection);
3467 NamedSelectionAdded (); /* EMIT SIGNAL */
3471 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3473 bool removed = false;
3476 Glib::Mutex::Lock lm (named_selection_lock);
3478 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3480 if (i != named_selections.end()) {
3481 named_selections.erase (i);
3488 NamedSelectionRemoved (); /* EMIT SIGNAL */
3493 Session::reset_native_file_format ()
3495 boost::shared_ptr<RouteList> rl = routes.reader ();
3496 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3497 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3499 /* don't save state as we do this, there's no point
3502 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3503 tr->reset_write_sources (false);
3504 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3510 Session::route_name_unique (string n) const
3512 shared_ptr<RouteList> r = routes.reader ();
3514 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3515 if ((*i)->name() == n) {
3524 Session::route_name_internal (string n) const
3526 if (auditioner && auditioner->name() == n) {
3530 if (_click_io && _click_io->name() == n) {
3538 Session::freeze_all (InterThreadInfo& itt)
3540 shared_ptr<RouteList> r = routes.reader ();
3542 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3544 boost::shared_ptr<Track> t;
3546 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3547 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3557 boost::shared_ptr<Region>
3558 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3559 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3560 InterThreadInfo& itt, bool enable_processing)
3562 boost::shared_ptr<Region> result;
3563 boost::shared_ptr<Playlist> playlist;
3564 boost::shared_ptr<AudioFileSource> fsource;
3566 char buf[PATH_MAX+1];
3567 ChanCount nchans(track.n_channels());
3568 framepos_t position;
3569 framecnt_t this_chunk;
3572 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3573 const string sound_dir = sdir.sound_path().to_string();
3574 framepos_t len = end - start;
3575 bool need_block_size_reset = false;
3579 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3580 end, start) << endmsg;
3584 const framecnt_t chunk_size = (256 * 1024)/4;
3586 // block all process callback handling
3588 block_processing ();
3590 /* call tree *MUST* hold route_lock */
3592 if ((playlist = track.playlist()) == 0) {
3596 /* external redirects will be a problem */
3598 if (track.has_external_redirects()) {
3602 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3604 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3606 for (x = 0; x < 99999; ++x) {
3607 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());
3608 if (access (buf, F_OK) != 0) {
3614 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3619 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3620 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3623 catch (failed_constructor& err) {
3624 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3628 srcs.push_back (fsource);
3631 /* tell redirects that care that we are about to use a much larger blocksize */
3633 need_block_size_reset = true;
3634 track.set_block_size (chunk_size);
3636 /* XXX need to flush all redirects */
3641 /* create a set of reasonably-sized buffers */
3642 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3643 buffers.set_count(nchans);
3645 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3646 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3648 afs->prepare_for_peakfile_writes ();
3651 while (to_do && !itt.cancel) {
3653 this_chunk = min (to_do, chunk_size);
3655 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3660 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3661 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3664 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3670 start += this_chunk;
3671 to_do -= this_chunk;
3673 itt.progress = (float) (1.0 - ((double) to_do / len));
3682 xnow = localtime (&now);
3684 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3685 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3688 afs->update_header (position, *xnow, now);
3689 afs->flush_header ();
3693 /* construct a region to represent the bounced material */
3697 plist.add (Properties::start, 0);
3698 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3699 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3701 result = RegionFactory::create (srcs, plist);
3707 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3708 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3711 afs->mark_for_remove ();
3714 (*src)->drop_references ();
3718 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3719 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3722 afs->done_with_peakfile_writes ();
3727 if (need_block_size_reset) {
3728 track.set_block_size (get_block_size());
3731 unblock_processing ();
3737 Session::gain_automation_buffer() const
3739 return ProcessThread::gain_automation_buffer ();
3743 Session::pan_automation_buffer() const
3745 return ProcessThread::pan_automation_buffer ();
3749 Session::get_silent_buffers (ChanCount count)
3751 return ProcessThread::get_silent_buffers (count);
3753 assert(_silent_buffers->available() >= count);
3754 _silent_buffers->set_count(count);
3756 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3757 for (size_t i= 0; i < count.get(*t); ++i) {
3758 _silent_buffers->get(*t, i).clear();
3762 return *_silent_buffers;
3767 Session::get_scratch_buffers (ChanCount count)
3769 return ProcessThread::get_scratch_buffers (count);
3771 if (count != ChanCount::ZERO) {
3772 assert(_scratch_buffers->available() >= count);
3773 _scratch_buffers->set_count(count);
3775 _scratch_buffers->set_count (_scratch_buffers->available());
3778 return *_scratch_buffers;
3783 Session::get_mix_buffers (ChanCount count)
3785 return ProcessThread::get_mix_buffers (count);
3787 assert(_mix_buffers->available() >= count);
3788 _mix_buffers->set_count(count);
3789 return *_mix_buffers;
3794 Session::ntracks () const
3797 shared_ptr<RouteList> r = routes.reader ();
3799 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3800 if (boost::dynamic_pointer_cast<Track> (*i)) {
3809 Session::nbusses () const
3812 shared_ptr<RouteList> r = routes.reader ();
3814 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3815 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3824 Session::add_automation_list(AutomationList *al)
3826 automation_lists[al->id()] = al;
3830 Session::sync_order_keys (std::string const & base)
3832 if (deletion_in_progress()) {
3836 if (!Config->get_sync_all_route_ordering()) {
3837 /* leave order keys as they are */
3841 boost::shared_ptr<RouteList> r = routes.reader ();
3843 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3844 (*i)->sync_order_keys (base);
3847 Route::SyncOrderKeys (base); // EMIT SIGNAL
3849 /* this might not do anything */
3851 set_remote_control_ids ();
3854 /** @return true if there is at least one record-enabled track, otherwise false */
3856 Session::have_rec_enabled_track () const
3858 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3861 /** Update the state of our rec-enabled tracks flag */
3863 Session::update_have_rec_enabled_track ()
3865 boost::shared_ptr<RouteList> rl = routes.reader ();
3866 RouteList::iterator i = rl->begin();
3867 while (i != rl->end ()) {
3869 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3870 if (tr && tr->record_enabled ()) {
3877 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3879 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3881 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3882 RecordStateChanged (); /* EMIT SIGNAL */
3887 Session::listen_position_changed ()
3891 switch (Config->get_listen_position()) {
3892 case AfterFaderListen:
3896 case PreFaderListen:
3901 boost::shared_ptr<RouteList> r = routes.reader ();
3903 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3904 (*i)->put_monitor_send_at (p);
3909 Session::solo_control_mode_changed ()
3911 /* cancel all solo or all listen when solo control mode changes */
3914 set_solo (get_routes(), false);
3915 } else if (listening()) {
3916 set_listen (get_routes(), false);
3920 /** Called when anything about any of our route groups changes (membership, state etc.) */
3922 Session::route_group_changed ()
3924 RouteGroupChanged (); /* EMIT SIGNAL */
3928 Session::get_available_sync_options () const
3930 vector<SyncSource> ret;
3932 ret.push_back (JACK);
3933 ret.push_back (MTC);
3934 ret.push_back (MIDIClock);
3939 boost::shared_ptr<RouteList>
3940 Session::get_routes_with_regions_at (framepos_t const p) const
3942 shared_ptr<RouteList> r = routes.reader ();
3943 shared_ptr<RouteList> rl (new RouteList);
3945 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3946 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3951 boost::shared_ptr<Playlist> pl = tr->playlist ();
3956 if (pl->has_region_at (p)) {
3965 Session::goto_end ()
3967 if (_session_range_location) {
3968 request_locate (_session_range_location->end(), false);
3970 request_locate (0, false);
3975 Session::goto_start ()
3977 if (_session_range_location) {
3978 request_locate (_session_range_location->start(), false);
3980 request_locate (0, false);
3985 Session::current_start_frame () const
3987 return _session_range_location ? _session_range_location->start() : 0;
3991 Session::current_end_frame () const
3993 return _session_range_location ? _session_range_location->end() : 0;
3997 Session::add_session_range_location (nframes_t start, nframes_t end)
3999 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4000 _locations->add (_session_range_location);
4003 /** Called when one of our routes' order keys has changed */
4005 Session::route_order_key_changed ()
4007 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4011 Session::step_edit_status_change (bool yn)
4017 send = (_step_editors == 0);
4022 send = (_step_editors == 1);
4025 if (_step_editors > 0) {
4031 StepEditStatusChange (val);
4037 Session::start_time_changed (framepos_t old)
4039 /* Update the auto loop range to match the session range
4040 (unless the auto loop range has been changed by the user)
4043 Location* s = _locations->session_range_location ();
4044 Location* l = _locations->auto_loop_location ();
4046 if (l->start() == old) {
4047 l->set_start (s->start(), true);
4052 Session::end_time_changed (framepos_t old)
4054 /* Update the auto loop range to match the session range
4055 (unless the auto loop range has been changed by the user)
4058 Location* s = _locations->session_range_location ();
4059 Location* l = _locations->auto_loop_location ();
4061 if (l->end() == old) {
4062 l->set_end (s->end(), true);
4067 Session::source_search_path (DataType type) const
4071 if (session_dirs.size() == 1) {
4073 case DataType::AUDIO:
4074 search_path = _session_dir->sound_path().to_string();
4076 case DataType::MIDI:
4077 search_path = _session_dir->midi_path().to_string();
4081 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4082 SessionDirectory sdir (i->path);
4083 if (!search_path.empty()) {
4087 case DataType::AUDIO:
4088 search_path += sdir.sound_path().to_string();
4090 case DataType::MIDI:
4091 search_path += sdir.midi_path().to_string();
4097 /* now add user-specified locations
4100 vector<string> dirs;
4103 case DataType::AUDIO:
4104 split (config.get_audio_search_path (), dirs, ':');
4106 case DataType::MIDI:
4107 split (config.get_midi_search_path (), dirs, ':');
4111 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4121 Session::ensure_search_path_includes (const string& path, DataType type)
4124 vector<string> dirs;
4127 case DataType::AUDIO:
4128 search_path = config.get_audio_search_path ();
4130 case DataType::MIDI:
4131 search_path = config.get_midi_search_path ();
4135 split (search_path, dirs, ':');
4137 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4143 if (!search_path.empty()) {
4147 search_path += path;
4150 case DataType::AUDIO:
4151 config.set_audio_search_path (search_path);
4153 case DataType::MIDI:
4154 config.set_midi_search_path (search_path);