2 Copyright (C) 1999-2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <cstdio> /* sprintf(3) ... grrr */
33 #include <glibmm/thread.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/error.h"
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
49 #include "ardour/amp.h"
50 #include "ardour/analyser.h"
51 #include "ardour/audio_buffer.h"
52 #include "ardour/audio_diskstream.h"
53 #include "ardour/audio_port.h"
54 #include "ardour/audio_track.h"
55 #include "ardour/audioengine.h"
56 #include "ardour/audiofilesource.h"
57 #include "ardour/audioplaylist.h"
58 #include "ardour/audioregion.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/buffer_manager.h"
61 #include "ardour/buffer_set.h"
62 #include "ardour/bundle.h"
63 #include "ardour/butler.h"
64 #include "ardour/click.h"
65 #include "ardour/configuration.h"
66 #include "ardour/crossfade.h"
67 #include "ardour/cycle_timer.h"
68 #include "ardour/data_type.h"
69 #include "ardour/debug.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/internal_send.h"
72 #include "ardour/io_processor.h"
73 #include "ardour/midi_diskstream.h"
74 #include "ardour/midi_playlist.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/midi_track.h"
77 #include "ardour/midi_ui.h"
78 #include "ardour/named_selection.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/playlist.h"
81 #include "ardour/plugin_insert.h"
82 #include "ardour/port_insert.h"
83 #include "ardour/processor.h"
84 #include "ardour/rc_configuration.h"
85 #include "ardour/recent_sessions.h"
86 #include "ardour/region_factory.h"
87 #include "ardour/return.h"
88 #include "ardour/route_group.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_metadata.h"
94 #include "ardour/session_playlists.h"
95 #include "ardour/slave.h"
96 #include "ardour/smf_source.h"
97 #include "ardour/source_factory.h"
98 #include "ardour/tape_file_matcher.h"
99 #include "ardour/tempo.h"
100 #include "ardour/utils.h"
101 #include "ardour/graph.h"
102 #include "ardour/speakers.h"
103 #include "ardour/operations.h"
105 #include "midi++/port.h"
106 #include "midi++/mmc.h"
107 #include "midi++/manager.h"
112 using namespace ARDOUR;
115 bool Session::_disable_all_loaded_plugins = false;
117 PBD::Signal1<void,std::string> Session::Dialog;
118 PBD::Signal0<int> Session::AskAboutPendingState;
119 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
120 PBD::Signal0<void> Session::SendFeedback;
121 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
123 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
124 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
125 PBD::Signal0<void> Session::AutoBindingOn;
126 PBD::Signal0<void> Session::AutoBindingOff;
127 PBD::Signal2<void,std::string, std::string> Session::Exported;
128 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
129 PBD::Signal0<void> Session::Quit;
131 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
132 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
134 Session::Session (AudioEngine &eng,
135 const string& fullpath,
136 const string& snapshot_name,
137 BusProfile* bus_profile,
140 , _target_transport_speed (0.0)
141 , _requested_return_frame (-1)
142 , _session_dir (new SessionDirectory(fullpath))
144 , _state_of_the_state (Clean)
145 , _butler (new Butler (*this))
146 , _post_transport_work (0)
147 , _send_timecode_update (false)
148 , _all_route_group (new RouteGroup (*this, "all"))
149 , route_graph (new Graph(*this))
150 , routes (new RouteList)
151 , _total_free_4k_blocks (0)
152 , _bundles (new BundleList)
153 , _bundle_xml_node (0)
155 , _click_io ((IO*) 0)
157 , click_emphasis_data (0)
159 , _metadata (new SessionMetadata())
160 , _have_rec_enabled_track (false)
161 , _suspend_timecode_transmission (0)
163 _locations = new Locations (*this);
165 playlists.reset (new SessionPlaylists);
167 _all_route_group->set_active (true, this);
169 interpolation.add_channel_to (0, 0);
171 if (!eng.connected()) {
172 throw failed_constructor();
175 n_physical_outputs = _engine.n_physical_outputs ();
176 n_physical_inputs = _engine.n_physical_inputs ();
178 first_stage_init (fullpath, snapshot_name);
180 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
183 if (create (mix_template, bus_profile)) {
185 throw failed_constructor ();
189 if (second_stage_init ()) {
191 throw failed_constructor ();
194 store_recent_sessions(_name, _path);
196 bool was_dirty = dirty();
198 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
200 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
201 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
204 DirtyChanged (); /* EMIT SIGNAL */
207 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
208 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
221 vector<void*> debug_pointers;
223 /* if we got to here, leaving pending capture state around
227 remove_pending_capture_state ();
229 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
231 _engine.remove_session ();
233 /* clear history so that no references to objects are held any more */
237 /* clear state tree so that no references to objects are held any more */
241 /* reset dynamic state version back to default */
243 Stateful::loading_state_version = 0;
245 _butler->drop_references ();
247 delete midi_control_ui;
248 delete _all_route_group;
250 if (click_data != default_click) {
251 delete [] click_data;
254 if (click_emphasis_data != default_click_emphasis) {
255 delete [] click_emphasis_data;
260 /* clear out any pending dead wood from RCU managed objects */
265 AudioDiskstream::free_working_buffers();
267 /* tell everyone who is still standing that we're about to die */
270 /* tell everyone to drop references and delete objects as we go */
272 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
273 named_selections.clear ();
275 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
276 RegionFactory::delete_all_regions ();
278 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
280 /* reset these three references to special routes before we do the usual route delete thing */
283 _master_out.reset ();
284 _monitor_out.reset ();
287 RCUWriter<RouteList> writer (routes);
288 boost::shared_ptr<RouteList> r = writer.get_copy ();
290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
291 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
292 (*i)->drop_references ();
296 /* writer goes out of scope and updates master */
300 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
301 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
302 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
303 i->second->drop_references ();
308 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
309 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
314 Crossfade::set_buffer_size (0);
316 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
321 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
323 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
324 boost_debug_list_ptrs ();
329 Session::set_worst_io_latencies ()
331 if (_state_of_the_state & InitialConnecting) {
335 _worst_output_latency = 0;
336 _worst_input_latency = 0;
338 if (!_engine.connected()) {
342 boost::shared_ptr<RouteList> r = routes.reader ();
344 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
345 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
346 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
349 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1 Worst input latency: %2\n",
350 _worst_output_latency, _worst_input_latency));
354 Session::when_engine_running ()
356 string first_physical_output;
358 BootMessage (_("Set block size and sample rate"));
360 set_block_size (_engine.frames_per_cycle());
361 set_frame_rate (_engine.frame_rate());
363 BootMessage (_("Using configuration"));
365 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
366 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
368 Config->map_parameters (ff);
369 config.map_parameters (ft);
371 /* every time we reconnect, recompute worst case output latencies */
373 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
375 if (synced_to_jack()) {
376 _engine.transport_stop ();
379 if (config.get_jack_time_master()) {
380 _engine.transport_locate (_transport_frame);
388 _click_io.reset (new ClickIO (*this, "click"));
390 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
392 /* existing state for Click */
395 if (Stateful::loading_state_version < 3000) {
396 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
398 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
403 _clicking = Config->get_clicking ();
407 error << _("could not setup Click I/O") << endmsg;
414 /* default state for Click: dual-mono to first 2 physical outputs */
417 _engine.get_physical_outputs (DataType::AUDIO, outs);
419 for (uint32_t physport = 0; physport < 2; ++physport) {
420 if (outs.size() > physport) {
421 if (_click_io->add_port (outs[physport], this)) {
422 // relax, even though its an error
427 if (_click_io->n_ports () > ChanCount::ZERO) {
428 _clicking = Config->get_clicking ();
433 catch (failed_constructor& err) {
434 error << _("cannot setup Click I/O") << endmsg;
437 BootMessage (_("Compute I/O 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 boost::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 boost::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 boost::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 boost::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 boost::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 boost::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 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
551 /* don't connect the master bus outputs if there is a monitor bus */
553 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
555 /* if requested auto-connect the outputs to the first N physical ports.
558 uint32_t limit = _master_out->n_outputs().n_total();
560 for (uint32_t n = 0; n < limit; ++n) {
561 Port* p = _master_out->output()->nth (n);
563 if (outputs[p->type()].size() > n) {
564 connect_to = outputs[p->type()][n];
567 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
568 if (_master_out->output()->connect (p, connect_to, this)) {
569 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
579 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
580 are undefined, at best.
583 /* control out listens to master bus (but ignores it
584 under some conditions)
587 uint32_t limit = _monitor_out->n_inputs().n_audio();
590 for (uint32_t n = 0; n < limit; ++n) {
591 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
592 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
595 string connect_to = o->name();
596 if (_monitor_out->input()->connect (p, connect_to, this)) {
597 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
605 /* if control out is not connected, connect control out to physical outs
608 if (!_monitor_out->output()->connected ()) {
610 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
612 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
615 _monitor_out->output()->connect_ports_to_bundle (b, this);
617 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
618 Config->get_monitor_bus_preferred_bundle())
624 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
625 uint32_t mod = n_physical_outputs.get (*t);
626 uint32_t limit = _monitor_out->n_outputs().get(*t);
628 for (uint32_t n = 0; n < limit; ++n) {
630 Port* p = _monitor_out->output()->ports().port(*t, n);
632 if (outputs[*t].size() > (n % mod)) {
633 connect_to = outputs[*t][n % mod];
636 if (!connect_to.empty()) {
637 if (_monitor_out->output()->connect (p, connect_to, this)) {
638 error << string_compose (
639 _("cannot connect control output %1 to %2"),
652 set_worst_io_latencies ();
654 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
656 /* hook us up to the engine */
658 BootMessage (_("Connect to engine"));
660 _engine.set_session (this);
661 _engine.update_total_latencies ();
665 Session::hookup_io ()
667 /* stop graph reordering notifications from
668 causing resorts, etc.
671 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
675 /* we delay creating the auditioner till now because
676 it makes its own connections to ports.
680 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
682 throw failed_constructor ();
684 a->use_new_diskstream ();
688 catch (failed_constructor& err) {
689 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
693 /* load bundles, which we may have postponed earlier on */
694 if (_bundle_xml_node) {
695 load_bundles (*_bundle_xml_node);
696 delete _bundle_xml_node;
699 /* Tell all IO objects to connect themselves together */
701 IO::enable_connecting ();
702 MIDI::Port::MakeConnections ();
704 /* Now reset all panners */
706 Delivery::reset_panners ();
708 /* Connect tracks to monitor/listen bus if there is one.
709 Note that in an existing session, the internal sends will
710 already exist, but we want the routes to notice that
711 they connect to the control out specifically.
715 boost::shared_ptr<RouteList> r = routes.reader ();
716 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
718 if ((*x)->is_monitor()) {
722 } else if ((*x)->is_master()) {
728 (*x)->listen_via_monitor ();
733 /* Anyone who cares about input state, wake up and do something */
735 IOConnectionsComplete (); /* EMIT SIGNAL */
737 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
739 /* now handle the whole enchilada as if it was one
745 /* update the full solo state, which can't be
746 correctly determined on a per-route basis, but
747 needs the global overview that only the session
751 update_route_solo_state ();
755 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
757 boost::shared_ptr<Track> track = wp.lock ();
762 boost::shared_ptr<Playlist> playlist;
764 if ((playlist = track->playlist()) != 0) {
765 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
766 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
767 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
772 Session::record_enabling_legal () const
774 /* this used to be in here, but survey says.... we don't need to restrict it */
775 // if (record_status() == Recording) {
779 if (Config->get_all_safe()) {
786 Session::set_track_monitor_input_status (bool yn)
788 boost::shared_ptr<RouteList> rl = routes.reader ();
789 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
790 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
791 if (tr && tr->record_enabled ()) {
792 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
793 tr->monitor_input (yn);
799 Session::reset_input_monitor_state ()
801 if (transport_rolling()) {
802 set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
804 set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring);
809 Session::auto_punch_start_changed (Location* location)
811 replace_event (SessionEvent::PunchIn, location->start());
813 if (get_record_enabled() && config.get_punch_in()) {
814 /* capture start has been changed, so save new pending state */
815 save_state ("", true);
820 Session::auto_punch_end_changed (Location* location)
822 framepos_t when_to_stop = location->end();
823 // when_to_stop += _worst_output_latency + _worst_input_latency;
824 replace_event (SessionEvent::PunchOut, when_to_stop);
828 Session::auto_punch_changed (Location* location)
830 framepos_t when_to_stop = location->end();
832 replace_event (SessionEvent::PunchIn, location->start());
833 //when_to_stop += _worst_output_latency + _worst_input_latency;
834 replace_event (SessionEvent::PunchOut, when_to_stop);
838 Session::auto_loop_changed (Location* location)
840 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
842 if (transport_rolling() && play_loop) {
845 // if (_transport_frame > location->end()) {
847 if (_transport_frame < location->start() || _transport_frame > location->end()) {
848 // relocate to beginning of loop
849 clear_events (SessionEvent::LocateRoll);
851 request_locate (location->start(), true);
854 else if (Config->get_seamless_loop() && !loop_changing) {
856 // schedule a locate-roll to refill the diskstreams at the
858 loop_changing = true;
860 if (location->end() > last_loopend) {
861 clear_events (SessionEvent::LocateRoll);
862 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
869 last_loopend = location->end();
873 Session::set_auto_punch_location (Location* location)
877 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
878 punch_connections.drop_connections();
879 existing->set_auto_punch (false, this);
880 remove_event (existing->start(), SessionEvent::PunchIn);
881 clear_events (SessionEvent::PunchOut);
882 auto_punch_location_changed (0);
891 if (location->end() <= location->start()) {
892 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
896 punch_connections.drop_connections ();
898 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
899 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
900 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
902 location->set_auto_punch (true, this);
904 auto_punch_changed (location);
906 auto_punch_location_changed (location);
910 Session::set_auto_loop_location (Location* location)
914 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
915 loop_connections.drop_connections ();
916 existing->set_auto_loop (false, this);
917 remove_event (existing->end(), SessionEvent::AutoLoop);
918 auto_loop_location_changed (0);
927 if (location->end() <= location->start()) {
928 error << _("Session: you can't use a mark for auto loop") << endmsg;
932 last_loopend = location->end();
934 loop_connections.drop_connections ();
936 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
937 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
938 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
940 location->set_auto_loop (true, this);
942 /* take care of our stuff first */
944 auto_loop_changed (location);
946 /* now tell everyone else */
948 auto_loop_location_changed (location);
952 Session::locations_added (Location *)
958 Session::locations_changed ()
960 _locations->apply (*this, &Session::handle_locations_changed);
964 Session::handle_locations_changed (Locations::LocationList& locations)
966 Locations::LocationList::iterator i;
968 bool set_loop = false;
969 bool set_punch = false;
971 for (i = locations.begin(); i != locations.end(); ++i) {
975 if (location->is_auto_punch()) {
976 set_auto_punch_location (location);
979 if (location->is_auto_loop()) {
980 set_auto_loop_location (location);
984 if (location->is_session_range()) {
985 _session_range_location = location;
990 set_auto_loop_location (0);
993 set_auto_punch_location (0);
1000 Session::enable_record ()
1003 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1005 if (rs == Recording) {
1009 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1011 _last_record_location = _transport_frame;
1012 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1014 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1015 set_track_monitor_input_status (true);
1018 RecordStateChanged ();
1025 Session::disable_record (bool rt_context, bool force)
1029 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1031 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1032 g_atomic_int_set (&_record_status, Disabled);
1033 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1035 if (rs == Recording) {
1036 g_atomic_int_set (&_record_status, Enabled);
1040 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1041 set_track_monitor_input_status (false);
1044 RecordStateChanged (); /* emit signal */
1047 remove_pending_capture_state ();
1053 Session::step_back_from_record ()
1055 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1057 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1058 set_track_monitor_input_status (false);
1064 Session::maybe_enable_record ()
1066 if (_step_editors > 0) {
1070 g_atomic_int_set (&_record_status, Enabled);
1072 /* This function is currently called from somewhere other than an RT thread.
1073 This save_state() call therefore doesn't impact anything. Doing it here
1074 means that we save pending state of which sources the next record will use,
1075 which gives us some chance of recovering from a crash during the record.
1078 save_state ("", true);
1080 if (_transport_speed) {
1081 if (!config.get_punch_in()) {
1085 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1086 RecordStateChanged (); /* EMIT SIGNAL */
1093 Session::audible_frame () const
1099 /* the first of these two possible settings for "offset"
1100 mean that the audible frame is stationary until
1101 audio emerges from the latency compensation
1104 the second means that the audible frame is stationary
1105 until audio would emerge from a physical port
1106 in the absence of any plugin latency compensation
1109 offset = worst_playback_latency ();
1111 if (offset > current_block_size) {
1112 offset -= current_block_size;
1114 /* XXX is this correct? if we have no external
1115 physical connections and everything is internal
1116 then surely this is zero? still, how
1117 likely is that anyway?
1119 offset = current_block_size;
1122 if (synced_to_jack()) {
1123 tf = _engine.transport_frame();
1125 tf = _transport_frame;
1130 if (!non_realtime_work_pending()) {
1134 /* Check to see if we have passed the first guaranteed
1135 audible frame past our last start position. if not,
1136 return that last start point because in terms
1137 of audible frames, we have not moved yet.
1139 `Start position' in this context means the time we last
1140 either started or changed transport direction.
1143 if (_transport_speed > 0.0f) {
1145 if (!play_loop || !have_looped) {
1146 if (tf < _last_roll_or_reversal_location + offset) {
1147 return _last_roll_or_reversal_location;
1155 } else if (_transport_speed < 0.0f) {
1157 /* XXX wot? no backward looping? */
1159 if (tf > _last_roll_or_reversal_location - offset) {
1160 return _last_roll_or_reversal_location;
1172 Session::set_frame_rate (framecnt_t frames_per_second)
1174 /** \fn void Session::set_frame_size(framecnt_t)
1175 the AudioEngine object that calls this guarantees
1176 that it will not be called while we are also in
1177 ::process(). Its fine to do things that block
1181 _base_frame_rate = frames_per_second;
1185 Automatable::set_automation_interval (ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1189 // XXX we need some equivalent to this, somehow
1190 // SndFileSource::setup_standard_crossfades (frames_per_second);
1194 /* XXX need to reset/reinstantiate all LADSPA plugins */
1198 Session::set_block_size (pframes_t nframes)
1200 /* the AudioEngine guarantees
1201 that it will not be called while we are also in
1202 ::process(). It is therefore fine to do things that block
1207 current_block_size = nframes;
1211 boost::shared_ptr<RouteList> r = routes.reader ();
1213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1214 (*i)->set_block_size (nframes);
1217 boost::shared_ptr<RouteList> rl = routes.reader ();
1218 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1219 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1221 tr->set_block_size (nframes);
1225 set_worst_io_latencies ();
1229 struct RouteSorter {
1230 /** @return true to run r1 before r2, otherwise false */
1231 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1232 if (r2->feeds (r1)) {
1233 /* r1 fed by r2; run r2 early */
1235 } else if (r1->feeds (r2)) {
1236 /* r2 fed by r1; run r1 early */
1239 if (r1->not_fed ()) {
1240 if (r2->not_fed ()) {
1241 /* no ardour-based connections inbound to either route. just use signal order */
1242 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1244 /* r2 has connections, r1 does not; run r1 early */
1248 if (r2->not_fed()) {
1249 /* r1 has connections, r2 does not; run r2 early */
1252 /* both r1 and r2 have connections, but not to each other. just use signal order */
1253 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1261 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1263 boost::shared_ptr<Route> r2;
1265 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1266 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1270 /* make a copy of the existing list of routes that feed r1 */
1272 Route::FedBy existing (r1->fed_by());
1274 /* for each route that feeds r1, recurse, marking it as feeding
1278 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1279 if (!(r2 = i->r.lock ())) {
1280 /* (*i) went away, ignore it */
1284 /* r2 is a route that feeds r1 which somehow feeds base. mark
1285 base as being fed by r2
1288 rbase->add_fed_by (r2, i->sends_only);
1292 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1296 if (r1->feeds (r2) && r2->feeds (r1)) {
1300 /* now recurse, so that we can mark base as being fed by
1301 all routes that feed r2
1304 trace_terminal (r2, rbase);
1311 Session::resort_routes ()
1313 /* don't do anything here with signals emitted
1314 by Routes while we are being destroyed.
1317 if (_state_of_the_state & Deletion) {
1322 RCUWriter<RouteList> writer (routes);
1323 boost::shared_ptr<RouteList> r = writer.get_copy ();
1324 resort_routes_using (r);
1325 /* writer goes out of scope and forces update */
1328 //route_graph->dump(1);
1331 boost::shared_ptr<RouteList> rl = routes.reader ();
1332 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1333 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1335 const Route::FedBy& fb ((*i)->fed_by());
1337 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1338 boost::shared_ptr<Route> sf = f->r.lock();
1340 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1348 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1350 RouteList::iterator i, j;
1352 for (i = r->begin(); i != r->end(); ++i) {
1354 (*i)->clear_fed_by ();
1356 for (j = r->begin(); j != r->end(); ++j) {
1358 /* although routes can feed themselves, it will
1359 cause an endless recursive descent if we
1360 detect it. so don't bother checking for
1368 bool via_sends_only;
1370 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1371 (*i)->add_fed_by (*j, via_sends_only);
1376 for (i = r->begin(); i != r->end(); ++i) {
1377 trace_terminal (*i, *i);
1383 route_graph->rechain (r);
1386 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1387 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1388 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1389 (*i)->name(), (*i)->order_key ("signal")));
1395 /** Find a route name starting with \a base, maybe followed by the
1396 * lowest \a id. \a id will always be added if \a definitely_add_number
1397 * is true on entry; otherwise it will only be added if required
1398 * to make the name unique.
1400 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1401 * The available route name with the lowest ID will be used, and \a id
1402 * will be set to the ID.
1404 * \return false if a route name could not be found, and \a track_name
1405 * and \a id do not reflect a free route name.
1408 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1410 if (!definitely_add_number && route_by_name (base) == 0) {
1411 /* juse use the base */
1412 snprintf (name, name_len, "%s", base.c_str());
1417 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1419 if (route_by_name (name) == 0) {
1425 } while (id < (UINT_MAX-1));
1430 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1432 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1434 in = ChanCount::ZERO;
1435 out = ChanCount::ZERO;
1436 boost::shared_ptr<RouteList> r = routes.reader ();
1437 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1438 if (!(*i)->is_hidden()) {
1439 in += (*i)->n_inputs();
1440 out += (*i)->n_outputs();
1445 /** Caller must not hold process lock
1446 * @param name_template string to use for the start of the name, or "" to use "Midi".
1448 list<boost::shared_ptr<MidiTrack> >
1449 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1451 char track_name[32];
1452 uint32_t track_id = 0;
1453 ChanCount existing_inputs;
1454 ChanCount existing_outputs;
1456 RouteList new_routes;
1457 list<boost::shared_ptr<MidiTrack> > ret;
1458 uint32_t control_id;
1460 count_existing_route_channels (existing_inputs, existing_outputs);
1462 control_id = ntracks() + nbusses();
1464 bool const use_number = (how_many != 1);
1467 if (!find_route_name (name_template.empty() ? _("Midi") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1468 error << "cannot find name for new midi track" << endmsg;
1472 boost::shared_ptr<MidiTrack> track;
1475 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1477 if (track->init ()) {
1481 track->use_new_diskstream();
1483 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1484 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1487 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1488 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1489 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1493 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1494 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1499 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1501 track->non_realtime_input_change();
1504 route_group->add (track);
1507 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1508 track->set_remote_control_id (control_id);
1510 new_routes.push_back (track);
1511 ret.push_back (track);
1514 catch (failed_constructor &err) {
1515 error << _("Session: could not create new midi track.") << endmsg;
1519 catch (AudioEngine::PortRegistrationFailure& pfe) {
1521 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;
1529 if (!new_routes.empty()) {
1530 add_routes (new_routes, false);
1531 save_state (_current_snapshot_name);
1537 /** Caller must hold process lock.
1538 * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1539 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1540 * @param output_start As \a input_start, but for outputs.
1543 Session::auto_connect_route (
1544 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1547 /* If both inputs and outputs are auto-connected to physical ports,
1548 use the max of input and output offsets to ensure auto-connected
1549 port numbers always match up (e.g. the first audio input and the
1550 first audio output of the route will have the same physical
1551 port number). Otherwise just use the lowest input or output
1555 const bool in_out_physical =
1556 (Config->get_input_auto_connect() & AutoConnectPhysical)
1557 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1560 const ChanCount in_offset = in_out_physical
1561 ? ChanCount::max(existing_inputs, existing_outputs)
1564 const ChanCount out_offset = in_out_physical
1565 ? ChanCount::max(existing_inputs, existing_outputs)
1568 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1569 vector<string> physinputs;
1570 vector<string> physoutputs;
1572 _engine.get_physical_outputs (*t, physoutputs);
1573 _engine.get_physical_inputs (*t, physinputs);
1575 if (!physinputs.empty() && connect_inputs) {
1576 uint32_t nphysical_in = physinputs.size();
1577 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1580 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1581 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1584 if (!port.empty() && route->input()->connect (
1585 route->input()->ports().port(*t, i), port, this)) {
1591 if (!physoutputs.empty()) {
1592 uint32_t nphysical_out = physoutputs.size();
1593 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1596 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1597 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1598 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1599 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1600 port = _master_out->input()->ports().port(*t,
1601 i % _master_out->input()->n_ports().get(*t))->name();
1605 if (!port.empty() && route->output()->connect (
1606 route->output()->ports().port(*t, i), port, this)) {
1613 existing_inputs += route->n_inputs();
1614 existing_outputs += route->n_outputs();
1617 /** Caller must not hold process lock
1618 * @param name_template string to use for the start of the name, or "" to use "Audio".
1620 list< boost::shared_ptr<AudioTrack> >
1621 Session::new_audio_track (
1622 int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template
1625 char track_name[32];
1626 uint32_t track_id = 0;
1627 ChanCount existing_inputs;
1628 ChanCount existing_outputs;
1630 RouteList new_routes;
1631 list<boost::shared_ptr<AudioTrack> > ret;
1632 uint32_t control_id;
1634 count_existing_route_channels (existing_inputs, existing_outputs);
1636 control_id = ntracks() + nbusses() + 1;
1638 bool const use_number = (how_many != 1);
1641 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1642 error << "cannot find name for new audio track" << endmsg;
1646 boost::shared_ptr<AudioTrack> track;
1649 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1651 if (track->init ()) {
1655 track->use_new_diskstream();
1657 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1658 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1661 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1663 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1664 error << string_compose (
1665 _("cannot configure %1 in/%2 out configuration for new audio track"),
1666 input_channels, output_channels)
1671 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1672 error << string_compose (
1673 _("cannot configure %1 in/%2 out configuration for new audio track"),
1674 input_channels, output_channels)
1679 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1683 route_group->add (track);
1686 track->non_realtime_input_change();
1688 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1689 track->set_remote_control_id (control_id);
1692 new_routes.push_back (track);
1693 ret.push_back (track);
1696 catch (failed_constructor &err) {
1697 error << _("Session: could not create new audio track.") << endmsg;
1701 catch (AudioEngine::PortRegistrationFailure& pfe) {
1703 error << pfe.what() << endmsg;
1711 if (!new_routes.empty()) {
1712 add_routes (new_routes, true);
1719 Session::set_remote_control_ids ()
1721 RemoteModel m = Config->get_remote_model();
1722 bool emit_signal = false;
1724 boost::shared_ptr<RouteList> r = routes.reader ();
1726 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1727 if (MixerOrdered == m) {
1728 int32_t order = (*i)->order_key(N_("signal"));
1729 (*i)->set_remote_control_id (order+1, false);
1731 } else if (EditorOrdered == m) {
1732 int32_t order = (*i)->order_key(N_("editor"));
1733 (*i)->set_remote_control_id (order+1, false);
1735 } else if (UserOrdered == m) {
1736 //do nothing ... only changes to remote id's are initiated by user
1741 Route::RemoteControlIDChange();
1745 /** Caller must not hold process lock.
1746 * @param name_template string to use for the start of the name, or "" to use "Bus".
1749 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1752 uint32_t bus_id = 0;
1753 ChanCount existing_inputs;
1754 ChanCount existing_outputs;
1757 uint32_t control_id;
1759 count_existing_route_channels (existing_inputs, existing_outputs);
1761 control_id = ntracks() + nbusses() + 1;
1763 bool const use_number = (how_many != 1);
1765 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1766 error << "cannot find name for new audio bus" << endmsg;
1771 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1777 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1778 boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1781 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1783 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1784 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1785 input_channels, output_channels)
1791 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1792 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1793 input_channels, output_channels)
1798 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1802 route_group->add (bus);
1804 bus->set_remote_control_id (control_id);
1807 bus->add_internal_return ();
1809 ret.push_back (bus);
1813 catch (failed_constructor &err) {
1814 error << _("Session: could not create new audio route.") << endmsg;
1818 catch (AudioEngine::PortRegistrationFailure& pfe) {
1819 error << pfe.what() << endmsg;
1829 add_routes (ret, true);
1837 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1841 uint32_t control_id;
1843 uint32_t number = 0;
1845 if (!tree.read (template_path.c_str())) {
1849 XMLNode* node = tree.root();
1851 control_id = ntracks() + nbusses() + 1;
1855 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1857 std::string node_name = IO::name_from_state (*node_copy.children().front());
1859 /* generate a new name by adding a number to the end of the template name */
1860 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name), true)) {
1861 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1865 /* set IO children to use the new name */
1866 XMLNodeList const & children = node_copy.children ();
1867 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1868 if ((*i)->name() == IO::state_node_name) {
1869 IO::set_name_in_state (**i, name);
1873 Track::zero_diskstream_id_in_xml (node_copy);
1876 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1879 error << _("Session: cannot create track/bus from template description") << endmsg;
1883 if (boost::dynamic_pointer_cast<Track>(route)) {
1884 /* force input/output change signals so that the new diskstream
1885 picks up the configuration of the route. During session
1886 loading this normally happens in a different way.
1889 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1891 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1892 change.after = route->input()->n_ports();
1893 route->input()->changed (change, this);
1894 change.after = route->output()->n_ports();
1895 route->output()->changed (change, this);
1898 route->set_remote_control_id (control_id);
1901 ret.push_back (route);
1904 catch (failed_constructor &err) {
1905 error << _("Session: could not create new route from template") << endmsg;
1909 catch (AudioEngine::PortRegistrationFailure& pfe) {
1910 error << pfe.what() << endmsg;
1919 add_routes (ret, true);
1926 Session::add_routes (RouteList& new_routes, bool save)
1929 RCUWriter<RouteList> writer (routes);
1930 boost::shared_ptr<RouteList> r = writer.get_copy ();
1931 r->insert (r->end(), new_routes.begin(), new_routes.end());
1934 /* if there is no control out and we're not in the middle of loading,
1935 resort the graph here. if there is a control out, we will resort
1936 toward the end of this method. if we are in the middle of loading,
1937 we will resort when done.
1940 if (!_monitor_out && IO::connecting_legal) {
1941 resort_routes_using (r);
1945 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1947 boost::weak_ptr<Route> wpr (*x);
1948 boost::shared_ptr<Route> r (*x);
1950 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1951 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1952 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1953 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1954 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1955 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1956 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1958 if (r->is_master()) {
1962 if (r->is_monitor()) {
1966 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1968 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1969 track_playlist_changed (boost::weak_ptr<Track> (tr));
1970 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1972 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
1974 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
1979 if (_monitor_out && IO::connecting_legal) {
1981 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1982 if ((*x)->is_monitor()) {
1984 } else if ((*x)->is_master()) {
1987 (*x)->listen_via_monitor ();
1997 save_state (_current_snapshot_name);
2000 RouteAdded (new_routes); /* EMIT SIGNAL */
2001 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2005 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2007 boost::shared_ptr<RouteList> r = routes.reader ();
2008 boost::shared_ptr<Send> s;
2010 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2011 if ((s = (*i)->internal_send_for (dest)) != 0) {
2012 s->amp()->gain_control()->set_value (0.0);
2018 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2020 boost::shared_ptr<RouteList> r = routes.reader ();
2021 boost::shared_ptr<Send> s;
2023 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2024 if ((s = (*i)->internal_send_for (dest)) != 0) {
2025 s->amp()->gain_control()->set_value (1.0);
2031 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2033 boost::shared_ptr<RouteList> r = routes.reader ();
2034 boost::shared_ptr<Send> s;
2036 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2037 if ((s = (*i)->internal_send_for (dest)) != 0) {
2038 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2043 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2045 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2047 boost::shared_ptr<RouteList> r = routes.reader ();
2048 boost::shared_ptr<RouteList> t (new RouteList);
2050 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2051 if (include_buses || boost::dynamic_pointer_cast<Track>(*i)) {
2056 add_internal_sends (dest, p, t);
2060 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2062 if (dest->is_monitor() || dest->is_master()) {
2066 if (!dest->internal_return()) {
2067 dest->add_internal_return();
2070 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2072 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2076 (*i)->listen_via (dest, p);
2083 Session::remove_route (boost::shared_ptr<Route> route)
2085 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2089 route->set_solo (false, this);
2092 RCUWriter<RouteList> writer (routes);
2093 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2097 /* deleting the master out seems like a dumb
2098 idea, but its more of a UI policy issue
2102 if (route == _master_out) {
2103 _master_out = boost::shared_ptr<Route> ();
2106 if (route == _monitor_out) {
2108 /* cancel control outs for all routes */
2110 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2111 (*r)->drop_listen (_monitor_out);
2114 _monitor_out.reset ();
2117 /* writer goes out of scope, forces route list update */
2120 update_route_solo_state ();
2122 // We need to disconnect the route's inputs and outputs
2124 route->input()->disconnect (0);
2125 route->output()->disconnect (0);
2127 /* if the route had internal sends sending to it, remove them */
2128 if (route->internal_return()) {
2130 boost::shared_ptr<RouteList> r = routes.reader ();
2131 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2132 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2134 (*i)->remove_processor (s);
2139 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2140 if (mt && mt->step_editing()) {
2141 if (_step_editors > 0) {
2146 update_latency_compensation (false, false);
2149 /* Re-sort routes to remove the graph's current references to the one that is
2150 * going away, then flush old references out of the graph.
2154 route_graph->clear_other_chain ();
2156 /* get rid of it from the dead wood collection in the route list manager */
2158 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2162 /* try to cause everyone to drop their references */
2164 route->drop_references ();
2166 sync_order_keys (N_("session"));
2168 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2170 /* save the new state of the world */
2172 if (save_state (_current_snapshot_name)) {
2173 save_history (_current_snapshot_name);
2178 Session::route_mute_changed (void* /*src*/)
2184 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2186 boost::shared_ptr<Route> route = wpr.lock();
2188 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2192 if (route->listening_via_monitor ()) {
2194 if (Config->get_exclusive_solo()) {
2195 /* new listen: disable all other listen */
2196 boost::shared_ptr<RouteList> r = routes.reader ();
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2201 (*i)->set_listen (false, this);
2207 } else if (_listen_cnt > 0) {
2212 update_route_solo_state ();
2215 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2217 boost::shared_ptr<Route> route = wpr.lock ();
2220 /* should not happen */
2221 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2225 bool send_changed = false;
2227 if (route->solo_isolated()) {
2228 if (_solo_isolated_cnt == 0) {
2229 send_changed = true;
2231 _solo_isolated_cnt++;
2232 } else if (_solo_isolated_cnt > 0) {
2233 _solo_isolated_cnt--;
2234 if (_solo_isolated_cnt == 0) {
2235 send_changed = true;
2240 IsolatedChanged (); /* EMIT SIGNAL */
2245 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2247 if (!self_solo_change) {
2248 // session doesn't care about changes to soloed-by-others
2252 if (solo_update_disabled) {
2257 boost::shared_ptr<Route> route = wpr.lock ();
2260 /* should not happen */
2261 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2265 boost::shared_ptr<RouteList> r = routes.reader ();
2268 if (route->self_soloed()) {
2274 if (delta == 1 && Config->get_exclusive_solo()) {
2275 /* new solo: disable all other solos */
2276 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2277 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2280 (*i)->set_solo (false, this);
2284 solo_update_disabled = true;
2286 RouteList uninvolved;
2288 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 bool via_sends_only;
2290 bool in_signal_flow;
2292 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2296 in_signal_flow = false;
2298 if ((*i)->feeds (route, &via_sends_only)) {
2299 if (!via_sends_only) {
2300 if (!route->soloed_by_others_upstream()) {
2301 (*i)->mod_solo_by_others_downstream (delta);
2303 in_signal_flow = true;
2307 if (route->feeds (*i, &via_sends_only)) {
2308 (*i)->mod_solo_by_others_upstream (delta);
2309 in_signal_flow = true;
2312 if (!in_signal_flow) {
2313 uninvolved.push_back (*i);
2317 solo_update_disabled = false;
2318 update_route_solo_state (r);
2320 /* now notify that the mute state of the routes not involved in the signal
2321 pathway of the just-solo-changed route may have altered.
2324 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2325 (*i)->mute_changed (this);
2328 SoloChanged (); /* EMIT SIGNAL */
2333 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2335 /* now figure out if anything that matters is soloed (or is "listening")*/
2337 bool something_soloed = false;
2338 uint32_t listeners = 0;
2339 uint32_t isolated = 0;
2342 r = routes.reader();
2345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2346 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2347 something_soloed = true;
2350 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2351 if (Config->get_solo_control_is_listen_control()) {
2354 (*i)->set_listen (false, this);
2358 if ((*i)->solo_isolated()) {
2363 if (something_soloed != _non_soloed_outs_muted) {
2364 _non_soloed_outs_muted = something_soloed;
2365 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2368 _listen_cnt = listeners;
2370 if (isolated != _solo_isolated_cnt) {
2371 _solo_isolated_cnt = isolated;
2372 IsolatedChanged (); /* EMIT SIGNAL */
2376 boost::shared_ptr<RouteList>
2377 Session::get_routes_with_internal_returns() const
2379 boost::shared_ptr<RouteList> r = routes.reader ();
2380 boost::shared_ptr<RouteList> rl (new RouteList);
2382 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2383 if ((*i)->internal_return ()) {
2391 Session::io_name_is_legal (const std::string& name)
2393 boost::shared_ptr<RouteList> r = routes.reader ();
2395 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2396 if ((*i)->name() == name) {
2400 if ((*i)->has_io_processor_named (name)) {
2408 boost::shared_ptr<Route>
2409 Session::route_by_name (string name)
2411 boost::shared_ptr<RouteList> r = routes.reader ();
2413 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2414 if ((*i)->name() == name) {
2419 return boost::shared_ptr<Route> ((Route*) 0);
2422 boost::shared_ptr<Route>
2423 Session::route_by_id (PBD::ID id)
2425 boost::shared_ptr<RouteList> r = routes.reader ();
2427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2428 if ((*i)->id() == id) {
2433 return boost::shared_ptr<Route> ((Route*) 0);
2436 boost::shared_ptr<Route>
2437 Session::route_by_remote_id (uint32_t id)
2439 boost::shared_ptr<RouteList> r = routes.reader ();
2441 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2442 if ((*i)->remote_control_id() == id) {
2447 return boost::shared_ptr<Route> ((Route*) 0);
2451 Session::playlist_region_added (boost::weak_ptr<Region> w)
2453 boost::shared_ptr<Region> r = w.lock ();
2458 /* These are the operations that are currently in progress... */
2459 list<GQuark> curr = _current_trans_quarks;
2462 /* ...and these are the operations during which we want to update
2463 the session range location markers.
2466 ops.push_back (Operations::capture);
2467 ops.push_back (Operations::paste);
2468 ops.push_back (Operations::duplicate_region);
2469 ops.push_back (Operations::insert_file);
2470 ops.push_back (Operations::insert_region);
2471 ops.push_back (Operations::drag_region_brush);
2472 ops.push_back (Operations::region_drag);
2473 ops.push_back (Operations::selection_grab);
2474 ops.push_back (Operations::region_fill);
2475 ops.push_back (Operations::fill_selection);
2476 ops.push_back (Operations::create_region);
2479 /* See if any of the current operations match the ones that we want */
2481 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2483 /* If so, update the session range markers */
2485 maybe_update_session_range (r->position (), r->last_frame ());
2489 /** Update the session range markers if a is before the current start or
2490 * b is after the current end.
2493 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2495 if (_state_of_the_state & Loading) {
2499 if (_session_range_location == 0) {
2501 add_session_range_location (a, b);
2505 if (a < _session_range_location->start()) {
2506 _session_range_location->set_start (a);
2509 if (b > _session_range_location->end()) {
2510 _session_range_location->set_end (b);
2516 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2518 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2519 maybe_update_session_range (i->to, i->to + i->length);
2524 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2526 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2527 maybe_update_session_range (i->from, i->to);
2531 /* Region management */
2533 boost::shared_ptr<Region>
2534 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2536 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2537 RegionFactory::RegionMap::const_iterator i;
2538 boost::shared_ptr<Region> region;
2540 Glib::Mutex::Lock lm (region_lock);
2542 for (i = regions.begin(); i != regions.end(); ++i) {
2546 if (region->whole_file()) {
2548 if (child->source_equivalent (region)) {
2554 return boost::shared_ptr<Region> ();
2558 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2560 set<boost::shared_ptr<Region> > relevant_regions;
2562 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2563 RegionFactory::get_regions_using_source (*s, relevant_regions);
2566 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2568 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2569 set<boost::shared_ptr<Region> >::iterator tmp;
2574 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2576 playlists->destroy_region (*r);
2577 RegionFactory::map_remove (*r);
2579 (*r)->drop_sources ();
2580 (*r)->drop_references ();
2582 cerr << "\tdone UC = " << (*r).use_count() << endl;
2584 relevant_regions.erase (r);
2589 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2592 Glib::Mutex::Lock ls (source_lock);
2593 /* remove from the main source list */
2594 sources.erase ((*s)->id());
2597 (*s)->mark_for_remove ();
2598 (*s)->drop_references ();
2607 Session::remove_last_capture ()
2609 list<boost::shared_ptr<Source> > srcs;
2611 boost::shared_ptr<RouteList> rl = routes.reader ();
2612 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2613 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2618 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2621 srcs.insert (srcs.end(), l.begin(), l.end());
2626 destroy_sources (srcs);
2628 save_state (_current_snapshot_name);
2633 /* Source Management */
2636 Session::add_source (boost::shared_ptr<Source> source)
2638 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2639 pair<SourceMap::iterator,bool> result;
2641 entry.first = source->id();
2642 entry.second = source;
2645 Glib::Mutex::Lock lm (source_lock);
2646 result = sources.insert (entry);
2649 if (result.second) {
2651 /* yay, new source */
2655 boost::shared_ptr<AudioFileSource> afs;
2657 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2658 if (Config->get_auto_analyse_audio()) {
2659 Analyser::queue_source_for_analysis (source, false);
2663 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
2668 Session::remove_source (boost::weak_ptr<Source> src)
2670 if (_state_of_the_state & Deletion) {
2674 SourceMap::iterator i;
2675 boost::shared_ptr<Source> source = src.lock();
2682 Glib::Mutex::Lock lm (source_lock);
2684 if ((i = sources.find (source->id())) != sources.end()) {
2689 if (!_state_of_the_state & InCleanup) {
2691 /* save state so we don't end up with a session file
2692 referring to non-existent sources.
2695 save_state (_current_snapshot_name);
2699 boost::shared_ptr<Source>
2700 Session::source_by_id (const PBD::ID& id)
2702 Glib::Mutex::Lock lm (source_lock);
2703 SourceMap::iterator i;
2704 boost::shared_ptr<Source> source;
2706 if ((i = sources.find (id)) != sources.end()) {
2713 boost::shared_ptr<Source>
2714 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2716 Glib::Mutex::Lock lm (source_lock);
2718 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2719 boost::shared_ptr<AudioFileSource> afs
2720 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2722 if (afs && afs->path() == path && chn == afs->channel()) {
2726 return boost::shared_ptr<Source>();
2730 Session::count_sources_by_origin (const string& path)
2733 Glib::Mutex::Lock lm (source_lock);
2735 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2736 boost::shared_ptr<FileSource> fs
2737 = boost::dynamic_pointer_cast<FileSource>(i->second);
2739 if (fs && fs->origin() == path) {
2749 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2752 string old_basename = PBD::basename_nosuffix (oldname);
2753 string new_legalized = legalize_for_path (newname);
2755 /* note: we know (or assume) the old path is already valid */
2759 /* destructive file sources have a name of the form:
2761 /path/to/Tnnnn-NAME(%[LR])?.wav
2763 the task here is to replace NAME with the new name.
2768 string::size_type dash;
2770 dir = Glib::path_get_dirname (path);
2771 path = Glib::path_get_basename (path);
2773 /* '-' is not a legal character for the NAME part of the path */
2775 if ((dash = path.find_last_of ('-')) == string::npos) {
2779 prefix = path.substr (0, dash);
2783 path += new_legalized;
2784 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2785 path = Glib::build_filename (dir, path);
2789 /* non-destructive file sources have a name of the form:
2791 /path/to/NAME-nnnnn(%[LR])?.ext
2793 the task here is to replace NAME with the new name.
2798 string::size_type dash;
2799 string::size_type postfix;
2801 dir = Glib::path_get_dirname (path);
2802 path = Glib::path_get_basename (path);
2804 /* '-' is not a legal character for the NAME part of the path */
2806 if ((dash = path.find_last_of ('-')) == string::npos) {
2810 suffix = path.substr (dash+1);
2812 // Suffix is now everything after the dash. Now we need to eliminate
2813 // the nnnnn part, which is done by either finding a '%' or a '.'
2815 postfix = suffix.find_last_of ("%");
2816 if (postfix == string::npos) {
2817 postfix = suffix.find_last_of ('.');
2820 if (postfix != string::npos) {
2821 suffix = suffix.substr (postfix);
2823 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2827 const uint32_t limit = 10000;
2828 char buf[PATH_MAX+1];
2830 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2832 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2834 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2835 path = Glib::build_filename (dir, buf);
2843 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2852 /** Return the full path (in some session directory) for a new within-session source.
2853 * \a name must be a session-unique name that does not contain slashes
2854 * (e.g. as returned by new_*_source_name)
2857 Session::new_source_path_from_name (DataType type, const string& name)
2859 assert(name.find("/") == string::npos);
2861 SessionDirectory sdir(get_best_session_directory_for_new_source());
2864 if (type == DataType::AUDIO) {
2865 p = sdir.sound_path();
2866 } else if (type == DataType::MIDI) {
2867 p = sdir.midi_path();
2869 error << "Unknown source type, unable to create file path" << endmsg;
2874 return p.to_string();
2878 Session::peak_path (string base) const
2880 sys::path peakfile_path(_session_dir->peak_path());
2881 peakfile_path /= base + peakfile_suffix;
2882 return peakfile_path.to_string();
2885 /** Return a unique name based on \a base for a new internal audio source */
2887 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2890 char buf[PATH_MAX+1];
2891 const uint32_t limit = 10000;
2893 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2896 legalized = legalize_for_path (base);
2898 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2899 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2901 vector<space_and_path>::iterator i;
2902 uint32_t existing = 0;
2904 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2909 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2910 cnt, legalized.c_str(), ext.c_str());
2911 } else if (nchan == 2) {
2913 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2914 cnt, legalized.c_str(), ext.c_str());
2916 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2917 cnt, legalized.c_str(), ext.c_str());
2919 } else if (nchan < 26) {
2920 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2921 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2923 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2924 cnt, legalized.c_str(), ext.c_str());
2930 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2931 } else if (nchan == 2) {
2933 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2935 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2937 } else if (nchan < 26) {
2938 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2940 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2944 SessionDirectory sdir((*i).path);
2946 string spath = sdir.sound_path().to_string();
2948 /* note that we search *without* the extension so that
2949 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2950 in the event that this new name is required for
2951 a file format change.
2954 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
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)
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);
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)
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);
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 (boost::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 (boost::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 */
3271 boost::shared_ptr<Bundle>
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 boost::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 boost::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 diskstream_channels (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;
3577 ChanCount const max_proc = track.max_processor_streams ();
3580 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3581 end, start) << endmsg;
3585 const framecnt_t chunk_size = (256 * 1024)/4;
3587 // block all process callback handling
3589 block_processing ();
3591 /* call tree *MUST* hold route_lock */
3593 if ((playlist = track.playlist()) == 0) {
3597 /* external redirects will be a problem */
3599 if (track.has_external_redirects()) {
3603 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3605 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3607 for (x = 0; x < 99999; ++x) {
3608 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());
3609 if (access (buf, F_OK) != 0) {
3615 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3620 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3621 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3624 catch (failed_constructor& err) {
3625 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3629 srcs.push_back (fsource);
3632 /* tell redirects that care that we are about to use a much larger blocksize */
3634 need_block_size_reset = true;
3635 track.set_block_size (chunk_size);
3637 /* XXX need to flush all redirects */
3642 /* create a set of reasonably-sized buffers */
3643 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
3644 buffers.set_count (max_proc);
3646 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3647 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3649 afs->prepare_for_peakfile_writes ();
3652 while (to_do && !itt.cancel) {
3654 this_chunk = min (to_do, chunk_size);
3656 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3661 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3662 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3665 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3671 start += this_chunk;
3672 to_do -= this_chunk;
3674 itt.progress = (float) (1.0 - ((double) to_do / len));
3683 xnow = localtime (&now);
3685 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3686 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3689 afs->update_header (position, *xnow, now);
3690 afs->flush_header ();
3694 /* construct a region to represent the bounced material */
3698 plist.add (Properties::start, 0);
3699 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3700 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3702 result = RegionFactory::create (srcs, plist);
3708 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3709 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3712 afs->mark_for_remove ();
3715 (*src)->drop_references ();
3719 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3720 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3723 afs->done_with_peakfile_writes ();
3728 if (need_block_size_reset) {
3729 track.set_block_size (get_block_size());
3732 unblock_processing ();
3738 Session::gain_automation_buffer() const
3740 return ProcessThread::gain_automation_buffer ();
3744 Session::pan_automation_buffer() const
3746 return ProcessThread::pan_automation_buffer ();
3750 Session::get_silent_buffers (ChanCount count)
3752 return ProcessThread::get_silent_buffers (count);
3756 Session::get_scratch_buffers (ChanCount count)
3758 return ProcessThread::get_scratch_buffers (count);
3762 Session::get_mix_buffers (ChanCount count)
3764 return ProcessThread::get_mix_buffers (count);
3768 Session::ntracks () const
3771 boost::shared_ptr<RouteList> r = routes.reader ();
3773 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3774 if (boost::dynamic_pointer_cast<Track> (*i)) {
3783 Session::nbusses () const
3786 boost::shared_ptr<RouteList> r = routes.reader ();
3788 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3789 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3798 Session::add_automation_list(AutomationList *al)
3800 automation_lists[al->id()] = al;
3804 Session::sync_order_keys (std::string const & base)
3806 if (deletion_in_progress()) {
3810 if (!Config->get_sync_all_route_ordering()) {
3811 /* leave order keys as they are */
3815 boost::shared_ptr<RouteList> r = routes.reader ();
3817 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3818 (*i)->sync_order_keys (base);
3821 Route::SyncOrderKeys (base); // EMIT SIGNAL
3823 /* this might not do anything */
3825 set_remote_control_ids ();
3828 /** @return true if there is at least one record-enabled track, otherwise false */
3830 Session::have_rec_enabled_track () const
3832 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3835 /** Update the state of our rec-enabled tracks flag */
3837 Session::update_have_rec_enabled_track ()
3839 boost::shared_ptr<RouteList> rl = routes.reader ();
3840 RouteList::iterator i = rl->begin();
3841 while (i != rl->end ()) {
3843 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3844 if (tr && tr->record_enabled ()) {
3851 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3853 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3855 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3856 RecordStateChanged (); /* EMIT SIGNAL */
3861 Session::listen_position_changed ()
3863 boost::shared_ptr<RouteList> r = routes.reader ();
3865 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3866 (*i)->listen_position_changed ();
3871 Session::solo_control_mode_changed ()
3873 /* cancel all solo or all listen when solo control mode changes */
3876 set_solo (get_routes(), false);
3877 } else if (listening()) {
3878 set_listen (get_routes(), false);
3882 /** Called when anything about any of our route groups changes (membership, state etc.) */
3884 Session::route_group_changed ()
3886 RouteGroupChanged (); /* EMIT SIGNAL */
3890 Session::get_available_sync_options () const
3892 vector<SyncSource> ret;
3894 ret.push_back (JACK);
3895 ret.push_back (MTC);
3896 ret.push_back (MIDIClock);
3901 boost::shared_ptr<RouteList>
3902 Session::get_routes_with_regions_at (framepos_t const p) const
3904 boost::shared_ptr<RouteList> r = routes.reader ();
3905 boost::shared_ptr<RouteList> rl (new RouteList);
3907 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3908 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3913 boost::shared_ptr<Playlist> pl = tr->playlist ();
3918 if (pl->has_region_at (p)) {
3927 Session::goto_end ()
3929 if (_session_range_location) {
3930 request_locate (_session_range_location->end(), false);
3932 request_locate (0, false);
3937 Session::goto_start ()
3939 if (_session_range_location) {
3940 request_locate (_session_range_location->start(), false);
3942 request_locate (0, false);
3947 Session::current_start_frame () const
3949 return _session_range_location ? _session_range_location->start() : 0;
3953 Session::current_end_frame () const
3955 return _session_range_location ? _session_range_location->end() : 0;
3959 Session::add_session_range_location (framepos_t start, framepos_t end)
3961 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
3962 _locations->add (_session_range_location);
3965 /** Called when one of our routes' order keys has changed */
3967 Session::route_order_key_changed ()
3969 RouteOrderKeyChanged (); /* EMIT SIGNAL */
3973 Session::step_edit_status_change (bool yn)
3979 send = (_step_editors == 0);
3984 send = (_step_editors == 1);
3987 if (_step_editors > 0) {
3993 StepEditStatusChange (val);
3999 Session::start_time_changed (framepos_t old)
4001 /* Update the auto loop range to match the session range
4002 (unless the auto loop range has been changed by the user)
4005 Location* s = _locations->session_range_location ();
4010 Location* l = _locations->auto_loop_location ();
4012 if (l->start() == old) {
4013 l->set_start (s->start(), true);
4018 Session::end_time_changed (framepos_t old)
4020 /* Update the auto loop range to match the session range
4021 (unless the auto loop range has been changed by the user)
4024 Location* s = _locations->session_range_location ();
4029 Location* l = _locations->auto_loop_location ();
4031 if (l->end() == old) {
4032 l->set_end (s->end(), true);
4037 Session::source_search_path (DataType type) const
4041 if (session_dirs.size() == 1) {
4043 case DataType::AUDIO:
4044 search_path = _session_dir->sound_path().to_string();
4046 case DataType::MIDI:
4047 search_path = _session_dir->midi_path().to_string();
4051 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4052 SessionDirectory sdir (i->path);
4053 if (!search_path.empty()) {
4057 case DataType::AUDIO:
4058 search_path += sdir.sound_path().to_string();
4060 case DataType::MIDI:
4061 search_path += sdir.midi_path().to_string();
4067 /* now add user-specified locations
4070 vector<string> dirs;
4073 case DataType::AUDIO:
4074 split (config.get_audio_search_path (), dirs, ':');
4076 case DataType::MIDI:
4077 split (config.get_midi_search_path (), dirs, ':');
4081 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4091 Session::ensure_search_path_includes (const string& path, DataType type)
4094 vector<string> dirs;
4101 case DataType::AUDIO:
4102 search_path = config.get_audio_search_path ();
4104 case DataType::MIDI:
4105 search_path = config.get_midi_search_path ();
4109 split (search_path, dirs, ':');
4111 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4117 if (!search_path.empty()) {
4121 search_path += path;
4124 case DataType::AUDIO:
4125 config.set_audio_search_path (search_path);
4127 case DataType::MIDI:
4128 config.set_midi_search_path (search_path);
4133 boost::shared_ptr<Speakers>
4134 Session::get_speakers()
4140 Session::unknown_processors () const
4144 boost::shared_ptr<RouteList> r = routes.reader ();
4145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4146 list<string> t = (*i)->unknown_processors ();
4147 copy (t.begin(), t.end(), back_inserter (p));
4156 #ifdef HAVE_JACK_NEW_LATENCY
4158 Session::update_latency (bool playback)
4160 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback\n");
4162 boost::shared_ptr<RouteList> r = routes.reader ();
4165 /* reverse the list so that we work backwards from the last route to run to the first */
4166 reverse (r->begin(), r->end());
4169 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4170 DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Working on latency for %1\n", (*i)->name()));
4171 (*i)->set_latency_ranges (playback);
4172 DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Done working on latency for %1\n\n", (*i)->name()));