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.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <glibmm/threads.h>
33 #include <glibmm/miscutils.h>
34 #include <glibmm/fileutils.h>
36 #include <boost/algorithm/string/erase.hpp>
38 #include "pbd/basename.h"
39 #include "pbd/convert.h"
40 #include "pbd/error.h"
41 #include "pbd/file_utils.h"
43 #include "pbd/pthread_utils.h"
44 #include "pbd/search_path.h"
45 #include "pbd/stacktrace.h"
46 #include "pbd/stl_delete.h"
47 #include "pbd/replace_all.h"
48 #include "pbd/unwind.h"
50 #include "ardour/amp.h"
51 #include "ardour/analyser.h"
52 #include "ardour/async_midi_port.h"
53 #include "ardour/audio_buffer.h"
54 #include "ardour/audio_diskstream.h"
55 #include "ardour/audio_port.h"
56 #include "ardour/audio_track.h"
57 #include "ardour/audioengine.h"
58 #include "ardour/audiofilesource.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/boost_debug.h"
61 #include "ardour/buffer_manager.h"
62 #include "ardour/buffer_set.h"
63 #include "ardour/bundle.h"
64 #include "ardour/butler.h"
65 #include "ardour/click.h"
66 #include "ardour/control_protocol_manager.h"
67 #include "ardour/data_type.h"
68 #include "ardour/debug.h"
69 #include "ardour/directory_names.h"
70 #ifdef USE_TRACKS_CODE_FEATURES
71 #include "ardour/engine_state_controller.h"
73 #include "ardour/filename_extensions.h"
74 #include "ardour/gain_control.h"
75 #include "ardour/graph.h"
76 #include "ardour/luabindings.h"
77 #include "ardour/midiport_manager.h"
78 #include "ardour/scene_changer.h"
79 #include "ardour/midi_patch_manager.h"
80 #include "ardour/midi_track.h"
81 #include "ardour/midi_ui.h"
82 #include "ardour/operations.h"
83 #include "ardour/playlist.h"
84 #include "ardour/playlist_factory.h"
85 #include "ardour/plugin.h"
86 #include "ardour/plugin_insert.h"
87 #include "ardour/process_thread.h"
88 #include "ardour/profile.h"
89 #include "ardour/rc_configuration.h"
90 #include "ardour/recent_sessions.h"
91 #include "ardour/region.h"
92 #include "ardour/region_factory.h"
93 #include "ardour/revision.h"
94 #include "ardour/route_graph.h"
95 #include "ardour/route_group.h"
96 #include "ardour/send.h"
97 #include "ardour/session.h"
98 #include "ardour/session_directory.h"
99 #include "ardour/session_playlists.h"
100 #include "ardour/smf_source.h"
101 #include "ardour/solo_isolate_control.h"
102 #include "ardour/source_factory.h"
103 #include "ardour/speakers.h"
104 #include "ardour/tempo.h"
105 #include "ardour/ticker.h"
106 #include "ardour/track.h"
107 #include "ardour/user_bundle.h"
108 #include "ardour/utils.h"
109 #include "ardour/vca_manager.h"
110 #include "ardour/vca.h"
112 #include "midi++/port.h"
113 #include "midi++/mmc.h"
115 #include "LuaBridge/LuaBridge.h"
117 #include "pbd/i18n.h"
119 #include <glibmm/checksum.h>
128 using namespace ARDOUR;
131 bool Session::_disable_all_loaded_plugins = false;
132 bool Session::_bypass_all_loaded_plugins = false;
133 guint Session::_name_id_counter = 0;
135 PBD::Signal1<int,uint32_t> Session::AudioEngineSetupRequired;
136 PBD::Signal1<void,std::string> Session::Dialog;
137 PBD::Signal0<int> Session::AskAboutPendingState;
138 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
139 PBD::Signal2<void, framecnt_t, framecnt_t> Session::NotifyAboutSampleRateMismatch;
140 PBD::Signal0<void> Session::SendFeedback;
141 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
143 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
144 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
145 PBD::Signal2<void,std::string, std::string> Session::Exported;
146 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
147 PBD::Signal0<void> Session::Quit;
148 PBD::Signal0<void> Session::FeedbackDetected;
149 PBD::Signal0<void> Session::SuccessfulGraphSort;
150 PBD::Signal2<void,std::string,std::string> Session::VersionMismatch;
152 const framecnt_t Session::bounce_chunk_size = 8192;
153 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
154 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
156 // seconds should be added after the region exceeds end marker
157 #ifdef USE_TRACKS_CODE_FEATURES
158 const uint32_t Session::session_end_shift = 5;
160 const uint32_t Session::session_end_shift = 0;
163 /** @param snapshot_name Snapshot name, without .ardour suffix */
164 Session::Session (AudioEngine &eng,
165 const string& fullpath,
166 const string& snapshot_name,
167 BusProfile* bus_profile,
169 : playlists (new SessionPlaylists)
171 , process_function (&Session::process_with_events)
172 , _bounce_processing_active (false)
173 , waiting_for_sync_offset (false)
174 , _base_frame_rate (0)
175 , _nominal_frame_rate (0)
176 , _current_frame_rate (0)
177 , transport_sub_state (0)
178 , _record_status (Disabled)
179 , _transport_frame (0)
180 , _session_range_location (0)
181 , _session_range_end_is_free (true)
184 , _transport_speed (0)
185 , _default_transport_speed (1.0)
186 , _last_transport_speed (0)
187 , _target_transport_speed (0.0)
188 , auto_play_legal (false)
189 , _last_slave_transport_frame (0)
190 , maximum_output_latency (0)
191 , _requested_return_frame (-1)
192 , current_block_size (0)
193 , _worst_output_latency (0)
194 , _worst_input_latency (0)
195 , _worst_track_latency (0)
196 , _have_captured (false)
197 , _non_soloed_outs_muted (false)
200 , _solo_isolated_cnt (0)
202 , _was_seamless (Config->get_seamless_loop ())
203 , _under_nsm_control (false)
205 , delta_accumulator_cnt (0)
206 , average_slave_delta (1800) // !!! why 1800 ???
208 , have_first_delta_accumulator (false)
209 , _slave_state (Stopped)
210 , _mtc_active (false)
211 , _ltc_active (false)
212 , post_export_sync (false)
213 , post_export_position (0)
215 , _export_rolling (false)
216 , _realtime_export (false)
217 , _region_export (false)
218 , _export_preroll (0)
219 , _export_latency (0)
220 , _pre_export_mmc_enabled (false)
221 , _name (snapshot_name)
223 , _send_qf_mtc (false)
224 , _pframes_since_last_mtc (0)
225 , session_midi_feedback (0)
227 , loop_changing (false)
229 , _session_dir (new SessionDirectory (fullpath))
230 , _current_snapshot_name (snapshot_name)
232 , state_was_pending (false)
233 , _state_of_the_state (StateOfTheState(CannotSave|InitialConnecting|Loading))
235 , _save_queued (false)
236 , _last_roll_location (0)
237 , _last_roll_or_reversal_location (0)
238 , _last_record_location (0)
239 , pending_locate_roll (false)
240 , pending_locate_frame (0)
241 , pending_locate_flush (false)
242 , pending_abort (false)
243 , pending_auto_loop (false)
244 , _mempool ("Session", 2097152)
245 , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
247 , _butler (new Butler (*this))
248 , _post_transport_work (0)
249 , cumulative_rf_motion (0)
251 , _locations (new Locations (*this))
252 , _ignore_skips_updates (false)
253 , _rt_thread_active (false)
254 , _rt_emit_pending (false)
255 , _ac_thread_active (false)
256 , _latency_recompute_pending (0)
258 , outbound_mtc_timecode_frame (0)
259 , next_quarter_frame_to_send (-1)
260 , _frames_per_timecode_frame (0)
261 , _frames_per_hour (0)
262 , _timecode_frames_per_hour (0)
263 , last_timecode_valid (false)
264 , last_timecode_when (0)
265 , _send_timecode_update (false)
277 , ltc_timecode_offset (0)
278 , ltc_timecode_negative_offset (false)
279 , midi_control_ui (0)
281 , _all_route_group (new RouteGroup (*this, "all"))
282 , routes (new RouteList)
283 , _adding_routes_in_progress (false)
284 , _reconnecting_routes_in_progress (false)
285 , _route_deletion_in_progress (false)
286 , destructive_index (0)
287 , _track_number_decimals(1)
288 , default_fade_steepness (0)
289 , default_fade_msecs (0)
290 , _total_free_4k_blocks (0)
291 , _total_free_4k_blocks_uncertain (false)
292 , no_questions_about_missing_files (false)
295 , _bundles (new BundleList)
296 , _bundle_xml_node (0)
300 , click_emphasis_data (0)
302 , click_emphasis_length (0)
303 , _clicks_cleared (0)
304 , _play_range (false)
305 , _range_selection (-1,-1)
306 , _object_selection (-1,-1)
308 , first_file_data_format_reset (true)
309 , first_file_header_format_reset (true)
310 , have_looped (false)
311 , _have_rec_enabled_track (false)
312 , _have_rec_disabled_track (true)
314 , _suspend_timecode_transmission (0)
315 , _speakers (new Speakers)
316 , _ignore_route_processor_changes (0)
321 , _vca_manager (new VCAManager (*this))
325 created_with = string_compose ("%1 %2", PROGRAM_NAME, revision);
327 pthread_mutex_init (&_rt_emit_mutex, 0);
328 pthread_cond_init (&_rt_emit_cond, 0);
330 pthread_mutex_init (&_auto_connect_mutex, 0);
331 pthread_cond_init (&_auto_connect_cond, 0);
333 init_name_id_counter (1); // reset for new sessions, start at 1
334 VCA::set_next_vca_number (1); // reset for new sessions, start at 1
336 pre_engine_init (fullpath);
342 Stateful::loading_state_version = CURRENT_SESSION_FILE_VERSION;
344 #ifdef USE_TRACKS_CODE_FEATURES
345 sr = EngineStateController::instance()->get_current_sample_rate();
347 if (ensure_engine (sr, true)) {
349 throw SessionException (_("Cannot connect to audio/midi engine"));
352 // set samplerate for plugins added early
353 // e.g from templates or MB channelstrip
354 set_block_size (_engine.samples_per_cycle());
355 set_frame_rate (_engine.sample_rate());
357 if (create (mix_template, bus_profile)) {
359 throw SessionException (_("Session initialization failed"));
362 /* if a mix template was provided, then ::create() will
363 * have copied it into the session and we need to load it
364 * so that we have the state ready for ::set_state()
365 * after the engine is started.
367 * Note that we do NOT try to get the sample rate from
368 * the template at this time, though doing so would
369 * be easy if we decided this was an appropriate part
373 if (!mix_template.empty()) {
374 if (load_state (_current_snapshot_name)) {
375 throw SessionException (_("Failed to load template/snapshot state"));
377 store_recent_templates (mix_template);
380 /* load default session properties - if any */
385 if (load_state (_current_snapshot_name)) {
386 throw SessionException (_("Failed to load state"));
389 /* try to get sample rate from XML state so that we
390 * can influence the SR if we set up the audio
395 XMLProperty const * prop;
396 XMLNode const * root (state_tree->root());
397 if ((prop = root->property (X_("sample-rate"))) != 0) {
398 sr = atoi (prop->value());
402 if (ensure_engine (sr, false)) {
404 throw SessionException (_("Cannot connect to audio/midi engine"));
408 if (post_engine_init ()) {
410 throw SessionException (_("Cannot configure audio/midi engine with session parameters"));
413 store_recent_sessions (_name, _path);
415 bool was_dirty = dirty();
417 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
419 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
420 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
423 DirtyChanged (); /* EMIT SIGNAL */
426 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
427 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
429 emit_thread_start ();
430 auto_connect_thread_start ();
432 /* hook us up to the engine since we are now completely constructed */
434 BootMessage (_("Connect to engine"));
436 _engine.set_session (this);
437 _engine.reset_timebase ();
439 #ifdef USE_TRACKS_CODE_FEATURES
441 EngineStateController::instance()->set_session(this);
444 if ( ARDOUR::Profile->get_trx () ) {
446 /* Waves Tracks: fill session with tracks basing on the amount of inputs.
447 * each available input must have corresponding track when session starts.
450 uint32_t how_many (0);
452 std::vector<std::string> inputs;
453 EngineStateController::instance()->get_physical_audio_inputs(inputs);
455 how_many = inputs.size();
457 list<boost::shared_ptr<AudioTrack> > tracks;
459 // Track names after driver
460 if (Config->get_tracks_auto_naming() == NameAfterDriver) {
461 string track_name = "";
462 for (std::vector<string>::size_type i = 0; i < inputs.size(); ++i) {
464 track_name = inputs[i];
465 replace_all (track_name, "system:capture", "");
467 list<boost::shared_ptr<AudioTrack> > single_track = new_audio_track (1, 1, Normal, 0, 1, track_name);
468 tracks.insert(tracks.begin(), single_track.front());
470 } else { // Default track names
471 tracks = new_audio_track (1, 1, Normal, 0, how_many, string());
474 if (tracks.size() != how_many) {
476 throw failed_constructor ();
485 BootMessage (_("Session loading complete"));
497 Session::next_name_id ()
499 return g_atomic_int_add (&_name_id_counter, 1);
503 Session::name_id_counter ()
505 return g_atomic_int_get (&_name_id_counter);
509 Session::init_name_id_counter (guint n)
511 g_atomic_int_set (&_name_id_counter, n);
515 Session::ensure_engine (uint32_t desired_sample_rate, bool isnew)
517 if (_engine.current_backend() == 0) {
518 /* backend is unknown ... */
519 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
520 if (r.get_value_or (-1) != 0) {
523 } else if (!isnew && _engine.running() && _engine.sample_rate () == desired_sample_rate) {
525 } else if (_engine.setup_required()) {
526 /* backend is known, but setup is needed */
527 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
528 if (r.get_value_or (-1) != 0) {
531 } else if (!_engine.running()) {
532 if (_engine.start()) {
537 /* at this point the engine should be running */
539 if (!_engine.running()) {
543 return immediately_post_engine ();
548 Session::immediately_post_engine ()
550 /* Do various initializations that should take place directly after we
551 * know that the engine is running, but before we either create a
552 * session or set state for an existing one.
555 if (how_many_dsp_threads () > 1) {
556 /* For now, only create the graph if we are using >1 DSP threads, as
557 it is a bit slower than the old code with 1 thread.
559 _process_graph.reset (new Graph (*this));
562 /* every time we reconnect, recompute worst case output latencies */
564 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
566 if (synced_to_engine()) {
567 _engine.transport_stop ();
570 if (config.get_jack_time_master()) {
571 _engine.transport_locate (_transport_frame);
576 BootMessage (_("Set up LTC"));
578 BootMessage (_("Set up Click"));
580 BootMessage (_("Set up standard connections"));
584 catch (failed_constructor& err) {
588 /* TODO, connect in different thread. (PortRegisteredOrUnregistered may be in RT context)
590 _engine.PortRegisteredOrUnregistered.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
598 vector<void*> debug_pointers;
600 /* if we got to here, leaving pending capture state around
604 remove_pending_capture_state ();
608 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
610 /* stop autoconnecting */
611 auto_connect_thread_terminate ();
613 /* disconnect from any and all signals that we are connected to */
615 Port::PortSignalDrop (); /* EMIT SIGNAL */
618 /* shutdown control surface protocols while we still have ports
619 and the engine to move data to any devices.
622 ControlProtocolManager::instance().drop_protocols ();
624 MIDI::Name::MidiPatchManager::instance().remove_search_path(session_directory().midi_patch_path());
626 _engine.remove_session ();
628 #ifdef USE_TRACKS_CODE_FEATURES
629 EngineStateController::instance()->remove_session();
632 /* deregister all ports - there will be no process or any other
633 * callbacks from the engine any more.
636 Port::PortDrop (); /* EMIT SIGNAL */
640 /* clear history so that no references to objects are held any more */
644 /* clear state tree so that no references to objects are held any more */
649 // unregister all lua functions, drop held references (if any)
651 lua.do_command ("Session = nil");
659 lua.collect_garbage ();
661 /* reset dynamic state version back to default */
662 Stateful::loading_state_version = 0;
664 _butler->drop_references ();
668 delete _all_route_group;
670 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
671 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
675 if (click_data != default_click) {
676 delete [] click_data;
679 if (click_emphasis_data != default_click_emphasis) {
680 delete [] click_emphasis_data;
685 /* need to remove auditioner before monitoring section
686 * otherwise it is re-connected */
689 /* drop references to routes held by the monitoring section
690 * specifically _monitor_out aux/listen references */
691 remove_monitor_section();
693 /* clear out any pending dead wood from RCU managed objects */
698 AudioDiskstream::free_working_buffers();
700 /* tell everyone who is still standing that we're about to die */
703 /* tell everyone to drop references and delete objects as we go */
705 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
706 RegionFactory::delete_all_regions ();
708 /* Do this early so that VCAs no longer hold references to routes */
710 DEBUG_TRACE (DEBUG::Destruction, "delete vcas\n");
713 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
715 /* reset these three references to special routes before we do the usual route delete thing */
717 _master_out.reset ();
718 _monitor_out.reset ();
721 RCUWriter<RouteList> writer (routes);
722 boost::shared_ptr<RouteList> r = writer.get_copy ();
724 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
725 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
726 (*i)->drop_references ();
730 /* writer goes out of scope and updates master */
735 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
736 Glib::Threads::Mutex::Lock lm (source_lock);
737 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
738 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
739 i->second->drop_references ();
745 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
748 emit_thread_terminate ();
750 pthread_cond_destroy (&_rt_emit_cond);
751 pthread_mutex_destroy (&_rt_emit_mutex);
753 pthread_cond_destroy (&_auto_connect_cond);
754 pthread_mutex_destroy (&_auto_connect_mutex);
756 delete _scene_changer; _scene_changer = 0;
757 delete midi_control_ui; midi_control_ui = 0;
759 delete _mmc; _mmc = 0;
760 delete _midi_ports; _midi_ports = 0;
761 delete _locations; _locations = 0;
766 /* clear event queue, the session is gone, nobody is interested in
767 * those anymore, but they do leak memory if not removed
769 while (!immediate_events.empty ()) {
770 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
771 SessionEvent *ev = immediate_events.front ();
772 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Drop event: %1\n", enum_2_string (ev->type)));
773 immediate_events.pop_front ();
777 case SessionEvent::AutoLoop:
778 case SessionEvent::AutoLoopDeclick:
779 case SessionEvent::Skip:
780 case SessionEvent::PunchIn:
781 case SessionEvent::PunchOut:
782 case SessionEvent::StopOnce:
783 case SessionEvent::RangeStop:
784 case SessionEvent::RangeLocate:
788 case SessionEvent::RealTimeOperation:
795 del = del && !_remove_event (ev);
802 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
804 BOOST_SHOW_POINTERS ();
808 Session::setup_ltc ()
812 _ltc_input.reset (new IO (*this, X_("LTC In"), IO::Input));
813 _ltc_output.reset (new IO (*this, X_("LTC Out"), IO::Output));
815 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC In"))) != 0) {
816 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
819 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
820 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
822 reconnect_ltc_input ();
825 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC Out"))) != 0) {
826 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
829 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
830 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
832 reconnect_ltc_output ();
835 /* fix up names of LTC ports because we don't want the normal
836 * IO style of NAME/TYPE-{in,out}N
839 _ltc_input->nth (0)->set_name (X_("LTC-in"));
840 _ltc_output->nth (0)->set_name (X_("LTC-out"));
844 Session::setup_click ()
848 boost::shared_ptr<AutomationList> gl (new AutomationList (Evoral::Parameter (GainAutomation)));
849 boost::shared_ptr<GainControl> gain_control = boost::shared_ptr<GainControl> (new GainControl (*this, Evoral::Parameter(GainAutomation), gl));
851 _click_io.reset (new ClickIO (*this, X_("Click")));
852 _click_gain.reset (new Amp (*this, _("Fader"), gain_control, true));
853 _click_gain->activate ();
855 setup_click_state (state_tree->root());
857 setup_click_state (0);
862 Session::setup_click_state (const XMLNode* node)
864 const XMLNode* child = 0;
866 if (node && (child = find_named_node (*node, "Click")) != 0) {
868 /* existing state for Click */
871 if (Stateful::loading_state_version < 3000) {
872 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
874 const XMLNodeList& children (child->children());
875 XMLNodeList::const_iterator i = children.begin();
876 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
878 if (i != children.end()) {
879 c = _click_gain->set_state (**i, Stateful::loading_state_version);
885 _clicking = Config->get_clicking ();
889 error << _("could not setup Click I/O") << endmsg;
896 /* default state for Click: dual-mono to first 2 physical outputs */
899 _engine.get_physical_outputs (DataType::AUDIO, outs);
901 for (uint32_t physport = 0; physport < 2; ++physport) {
902 if (outs.size() > physport) {
903 if (_click_io->add_port (outs[physport], this)) {
904 // relax, even though its an error
909 if (_click_io->n_ports () > ChanCount::ZERO) {
910 _clicking = Config->get_clicking ();
916 Session::get_physical_ports (vector<string>& inputs, vector<string>& outputs, DataType type,
917 MidiPortFlags include, MidiPortFlags exclude)
919 _engine.get_physical_inputs (type, inputs, include, exclude);
920 _engine.get_physical_outputs (type, outputs, include, exclude);
924 Session::setup_bundles ()
928 RCUWriter<BundleList> writer (_bundles);
929 boost::shared_ptr<BundleList> b = writer.get_copy ();
930 for (BundleList::iterator i = b->begin(); i != b->end();) {
931 if (boost::dynamic_pointer_cast<UserBundle>(*i)) {
939 vector<string> inputs[DataType::num_types];
940 vector<string> outputs[DataType::num_types];
942 for (uint32_t i = 0; i < DataType::num_types; ++i) {
943 get_physical_ports (inputs[i], outputs[i], DataType (DataType::Symbol (i)),
944 MidiPortFlags (0), /* no specific inclusions */
945 MidiPortFlags (MidiPortControl|MidiPortVirtual) /* exclude control & virtual ports */
949 /* Create a set of Bundle objects that map
950 to the physical I/O currently available. We create both
951 mono and stereo bundles, so that the common cases of mono
952 and stereo tracks get bundles to put in their mixer strip
953 in / out menus. There may be a nicer way of achieving that;
954 it doesn't really scale that well to higher channel counts
957 /* mono output bundles */
959 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
961 std::string pn = _engine.get_pretty_name_by_name (outputs[DataType::AUDIO][np]);
963 snprintf (buf, sizeof (buf), _("out %s"), pn.c_str());
965 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
968 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
969 c->add_channel (_("mono"), DataType::AUDIO);
970 c->set_port (0, outputs[DataType::AUDIO][np]);
972 add_bundle (c, false);
975 /* stereo output bundles */
977 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
978 if (np + 1 < outputs[DataType::AUDIO].size()) {
980 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
981 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
982 c->add_channel (_("L"), DataType::AUDIO);
983 c->set_port (0, outputs[DataType::AUDIO][np]);
984 c->add_channel (_("R"), DataType::AUDIO);
985 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
987 add_bundle (c, false);
991 /* mono input bundles */
993 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
995 std::string pn = _engine.get_pretty_name_by_name (inputs[DataType::AUDIO][np]);
997 snprintf (buf, sizeof (buf), _("in %s"), pn.c_str());
999 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
1002 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
1003 c->add_channel (_("mono"), DataType::AUDIO);
1004 c->set_port (0, inputs[DataType::AUDIO][np]);
1006 add_bundle (c, false);
1009 /* stereo input bundles */
1011 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
1012 if (np + 1 < inputs[DataType::AUDIO].size()) {
1014 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
1016 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
1017 c->add_channel (_("L"), DataType::AUDIO);
1018 c->set_port (0, inputs[DataType::AUDIO][np]);
1019 c->add_channel (_("R"), DataType::AUDIO);
1020 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
1022 add_bundle (c, false);
1026 /* MIDI input bundles */
1028 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
1029 string n = inputs[DataType::MIDI][np];
1031 std::string pn = _engine.get_pretty_name_by_name (n);
1035 boost::erase_first (n, X_("alsa_pcm:"));
1037 boost::shared_ptr<Bundle> c (new Bundle (n, false));
1038 c->add_channel ("", DataType::MIDI);
1039 c->set_port (0, inputs[DataType::MIDI][np]);
1040 add_bundle (c, false);
1043 /* MIDI output bundles */
1045 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
1046 string n = outputs[DataType::MIDI][np];
1047 std::string pn = _engine.get_pretty_name_by_name (n);
1051 boost::erase_first (n, X_("alsa_pcm:"));
1053 boost::shared_ptr<Bundle> c (new Bundle (n, true));
1054 c->add_channel ("", DataType::MIDI);
1055 c->set_port (0, outputs[DataType::MIDI][np]);
1056 add_bundle (c, false);
1059 // we trust the backend to only calls us if there's a change
1060 BundleAddedOrRemoved (); /* EMIT SIGNAL */
1064 Session::auto_connect_master_bus ()
1066 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
1070 // Waves Tracks: Do not connect master bas for Tracks if AutoConnectMaster option is not set
1071 // In this case it means "Multi Out" output mode
1072 if (ARDOUR::Profile->get_trx() && !(Config->get_output_auto_connect() & AutoConnectMaster) ) {
1076 /* if requested auto-connect the outputs to the first N physical ports.
1079 uint32_t limit = _master_out->n_outputs().n_total();
1080 vector<string> outputs[DataType::num_types];
1082 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1083 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1086 for (uint32_t n = 0; n < limit; ++n) {
1087 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
1089 if (outputs[p->type()].size() > n) {
1090 connect_to = outputs[p->type()][n];
1093 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
1094 if (_master_out->output()->connect (p, connect_to, this)) {
1095 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
1104 Session::remove_monitor_section ()
1106 if (!_monitor_out || Profile->get_trx()) {
1110 /* force reversion to Solo-In-Place */
1111 Config->set_solo_control_is_listen_control (false);
1113 /* if we are auditioning, cancel it ... this is a workaround
1114 to a problem (auditioning does not execute the process graph,
1115 which is needed to remove routes when using >1 core for processing)
1120 /* Hold process lock while doing this so that we don't hear bits and
1121 * pieces of audio as we work on each route.
1124 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1126 /* Connect tracks to monitor section. Note that in an
1127 existing session, the internal sends will already exist, but we want the
1128 routes to notice that they connect to the control out specifically.
1132 boost::shared_ptr<RouteList> r = routes.reader ();
1133 ProcessorChangeBlocker pcb (this, false);
1135 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
1137 if ((*x)->is_monitor()) {
1139 } else if ((*x)->is_master()) {
1142 (*x)->remove_aux_or_listen (_monitor_out);
1147 remove_route (_monitor_out);
1148 if (_state_of_the_state & Deletion) {
1152 auto_connect_master_bus ();
1155 auditioner->connect ();
1158 Config->ParameterChanged ("use-monitor-bus");
1162 Session::add_monitor_section ()
1166 if (_monitor_out || !_master_out || Profile->get_trx()) {
1170 boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), PresentationInfo::MonitorOut, DataType::AUDIO));
1176 BOOST_MARK_ROUTE(r);
1179 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1180 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
1181 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
1183 error << _("Cannot create monitor section. 'Monitor' Port name is not unique.") << endmsg;
1188 add_routes (rl, false, false, false, 0);
1190 assert (_monitor_out);
1192 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
1193 are undefined, at best.
1196 uint32_t limit = _monitor_out->n_inputs().n_audio();
1200 /* connect the inputs to the master bus outputs. this
1201 * represents a separate data feed from the internal sends from
1202 * each route. as of jan 2011, it allows the monitor section to
1203 * conditionally ignore either the internal sends or the normal
1204 * input feed, but we should really find a better way to do
1208 _master_out->output()->disconnect (this);
1210 for (uint32_t n = 0; n < limit; ++n) {
1211 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1212 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1215 string connect_to = o->name();
1216 if (_monitor_out->input()->connect (p, connect_to, this)) {
1217 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1225 /* if monitor section is not connected, connect it to physical outs
1228 if ((Config->get_auto_connect_standard_busses () || Profile->get_mixbus ()) && !_monitor_out->output()->connected ()) {
1230 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1232 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1235 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1237 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1238 Config->get_monitor_bus_preferred_bundle())
1244 /* Monitor bus is audio only */
1246 vector<string> outputs[DataType::num_types];
1248 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1249 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1252 uint32_t mod = outputs[DataType::AUDIO].size();
1253 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1257 for (uint32_t n = 0; n < limit; ++n) {
1259 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1261 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1262 connect_to = outputs[DataType::AUDIO][n % mod];
1265 if (!connect_to.empty()) {
1266 if (_monitor_out->output()->connect (p, connect_to, this)) {
1267 error << string_compose (
1268 _("cannot connect control output %1 to %2"),
1279 /* Hold process lock while doing this so that we don't hear bits and
1280 * pieces of audio as we work on each route.
1283 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1285 /* Connect tracks to monitor section. Note that in an
1286 existing session, the internal sends will already exist, but we want the
1287 routes to notice that they connect to the control out specifically.
1291 boost::shared_ptr<RouteList> rls = routes.reader ();
1293 ProcessorChangeBlocker pcb (this, false /* XXX */);
1295 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1297 if ((*x)->is_monitor()) {
1299 } else if ((*x)->is_master()) {
1302 (*x)->enable_monitor_send ();
1307 auditioner->connect ();
1309 Config->ParameterChanged ("use-monitor-bus");
1313 Session::reset_monitor_section ()
1315 /* Process lock should be held by the caller.*/
1317 if (!_monitor_out || Profile->get_trx()) {
1321 uint32_t limit = _master_out->n_outputs().n_audio();
1323 /* connect the inputs to the master bus outputs. this
1324 * represents a separate data feed from the internal sends from
1325 * each route. as of jan 2011, it allows the monitor section to
1326 * conditionally ignore either the internal sends or the normal
1327 * input feed, but we should really find a better way to do
1331 _master_out->output()->disconnect (this);
1332 _monitor_out->output()->disconnect (this);
1334 // monitor section follow master bus - except midi
1335 ChanCount mon_chn (_master_out->output()->n_ports());
1336 mon_chn.set_midi (0);
1338 _monitor_out->input()->ensure_io (mon_chn, false, this);
1339 _monitor_out->output()->ensure_io (mon_chn, false, this);
1341 for (uint32_t n = 0; n < limit; ++n) {
1342 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1343 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1346 string connect_to = o->name();
1347 if (_monitor_out->input()->connect (p, connect_to, this)) {
1348 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1355 /* connect monitor section to physical outs
1358 if (Config->get_auto_connect_standard_busses()) {
1360 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1362 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1365 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1367 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1368 Config->get_monitor_bus_preferred_bundle())
1374 /* Monitor bus is audio only */
1376 vector<string> outputs[DataType::num_types];
1378 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1379 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1382 uint32_t mod = outputs[DataType::AUDIO].size();
1383 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1387 for (uint32_t n = 0; n < limit; ++n) {
1389 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1391 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1392 connect_to = outputs[DataType::AUDIO][n % mod];
1395 if (!connect_to.empty()) {
1396 if (_monitor_out->output()->connect (p, connect_to, this)) {
1397 error << string_compose (
1398 _("cannot connect control output %1 to %2"),
1409 /* Connect tracks to monitor section. Note that in an
1410 existing session, the internal sends will already exist, but we want the
1411 routes to notice that they connect to the control out specifically.
1415 boost::shared_ptr<RouteList> rls = routes.reader ();
1417 ProcessorChangeBlocker pcb (this, false);
1419 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1421 if ((*x)->is_monitor()) {
1423 } else if ((*x)->is_master()) {
1426 (*x)->enable_monitor_send ();
1432 Session::hookup_io ()
1434 /* stop graph reordering notifications from
1435 causing resorts, etc.
1438 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
1442 /* we delay creating the auditioner till now because
1443 it makes its own connections to ports.
1447 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
1449 throw failed_constructor ();
1451 a->use_new_diskstream ();
1455 catch (failed_constructor& err) {
1456 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
1460 /* load bundles, which we may have postponed earlier on */
1461 if (_bundle_xml_node) {
1462 load_bundles (*_bundle_xml_node);
1463 delete _bundle_xml_node;
1466 /* Tell all IO objects to connect themselves together */
1468 IO::enable_connecting ();
1470 /* Now tell all "floating" ports to connect to whatever
1471 they should be connected to.
1474 AudioEngine::instance()->reconnect_ports ();
1476 /* Anyone who cares about input state, wake up and do something */
1478 IOConnectionsComplete (); /* EMIT SIGNAL */
1480 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
1482 /* now handle the whole enchilada as if it was one
1483 graph reorder event.
1488 /* update the full solo state, which can't be
1489 correctly determined on a per-route basis, but
1490 needs the global overview that only the session
1494 update_route_solo_state ();
1498 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
1500 boost::shared_ptr<Track> track = wp.lock ();
1505 boost::shared_ptr<Playlist> playlist;
1507 if ((playlist = track->playlist()) != 0) {
1508 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
1509 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
1510 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
1515 Session::record_enabling_legal () const
1517 /* this used to be in here, but survey says.... we don't need to restrict it */
1518 // if (record_status() == Recording) {
1522 if (Config->get_all_safe()) {
1529 Session::set_track_monitor_input_status (bool yn)
1531 boost::shared_ptr<RouteList> rl = routes.reader ();
1532 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1533 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
1534 if (tr && tr->rec_enable_control()->get_value()) {
1535 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1536 tr->request_input_monitoring (yn);
1542 Session::auto_punch_start_changed (Location* location)
1544 replace_event (SessionEvent::PunchIn, location->start());
1546 if (get_record_enabled() && config.get_punch_in()) {
1547 /* capture start has been changed, so save new pending state */
1548 save_state ("", true);
1553 Session::auto_punch_end_changed (Location* location)
1555 framepos_t when_to_stop = location->end();
1556 // when_to_stop += _worst_output_latency + _worst_input_latency;
1557 replace_event (SessionEvent::PunchOut, when_to_stop);
1561 Session::auto_punch_changed (Location* location)
1563 framepos_t when_to_stop = location->end();
1565 replace_event (SessionEvent::PunchIn, location->start());
1566 //when_to_stop += _worst_output_latency + _worst_input_latency;
1567 replace_event (SessionEvent::PunchOut, when_to_stop);
1570 /** @param loc A loop location.
1571 * @param pos Filled in with the start time of the required fade-out (in session frames).
1572 * @param length Filled in with the length of the required fade-out.
1575 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
1577 pos = max (loc->start(), loc->end() - 64);
1578 length = loc->end() - pos;
1582 Session::auto_loop_changed (Location* location)
1584 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
1587 auto_loop_declick_range (location, dcp, dcl);
1589 if (transport_rolling() && play_loop) {
1591 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
1593 // if (_transport_frame > location->end()) {
1595 if (_transport_frame < location->start() || _transport_frame > location->end()) {
1596 // relocate to beginning of loop
1597 clear_events (SessionEvent::LocateRoll);
1599 request_locate (location->start(), true);
1602 else if (Config->get_seamless_loop() && !loop_changing) {
1604 // schedule a locate-roll to refill the diskstreams at the
1605 // previous loop end
1606 loop_changing = true;
1608 if (location->end() > last_loopend) {
1609 clear_events (SessionEvent::LocateRoll);
1610 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1616 clear_events (SessionEvent::AutoLoopDeclick);
1617 clear_events (SessionEvent::AutoLoop);
1620 /* possibly move playhead if not rolling; if we are rolling we'll move
1621 to the loop start on stop if that is appropriate.
1626 if (!transport_rolling() && select_playhead_priority_target (pos)) {
1627 if (pos == location->start()) {
1628 request_locate (pos);
1633 last_loopend = location->end();
1638 Session::set_auto_punch_location (Location* location)
1642 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1643 punch_connections.drop_connections();
1644 existing->set_auto_punch (false, this);
1645 remove_event (existing->start(), SessionEvent::PunchIn);
1646 clear_events (SessionEvent::PunchOut);
1647 auto_punch_location_changed (0);
1652 if (location == 0) {
1656 if (location->end() <= location->start()) {
1657 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1661 punch_connections.drop_connections ();
1663 location->StartChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, location));
1664 location->EndChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, location));
1665 location->Changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, location));
1667 location->set_auto_punch (true, this);
1669 auto_punch_changed (location);
1671 auto_punch_location_changed (location);
1675 Session::set_session_extents (framepos_t start, framepos_t end)
1678 if ((existing = _locations->session_range_location()) == 0) {
1679 //if there is no existing session, we need to make a new session location (should never happen)
1680 existing = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1684 error << _("Session: you can't use that location for session start/end)") << endmsg;
1688 existing->set( start, end );
1694 Session::set_auto_loop_location (Location* location)
1698 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1699 loop_connections.drop_connections ();
1700 existing->set_auto_loop (false, this);
1701 remove_event (existing->end(), SessionEvent::AutoLoop);
1704 auto_loop_declick_range (existing, dcp, dcl);
1705 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1706 auto_loop_location_changed (0);
1711 if (location == 0) {
1715 if (location->end() <= location->start()) {
1716 error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
1720 last_loopend = location->end();
1722 loop_connections.drop_connections ();
1724 location->StartChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1725 location->EndChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1726 location->Changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1727 location->FlagsChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1729 location->set_auto_loop (true, this);
1731 if (Config->get_loop_is_mode() && play_loop && Config->get_seamless_loop()) {
1732 // set all tracks to use internal looping
1733 boost::shared_ptr<RouteList> rl = routes.reader ();
1734 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1735 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1736 if (tr && !tr->hidden()) {
1737 tr->set_loop (location);
1742 /* take care of our stuff first */
1744 auto_loop_changed (location);
1746 /* now tell everyone else */
1748 auto_loop_location_changed (location);
1752 Session::update_marks (Location*)
1758 Session::update_skips (Location* loc, bool consolidate)
1760 if (_ignore_skips_updates) {
1764 Locations::LocationList skips;
1767 PBD::Unwinder<bool> uw (_ignore_skips_updates, true);
1768 consolidate_skips (loc);
1771 sync_locations_to_skips ();
1777 Session::consolidate_skips (Location* loc)
1779 Locations::LocationList all_locations = _locations->list ();
1781 for (Locations::LocationList::iterator l = all_locations.begin(); l != all_locations.end(); ) {
1783 if (!(*l)->is_skip ()) {
1788 /* don't test against self */
1795 switch (Evoral::coverage ((*l)->start(), (*l)->end(), loc->start(), loc->end())) {
1796 case Evoral::OverlapInternal:
1797 case Evoral::OverlapExternal:
1798 case Evoral::OverlapStart:
1799 case Evoral::OverlapEnd:
1800 /* adjust new location to cover existing one */
1801 loc->set_start (min (loc->start(), (*l)->start()));
1802 loc->set_end (max (loc->end(), (*l)->end()));
1803 /* we don't need this one any more */
1804 _locations->remove (*l);
1805 /* the location has been deleted, so remove reference to it in our local list */
1806 l = all_locations.erase (l);
1809 case Evoral::OverlapNone:
1817 Session::sync_locations_to_skips ()
1819 /* This happens asynchronously (in the audioengine thread). After the clear is done, we will call
1820 * Session::_sync_locations_to_skips() from the audioengine thread.
1822 clear_events (SessionEvent::Skip, boost::bind (&Session::_sync_locations_to_skips, this));
1826 Session::_sync_locations_to_skips ()
1828 /* called as a callback after existing Skip events have been cleared from a realtime audioengine thread */
1830 Locations::LocationList const & locs (_locations->list());
1832 for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) {
1834 Location* location = *i;
1836 if (location->is_skip() && location->is_skipping()) {
1837 SessionEvent* ev = new SessionEvent (SessionEvent::Skip, SessionEvent::Add, location->start(), location->end(), 1.0);
1845 Session::location_added (Location *location)
1847 if (location->is_auto_punch()) {
1848 set_auto_punch_location (location);
1851 if (location->is_auto_loop()) {
1852 set_auto_loop_location (location);
1855 if (location->is_session_range()) {
1856 /* no need for any signal handling or event setting with the session range,
1857 because we keep a direct reference to it and use its start/end directly.
1859 _session_range_location = location;
1862 if (location->is_mark()) {
1863 /* listen for per-location signals that require us to do any * global updates for marks */
1865 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1866 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1867 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1868 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1871 if (location->is_skip()) {
1872 /* listen for per-location signals that require us to update skip-locate events */
1874 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1875 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1876 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1877 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, false));
1879 update_skips (location, true);
1886 Session::location_removed (Location *location)
1888 if (location->is_auto_loop()) {
1889 set_auto_loop_location (0);
1890 set_track_loop (false);
1893 if (location->is_auto_punch()) {
1894 set_auto_punch_location (0);
1897 if (location->is_session_range()) {
1898 /* this is never supposed to happen */
1899 error << _("programming error: session range removed!") << endl;
1902 if (location->is_skip()) {
1904 update_skips (location, false);
1911 Session::locations_changed ()
1913 _locations->apply (*this, &Session::_locations_changed);
1917 Session::_locations_changed (const Locations::LocationList& locations)
1919 /* There was some mass-change in the Locations object.
1921 We might be re-adding a location here but it doesn't actually matter
1922 for all the locations that the Session takes an interest in.
1926 PBD::Unwinder<bool> protect_ignore_skip_updates (_ignore_skips_updates, true);
1927 for (Locations::LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
1928 location_added (*i);
1932 update_skips (NULL, false);
1936 Session::enable_record ()
1938 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1939 /* no recording at anything except normal speed */
1944 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1946 if (rs == Recording) {
1950 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1952 _last_record_location = _transport_frame;
1953 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1955 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1956 set_track_monitor_input_status (true);
1959 RecordStateChanged ();
1966 Session::set_all_tracks_record_enabled (bool enable )
1968 boost::shared_ptr<RouteList> rl = routes.reader();
1969 set_controls (route_list_to_control_list (rl, &Stripable::rec_enable_control), enable, Controllable::NoGroup);
1973 Session::disable_record (bool rt_context, bool force)
1977 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1979 if (!Config->get_latched_record_enable () || force) {
1980 g_atomic_int_set (&_record_status, Disabled);
1981 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1983 if (rs == Recording) {
1984 g_atomic_int_set (&_record_status, Enabled);
1988 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1989 set_track_monitor_input_status (false);
1992 RecordStateChanged (); /* emit signal */
1995 remove_pending_capture_state ();
2001 Session::step_back_from_record ()
2003 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
2005 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
2006 set_track_monitor_input_status (false);
2009 RecordStateChanged (); /* emit signal */
2014 Session::maybe_enable_record ()
2016 if (_step_editors > 0) {
2020 g_atomic_int_set (&_record_status, Enabled);
2022 /* This function is currently called from somewhere other than an RT thread.
2023 This save_state() call therefore doesn't impact anything. Doing it here
2024 means that we save pending state of which sources the next record will use,
2025 which gives us some chance of recovering from a crash during the record.
2028 save_state ("", true);
2030 if (_transport_speed) {
2031 if (!config.get_punch_in()) {
2035 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
2036 RecordStateChanged (); /* EMIT SIGNAL */
2043 Session::audible_frame () const
2047 frameoffset_t offset = worst_playback_latency (); // - _engine.samples_since_cycle_start ();
2048 offset *= transport_speed ();
2050 if (synced_to_engine()) {
2051 /* Note: this is basically just sync-to-JACK */
2052 ret = _engine.transport_frame();
2054 ret = _transport_frame;
2057 if (transport_rolling()) {
2060 /* Check to see if we have passed the first guaranteed
2061 * audible frame past our last start position. if not,
2062 * return that last start point because in terms
2063 * of audible frames, we have not moved yet.
2065 * `Start position' in this context means the time we last
2066 * either started, located, or changed transport direction.
2069 if (_transport_speed > 0.0f) {
2071 if (!play_loop || !have_looped) {
2072 if (ret < _last_roll_or_reversal_location) {
2073 return _last_roll_or_reversal_location;
2077 Location *location = _locations->auto_loop_location();
2078 frameoffset_t lo = location->start() - ret;
2080 ret = location->end () - lo;
2084 } else if (_transport_speed < 0.0f) {
2086 /* XXX wot? no backward looping? */
2088 if (ret > _last_roll_or_reversal_location) {
2089 return _last_roll_or_reversal_location;
2094 return std::max ((framepos_t)0, ret);
2098 Session::set_frame_rate (framecnt_t frames_per_second)
2100 /** \fn void Session::set_frame_size(framecnt_t)
2101 the AudioEngine object that calls this guarantees
2102 that it will not be called while we are also in
2103 ::process(). Its fine to do things that block
2107 if (_base_frame_rate == 0) {
2108 _base_frame_rate = frames_per_second;
2110 else if (_base_frame_rate != frames_per_second && frames_per_second != _nominal_frame_rate) {
2111 NotifyAboutSampleRateMismatch (_base_frame_rate, frames_per_second);
2113 _nominal_frame_rate = frames_per_second;
2118 reset_write_sources (false);
2120 // XXX we need some equivalent to this, somehow
2121 // SndFileSource::setup_standard_crossfades (frames_per_second);
2125 /* XXX need to reset/reinstantiate all LADSPA plugins */
2129 Session::set_block_size (pframes_t nframes)
2131 /* the AudioEngine guarantees
2132 that it will not be called while we are also in
2133 ::process(). It is therefore fine to do things that block
2138 current_block_size = nframes;
2142 boost::shared_ptr<RouteList> r = routes.reader ();
2144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2145 (*i)->set_block_size (nframes);
2148 boost::shared_ptr<RouteList> rl = routes.reader ();
2149 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2150 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2152 tr->set_block_size (nframes);
2156 set_worst_io_latencies ();
2162 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
2164 boost::shared_ptr<Route> r2;
2166 if (r1->feeds (rbase) && rbase->feeds (r1)) {
2167 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
2171 /* make a copy of the existing list of routes that feed r1 */
2173 Route::FedBy existing (r1->fed_by());
2175 /* for each route that feeds r1, recurse, marking it as feeding
2179 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
2180 if (!(r2 = i->r.lock ())) {
2181 /* (*i) went away, ignore it */
2185 /* r2 is a route that feeds r1 which somehow feeds base. mark
2186 base as being fed by r2
2189 rbase->add_fed_by (r2, i->sends_only);
2193 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
2197 if (r1->feeds (r2) && r2->feeds (r1)) {
2201 /* now recurse, so that we can mark base as being fed by
2202 all routes that feed r2
2205 trace_terminal (r2, rbase);
2212 Session::resort_routes ()
2214 /* don't do anything here with signals emitted
2215 by Routes during initial setup or while we
2216 are being destroyed.
2219 if (_state_of_the_state & (InitialConnecting | Deletion)) {
2223 if (_route_deletion_in_progress) {
2228 RCUWriter<RouteList> writer (routes);
2229 boost::shared_ptr<RouteList> r = writer.get_copy ();
2230 resort_routes_using (r);
2231 /* writer goes out of scope and forces update */
2235 if (DEBUG_ENABLED(DEBUG::Graph)) {
2236 boost::shared_ptr<RouteList> rl = routes.reader ();
2237 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2238 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
2240 const Route::FedBy& fb ((*i)->fed_by());
2242 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
2243 boost::shared_ptr<Route> sf = f->r.lock();
2245 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
2254 /** This is called whenever we need to rebuild the graph of how we will process
2256 * @param r List of routes, in any order.
2260 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
2262 /* We are going to build a directed graph of our routes;
2263 this is where the edges of that graph are put.
2268 /* Go through all routes doing two things:
2270 * 1. Collect the edges of the route graph. Each of these edges
2271 * is a pair of routes, one of which directly feeds the other
2272 * either by a JACK connection or by an internal send.
2274 * 2. Begin the process of making routes aware of which other
2275 * routes directly or indirectly feed them. This information
2276 * is used by the solo code.
2279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 /* Clear out the route's list of direct or indirect feeds */
2282 (*i)->clear_fed_by ();
2284 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
2286 bool via_sends_only;
2288 /* See if this *j feeds *i according to the current state of the JACK
2289 connections and internal sends.
2291 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
2292 /* add the edge to the graph (part #1) */
2293 edges.add (*j, *i, via_sends_only);
2294 /* tell the route (for part #2) */
2295 (*i)->add_fed_by (*j, via_sends_only);
2300 /* Attempt a topological sort of the route graph */
2301 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
2303 if (sorted_routes) {
2304 /* We got a satisfactory topological sort, so there is no feedback;
2307 Note: the process graph rechain does not require a
2308 topologically-sorted list, but hey ho.
2310 if (_process_graph) {
2311 _process_graph->rechain (sorted_routes, edges);
2314 _current_route_graph = edges;
2316 /* Complete the building of the routes' lists of what directly
2317 or indirectly feeds them.
2319 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2320 trace_terminal (*i, *i);
2323 *r = *sorted_routes;
2326 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
2327 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2328 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 presentation order %2\n", (*i)->name(), (*i)->presentation_info().order()));
2332 SuccessfulGraphSort (); /* EMIT SIGNAL */
2335 /* The topological sort failed, so we have a problem. Tell everyone
2336 and stick to the old graph; this will continue to be processed, so
2337 until the feedback is fixed, what is played back will not quite
2338 reflect what is actually connected. Note also that we do not
2339 do trace_terminal here, as it would fail due to an endless recursion,
2340 so the solo code will think that everything is still connected
2344 FeedbackDetected (); /* EMIT SIGNAL */
2349 /** Find a route name starting with \a base, maybe followed by the
2350 * lowest \a id. \a id will always be added if \a definitely_add_number
2351 * is true on entry; otherwise it will only be added if required
2352 * to make the name unique.
2354 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
2355 * The available route name with the lowest ID will be used, and \a id
2356 * will be set to the ID.
2358 * \return false if a route name could not be found, and \a track_name
2359 * and \a id do not reflect a free route name.
2362 Session::find_route_name (string const & base, uint32_t& id, string& name, bool definitely_add_number)
2364 /* the base may conflict with ports that do not belong to existing
2365 routes, but hidden objects like the click track. So check port names
2366 before anything else.
2369 for (vector<string>::const_iterator reserved = reserved_io_names.begin(); reserved != reserved_io_names.end(); ++reserved) {
2370 if (base == *reserved) {
2371 /* Check if this reserved name already exists, and if
2372 so, disallow it without a numeric suffix.
2374 if (route_by_name (*reserved)) {
2375 definitely_add_number = true;
2384 /* if we have "base 1" already, it doesn't make sense to add "base"
2385 * if "base 1" has been deleted, adding "base" is no worse than "base 1"
2387 if (!definitely_add_number && route_by_name (base) == 0 && (route_by_name (string_compose("%1 1", base)) == 0)) {
2388 /* just use the base */
2394 name = string_compose ("%1 %2", base, id);
2396 if (route_by_name (name) == 0) {
2402 } while (id < (UINT_MAX-1));
2407 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
2409 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
2411 in = ChanCount::ZERO;
2412 out = ChanCount::ZERO;
2414 boost::shared_ptr<RouteList> r = routes.reader ();
2416 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2417 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2418 if (tr && !tr->is_auditioner()) {
2419 in += tr->n_inputs();
2420 out += tr->n_outputs();
2426 Session::default_track_name_pattern (DataType t)
2429 case DataType::AUDIO:
2430 if (Profile->get_trx()) {
2437 case DataType::MIDI:
2444 /** Caller must not hold process lock
2445 * @param name_template string to use for the start of the name, or "" to use "MIDI".
2446 * @param instrument plugin info for the instrument to insert pre-fader, if any
2448 list<boost::shared_ptr<MidiTrack> >
2449 Session::new_midi_track (const ChanCount& input, const ChanCount& output,
2450 boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
2451 RouteGroup* route_group, uint32_t how_many, string name_template, PresentationInfo::order_t order,
2455 uint32_t track_id = 0;
2457 RouteList new_routes;
2458 list<boost::shared_ptr<MidiTrack> > ret;
2460 const string name_pattern = default_track_name_pattern (DataType::MIDI);
2461 bool const use_number = (how_many != 1) || name_template.empty () || (name_template == name_pattern);
2464 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, use_number)) {
2465 error << "cannot find name for new midi track" << endmsg;
2469 boost::shared_ptr<MidiTrack> track;
2472 track.reset (new MidiTrack (*this, track_name, mode));
2474 if (track->init ()) {
2478 if (Profile->get_mixbus ()) {
2479 track->set_strict_io (true);
2482 track->use_new_diskstream();
2484 BOOST_MARK_TRACK (track);
2487 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2488 if (track->input()->ensure_io (input, false, this)) {
2489 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
2493 if (track->output()->ensure_io (output, false, this)) {
2494 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
2499 track->non_realtime_input_change();
2502 route_group->add (track);
2505 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
2507 new_routes.push_back (track);
2508 ret.push_back (track);
2511 catch (failed_constructor &err) {
2512 error << _("Session: could not create new midi track.") << endmsg;
2516 catch (AudioEngine::PortRegistrationFailure& pfe) {
2518 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with more ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
2526 if (!new_routes.empty()) {
2527 StateProtector sp (this);
2528 if (Profile->get_trx()) {
2529 add_routes (new_routes, false, false, false, order);
2531 add_routes (new_routes, true, true, false, order);
2535 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
2536 PluginPtr plugin = instrument->load (*this);
2538 warning << "Failed to add Synth Plugin to newly created track." << endmsg;
2542 plugin->load_preset (*pset);
2544 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
2545 (*r)->add_processor (p, PreFader);
2554 Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
2555 PresentationInfo::Flag flag, PresentationInfo::order_t order)
2558 uint32_t bus_id = 0;
2562 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Midi Bus");
2565 if (!find_route_name (name_template.empty () ? _("Midi Bus") : name_template, ++bus_id, bus_name, use_number)) {
2566 error << "cannot find name for new midi bus" << endmsg;
2571 boost::shared_ptr<Route> bus (new Route (*this, bus_name, flag, DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
2577 if (Profile->get_mixbus ()) {
2578 bus->set_strict_io (true);
2581 BOOST_MARK_ROUTE(bus);
2584 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2586 if (bus->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
2587 error << _("cannot configure new midi bus input") << endmsg;
2592 if (bus->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
2593 error << _("cannot configure new midi bus output") << endmsg;
2599 route_group->add (bus);
2602 bus->add_internal_return ();
2603 ret.push_back (bus);
2606 catch (failed_constructor &err) {
2607 error << _("Session: could not create new audio route.") << endmsg;
2611 catch (AudioEngine::PortRegistrationFailure& pfe) {
2612 error << pfe.what() << endmsg;
2622 StateProtector sp (this);
2623 add_routes (ret, false, false, false, order);
2626 for (RouteList::iterator r = ret.begin(); r != ret.end(); ++r) {
2627 PluginPtr plugin = instrument->load (*this);
2629 warning << "Failed to add Synth Plugin to newly created track." << endmsg;
2633 plugin->load_preset (*pset);
2635 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
2636 (*r)->add_processor (p, PreFader);
2647 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
2649 boost::shared_ptr<Route> midi_track (wmt.lock());
2655 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
2657 if (change.after.n_audio() <= change.before.n_audio()) {
2661 /* new audio ports: make sure the audio goes somewhere useful,
2662 * unless the user has no-auto-connect selected.
2664 * The existing ChanCounts don't matter for this call as they are only
2665 * to do with matching input and output indices, and we are only changing
2668 auto_connect_route (midi_track, false, ChanCount(), change.before);
2672 #ifdef USE_TRACKS_CODE_FEATURES
2675 compare_routes_by_remote_id (const boost::shared_ptr<Route>& route1, const boost::shared_ptr<Route>& route2)
2677 return route1->remote_control_id() < route2->remote_control_id();
2681 Session::reconnect_existing_routes (bool withLock, bool reconnect_master, bool reconnect_inputs, bool reconnect_outputs)
2683 // it is not allowed to perform connection
2684 if (!IO::connecting_legal) {
2688 // if we are deleting routes we will call this once at the end
2689 if (_route_deletion_in_progress) {
2693 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
2699 // We need to disconnect the route's inputs and outputs first
2700 // basing on autoconnect configuration
2701 bool reconnectIputs = !(Config->get_input_auto_connect() & ManualConnect) && reconnect_inputs;
2702 bool reconnectOutputs = !(Config->get_output_auto_connect() & ManualConnect) && reconnect_outputs;
2704 ChanCount existing_inputs;
2705 ChanCount existing_outputs;
2706 count_existing_track_channels (existing_inputs, existing_outputs);
2708 //ChanCount inputs = ChanCount::ZERO;
2709 //ChanCount outputs = ChanCount::ZERO;
2711 RouteList existing_routes = *routes.reader ();
2712 existing_routes.sort (compare_routes_by_remote_id);
2715 PBD::Unwinder<bool> protect_ignore_changes (_reconnecting_routes_in_progress, true);
2717 vector<string> physinputs;
2718 vector<string> physoutputs;
2720 EngineStateController::instance()->get_physical_audio_outputs(physoutputs);
2721 EngineStateController::instance()->get_physical_audio_inputs(physinputs);
2723 uint32_t input_n = 0;
2724 uint32_t output_n = 0;
2725 RouteList::iterator rIter = existing_routes.begin();
2726 const AutoConnectOption current_input_auto_connection (Config->get_input_auto_connect());
2727 const AutoConnectOption current_output_auto_connection (Config->get_output_auto_connect());
2728 for (; rIter != existing_routes.end(); ++rIter) {
2729 if (*rIter == _master_out || *rIter == _monitor_out ) {
2733 if (current_output_auto_connection == AutoConnectPhysical) {
2734 (*rIter)->amp()->deactivate();
2735 } else if (current_output_auto_connection == AutoConnectMaster) {
2736 (*rIter)->amp()->activate();
2739 if (reconnectIputs) {
2740 (*rIter)->input()->disconnect (this); //GZ: check this; could be heavy
2742 for (uint32_t route_input_n = 0; route_input_n < (*rIter)->n_inputs().get(DataType::AUDIO); ++route_input_n) {
2744 if (current_input_auto_connection & AutoConnectPhysical) {
2746 if ( input_n == physinputs.size() ) {
2750 string port = physinputs[input_n];
2752 if (port.empty() ) {
2753 error << "Physical Input number "<< input_n << " is unavailable and cannot be connected" << endmsg;
2756 //GZ: check this; could be heavy
2757 (*rIter)->input()->connect ((*rIter)->input()->ports().port(DataType::AUDIO, route_input_n), port, this);
2763 if (reconnectOutputs) {
2765 //normalize route ouptuts: reduce the amount outputs to be equal to the amount of inputs
2766 if (current_output_auto_connection & AutoConnectPhysical) {
2768 //GZ: check this; could be heavy
2769 (*rIter)->output()->disconnect (this);
2770 size_t route_inputs_count = (*rIter)->n_inputs().get(DataType::AUDIO);
2772 //GZ: check this; could be heavy
2773 (*rIter)->output()->ensure_io(ChanCount(DataType::AUDIO, route_inputs_count), false, this );
2775 } else if (current_output_auto_connection & AutoConnectMaster){
2777 if (!reconnect_master) {
2781 //GZ: check this; could be heavy
2782 (*rIter)->output()->disconnect (this);
2785 uint32_t master_inputs_count = _master_out->n_inputs().get(DataType::AUDIO);
2786 (*rIter)->output()->ensure_io(ChanCount(DataType::AUDIO, master_inputs_count), false, this );
2788 error << error << "Master bus is not available" << endmsg;
2793 for (uint32_t route_output_n = 0; route_output_n < (*rIter)->n_outputs().get(DataType::AUDIO); ++route_output_n) {
2794 if (current_output_auto_connection & AutoConnectPhysical) {
2796 if ( output_n == physoutputs.size() ) {
2800 string port = physoutputs[output_n];
2802 if (port.empty() ) {
2803 error << "Physical Output number "<< output_n << " is unavailable and cannot be connected" << endmsg;
2806 //GZ: check this; could be heavy
2807 (*rIter)->output()->connect ((*rIter)->output()->ports().port(DataType::AUDIO, route_output_n), port, this);
2810 } else if (current_output_auto_connection & AutoConnectMaster) {
2812 if ( route_output_n == _master_out->n_inputs().get(DataType::AUDIO) ) {
2816 // connect to master bus
2817 string port = _master_out->input()->ports().port(DataType::AUDIO, route_output_n)->name();
2819 if (port.empty() ) {
2820 error << "MasterBus Input number "<< route_output_n << " is unavailable and cannot be connected" << endmsg;
2824 //GZ: check this; could be heavy
2825 (*rIter)->output()->connect ((*rIter)->output()->ports().port(DataType::AUDIO, route_output_n), port, this);
2832 _master_out->output()->disconnect (this);
2833 auto_connect_master_bus ();
2838 session_routes_reconnected (); /* EMIT SIGNAL */
2842 Session::reconnect_midi_scene_ports(bool inputs)
2846 boost::shared_ptr<MidiPort> scene_in_ptr = scene_in();
2848 scene_in_ptr->disconnect_all ();
2850 std::vector<EngineStateController::MidiPortState> midi_port_states;
2851 EngineStateController::instance()->get_physical_midi_input_states (midi_port_states);
2853 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2855 for (; state_iter != midi_port_states.end(); ++state_iter) {
2856 if (state_iter->active && state_iter->available && state_iter->scene_connected) {
2857 scene_in_ptr->connect (state_iter->name);
2864 boost::shared_ptr<MidiPort> scene_out_ptr = scene_out();
2866 if (scene_out_ptr ) {
2867 scene_out_ptr->disconnect_all ();
2869 std::vector<EngineStateController::MidiPortState> midi_port_states;
2870 EngineStateController::instance()->get_physical_midi_output_states (midi_port_states);
2872 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2874 for (; state_iter != midi_port_states.end(); ++state_iter) {
2875 if (state_iter->active && state_iter->available && state_iter->scene_connected) {
2876 scene_out_ptr->connect (state_iter->name);
2884 Session::reconnect_mtc_ports ()
2886 boost::shared_ptr<MidiPort> mtc_in_ptr = _midi_ports->mtc_input_port();
2892 mtc_in_ptr->disconnect_all ();
2894 std::vector<EngineStateController::MidiPortState> midi_port_states;
2895 EngineStateController::instance()->get_physical_midi_input_states (midi_port_states);
2897 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2899 for (; state_iter != midi_port_states.end(); ++state_iter) {
2900 if (state_iter->available && state_iter->mtc_in) {
2901 mtc_in_ptr->connect (state_iter->name);
2905 if (!_midi_ports->mtc_input_port ()->connected () &&
2906 config.get_external_sync () &&
2907 (Config->get_sync_source () == MTC) ) {
2908 config.set_external_sync (false);
2911 if ( ARDOUR::Profile->get_trx () ) {
2912 // Tracks need this signal to update timecode_source_dropdown
2913 MtcOrLtcInputPortChanged (); //emit signal
2918 Session::reconnect_mmc_ports(bool inputs)
2920 if (inputs ) { // get all enabled midi input ports
2922 boost::shared_ptr<MidiPort> mmc_in_ptr = _midi_ports->mmc_in();
2924 mmc_in_ptr->disconnect_all ();
2925 std::vector<std::string> enabled_midi_inputs;
2926 EngineStateController::instance()->get_physical_midi_inputs (enabled_midi_inputs);
2928 std::vector<std::string>::iterator port_iter = enabled_midi_inputs.begin();
2930 for (; port_iter != enabled_midi_inputs.end(); ++port_iter) {
2931 mmc_in_ptr->connect (*port_iter);
2935 } else { // get all enabled midi output ports
2937 boost::shared_ptr<MidiPort> mmc_out_ptr = _midi_ports->mmc_out();
2939 mmc_out_ptr->disconnect_all ();
2940 std::vector<std::string> enabled_midi_outputs;
2941 EngineStateController::instance()->get_physical_midi_outputs (enabled_midi_outputs);
2943 std::vector<std::string>::iterator port_iter = enabled_midi_outputs.begin();
2945 for (; port_iter != enabled_midi_outputs.end(); ++port_iter) {
2946 mmc_out_ptr->connect (*port_iter);
2955 Session::ensure_route_presentation_info_gap (PresentationInfo::order_t first_new_order, uint32_t how_many)
2957 if (first_new_order == PresentationInfo::max_order) {
2958 /* adding at end, no worries */
2962 /* create a gap in the presentation info to accomodate @param how_many
2966 get_stripables (sl);
2968 for (StripableList::iterator si = sl.begin(); si != sl.end(); ++si) {
2969 boost::shared_ptr<Stripable> s (*si);
2971 if (s->is_monitor() || s->is_auditioner()) {
2975 if (s->presentation_info().order () >= first_new_order) {
2976 s->set_presentation_order (s->presentation_info().order () + how_many);
2981 /** Caller must not hold process lock
2982 * @param name_template string to use for the start of the name, or "" to use "Audio".
2984 list< boost::shared_ptr<AudioTrack> >
2985 Session::new_audio_track (int input_channels, int output_channels, RouteGroup* route_group,
2986 uint32_t how_many, string name_template, PresentationInfo::order_t order,
2990 uint32_t track_id = 0;
2992 RouteList new_routes;
2993 list<boost::shared_ptr<AudioTrack> > ret;
2995 const string name_pattern = default_track_name_pattern (DataType::AUDIO);
2996 bool const use_number = (how_many != 1) || name_template.empty () || (name_template == name_pattern);
3000 if (!find_route_name (name_template.empty() ? _(name_pattern.c_str()) : name_template, ++track_id, track_name, use_number)) {
3001 error << "cannot find name for new audio track" << endmsg;
3005 boost::shared_ptr<AudioTrack> track;
3008 track.reset (new AudioTrack (*this, track_name, mode));
3010 if (track->init ()) {
3014 if (Profile->get_mixbus ()) {
3015 track->set_strict_io (true);
3018 if (ARDOUR::Profile->get_trx ()) {
3019 // TRACKS considers it's not a USE CASE, it's
3020 // a piece of behavior of the session model:
3022 // Gain for a newly created route depends on
3023 // the current output_auto_connect mode:
3025 // 0 for Stereo Out mode
3027 if (Config->get_output_auto_connect() & AutoConnectMaster) {
3028 track->gain_control()->set_value (dB_to_coefficient (0), Controllable::NoGroup);
3032 track->use_new_diskstream();
3034 BOOST_MARK_TRACK (track);
3037 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3039 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
3040 error << string_compose (
3041 _("cannot configure %1 in/%2 out configuration for new audio track"),
3042 input_channels, output_channels)
3047 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
3048 error << string_compose (
3049 _("cannot configure %1 in/%2 out configuration for new audio track"),
3050 input_channels, output_channels)
3057 route_group->add (track);
3060 track->non_realtime_input_change();
3062 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
3064 new_routes.push_back (track);
3065 ret.push_back (track);
3068 catch (failed_constructor &err) {
3069 error << _("Session: could not create new audio track.") << endmsg;
3073 catch (AudioEngine::PortRegistrationFailure& pfe) {
3075 error << pfe.what() << endmsg;
3083 if (!new_routes.empty()) {
3084 StateProtector sp (this);
3085 if (Profile->get_trx()) {
3086 add_routes (new_routes, false, false, false, order);
3088 add_routes (new_routes, true, true, false, order);
3095 /** Caller must not hold process lock.
3096 * @param name_template string to use for the start of the name, or "" to use "Bus".
3099 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template,
3100 PresentationInfo::Flag flags, PresentationInfo::order_t order)
3103 uint32_t bus_id = 0;
3107 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
3110 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, use_number)) {
3111 error << "cannot find name for new audio bus" << endmsg;
3116 boost::shared_ptr<Route> bus (new Route (*this, bus_name, flags, DataType::AUDIO));
3122 if (Profile->get_mixbus ()) {
3123 bus->set_strict_io (true);
3126 BOOST_MARK_ROUTE(bus);
3129 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3131 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
3132 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
3133 input_channels, output_channels)
3139 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
3140 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
3141 input_channels, output_channels)
3148 route_group->add (bus);
3151 bus->add_internal_return ();
3152 ret.push_back (bus);
3155 catch (failed_constructor &err) {
3156 error << _("Session: could not create new audio route.") << endmsg;
3160 catch (AudioEngine::PortRegistrationFailure& pfe) {
3161 error << pfe.what() << endmsg;
3171 StateProtector sp (this);
3172 if (Profile->get_trx()) {
3173 add_routes (ret, false, false, false, order);
3175 add_routes (ret, false, true, true, order); // autoconnect // outputs only
3184 Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t insert_at, const std::string& template_path, const std::string& name_base,
3185 PlaylistDisposition pd)
3189 if (!tree.read (template_path.c_str())) {
3193 return new_route_from_template (how_many, insert_at, *tree.root(), name_base, pd);
3197 Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t insert_at, XMLNode& node, const std::string& name_base, PlaylistDisposition pd)
3200 uint32_t number = 0;
3201 const uint32_t being_added = how_many;
3202 /* This will prevent the use of any existing XML-provided PBD::ID
3205 Stateful::ForceIDRegeneration force_ids;
3206 IO::disable_connecting ();
3210 /* We're going to modify the node contents a bit so take a
3211 * copy. The node may be re-used when duplicating more than once.
3214 XMLNode node_copy (node);
3219 if (!name_base.empty()) {
3221 /* if we're adding more than one routes, force
3222 * all the names of the new routes to be
3223 * numbered, via the final parameter.
3226 if (!find_route_name (name_base.c_str(), ++number, name, (being_added > 1))) {
3227 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
3233 string const route_name = node_copy.property(X_("name"))->value ();
3235 /* generate a new name by adding a number to the end of the template name */
3236 if (!find_route_name (route_name.c_str(), ++number, name, true)) {
3237 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
3238 abort(); /*NOTREACHED*/
3242 /* set this name in the XML description that we are about to use */
3244 if (pd == CopyPlaylist) {
3245 XMLNode* ds_node = find_named_node (node_copy, "Diskstream");
3247 const std::string playlist_name = ds_node->property (X_("playlist"))->value ();
3248 boost::shared_ptr<Playlist> playlist = playlists->by_name (playlist_name);
3249 // Use same name as Route::set_name_in_state so playlist copy
3250 // is picked up when creating the Route in XMLRouteFactory below
3251 PlaylistFactory::create (playlist, string_compose ("%1.1", name));
3255 bool rename_playlist = (pd == CopyPlaylist || pd == NewPlaylist);
3257 Route::set_name_in_state (node_copy, name, rename_playlist);
3259 /* trim bitslots from listen sends so that new ones are used */
3260 XMLNodeList children = node_copy.children ();
3261 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
3262 if ((*i)->name() == X_("Processor")) {
3263 /* ForceIDRegeneration does not catch the following */
3264 XMLProperty const * role = (*i)->property (X_("role"));
3265 XMLProperty const * type = (*i)->property (X_("type"));
3266 if (role && role->value() == X_("Aux")) {
3267 /* check if the target bus exists.
3268 * we should not save aux-sends in templates.
3270 XMLProperty const * target = (*i)->property (X_("target"));
3272 (*i)->add_property ("type", "dangling-aux-send");
3275 boost::shared_ptr<Route> r = route_by_id (target->value());
3276 if (!r || boost::dynamic_pointer_cast<Track>(r)) {
3277 (*i)->add_property ("type", "dangling-aux-send");
3281 if (role && role->value() == X_("Listen")) {
3282 (*i)->remove_property (X_("bitslot"));
3284 else if (role && (role->value() == X_("Send") || role->value() == X_("Aux"))) {
3286 Delivery::Role xrole;
3287 uint32_t bitslot = 0;
3288 xrole = Delivery::Role (string_2_enum (role->value(), xrole));
3289 std::string name = Send::name_and_id_new_send(*this, xrole, bitslot, false);
3290 snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
3291 (*i)->remove_property (X_("bitslot"));
3292 (*i)->remove_property (X_("name"));
3293 (*i)->add_property ("bitslot", buf);
3294 (*i)->add_property ("name", name);
3296 else if (type && type->value() == X_("intreturn")) {
3297 (*i)->remove_property (X_("bitslot"));
3298 (*i)->add_property ("ignore-bitslot", "1");
3300 else if (type && type->value() == X_("return")) {
3301 // Return::set_state() generates a new one
3302 (*i)->remove_property (X_("bitslot"));
3304 else if (type && type->value() == X_("port")) {
3305 // PortInsert::set_state() handles the bitslot
3306 (*i)->remove_property (X_("bitslot"));
3307 (*i)->add_property ("ignore-name", "1");
3312 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
3315 error << _("Session: cannot create track/bus from template description") << endmsg;
3319 if (boost::dynamic_pointer_cast<Track>(route)) {
3320 /* force input/output change signals so that the new diskstream
3321 picks up the configuration of the route. During session
3322 loading this normally happens in a different way.
3325 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3327 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
3328 change.after = route->input()->n_ports();
3329 route->input()->changed (change, this);
3330 change.after = route->output()->n_ports();
3331 route->output()->changed (change, this);
3334 ret.push_back (route);
3337 catch (failed_constructor &err) {
3338 error << _("Session: could not create new route from template") << endmsg;
3342 catch (AudioEngine::PortRegistrationFailure& pfe) {
3343 error << pfe.what() << endmsg;
3352 StateProtector sp (this);
3353 if (Profile->get_trx()) {
3354 add_routes (ret, false, false, false, insert_at);
3356 add_routes (ret, true, true, false, insert_at);
3358 IO::enable_connecting ();
3365 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save, PresentationInfo::order_t order)
3368 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
3369 add_routes_inner (new_routes, input_auto_connect, output_auto_connect, order);
3372 error << _("Adding new tracks/busses failed") << endmsg;
3377 update_latency (true);
3378 update_latency (false);
3383 save_state (_current_snapshot_name);
3386 update_route_record_state ();
3388 RouteAdded (new_routes); /* EMIT SIGNAL */
3392 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t order)
3394 ChanCount existing_inputs;
3395 ChanCount existing_outputs;
3399 count_existing_track_channels (existing_inputs, existing_outputs);
3402 RCUWriter<RouteList> writer (routes);
3403 boost::shared_ptr<RouteList> r = writer.get_copy ();
3404 r->insert (r->end(), new_routes.begin(), new_routes.end());
3405 n_routes = r->size();
3407 /* if there is no control out and we're not in the middle of loading,
3408 * resort the graph here. if there is a control out, we will resort
3409 * toward the end of this method. if we are in the middle of loading,
3410 * we will resort when done.
3413 if (!_monitor_out && IO::connecting_legal) {
3414 resort_routes_using (r);
3418 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("ensure order gap starting at %1 for %2\n", order, new_routes.size()));
3419 ensure_route_presentation_info_gap (order, new_routes.size());
3421 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x, ++added) {
3423 boost::weak_ptr<Route> wpr (*x);
3424 boost::shared_ptr<Route> r (*x);
3426 r->solo_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2,wpr));
3427 r->solo_isolate_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr));
3428 r->mute_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this));
3430 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
3431 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
3432 r->processor_latency_changed.connect_same_thread (*this, boost::bind (&Session::queue_latency_recompute, this));
3434 if (r->is_master()) {
3438 if (r->is_monitor()) {
3442 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
3444 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
3445 track_playlist_changed (boost::weak_ptr<Track> (tr));
3446 tr->rec_enable_control()->Changed.connect_same_thread (*this, boost::bind (&Session::update_route_record_state, this));
3448 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
3450 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
3451 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
3452 mt->presentation_info().PropertyChanged.connect_same_thread (*this, boost::bind (&Session::midi_track_presentation_info_changed, this, _1, boost::weak_ptr<MidiTrack>(mt)));
3456 if (!r->presentation_info().special()) {
3458 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("checking PI state for %1\n", r->name()));
3460 /* presentation info order may already have been set from XML */
3462 if (!r->presentation_info().order_set()) {
3464 if (order == PresentationInfo::max_order) {
3465 /* just add to the end */
3466 r->set_presentation_order (n_routes + added, false);
3467 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to NR %1 + %2 = %3\n", n_routes, added, n_routes + added));
3469 r->set_presentation_order (order + added);
3470 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to %1 + %2 = %3\n", order, added, order + added));
3473 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order already set to %1\n", r->presentation_info().order()));
3477 #if !defined(__APPLE__) && !defined(__FreeBSD__)
3478 /* clang complains: 'operator<<' should be declared prior to the call site or in an associated namespace of one of its
3479 * arguments std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid)"
3481 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("added route %1, group order %2 type %3 (summary: %4)\n",
3483 r->presentation_info().order(),
3484 enum_2_string (r->presentation_info().flags()),
3485 r->presentation_info()));
3489 if (input_auto_connect || output_auto_connect) {
3490 auto_connect_route (r, input_auto_connect, ChanCount (), ChanCount (), existing_inputs, existing_outputs);
3491 existing_inputs += r->n_inputs();
3492 existing_outputs += r->n_outputs();
3498 if (_monitor_out && IO::connecting_legal) {
3499 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
3501 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
3502 if ((*x)->is_monitor()) {
3504 } else if ((*x)->is_master()) {
3507 (*x)->enable_monitor_send ();
3512 reassign_track_numbers ();
3516 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
3518 boost::shared_ptr<RouteList> r = routes.reader ();
3519 boost::shared_ptr<Send> s;
3521 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3522 if ((s = (*i)->internal_send_for (dest)) != 0) {
3523 s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO, Controllable::NoGroup);
3529 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
3531 boost::shared_ptr<RouteList> r = routes.reader ();
3532 boost::shared_ptr<Send> s;
3534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3535 if ((s = (*i)->internal_send_for (dest)) != 0) {
3536 s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY, Controllable::NoGroup);
3542 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
3544 boost::shared_ptr<RouteList> r = routes.reader ();
3545 boost::shared_ptr<Send> s;
3547 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3548 if ((s = (*i)->internal_send_for (dest)) != 0) {
3549 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value(), Controllable::NoGroup);
3554 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
3556 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
3558 boost::shared_ptr<RouteList> r = routes.reader ();
3559 boost::shared_ptr<RouteList> t (new RouteList);
3561 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3562 /* no MIDI sends because there are no MIDI busses yet */
3563 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
3568 add_internal_sends (dest, p, t);
3572 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
3574 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
3575 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
3580 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
3582 add_internal_send (dest, sender->before_processor_for_index (index), sender);
3586 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
3588 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
3592 if (!dest->internal_return()) {
3593 dest->add_internal_return ();
3596 sender->add_aux_send (dest, before);
3602 Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
3604 { // RCU Writer scope
3605 PBD::Unwinder<bool> uw_flag (_route_deletion_in_progress, true);
3606 RCUWriter<RouteList> writer (routes);
3607 boost::shared_ptr<RouteList> rs = writer.get_copy ();
3610 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3612 if (*iter == _master_out) {
3616 (*iter)->solo_control()->set_value (0.0, Controllable::NoGroup);
3620 /* deleting the master out seems like a dumb
3621 idea, but its more of a UI policy issue
3625 if (*iter == _master_out) {
3626 _master_out = boost::shared_ptr<Route> ();
3629 if (*iter == _monitor_out) {
3630 _monitor_out.reset ();
3633 // We need to disconnect the route's inputs and outputs
3635 (*iter)->input()->disconnect (0);
3636 (*iter)->output()->disconnect (0);
3638 /* if the route had internal sends sending to it, remove them */
3639 if ((*iter)->internal_return()) {
3641 boost::shared_ptr<RouteList> r = routes.reader ();
3642 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3643 boost::shared_ptr<Send> s = (*i)->internal_send_for (*iter);
3645 (*i)->remove_processor (s);
3650 /* if the monitoring section had a pointer to this route, remove it */
3651 if (_monitor_out && !(*iter)->is_master() && !(*iter)->is_monitor()) {
3652 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3653 ProcessorChangeBlocker pcb (this, false);
3654 (*iter)->remove_aux_or_listen (_monitor_out);
3657 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*iter);
3658 if (mt && mt->step_editing()) {
3659 if (_step_editors > 0) {
3665 /* writer goes out of scope, forces route list update */
3667 } // end of RCU Writer scope
3669 update_route_solo_state ();
3670 update_latency_compensation ();
3673 /* Re-sort routes to remove the graph's current references to the one that is
3674 * going away, then flush old references out of the graph.
3675 * Wave Tracks: reconnect routes
3678 #ifdef USE_TRACKS_CODE_FEATURES
3679 reconnect_existing_routes(true, false);
3681 routes.flush (); // maybe unsafe, see below.
3685 if (_process_graph && !(_state_of_the_state & Deletion)) {
3686 _process_graph->clear_other_chain ();
3689 /* get rid of it from the dead wood collection in the route list manager */
3690 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
3694 /* try to cause everyone to drop their references
3695 * and unregister ports from the backend
3698 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3699 cerr << "Drop references to " << (*iter)->name() << endl;
3700 (*iter)->drop_references ();
3703 if (_state_of_the_state & Deletion) {
3707 PresentationInfo::Change(); /* EMIT SIGNAL */
3709 /* save the new state of the world */
3711 if (save_state (_current_snapshot_name)) {
3712 save_history (_current_snapshot_name);
3715 update_route_record_state ();
3719 Session::remove_route (boost::shared_ptr<Route> route)
3721 boost::shared_ptr<RouteList> rl (new RouteList);
3722 rl->push_back (route);
3727 Session::route_mute_changed ()
3733 Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
3735 boost::shared_ptr<Route> route (wpr.lock());
3741 assert (Config->get_solo_control_is_listen_control());
3743 if (route->solo_control()->soloed_by_self_or_masters()) {
3745 if (Config->get_exclusive_solo()) {
3747 RouteGroup* rg = route->route_group ();
3748 const bool group_already_accounted_for = (group_override == Controllable::ForGroup);
3750 boost::shared_ptr<RouteList> r = routes.reader ();
3752 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3753 if ((*i) == route) {
3754 /* already changed */
3758 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3759 /* route does not get solo propagated to it */
3763 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3764 /* this route is a part of the same solo group as the route
3765 * that was changed. Changing that route did change or will
3766 * change all group members appropriately, so we can ignore it
3771 (*i)->solo_control()->set_value (0.0, Controllable::NoGroup);
3777 } else if (_listen_cnt > 0) {
3784 Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr)
3786 boost::shared_ptr<Route> route (wpr.lock());
3792 bool send_changed = false;
3794 if (route->solo_isolate_control()->solo_isolated()) {
3795 if (_solo_isolated_cnt == 0) {
3796 send_changed = true;
3798 _solo_isolated_cnt++;
3799 } else if (_solo_isolated_cnt > 0) {
3800 _solo_isolated_cnt--;
3801 if (_solo_isolated_cnt == 0) {
3802 send_changed = true;
3807 IsolatedChanged (); /* EMIT SIGNAL */
3812 Session::route_solo_changed (bool self_solo_changed, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
3814 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1, update\n", self_solo_changed));
3816 boost::shared_ptr<Route> route (wpr.lock());
3822 if (Config->get_solo_control_is_listen_control()) {
3823 route_listen_changed (group_override, wpr);
3827 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: self %2 masters %3 transition %4\n", route->name(), route->self_soloed(), route->solo_control()->get_masters_value(), route->solo_control()->transitioned_into_solo()));
3829 if (route->solo_control()->transitioned_into_solo() == 0) {
3830 /* route solo changed by upstream/downstream or clear all solo state; not interesting
3833 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 not self-soloed nor soloed by master (%2), ignoring\n", route->name(), route->solo_control()->get_masters_value()));
3837 boost::shared_ptr<RouteList> r = routes.reader ();
3838 int32_t delta = route->solo_control()->transitioned_into_solo ();
3840 /* the route may be a member of a group that has shared-solo
3841 * semantics. If so, then all members of that group should follow the
3842 * solo of the changed route. But ... this is optional, controlled by a
3843 * Controllable::GroupControlDisposition.
3845 * The first argument to the signal that this method is connected to is the
3846 * GroupControlDisposition value that was used to change solo.
3848 * If the solo change was done with group semantics (either InverseGroup
3849 * (force the entire group to change even if the group shared solo is
3850 * disabled) or UseGroup (use the group, which may or may not have the
3851 * shared solo property enabled)) then as we propagate the change to
3852 * the entire session we should IGNORE THE GROUP that the changed route
3856 RouteGroup* rg = route->route_group ();
3857 const bool group_already_accounted_for = (group_override == Controllable::ForGroup);
3859 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate to session, group accounted for ? %1\n", group_already_accounted_for));
3861 if (delta == 1 && Config->get_exclusive_solo()) {
3863 /* new solo: disable all other solos, but not the group if its solo-enabled */
3865 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3867 if ((*i) == route) {
3868 /* already changed */
3872 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3873 /* route does not get solo propagated to it */
3877 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3878 /* this route is a part of the same solo group as the route
3879 * that was changed. Changing that route did change or will
3880 * change all group members appropriately, so we can ignore it
3886 (*i)->solo_control()->set_value (0.0, group_override);
3890 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
3892 RouteList uninvolved;
3894 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
3896 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3897 bool via_sends_only;
3898 bool in_signal_flow;
3900 if ((*i) == route) {
3901 /* already changed */
3905 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3906 /* route does not get solo propagated to it */
3907 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 excluded from solo because iso = %2 can_solo = %3\n", (*i)->name(), (*i)->solo_isolate_control()->solo_isolated(),
3912 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3913 /* this route is a part of the same solo group as the route
3914 * that was changed. Changing that route did change or will
3915 * change all group members appropriately, so we can ignore it
3921 in_signal_flow = false;
3923 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
3925 if ((*i)->feeds (route, &via_sends_only)) {
3926 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
3927 if (!via_sends_only) {
3928 if (!route->soloed_by_others_upstream()) {
3929 (*i)->solo_control()->mod_solo_by_others_downstream (delta);
3931 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others upstream\n");
3934 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
3936 in_signal_flow = true;
3938 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
3941 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
3943 if (route->feeds (*i, &via_sends_only)) {
3944 /* propagate solo upstream only if routing other than
3945 sends is involved, but do consider the other route
3946 (*i) to be part of the signal flow even if only
3949 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
3953 route->soloed_by_others_downstream(),
3954 route->soloed_by_others_upstream()));
3955 if (!via_sends_only) {
3956 //NB. Triggers Invert Push, which handles soloed by downstream
3957 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
3958 (*i)->solo_control()->mod_solo_by_others_upstream (delta);
3960 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
3962 in_signal_flow = true;
3964 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
3967 if (!in_signal_flow) {
3968 uninvolved.push_back (*i);
3972 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
3974 /* now notify that the mute state of the routes not involved in the signal
3975 pathway of the just-solo-changed route may have altered.
3978 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
3979 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
3980 (*i)->act_on_mute ();
3981 /* Session will emit SoloChanged() after all solo changes are
3982 * complete, which should be used by UIs to update mute status
3988 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
3990 /* now figure out if anything that matters is soloed (or is "listening")*/
3992 bool something_soloed = false;
3993 bool something_listening = false;
3994 uint32_t listeners = 0;
3995 uint32_t isolated = 0;
3998 r = routes.reader();
4001 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4002 if ((*i)->can_solo()) {
4003 if (Config->get_solo_control_is_listen_control()) {
4004 if ((*i)->solo_control()->soloed_by_self_or_masters()) {
4006 something_listening = true;
4009 (*i)->set_listen (false);
4010 if ((*i)->can_solo() && (*i)->solo_control()->soloed_by_self_or_masters()) {
4011 something_soloed = true;
4016 if ((*i)->solo_isolate_control()->solo_isolated()) {
4021 if (something_soloed != _non_soloed_outs_muted) {
4022 _non_soloed_outs_muted = something_soloed;
4023 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
4026 if (something_listening != _listening) {
4027 _listening = something_listening;
4028 SoloActive (_listening);
4031 _listen_cnt = listeners;
4033 if (isolated != _solo_isolated_cnt) {
4034 _solo_isolated_cnt = isolated;
4035 IsolatedChanged (); /* EMIT SIGNAL */
4038 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
4039 something_soloed, listeners, isolated));
4042 SoloChanged (); /* EMIT SIGNAL */
4047 Session::get_stripables (StripableList& sl) const
4049 boost::shared_ptr<RouteList> r = routes.reader ();
4050 sl.insert (sl.end(), r->begin(), r->end());
4052 VCAList v = _vca_manager->vcas ();
4053 sl.insert (sl.end(), v.begin(), v.end());
4056 boost::shared_ptr<RouteList>
4057 Session::get_routes_with_internal_returns() const
4059 boost::shared_ptr<RouteList> r = routes.reader ();
4060 boost::shared_ptr<RouteList> rl (new RouteList);
4062 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4063 if ((*i)->internal_return ()) {
4071 Session::io_name_is_legal (const std::string& name) const
4073 boost::shared_ptr<RouteList> r = routes.reader ();
4075 for (vector<string>::const_iterator reserved = reserved_io_names.begin(); reserved != reserved_io_names.end(); ++reserved) {
4076 if (name == *reserved) {
4077 if (!route_by_name (*reserved)) {
4078 /* first instance of a reserved name is allowed */
4081 /* all other instances of a reserved name are not allowed */
4086 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4087 if ((*i)->name() == name) {
4091 if ((*i)->has_io_processor_named (name)) {
4100 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
4103 vector<string> connections;
4105 /* if we are passed only a single route and we're not told to turn
4106 * others off, then just do the simple thing.
4109 if (flip_others == false && rl->size() == 1) {
4110 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
4112 mt->set_input_active (onoff);
4117 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
4119 PortSet& ps ((*rt)->input()->ports());
4121 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
4122 p->get_connections (connections);
4125 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
4126 routes_using_input_from (*s, rl2);
4129 /* scan all relevant routes to see if others are on or off */
4131 bool others_are_already_on = false;
4133 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
4135 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
4141 if ((*r) != (*rt)) {
4142 if (mt->input_active()) {
4143 others_are_already_on = true;
4146 /* this one needs changing */
4147 mt->set_input_active (onoff);
4153 /* globally reverse other routes */
4155 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
4156 if ((*r) != (*rt)) {
4157 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
4159 mt->set_input_active (!others_are_already_on);
4168 Session::routes_using_input_from (const string& str, RouteList& rl)
4170 boost::shared_ptr<RouteList> r = routes.reader();
4172 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4173 if ((*i)->input()->connected_to (str)) {
4179 boost::shared_ptr<Route>
4180 Session::route_by_name (string name) const
4182 boost::shared_ptr<RouteList> r = routes.reader ();
4184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4185 if ((*i)->name() == name) {
4190 return boost::shared_ptr<Route> ((Route*) 0);
4193 boost::shared_ptr<Route>
4194 Session::route_by_id (PBD::ID id) const
4196 boost::shared_ptr<RouteList> r = routes.reader ();
4198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4199 if ((*i)->id() == id) {
4204 return boost::shared_ptr<Route> ((Route*) 0);
4207 boost::shared_ptr<Processor>
4208 Session::processor_by_id (PBD::ID id) const
4210 boost::shared_ptr<RouteList> r = routes.reader ();
4212 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4213 boost::shared_ptr<Processor> p = (*i)->Route::processor_by_id (id);
4219 return boost::shared_ptr<Processor> ();
4222 boost::shared_ptr<Track>
4223 Session::track_by_diskstream_id (PBD::ID id) const
4225 boost::shared_ptr<RouteList> r = routes.reader ();
4227 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4228 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
4229 if (t && t->using_diskstream_id (id)) {
4234 return boost::shared_ptr<Track> ();
4237 boost::shared_ptr<Route>
4238 Session::get_remote_nth_route (PresentationInfo::order_t n) const
4240 return boost::dynamic_pointer_cast<Route> (get_remote_nth_stripable (n, PresentationInfo::Route));
4243 boost::shared_ptr<Stripable>
4244 Session::get_remote_nth_stripable (PresentationInfo::order_t n, PresentationInfo::Flag flags) const
4247 PresentationInfo::order_t match_cnt = 0;
4249 get_stripables (sl);
4250 sl.sort (Stripable::PresentationOrderSorter());
4252 for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
4254 if ((*s)->presentation_info().hidden()) {
4255 /* if the caller didn't explicitly ask for hidden
4256 stripables, ignore hidden ones. This matches
4257 the semantics of the pre-PresentationOrder
4258 "get by RID" logic of Ardour 4.x and earlier.
4260 XXX at some point we should likely reverse
4261 the logic of the flags, because asking for "the
4262 hidden stripables" is not going to be common,
4263 whereas asking for visible ones is normal.
4266 if (! (flags & PresentationInfo::Hidden)) {
4271 if ((*s)->presentation_info().flag_match (flags)) {
4272 if (match_cnt++ == n) {
4278 /* there is no nth stripable that matches the given flags */
4279 return boost::shared_ptr<Stripable>();
4282 boost::shared_ptr<Route>
4283 Session::route_by_selected_count (uint32_t id) const
4285 boost::shared_ptr<RouteList> r = routes.reader ();
4287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4288 /* NOT IMPLEMENTED */
4291 return boost::shared_ptr<Route> ((Route*) 0);
4294 struct PresentationOrderSorter {
4295 bool operator() (boost::shared_ptr<Stripable> a, boost::shared_ptr<Stripable> b) {
4296 if (a->presentation_info().special() && !b->presentation_info().special()) {
4297 /* a is not ordered, b is; b comes before a */
4299 } else if (!b->presentation_info().order_set() && a->presentation_info().order_set()) {
4300 /* b is not ordered, a is; a comes before b */
4303 return a->presentation_info().order() < b->presentation_info().order();
4309 Session::reassign_track_numbers ()
4313 RouteList r (*(routes.reader ()));
4314 PresentationOrderSorter sorter;
4317 StateProtector sp (this);
4319 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
4320 if (boost::dynamic_pointer_cast<Track> (*i)) {
4321 (*i)->set_track_number(++tn);
4323 else if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
4324 (*i)->set_track_number(--bn);
4327 const uint32_t decimals = ceilf (log10f (tn + 1));
4328 const bool decimals_changed = _track_number_decimals != decimals;
4329 _track_number_decimals = decimals;
4331 if (decimals_changed && config.get_track_name_number ()) {
4332 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
4333 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
4335 t->resync_track_name();
4338 // trigger GUI re-layout
4339 config.ParameterChanged("track-name-number");
4343 if (DEBUG_ENABLED(DEBUG::OrderKeys)) {
4344 boost::shared_ptr<RouteList> rl = routes.reader ();
4345 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4346 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 numbered %2\n", (*i)->name(), (*i)->track_number()));
4354 Session::playlist_region_added (boost::weak_ptr<Region> w)
4356 boost::shared_ptr<Region> r = w.lock ();
4361 /* These are the operations that are currently in progress... */
4362 list<GQuark> curr = _current_trans_quarks;
4365 /* ...and these are the operations during which we want to update
4366 the session range location markers.
4369 ops.push_back (Operations::capture);
4370 ops.push_back (Operations::paste);
4371 ops.push_back (Operations::duplicate_region);
4372 ops.push_back (Operations::insert_file);
4373 ops.push_back (Operations::insert_region);
4374 ops.push_back (Operations::drag_region_brush);
4375 ops.push_back (Operations::region_drag);
4376 ops.push_back (Operations::selection_grab);
4377 ops.push_back (Operations::region_fill);
4378 ops.push_back (Operations::fill_selection);
4379 ops.push_back (Operations::create_region);
4380 ops.push_back (Operations::region_copy);
4381 ops.push_back (Operations::fixed_time_region_copy);
4384 /* See if any of the current operations match the ones that we want */
4386 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
4388 /* If so, update the session range markers */
4390 maybe_update_session_range (r->position (), r->last_frame ());
4394 /** Update the session range markers if a is before the current start or
4395 * b is after the current end.
4398 Session::maybe_update_session_range (framepos_t a, framepos_t b)
4400 if (_state_of_the_state & Loading) {
4404 framepos_t session_end_marker_shift_samples = session_end_shift * _nominal_frame_rate;
4406 if (_session_range_location == 0) {
4408 set_session_range_location (a, b + session_end_marker_shift_samples);
4412 if (a < _session_range_location->start()) {
4413 _session_range_location->set_start (a);
4416 if (_session_range_end_is_free && (b > _session_range_location->end())) {
4417 _session_range_location->set_end (b);
4423 Session::set_end_is_free (bool yn)
4425 _session_range_end_is_free = yn;
4429 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
4431 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
4432 maybe_update_session_range (i->to, i->to + i->length);
4437 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
4439 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
4440 maybe_update_session_range (i->from, i->to);
4444 /* Region management */
4446 boost::shared_ptr<Region>
4447 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
4449 const RegionFactory::RegionMap& regions (RegionFactory::regions());
4450 RegionFactory::RegionMap::const_iterator i;
4451 boost::shared_ptr<Region> region;
4453 Glib::Threads::Mutex::Lock lm (region_lock);
4455 for (i = regions.begin(); i != regions.end(); ++i) {
4459 if (region->whole_file()) {
4461 if (child->source_equivalent (region)) {
4467 return boost::shared_ptr<Region> ();
4471 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
4473 set<boost::shared_ptr<Region> > relevant_regions;
4475 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
4476 RegionFactory::get_regions_using_source (*s, relevant_regions);
4479 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
4480 set<boost::shared_ptr<Region> >::iterator tmp;
4485 playlists->destroy_region (*r);
4486 RegionFactory::map_remove (*r);
4488 (*r)->drop_sources ();
4489 (*r)->drop_references ();
4491 relevant_regions.erase (r);
4496 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
4499 Glib::Threads::Mutex::Lock ls (source_lock);
4500 /* remove from the main source list */
4501 sources.erase ((*s)->id());
4504 (*s)->mark_for_remove ();
4505 (*s)->drop_references ();
4514 Session::remove_last_capture ()
4516 list<boost::shared_ptr<Source> > srcs;
4518 boost::shared_ptr<RouteList> rl = routes.reader ();
4519 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4520 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4525 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
4528 srcs.insert (srcs.end(), l.begin(), l.end());
4533 destroy_sources (srcs);
4535 save_state (_current_snapshot_name);
4540 /* Source Management */
4543 Session::add_source (boost::shared_ptr<Source> source)
4545 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
4546 pair<SourceMap::iterator,bool> result;
4548 entry.first = source->id();
4549 entry.second = source;
4552 Glib::Threads::Mutex::Lock lm (source_lock);
4553 result = sources.insert (entry);
4556 if (result.second) {
4558 /* yay, new source */
4560 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
4563 if (!fs->within_session()) {
4564 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
4570 boost::shared_ptr<AudioFileSource> afs;
4572 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
4573 if (Config->get_auto_analyse_audio()) {
4574 Analyser::queue_source_for_analysis (source, false);
4578 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
4583 Session::remove_source (boost::weak_ptr<Source> src)
4585 if (_state_of_the_state & Deletion) {
4589 SourceMap::iterator i;
4590 boost::shared_ptr<Source> source = src.lock();
4597 Glib::Threads::Mutex::Lock lm (source_lock);
4599 if ((i = sources.find (source->id())) != sources.end()) {
4604 if (!(_state_of_the_state & StateOfTheState (InCleanup|Loading))) {
4606 /* save state so we don't end up with a session file
4607 referring to non-existent sources.
4610 save_state (_current_snapshot_name);
4614 boost::shared_ptr<Source>
4615 Session::source_by_id (const PBD::ID& id)
4617 Glib::Threads::Mutex::Lock lm (source_lock);
4618 SourceMap::iterator i;
4619 boost::shared_ptr<Source> source;
4621 if ((i = sources.find (id)) != sources.end()) {
4628 boost::shared_ptr<AudioFileSource>
4629 Session::audio_source_by_path_and_channel (const string& path, uint16_t chn) const
4631 /* Restricted to audio files because only audio sources have channel
4635 Glib::Threads::Mutex::Lock lm (source_lock);
4637 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4638 boost::shared_ptr<AudioFileSource> afs
4639 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
4641 if (afs && afs->path() == path && chn == afs->channel()) {
4646 return boost::shared_ptr<AudioFileSource>();
4649 boost::shared_ptr<MidiSource>
4650 Session::midi_source_by_path (const std::string& path) const
4652 /* Restricted to MIDI files because audio sources require a channel
4653 for unique identification, in addition to a path.
4656 Glib::Threads::Mutex::Lock lm (source_lock);
4658 for (SourceMap::const_iterator s = sources.begin(); s != sources.end(); ++s) {
4659 boost::shared_ptr<MidiSource> ms
4660 = boost::dynamic_pointer_cast<MidiSource>(s->second);
4661 boost::shared_ptr<FileSource> fs
4662 = boost::dynamic_pointer_cast<FileSource>(s->second);
4664 if (ms && fs && fs->path() == path) {
4669 return boost::shared_ptr<MidiSource>();
4673 Session::count_sources_by_origin (const string& path)
4676 Glib::Threads::Mutex::Lock lm (source_lock);
4678 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
4679 boost::shared_ptr<FileSource> fs
4680 = boost::dynamic_pointer_cast<FileSource>(i->second);
4682 if (fs && fs->origin() == path) {
4691 peak_file_helper (const string& peak_path, const string& file_path, const string& file_base, bool hash) {
4693 std::string checksum = Glib::Checksum::compute_checksum(Glib::Checksum::CHECKSUM_SHA1, file_path + G_DIR_SEPARATOR + file_base);
4694 return Glib::build_filename (peak_path, checksum + peakfile_suffix);
4696 return Glib::build_filename (peak_path, file_base + peakfile_suffix);
4701 Session::construct_peak_filepath (const string& filepath, const bool in_session, const bool old_peak_name) const
4703 string interchange_dir_string = string (interchange_dir_name) + G_DIR_SEPARATOR;
4705 if (Glib::path_is_absolute (filepath)) {
4707 /* rip the session dir from the audiofile source */
4709 string session_path;
4710 bool in_another_session = true;
4712 if (filepath.find (interchange_dir_string) != string::npos) {
4714 session_path = Glib::path_get_dirname (filepath); /* now ends in audiofiles */
4715 session_path = Glib::path_get_dirname (session_path); /* now ends in session name */
4716 session_path = Glib::path_get_dirname (session_path); /* now ends in interchange */
4717 session_path = Glib::path_get_dirname (session_path); /* now has session path */
4719 /* see if it is within our session */
4721 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4722 if (i->path == session_path) {
4723 in_another_session = false;
4728 in_another_session = false;
4732 if (in_another_session) {
4733 SessionDirectory sd (session_path);
4734 return peak_file_helper (sd.peak_path(), "", Glib::path_get_basename (filepath), !old_peak_name);
4738 /* 1) if file belongs to this session
4739 * it may be a relative path (interchange/...)
4740 * or just basename (session_state, remove source)
4741 * -> just use the basename
4743 std::string filename = Glib::path_get_basename (filepath);
4746 /* 2) if the file is outside our session dir:
4747 * (imported but not copied) add the path for check-summming */
4749 path = Glib::path_get_dirname (filepath);
4752 return peak_file_helper (_session_dir->peak_path(), path, Glib::path_get_basename (filepath), !old_peak_name);
4756 Session::new_audio_source_path_for_embedded (const std::string& path)
4760 * we know that the filename is already unique because it exists
4761 * out in the filesystem.
4763 * However, when we bring it into the session, we could get a
4766 * Eg. two embedded files:
4771 * When merged into session, these collide.
4773 * There will not be a conflict with in-memory sources
4774 * because when the source was created we already picked
4775 * a unique name for it.
4777 * This collision is not likely to be common, but we have to guard
4778 * against it. So, if there is a collision, take the md5 hash of the
4779 * the path, and use that as the filename instead.
4782 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4783 string base = Glib::path_get_basename (path);
4784 string newpath = Glib::build_filename (sdir.sound_path(), base);
4786 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4790 md5.digestString (path.c_str());
4791 md5.writeToString ();
4792 base = md5.digestChars;
4794 string ext = get_suffix (path);
4801 newpath = Glib::build_filename (sdir.sound_path(), base);
4803 /* if this collides, we're screwed */
4805 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4806 error << string_compose (_("Merging embedded file %1: name collision AND md5 hash collision!"), path) << endmsg;
4815 /** Return true if there are no audio file sources that use @param name as
4816 * the filename component of their path.
4818 * Return false otherwise.
4820 * This method MUST ONLY be used to check in-session, mono files since it
4821 * hard-codes the channel of the audio file source we are looking for as zero.
4823 * If/when Ardour supports native files in non-mono formats, the logic here
4824 * will need to be revisited.
4827 Session::audio_source_name_is_unique (const string& name)
4829 std::vector<string> sdirs = source_search_path (DataType::AUDIO);
4830 vector<space_and_path>::iterator i;
4831 uint32_t existing = 0;
4833 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4835 /* note that we search *without* the extension so that
4836 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
4837 in the event that this new name is required for
4838 a file format change.
4841 const string spath = *i;
4843 if (matching_unsuffixed_filename_exists_in (spath, name)) {
4848 /* it is possible that we have the path already
4849 * assigned to a source that has not yet been written
4850 * (ie. the write source for a diskstream). we have to
4851 * check this in order to make sure that our candidate
4852 * path isn't used again, because that can lead to
4853 * two Sources point to the same file with different
4854 * notions of their removability.
4858 string possible_path = Glib::build_filename (spath, name);
4860 if (audio_source_by_path_and_channel (possible_path, 0)) {
4866 return (existing == 0);
4870 Session::format_audio_source_name (const string& legalized_base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required, uint32_t cnt, bool related_exists)
4873 const string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
4875 if (Profile->get_trx() && destructive) {
4877 sstr << setfill ('0') << setw (4) << cnt;
4878 sstr << legalized_base;
4880 sstr << legalized_base;
4882 if (take_required || related_exists) {
4894 } else if (nchan > 2) {
4899 /* XXX what? more than 26 channels! */
4910 /** Return a unique name based on \a base for a new internal audio source */
4912 Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required)
4915 string possible_name;
4916 const uint32_t limit = 9999; // arbitrary limit on number of files with the same basic name
4918 bool some_related_source_name_exists = false;
4920 legalized = legalize_for_path (base);
4922 // Find a "version" of the base name that doesn't exist in any of the possible directories.
4924 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
4926 possible_name = format_audio_source_name (legalized, nchan, chan, destructive, take_required, cnt, some_related_source_name_exists);
4928 if (audio_source_name_is_unique (possible_name)) {
4932 some_related_source_name_exists = true;
4935 error << string_compose(
4936 _("There are already %1 recordings for %2, which I consider too many."),
4937 limit, base) << endmsg;
4939 throw failed_constructor();
4943 /* We've established that the new name does not exist in any session
4944 * directory, so now find out which one we should use for this new
4948 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4950 std::string s = Glib::build_filename (sdir.sound_path(), possible_name);
4955 /** Return a unique name based on `base` for a new internal MIDI source */
4957 Session::new_midi_source_path (const string& base)
4960 char buf[PATH_MAX+1];
4961 const uint32_t limit = 10000;
4963 string possible_path;
4964 string possible_name;
4967 legalized = legalize_for_path (base);
4969 // Find a "version" of the file name that doesn't exist in any of the possible directories.
4970 std::vector<string> sdirs = source_search_path(DataType::MIDI);
4972 /* - the main session folder is the first in the vector.
4973 * - after checking all locations for file-name uniqueness,
4974 * we keep the one from the last iteration as new file name
4975 * - midi files are small and should just be kept in the main session-folder
4977 * -> reverse the array, check main session folder last and use that as location
4980 std::reverse(sdirs.begin(), sdirs.end());
4982 for (cnt = 1; cnt <= limit; ++cnt) {
4984 vector<space_and_path>::iterator i;
4985 uint32_t existing = 0;
4987 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4989 snprintf (buf, sizeof(buf), "%s-%u.mid", legalized.c_str(), cnt);
4990 possible_name = buf;
4992 possible_path = Glib::build_filename (*i, possible_name);
4994 if (Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
4998 if (midi_source_by_path (possible_path)) {
5003 if (existing == 0) {
5008 error << string_compose(
5009 _("There are already %1 recordings for %2, which I consider too many."),
5010 limit, base) << endmsg;
5016 /* No need to "find best location" for software/app-based RAID, because
5017 MIDI is so small that we always put it in the same place.
5020 return possible_path;
5024 /** Create a new within-session audio source */
5025 boost::shared_ptr<AudioFileSource>
5026 Session::create_audio_source_for_session (size_t n_chans, string const & base, uint32_t chan, bool destructive)
5028 const string path = new_audio_source_path (base, n_chans, chan, destructive, true);
5030 if (!path.empty()) {
5031 return boost::dynamic_pointer_cast<AudioFileSource> (
5032 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate(), true, true));
5034 throw failed_constructor ();
5038 /** Create a new within-session MIDI source */
5039 boost::shared_ptr<MidiSource>
5040 Session::create_midi_source_for_session (string const & basic_name)
5042 const string path = new_midi_source_path (basic_name);
5044 if (!path.empty()) {
5045 return boost::dynamic_pointer_cast<SMFSource> (
5046 SourceFactory::createWritable (
5047 DataType::MIDI, *this, path, false, frame_rate()));
5049 throw failed_constructor ();
5053 /** Create a new within-session MIDI source */
5054 boost::shared_ptr<MidiSource>
5055 Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
5057 /* the caller passes in the track the source will be used in,
5058 so that we can keep the numbering sane.
5060 Rationale: a track with the name "Foo" that has had N
5061 captures carried out so far will ALREADY have a write source
5062 named "Foo-N+1.mid" waiting to be used for the next capture.
5064 If we call new_midi_source_name() we will get "Foo-N+2". But
5065 there is no region corresponding to "Foo-N+1", so when
5066 "Foo-N+2" appears in the track, the gap presents the user
5067 with odd behaviour - why did it skip past Foo-N+1?
5069 We could explain this to the user in some odd way, but
5070 instead we rename "Foo-N+1.mid" as "Foo-N+2.mid", and then
5073 If that attempted rename fails, we get "Foo-N+2.mid" anyway.
5076 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (track);
5078 std::string name = track->steal_write_source_name ();
5081 return boost::shared_ptr<MidiSource>();
5084 /* MIDI files are small, just put them in the first location of the
5085 session source search path.
5088 const string path = Glib::build_filename (source_search_path (DataType::MIDI).front(), name);
5090 return boost::dynamic_pointer_cast<SMFSource> (
5091 SourceFactory::createWritable (
5092 DataType::MIDI, *this, path, false, frame_rate()));
5097 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
5099 if (playlist->hidden()) {
5103 playlists->add (playlist);
5106 playlist->release();
5113 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
5115 if (_state_of_the_state & Deletion) {
5119 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
5125 playlists->remove (playlist);
5131 Session::set_audition (boost::shared_ptr<Region> r)
5133 pending_audition_region = r;
5134 add_post_transport_work (PostTransportAudition);
5135 _butler->schedule_transport_work ();
5139 Session::audition_playlist ()
5141 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
5142 ev->region.reset ();
5148 Session::register_lua_function (
5149 const std::string& name,
5150 const std::string& script,
5151 const LuaScriptParamList& args
5154 Glib::Threads::Mutex::Lock lm (lua_lock);
5156 lua_State* L = lua.getState();
5158 const std::string& bytecode = LuaScripting::get_factory_bytecode (script);
5159 luabridge::LuaRef tbl_arg (luabridge::newTable(L));
5160 for (LuaScriptParamList::const_iterator i = args.begin(); i != args.end(); ++i) {
5161 if ((*i)->optional && !(*i)->is_set) { continue; }
5162 tbl_arg[(*i)->name] = (*i)->value;
5164 (*_lua_add)(name, bytecode, tbl_arg); // throws luabridge::LuaException
5169 Session::unregister_lua_function (const std::string& name)
5171 Glib::Threads::Mutex::Lock lm (lua_lock);
5172 (*_lua_del)(name); // throws luabridge::LuaException
5173 lua.collect_garbage ();
5177 std::vector<std::string>
5178 Session::registered_lua_functions ()
5180 Glib::Threads::Mutex::Lock lm (lua_lock);
5181 std::vector<std::string> rv;
5184 luabridge::LuaRef list ((*_lua_list)());
5185 for (luabridge::Iterator i (list); !i.isNil (); ++i) {
5186 if (!i.key ().isString ()) { assert(0); continue; }
5187 rv.push_back (i.key ().cast<std::string> ());
5189 } catch (luabridge::LuaException const& e) { }
5194 static void _lua_print (std::string s) {
5195 std::cout << "SessionLua: " << s << "\n";
5200 Session::try_run_lua (pframes_t nframes)
5202 if (_n_lua_scripts == 0) return;
5203 Glib::Threads::Mutex::Lock tm (lua_lock, Glib::Threads::TRY_LOCK);
5205 try { (*_lua_run)(nframes); } catch (luabridge::LuaException const& e) { }
5206 lua.collect_garbage_step ();
5211 Session::setup_lua ()
5214 lua.Print.connect (&_lua_print);
5218 "function ArdourSession ()"
5219 " local self = { scripts = {}, instances = {} }"
5221 " local remove = function (n)"
5222 " self.scripts[n] = nil"
5223 " self.instances[n] = nil"
5224 " Session:scripts_changed()" // call back
5227 " local addinternal = function (n, f, a)"
5228 " assert(type(n) == 'string', 'function-name must be string')"
5229 " assert(type(f) == 'function', 'Given script is a not a function')"
5230 " assert(type(a) == 'table' or type(a) == 'nil', 'Given argument is invalid')"
5231 " assert(self.scripts[n] == nil, 'Callback \"'.. n ..'\" already exists.')"
5232 " self.scripts[n] = { ['f'] = f, ['a'] = a }"
5233 " local env = _ENV; env.f = nil env.io = nil env.os = nil env.loadfile = nil env.require = nil env.dofile = nil env.package = nil env.debug = nil"
5234 " local env = { print = print, tostring = tostring, assert = assert, ipairs = ipairs, error = error, select = select, string = string, type = type, tonumber = tonumber, collectgarbage = collectgarbage, pairs = pairs, math = math, table = table, pcall = pcall, Session = Session, PBD = PBD, Timecode = Timecode, Evoral = Evoral, C = C, ARDOUR = ARDOUR }"
5235 " self.instances[n] = load (string.dump(f, true), nil, nil, env)(a)"
5236 " Session:scripts_changed()" // call back
5239 " local add = function (n, b, a)"
5240 " assert(type(b) == 'string', 'ByteCode must be string')"
5241 " load (b)()" // assigns f
5242 " assert(type(f) == 'string', 'Assigned ByteCode must be string')"
5243 " addinternal (n, load(f), a)"
5246 " local run = function (...)"
5247 " for n, s in pairs (self.instances) do"
5248 " local status, err = pcall (s, ...)"
5249 " if not status then"
5250 " print ('fn \"'.. n .. '\": ', err)"
5257 " local cleanup = function ()"
5258 " self.scripts = nil"
5259 " self.instances = nil"
5262 " local list = function ()"
5264 " for n, _ in pairs (self.scripts) do"
5270 " local function basic_serialize (o)"
5271 " if type(o) == \"number\" then"
5272 " return tostring(o)"
5274 " return string.format(\"%q\", o)"
5278 " local function serialize (name, value)"
5279 " local rv = name .. ' = '"
5281 " if type(value) == \"number\" or type(value) == \"string\" or type(value) == \"nil\" then"
5282 " return rv .. basic_serialize(value) .. ' '"
5283 " elseif type(value) == \"table\" then"
5285 " for k,v in pairs(value) do"
5286 " local fieldname = string.format(\"%s[%s]\", name, basic_serialize(k))"
5287 " rv = rv .. serialize(fieldname, v) .. ' '"
5288 " collectgarbage()" // string concatenation allocates a new string :(
5291 " elseif type(value) == \"function\" then"
5292 " return rv .. string.format(\"%q\", string.dump(value, true))"
5294 " error('cannot save a ' .. type(value))"
5299 " local save = function ()"
5300 " return (serialize('scripts', self.scripts))"
5303 " local restore = function (state)"
5304 " self.scripts = {}"
5306 " for n, s in pairs (scripts) do"
5307 " addinternal (n, load(s['f']), s['a'])"
5311 " return { run = run, add = add, remove = remove,"
5312 " list = list, restore = restore, save = save, cleanup = cleanup}"
5315 " sess = ArdourSession ()"
5316 " ArdourSession = nil"
5318 "function ardour () end"
5321 lua_State* L = lua.getState();
5324 luabridge::LuaRef lua_sess = luabridge::getGlobal (L, "sess");
5325 lua.do_command ("sess = nil"); // hide it.
5326 lua.do_command ("collectgarbage()");
5328 _lua_run = new luabridge::LuaRef(lua_sess["run"]);
5329 _lua_add = new luabridge::LuaRef(lua_sess["add"]);
5330 _lua_del = new luabridge::LuaRef(lua_sess["remove"]);
5331 _lua_list = new luabridge::LuaRef(lua_sess["list"]);
5332 _lua_save = new luabridge::LuaRef(lua_sess["save"]);
5333 _lua_load = new luabridge::LuaRef(lua_sess["restore"]);
5334 _lua_cleanup = new luabridge::LuaRef(lua_sess["cleanup"]);
5335 } catch (luabridge::LuaException const& e) {
5336 fatal << string_compose (_("programming error: %1"),
5337 X_("Failed to setup Lua interpreter"))
5339 abort(); /*NOTREACHED*/
5342 LuaBindings::stddef (L);
5343 LuaBindings::common (L);
5344 LuaBindings::dsp (L);
5345 luabridge::push <Session *> (L, this);
5346 lua_setglobal (L, "Session");
5350 Session::scripts_changed ()
5352 assert (!lua_lock.trylock()); // must hold lua_lock
5355 luabridge::LuaRef list ((*_lua_list)());
5357 for (luabridge::Iterator i (list); !i.isNil (); ++i) {
5358 if (!i.key ().isString ()) { assert(0); continue; }
5361 _n_lua_scripts = cnt;
5362 } catch (luabridge::LuaException const& e) {
5363 fatal << string_compose (_("programming error: %1"),
5364 X_("Indexing Lua Session Scripts failed."))
5366 abort(); /*NOTREACHED*/
5371 Session::non_realtime_set_audition ()
5373 assert (pending_audition_region);
5374 auditioner->audition_region (pending_audition_region);
5375 pending_audition_region.reset ();
5376 AuditionActive (true); /* EMIT SIGNAL */
5380 Session::audition_region (boost::shared_ptr<Region> r)
5382 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
5388 Session::cancel_audition ()
5393 if (auditioner->auditioning()) {
5394 auditioner->cancel_audition ();
5395 AuditionActive (false); /* EMIT SIGNAL */
5400 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
5402 if (a->is_monitor()) {
5405 if (b->is_monitor()) {
5408 return a->presentation_info().order() < b->presentation_info().order();
5412 Session::is_auditioning () const
5414 /* can be called before we have an auditioner object */
5416 return auditioner->auditioning();
5423 Session::graph_reordered ()
5425 /* don't do this stuff if we are setting up connections
5426 from a set_state() call or creating new tracks. Ditto for deletion.
5429 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress || _reconnecting_routes_in_progress || _route_deletion_in_progress) {
5433 /* every track/bus asked for this to be handled but it was deferred because
5434 we were connecting. do it now.
5437 request_input_change_handling ();
5441 /* force all diskstreams to update their capture offset values to
5442 reflect any changes in latencies within the graph.
5445 boost::shared_ptr<RouteList> rl = routes.reader ();
5446 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5447 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5449 tr->set_capture_offset ();
5454 /** @return Number of frames that there is disk space available to write,
5457 boost::optional<framecnt_t>
5458 Session::available_capture_duration ()
5460 Glib::Threads::Mutex::Lock lm (space_lock);
5462 if (_total_free_4k_blocks_uncertain) {
5463 return boost::optional<framecnt_t> ();
5466 float sample_bytes_on_disk = 4.0; // keep gcc happy
5468 switch (config.get_native_file_data_format()) {
5470 sample_bytes_on_disk = 4.0;
5474 sample_bytes_on_disk = 3.0;
5478 sample_bytes_on_disk = 2.0;
5482 /* impossible, but keep some gcc versions happy */
5483 fatal << string_compose (_("programming error: %1"),
5484 X_("illegal native file data format"))
5486 abort(); /*NOTREACHED*/
5489 double scale = 4096.0 / sample_bytes_on_disk;
5491 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
5492 return max_framecnt;
5495 return (framecnt_t) floor (_total_free_4k_blocks * scale);
5499 Session::add_bundle (boost::shared_ptr<Bundle> bundle, bool emit_signal)
5502 RCUWriter<BundleList> writer (_bundles);
5503 boost::shared_ptr<BundleList> b = writer.get_copy ();
5504 b->push_back (bundle);
5508 BundleAddedOrRemoved (); /* EMIT SIGNAL */
5515 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
5517 bool removed = false;
5520 RCUWriter<BundleList> writer (_bundles);
5521 boost::shared_ptr<BundleList> b = writer.get_copy ();
5522 BundleList::iterator i = find (b->begin(), b->end(), bundle);
5524 if (i != b->end()) {
5531 BundleAddedOrRemoved (); /* EMIT SIGNAL */
5537 boost::shared_ptr<Bundle>
5538 Session::bundle_by_name (string name) const
5540 boost::shared_ptr<BundleList> b = _bundles.reader ();
5542 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
5543 if ((*i)->name() == name) {
5548 return boost::shared_ptr<Bundle> ();
5552 Session::tempo_map_changed (const PropertyChange&)
5556 playlists->update_after_tempo_map_change ();
5558 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
5564 Session::gui_tempo_map_changed ()
5568 playlists->update_after_tempo_map_change ();
5570 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
5574 Session::update_locations_after_tempo_map_change (const Locations::LocationList& loc)
5576 for (Locations::LocationList::const_iterator i = loc.begin(); i != loc.end(); ++i) {
5577 (*i)->recompute_frames_from_bbt ();
5581 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
5582 * the given count with the current block size.
5585 Session::ensure_buffers (ChanCount howmany)
5587 BufferManager::ensure_buffers (howmany, bounce_processing() ? bounce_chunk_size : 0);
5591 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
5593 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
5594 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
5599 Session::next_insert_id ()
5601 /* this doesn't really loop forever. just think about it */
5604 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < insert_bitset.size(); ++n) {
5605 if (!insert_bitset[n]) {
5606 insert_bitset[n] = true;
5612 /* none available, so resize and try again */
5614 insert_bitset.resize (insert_bitset.size() + 16, false);
5619 Session::next_send_id ()
5621 /* this doesn't really loop forever. just think about it */
5624 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < send_bitset.size(); ++n) {
5625 if (!send_bitset[n]) {
5626 send_bitset[n] = true;
5632 /* none available, so resize and try again */
5634 send_bitset.resize (send_bitset.size() + 16, false);
5639 Session::next_aux_send_id ()
5641 /* this doesn't really loop forever. just think about it */
5644 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < aux_send_bitset.size(); ++n) {
5645 if (!aux_send_bitset[n]) {
5646 aux_send_bitset[n] = true;
5652 /* none available, so resize and try again */
5654 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
5659 Session::next_return_id ()
5661 /* this doesn't really loop forever. just think about it */
5664 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < return_bitset.size(); ++n) {
5665 if (!return_bitset[n]) {
5666 return_bitset[n] = true;
5672 /* none available, so resize and try again */
5674 return_bitset.resize (return_bitset.size() + 16, false);
5679 Session::mark_send_id (uint32_t id)
5681 if (id >= send_bitset.size()) {
5682 send_bitset.resize (id+16, false);
5684 if (send_bitset[id]) {
5685 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
5687 send_bitset[id] = true;
5691 Session::mark_aux_send_id (uint32_t id)
5693 if (id >= aux_send_bitset.size()) {
5694 aux_send_bitset.resize (id+16, false);
5696 if (aux_send_bitset[id]) {
5697 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
5699 aux_send_bitset[id] = true;
5703 Session::mark_return_id (uint32_t id)
5705 if (id >= return_bitset.size()) {
5706 return_bitset.resize (id+16, false);
5708 if (return_bitset[id]) {
5709 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
5711 return_bitset[id] = true;
5715 Session::mark_insert_id (uint32_t id)
5717 if (id >= insert_bitset.size()) {
5718 insert_bitset.resize (id+16, false);
5720 if (insert_bitset[id]) {
5721 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
5723 insert_bitset[id] = true;
5727 Session::unmark_send_id (uint32_t id)
5729 if (id < send_bitset.size()) {
5730 send_bitset[id] = false;
5735 Session::unmark_aux_send_id (uint32_t id)
5737 if (id < aux_send_bitset.size()) {
5738 aux_send_bitset[id] = false;
5743 Session::unmark_return_id (uint32_t id)
5745 if (_state_of_the_state & Deletion) { return; }
5746 if (id < return_bitset.size()) {
5747 return_bitset[id] = false;
5752 Session::unmark_insert_id (uint32_t id)
5754 if (id < insert_bitset.size()) {
5755 insert_bitset[id] = false;
5760 Session::reset_native_file_format ()
5762 boost::shared_ptr<RouteList> rl = routes.reader ();
5764 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5765 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5767 /* don't save state as we do this, there's no point
5769 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
5770 tr->reset_write_sources (false);
5771 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
5777 Session::route_name_unique (string n) const
5779 boost::shared_ptr<RouteList> r = routes.reader ();
5781 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5782 if ((*i)->name() == n) {
5791 Session::route_name_internal (string n) const
5793 if (auditioner && auditioner->name() == n) {
5797 if (_click_io && _click_io->name() == n) {
5805 Session::freeze_all (InterThreadInfo& itt)
5807 boost::shared_ptr<RouteList> r = routes.reader ();
5809 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5811 boost::shared_ptr<Track> t;
5813 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
5814 /* XXX this is wrong because itt.progress will keep returning to zero at the start
5824 boost::shared_ptr<Region>
5825 Session::write_one_track (Track& track, framepos_t start, framepos_t end,
5826 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
5827 InterThreadInfo& itt,
5828 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
5829 bool for_export, bool for_freeze)
5831 boost::shared_ptr<Region> result;
5832 boost::shared_ptr<Playlist> playlist;
5833 boost::shared_ptr<Source> source;
5834 ChanCount diskstream_channels (track.n_channels());
5835 framepos_t position;
5836 framecnt_t this_chunk;
5838 framepos_t latency_skip;
5840 framepos_t len = end - start;
5841 bool need_block_size_reset = false;
5842 ChanCount const max_proc = track.max_processor_streams ();
5843 string legal_playlist_name;
5844 string possible_path;
5847 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
5848 end, start) << endmsg;
5852 diskstream_channels = track.bounce_get_output_streams (diskstream_channels, endpoint,
5853 include_endpoint, for_export, for_freeze);
5855 if (diskstream_channels.n(track.data_type()) < 1) {
5856 error << _("Cannot write a range with no data.") << endmsg;
5860 // block all process callback handling
5862 block_processing ();
5865 // synchronize with AudioEngine::process_callback()
5866 // make sure processing is not currently running
5867 // and processing_blocked() is honored before
5868 // acquiring thread buffers
5869 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
5872 _bounce_processing_active = true;
5874 /* call tree *MUST* hold route_lock */
5876 if ((playlist = track.playlist()) == 0) {
5880 legal_playlist_name = legalize_for_path (playlist->name());
5882 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n(track.data_type()); ++chan_n) {
5884 string base_name = string_compose ("%1-%2-bounce", playlist->name(), chan_n);
5885 string path = ((track.data_type() == DataType::AUDIO)
5886 ? new_audio_source_path (legal_playlist_name, diskstream_channels.n_audio(), chan_n, false, true)
5887 : new_midi_source_path (legal_playlist_name));
5894 source = SourceFactory::createWritable (track.data_type(), *this, path, false, frame_rate());
5897 catch (failed_constructor& err) {
5898 error << string_compose (_("cannot create new file \"%1\" for %2"), path, track.name()) << endmsg;
5902 srcs.push_back (source);
5905 /* tell redirects that care that we are about to use a much larger
5906 * blocksize. this will flush all plugins too, so that they are ready
5907 * to be used for this process.
5910 need_block_size_reset = true;
5911 track.set_block_size (bounce_chunk_size);
5912 _engine.main_thread()->get_buffers ();
5916 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
5918 /* create a set of reasonably-sized buffers */
5919 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
5920 buffers.ensure_buffers(*t, max_proc.get(*t), bounce_chunk_size);
5922 buffers.set_count (max_proc);
5924 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
5925 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5926 boost::shared_ptr<MidiSource> ms;
5928 afs->prepare_for_peakfile_writes ();
5929 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
5930 Source::Lock lock(ms->mutex());
5931 ms->mark_streaming_write_started(lock);
5935 while (to_do && !itt.cancel) {
5937 this_chunk = min (to_do, bounce_chunk_size);
5939 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze)) {
5943 start += this_chunk;
5944 to_do -= this_chunk;
5945 itt.progress = (float) (1.0 - ((double) to_do / len));
5947 if (latency_skip >= bounce_chunk_size) {
5948 latency_skip -= bounce_chunk_size;
5952 const framecnt_t current_chunk = this_chunk - latency_skip;
5955 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
5956 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5957 boost::shared_ptr<MidiSource> ms;
5960 if (afs->write (buffers.get_audio(n).data(latency_skip), current_chunk) != current_chunk) {
5963 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
5964 Source::Lock lock(ms->mutex());
5966 const MidiBuffer& buf = buffers.get_midi(0);
5967 for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
5968 Evoral::Event<framepos_t> ev = *i;
5969 ev.set_time(ev.time() - position);
5970 ms->append_event_frames(lock, ev, ms->timeline_position());
5977 /* post-roll, pick up delayed processor output */
5978 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
5980 while (latency_skip && !itt.cancel) {
5981 this_chunk = min (latency_skip, bounce_chunk_size);
5982 latency_skip -= this_chunk;
5984 buffers.silence (this_chunk, 0);
5985 track.bounce_process (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze);
5988 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
5989 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5992 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
6004 xnow = localtime (&now);
6006 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
6007 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
6008 boost::shared_ptr<MidiSource> ms;
6011 afs->update_header (position, *xnow, now);
6012 afs->flush_header ();
6013 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
6014 Source::Lock lock(ms->mutex());
6015 ms->mark_streaming_write_completed(lock);
6019 /* construct a region to represent the bounced material */
6023 plist.add (Properties::start, 0);
6024 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
6025 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
6027 result = RegionFactory::create (srcs, plist);
6033 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
6034 (*src)->mark_for_remove ();
6035 (*src)->drop_references ();
6039 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
6040 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
6043 afs->done_with_peakfile_writes ();
6047 _bounce_processing_active = false;
6049 if (need_block_size_reset) {
6050 _engine.main_thread()->drop_buffers ();
6051 track.set_block_size (get_block_size());
6054 unblock_processing ();
6060 Session::gain_automation_buffer() const
6062 return ProcessThread::gain_automation_buffer ();
6066 Session::trim_automation_buffer() const
6068 return ProcessThread::trim_automation_buffer ();
6072 Session::send_gain_automation_buffer() const
6074 return ProcessThread::send_gain_automation_buffer ();
6078 Session::pan_automation_buffer() const
6080 return ProcessThread::pan_automation_buffer ();
6084 Session::get_silent_buffers (ChanCount count)
6086 return ProcessThread::get_silent_buffers (count);
6090 Session::get_scratch_buffers (ChanCount count, bool silence)
6092 return ProcessThread::get_scratch_buffers (count, silence);
6096 Session::get_noinplace_buffers (ChanCount count)
6098 return ProcessThread::get_noinplace_buffers (count);
6102 Session::get_route_buffers (ChanCount count, bool silence)
6104 return ProcessThread::get_route_buffers (count, silence);
6109 Session::get_mix_buffers (ChanCount count)
6111 return ProcessThread::get_mix_buffers (count);
6115 Session::ntracks () const
6118 boost::shared_ptr<RouteList> r = routes.reader ();
6120 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
6121 if (boost::dynamic_pointer_cast<Track> (*i)) {
6130 Session::nbusses () const
6133 boost::shared_ptr<RouteList> r = routes.reader ();
6135 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
6136 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
6145 Session::add_automation_list(AutomationList *al)
6147 automation_lists[al->id()] = al;
6150 /** @return true if there is at least one record-enabled track, otherwise false */
6152 Session::have_rec_enabled_track () const
6154 return g_atomic_int_get (const_cast<gint*>(&_have_rec_enabled_track)) == 1;
6158 Session::have_rec_disabled_track () const
6160 return g_atomic_int_get (const_cast<gint*>(&_have_rec_disabled_track)) == 1;
6163 /** Update the state of our rec-enabled tracks flag */
6165 Session::update_route_record_state ()
6167 boost::shared_ptr<RouteList> rl = routes.reader ();
6168 RouteList::iterator i = rl->begin();
6169 while (i != rl->end ()) {
6171 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6172 if (tr && tr->rec_enable_control()->get_value()) {
6179 int const old = g_atomic_int_get (&_have_rec_enabled_track);
6181 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
6183 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
6184 RecordStateChanged (); /* EMIT SIGNAL */
6187 for (i = rl->begin(); i != rl->end (); ++i) {
6188 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6189 if (tr && !tr->rec_enable_control()->get_value()) {
6194 g_atomic_int_set (&_have_rec_disabled_track, i != rl->end () ? 1 : 0);
6196 bool record_arm_state_changed = (old != g_atomic_int_get (&_have_rec_enabled_track) );
6198 if (record_status() == Recording && record_arm_state_changed ) {
6199 RecordArmStateChanged ();
6205 Session::listen_position_changed ()
6207 ProcessorChangeBlocker pcb (this);
6208 boost::shared_ptr<RouteList> r = routes.reader ();
6209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6210 (*i)->listen_position_changed ();
6215 Session::solo_control_mode_changed ()
6217 if (soloing() || listening()) {
6219 /* We can't use ::clear_all_solo_state() here because during
6220 session loading at program startup, that will queue a call
6221 to rt_clear_all_solo_state() that will not execute until
6222 AFTER solo states have been established (thus throwing away
6223 the session's saved solo state). So just explicitly turn
6226 set_controls (route_list_to_control_list (get_routes(), &Stripable::solo_control), 0.0, Controllable::NoGroup);
6228 clear_all_solo_state (get_routes());
6233 /** Called when a property of one of our route groups changes */
6235 Session::route_group_property_changed (RouteGroup* rg)
6237 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
6240 /** Called when a route is added to one of our route groups */
6242 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
6244 RouteAddedToRouteGroup (rg, r);
6247 /** Called when a route is removed from one of our route groups */
6249 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
6251 update_route_record_state ();
6252 RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */
6254 if (!rg->has_control_master () && !rg->has_subgroup () && rg->empty()) {
6255 remove_route_group (*rg);
6259 boost::shared_ptr<RouteList>
6260 Session::get_tracks () const
6262 boost::shared_ptr<RouteList> rl = routes.reader ();
6263 boost::shared_ptr<RouteList> tl (new RouteList);
6265 for (RouteList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
6266 if (boost::dynamic_pointer_cast<Track> (*r)) {
6267 if (!(*r)->is_auditioner()) {
6275 boost::shared_ptr<RouteList>
6276 Session::get_routes_with_regions_at (framepos_t const p) const
6278 boost::shared_ptr<RouteList> r = routes.reader ();
6279 boost::shared_ptr<RouteList> rl (new RouteList);
6281 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6282 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6287 boost::shared_ptr<Playlist> pl = tr->playlist ();
6292 if (pl->has_region_at (p)) {
6301 Session::goto_end ()
6303 if (_session_range_location) {
6304 request_locate (_session_range_location->end(), false);
6306 request_locate (0, false);
6311 Session::goto_start (bool and_roll)
6313 if (_session_range_location) {
6314 request_locate (_session_range_location->start(), and_roll);
6316 request_locate (0, and_roll);
6321 Session::current_start_frame () const
6323 return _session_range_location ? _session_range_location->start() : 0;
6327 Session::current_end_frame () const
6329 return _session_range_location ? _session_range_location->end() : 0;
6333 Session::set_session_range_location (framepos_t start, framepos_t end)
6335 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
6336 _locations->add (_session_range_location);
6340 Session::step_edit_status_change (bool yn)
6346 send = (_step_editors == 0);
6351 send = (_step_editors == 1);
6354 if (_step_editors > 0) {
6360 StepEditStatusChange (val);
6366 Session::start_time_changed (framepos_t old)
6368 /* Update the auto loop range to match the session range
6369 (unless the auto loop range has been changed by the user)
6372 Location* s = _locations->session_range_location ();
6377 Location* l = _locations->auto_loop_location ();
6379 if (l && l->start() == old) {
6380 l->set_start (s->start(), true);
6386 Session::end_time_changed (framepos_t old)
6388 /* Update the auto loop range to match the session range
6389 (unless the auto loop range has been changed by the user)
6392 Location* s = _locations->session_range_location ();
6397 Location* l = _locations->auto_loop_location ();
6399 if (l && l->end() == old) {
6400 l->set_end (s->end(), true);
6405 std::vector<std::string>
6406 Session::source_search_path (DataType type) const
6410 if (session_dirs.size() == 1) {
6412 case DataType::AUDIO:
6413 sp.push_back (_session_dir->sound_path());
6415 case DataType::MIDI:
6416 sp.push_back (_session_dir->midi_path());
6420 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
6421 SessionDirectory sdir (i->path);
6423 case DataType::AUDIO:
6424 sp.push_back (sdir.sound_path());
6426 case DataType::MIDI:
6427 sp.push_back (sdir.midi_path());
6433 if (type == DataType::AUDIO) {
6434 const string sound_path_2X = _session_dir->sound_path_2X();
6435 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
6436 if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) {
6437 sp.push_back (sound_path_2X);
6442 // now check the explicit (possibly user-specified) search path
6445 case DataType::AUDIO:
6446 sp += Searchpath(config.get_audio_search_path ());
6448 case DataType::MIDI:
6449 sp += Searchpath(config.get_midi_search_path ());
6457 Session::ensure_search_path_includes (const string& path, DataType type)
6466 case DataType::AUDIO:
6467 sp += Searchpath(config.get_audio_search_path ());
6469 case DataType::MIDI:
6470 sp += Searchpath (config.get_midi_search_path ());
6474 for (vector<std::string>::iterator i = sp.begin(); i != sp.end(); ++i) {
6475 /* No need to add this new directory if it has the same inode as
6476 an existing one; checking inode rather than name prevents duplicated
6477 directories when we are using symlinks.
6479 On Windows, I think we could just do if (*i == path) here.
6481 if (PBD::equivalent_paths (*i, path)) {
6489 case DataType::AUDIO:
6490 config.set_audio_search_path (sp.to_string());
6492 case DataType::MIDI:
6493 config.set_midi_search_path (sp.to_string());
6499 Session::remove_dir_from_search_path (const string& dir, DataType type)
6504 case DataType::AUDIO:
6505 sp = Searchpath(config.get_audio_search_path ());
6507 case DataType::MIDI:
6508 sp = Searchpath (config.get_midi_search_path ());
6515 case DataType::AUDIO:
6516 config.set_audio_search_path (sp.to_string());
6518 case DataType::MIDI:
6519 config.set_midi_search_path (sp.to_string());
6525 boost::shared_ptr<Speakers>
6526 Session::get_speakers()
6532 Session::unknown_processors () const
6536 boost::shared_ptr<RouteList> r = routes.reader ();
6537 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6538 list<string> t = (*i)->unknown_processors ();
6539 copy (t.begin(), t.end(), back_inserter (p));
6549 Session::update_latency (bool playback)
6552 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
6554 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress || _route_deletion_in_progress) {
6558 boost::shared_ptr<RouteList> r = routes.reader ();
6559 framecnt_t max_latency = 0;
6562 /* reverse the list so that we work backwards from the last route to run to the first */
6563 RouteList* rl = routes.reader().get();
6564 r.reset (new RouteList (*rl));
6565 reverse (r->begin(), r->end());
6568 /* compute actual latency values for the given direction and store them all in per-port
6569 structures. this will also publish the same values (to JACK) so that computation of latency
6570 for routes can consistently use public latency values.
6573 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6574 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
6577 /* because we latency compensate playback, our published playback latencies should
6578 be the same for all output ports - all material played back by ardour has
6579 the same latency, whether its caused by plugins or by latency compensation. since
6580 these may differ from the values computed above, reset all playback port latencies
6584 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
6586 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6587 (*i)->set_public_port_latencies (max_latency, playback);
6592 post_playback_latency ();
6596 post_capture_latency ();
6599 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
6603 Session::post_playback_latency ()
6605 set_worst_playback_latency ();
6607 boost::shared_ptr<RouteList> r = routes.reader ();
6609 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6610 if (!(*i)->is_auditioner() && ((*i)->active())) {
6611 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
6615 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6616 (*i)->set_latency_compensation (_worst_track_latency);
6621 Session::post_capture_latency ()
6623 set_worst_capture_latency ();
6625 /* reflect any changes in capture latencies into capture offsets
6628 boost::shared_ptr<RouteList> rl = routes.reader();
6629 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
6630 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6632 tr->set_capture_offset ();
6638 Session::initialize_latencies ()
6641 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
6642 update_latency (false);
6643 update_latency (true);
6646 set_worst_io_latencies ();
6650 Session::set_worst_io_latencies ()
6652 set_worst_playback_latency ();
6653 set_worst_capture_latency ();
6657 Session::set_worst_playback_latency ()
6659 if (_state_of_the_state & (InitialConnecting|Deletion)) {
6663 _worst_output_latency = 0;
6665 if (!_engine.connected()) {
6669 boost::shared_ptr<RouteList> r = routes.reader ();
6671 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6672 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
6675 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
6679 Session::set_worst_capture_latency ()
6681 if (_state_of_the_state & (InitialConnecting|Deletion)) {
6685 _worst_input_latency = 0;
6687 if (!_engine.connected()) {
6691 boost::shared_ptr<RouteList> r = routes.reader ();
6693 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6694 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
6697 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
6701 Session::update_latency_compensation (bool force_whole_graph)
6703 bool some_track_latency_changed = false;
6705 if (_state_of_the_state & (InitialConnecting|Deletion)) {
6709 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
6711 _worst_track_latency = 0;
6713 boost::shared_ptr<RouteList> r = routes.reader ();
6715 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6716 if (!(*i)->is_auditioner() && ((*i)->active())) {
6718 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
6719 some_track_latency_changed = true;
6721 _worst_track_latency = max (tl, _worst_track_latency);
6725 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
6726 (some_track_latency_changed ? "yes" : "no")));
6728 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
6730 if (some_track_latency_changed || force_whole_graph) {
6731 _engine.update_latencies ();
6735 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6736 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6740 tr->set_capture_offset ();
6745 Session::session_name_is_legal (const string& path)
6747 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
6749 for (int i = 0; illegal_chars[i]; ++i) {
6750 if (path.find (illegal_chars[i]) != string::npos) {
6751 return illegal_chars[i];
6759 Session::notify_presentation_info_change ()
6761 if (deletion_in_progress()) {
6765 PresentationInfo::Change (); /* EMIT SIGNAL */
6766 reassign_track_numbers();
6768 #ifdef USE_TRACKS_CODE_FEATURES
6769 /* Waves Tracks: for Waves Tracks session it's required to reconnect their IOs
6770 * if track order has been changed by user
6772 reconnect_existing_routes(true, true);
6778 Session::operation_in_progress (GQuark op) const
6780 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
6783 boost::shared_ptr<Port>
6784 Session::ltc_input_port () const
6786 return _ltc_input->nth (0);
6789 boost::shared_ptr<Port>
6790 Session::ltc_output_port () const
6792 return _ltc_output->nth (0);
6796 Session::reconnect_ltc_input ()
6800 string src = Config->get_ltc_source_port();
6802 _ltc_input->disconnect (this);
6804 if (src != _("None") && !src.empty()) {
6805 _ltc_input->nth (0)->connect (src);
6808 if ( ARDOUR::Profile->get_trx () ) {
6809 // Tracks need this signal to update timecode_source_dropdown
6810 MtcOrLtcInputPortChanged (); //emit signal
6816 Session::reconnect_ltc_output ()
6820 string src = Config->get_ltc_output_port();
6822 _ltc_output->disconnect (this);
6824 if (src != _("None") && !src.empty()) {
6825 _ltc_output->nth (0)->connect (src);
6831 Session::set_range_selection (framepos_t start, framepos_t end)
6833 _range_selection = Evoral::Range<framepos_t> (start, end);
6834 #ifdef USE_TRACKS_CODE_FEATURES
6835 follow_playhead_priority ();
6840 Session::set_object_selection (framepos_t start, framepos_t end)
6842 _object_selection = Evoral::Range<framepos_t> (start, end);
6843 #ifdef USE_TRACKS_CODE_FEATURES
6844 follow_playhead_priority ();
6849 Session::clear_range_selection ()
6851 _range_selection = Evoral::Range<framepos_t> (-1,-1);
6852 #ifdef USE_TRACKS_CODE_FEATURES
6853 follow_playhead_priority ();
6858 Session::clear_object_selection ()
6860 _object_selection = Evoral::Range<framepos_t> (-1,-1);
6861 #ifdef USE_TRACKS_CODE_FEATURES
6862 follow_playhead_priority ();
6867 Session::auto_connect_route (boost::shared_ptr<Route> route, bool connect_inputs,
6868 const ChanCount& input_start,
6869 const ChanCount& output_start,
6870 const ChanCount& input_offset,
6871 const ChanCount& output_offset)
6873 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
6874 _auto_connect_queue.push (AutoConnectRequest (route, connect_inputs,
6875 input_start, output_start,
6876 input_offset, output_offset));
6878 auto_connect_thread_wakeup ();
6882 Session::auto_connect_thread_wakeup ()
6884 if (pthread_mutex_trylock (&_auto_connect_mutex) == 0) {
6885 pthread_cond_signal (&_auto_connect_cond);
6886 pthread_mutex_unlock (&_auto_connect_mutex);
6891 Session::queue_latency_recompute ()
6893 g_atomic_int_inc (&_latency_recompute_pending);
6894 auto_connect_thread_wakeup ();
6898 Session::auto_connect (const AutoConnectRequest& ar)
6900 boost::shared_ptr<Route> route = ar.route.lock();
6902 if (!route) { return; }
6904 if (!IO::connecting_legal) {
6908 /* If both inputs and outputs are auto-connected to physical ports,
6909 * use the max of input and output offsets to ensure auto-connected
6910 * port numbers always match up (e.g. the first audio input and the
6911 * first audio output of the route will have the same physical
6912 * port number). Otherwise just use the lowest input or output
6916 const bool in_out_physical =
6917 (Config->get_input_auto_connect() & AutoConnectPhysical)
6918 && (Config->get_output_auto_connect() & AutoConnectPhysical)
6919 && ar.connect_inputs;
6921 const ChanCount in_offset = in_out_physical
6922 ? ChanCount::max(ar.input_offset, ar.output_offset)
6925 const ChanCount out_offset = in_out_physical
6926 ? ChanCount::max(ar.input_offset, ar.output_offset)
6929 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
6930 vector<string> physinputs;
6931 vector<string> physoutputs;
6934 /* for connecting track inputs we only want MIDI ports marked
6938 get_physical_ports (physinputs, physoutputs, *t, MidiPortMusic);
6940 if (!physinputs.empty() && ar.connect_inputs) {
6941 uint32_t nphysical_in = physinputs.size();
6943 for (uint32_t i = ar.input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
6946 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
6947 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
6950 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
6956 if (!physoutputs.empty()) {
6957 uint32_t nphysical_out = physoutputs.size();
6958 for (uint32_t i = ar.output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
6962 * do not create new connections if we reached the limit of physical outputs
6965 if (!(Config->get_output_auto_connect() & AutoConnectMaster) &&
6966 ARDOUR::Profile->get_trx () &&
6967 ar.output_offset.get(*t) == nphysical_out ) {
6971 if ((*t) == DataType::MIDI && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
6972 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
6973 } else if ((*t) == DataType::AUDIO && (Config->get_output_auto_connect() & AutoConnectMaster)) {
6974 /* master bus is audio only */
6975 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
6976 port = _master_out->input()->ports().port(*t,
6977 i % _master_out->input()->n_ports().get(*t))->name();
6981 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
6990 Session::auto_connect_thread_start ()
6992 if (_ac_thread_active) {
6996 while (!_auto_connect_queue.empty ()) {
6997 _auto_connect_queue.pop ();
7000 _ac_thread_active = true;
7001 if (pthread_create (&_auto_connect_thread, NULL, auto_connect_thread, this)) {
7002 _ac_thread_active = false;
7007 Session::auto_connect_thread_terminate ()
7009 if (!_ac_thread_active) {
7012 _ac_thread_active = false;
7015 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
7016 while (!_auto_connect_queue.empty ()) {
7017 _auto_connect_queue.pop ();
7021 auto_connect_thread_wakeup ();
7024 pthread_join (_auto_connect_thread, &status);
7028 Session::auto_connect_thread (void *arg)
7030 Session *s = static_cast<Session *>(arg);
7031 s->auto_connect_thread_run ();
7037 Session::auto_connect_thread_run ()
7039 pthread_set_name (X_("autoconnect"));
7040 SessionEvent::create_per_thread_pool (X_("autoconnect"), 1024);
7041 PBD::notify_event_loops_about_thread_creation (pthread_self(), X_("autoconnect"), 1024);
7042 pthread_mutex_lock (&_auto_connect_mutex);
7043 while (_ac_thread_active) {
7045 if (!_auto_connect_queue.empty ()) {
7046 // Why would we need the process lock ??
7047 // A: if ports are added while we're connecting, the backend's iterator may be invalidated:
7048 // graph_order_callback() -> resort_routes() -> direct_feeds_according_to_reality () -> backend::connected_to()
7049 // All ardour-internal backends use a std::vector xxxAudioBackend::find_port()
7050 // We have control over those, but what does jack do?
7051 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
7053 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
7054 while (!_auto_connect_queue.empty ()) {
7055 const AutoConnectRequest ar (_auto_connect_queue.front());
7056 _auto_connect_queue.pop ();
7063 if (!actively_recording ()) { // might not be needed,
7064 /* this is only used for updating plugin latencies, the
7065 * graph does not change. so it's safe in general.
7067 * .. update_latency_compensation () entails set_capture_offset()
7068 * which calls Diskstream::set_capture_offset () which
7069 * modifies the capture offset... which can be a proplem
7070 * in "prepare_to_stop"
7072 while (g_atomic_int_and (&_latency_recompute_pending, 0)) {
7073 update_latency_compensation ();
7077 AudioEngine::instance()->clear_pending_port_deletions ();
7079 pthread_cond_wait (&_auto_connect_cond, &_auto_connect_mutex);
7081 pthread_mutex_unlock (&_auto_connect_mutex);
7085 Session::cancel_all_solo ()
7089 get_stripables (sl);
7091 set_controls (stripable_list_to_control_list (sl, &Stripable::solo_control), 0.0, Controllable::NoGroup);
7092 clear_all_solo_state (routes.reader());