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/plugin.h"
85 #include "ardour/plugin_insert.h"
86 #include "ardour/process_thread.h"
87 #include "ardour/profile.h"
88 #include "ardour/rc_configuration.h"
89 #include "ardour/recent_sessions.h"
90 #include "ardour/region.h"
91 #include "ardour/region_factory.h"
92 #include "ardour/revision.h"
93 #include "ardour/route_graph.h"
94 #include "ardour/route_group.h"
95 #include "ardour/send.h"
96 #include "ardour/session.h"
97 #include "ardour/session_directory.h"
98 #include "ardour/session_playlists.h"
99 #include "ardour/smf_source.h"
100 #include "ardour/solo_isolate_control.h"
101 #include "ardour/source_factory.h"
102 #include "ardour/speakers.h"
103 #include "ardour/tempo.h"
104 #include "ardour/ticker.h"
105 #include "ardour/track.h"
106 #include "ardour/user_bundle.h"
107 #include "ardour/utils.h"
108 #include "ardour/vca_manager.h"
109 #include "ardour/vca.h"
111 #include "midi++/port.h"
112 #include "midi++/mmc.h"
114 #include "LuaBridge/LuaBridge.h"
116 #include "pbd/i18n.h"
118 #include <glibmm/checksum.h>
127 using namespace ARDOUR;
130 bool Session::_disable_all_loaded_plugins = false;
131 bool Session::_bypass_all_loaded_plugins = false;
132 guint Session::_name_id_counter = 0;
134 PBD::Signal1<int,uint32_t> Session::AudioEngineSetupRequired;
135 PBD::Signal1<void,std::string> Session::Dialog;
136 PBD::Signal0<int> Session::AskAboutPendingState;
137 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
138 PBD::Signal2<void, framecnt_t, framecnt_t> Session::NotifyAboutSampleRateMismatch;
139 PBD::Signal0<void> Session::SendFeedback;
140 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
142 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
143 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
144 PBD::Signal2<void,std::string, std::string> Session::Exported;
145 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
146 PBD::Signal0<void> Session::Quit;
147 PBD::Signal0<void> Session::FeedbackDetected;
148 PBD::Signal0<void> Session::SuccessfulGraphSort;
149 PBD::Signal2<void,std::string,std::string> Session::VersionMismatch;
151 const framecnt_t Session::bounce_chunk_size = 8192;
152 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
153 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
155 // seconds should be added after the region exceeds end marker
156 #ifdef USE_TRACKS_CODE_FEATURES
157 const uint32_t Session::session_end_shift = 5;
159 const uint32_t Session::session_end_shift = 0;
162 /** @param snapshot_name Snapshot name, without .ardour suffix */
163 Session::Session (AudioEngine &eng,
164 const string& fullpath,
165 const string& snapshot_name,
166 BusProfile* bus_profile,
168 : playlists (new SessionPlaylists)
170 , process_function (&Session::process_with_events)
171 , _bounce_processing_active (false)
172 , waiting_for_sync_offset (false)
173 , _base_frame_rate (0)
174 , _nominal_frame_rate (0)
175 , _current_frame_rate (0)
176 , transport_sub_state (0)
177 , _record_status (Disabled)
178 , _transport_frame (0)
179 , _session_range_location (0)
180 , _session_range_end_is_free (true)
183 , _transport_speed (0)
184 , _default_transport_speed (1.0)
185 , _last_transport_speed (0)
186 , _target_transport_speed (0.0)
187 , auto_play_legal (false)
188 , _last_slave_transport_frame (0)
189 , maximum_output_latency (0)
190 , _requested_return_frame (-1)
191 , current_block_size (0)
192 , _worst_output_latency (0)
193 , _worst_input_latency (0)
194 , _worst_track_latency (0)
195 , _have_captured (false)
196 , _non_soloed_outs_muted (false)
199 , _solo_isolated_cnt (0)
201 , _was_seamless (Config->get_seamless_loop ())
202 , _under_nsm_control (false)
204 , delta_accumulator_cnt (0)
205 , average_slave_delta (1800) // !!! why 1800 ???
207 , have_first_delta_accumulator (false)
208 , _slave_state (Stopped)
209 , _mtc_active (false)
210 , _ltc_active (false)
211 , post_export_sync (false)
212 , post_export_position (0)
214 , _export_rolling (false)
215 , _realtime_export (false)
216 , _region_export (false)
217 , _export_preroll (0)
218 , _export_latency (0)
219 , _pre_export_mmc_enabled (false)
220 , _name (snapshot_name)
222 , _send_qf_mtc (false)
223 , _pframes_since_last_mtc (0)
224 , session_midi_feedback (0)
226 , loop_changing (false)
228 , _session_dir (new SessionDirectory (fullpath))
229 , _current_snapshot_name (snapshot_name)
231 , state_was_pending (false)
232 , _state_of_the_state (StateOfTheState(CannotSave|InitialConnecting|Loading))
234 , _save_queued (false)
235 , _last_roll_location (0)
236 , _last_roll_or_reversal_location (0)
237 , _last_record_location (0)
238 , pending_locate_roll (false)
239 , pending_locate_frame (0)
240 , pending_locate_flush (false)
241 , pending_abort (false)
242 , pending_auto_loop (false)
243 , _mempool ("Session", 2097152)
244 , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
246 , _butler (new Butler (*this))
247 , _post_transport_work (0)
248 , cumulative_rf_motion (0)
250 , _locations (new Locations (*this))
251 , _ignore_skips_updates (false)
252 , _rt_thread_active (false)
253 , _rt_emit_pending (false)
254 , _ac_thread_active (false)
255 , _latency_recompute_pending (0)
257 , outbound_mtc_timecode_frame (0)
258 , next_quarter_frame_to_send (-1)
259 , _frames_per_timecode_frame (0)
260 , _frames_per_hour (0)
261 , _timecode_frames_per_hour (0)
262 , last_timecode_valid (false)
263 , last_timecode_when (0)
264 , _send_timecode_update (false)
276 , ltc_timecode_offset (0)
277 , ltc_timecode_negative_offset (false)
278 , midi_control_ui (0)
280 , _all_route_group (new RouteGroup (*this, "all"))
281 , routes (new RouteList)
282 , _adding_routes_in_progress (false)
283 , _reconnecting_routes_in_progress (false)
284 , _route_deletion_in_progress (false)
285 , destructive_index (0)
286 , _track_number_decimals(1)
287 , default_fade_steepness (0)
288 , default_fade_msecs (0)
289 , _total_free_4k_blocks (0)
290 , _total_free_4k_blocks_uncertain (false)
291 , no_questions_about_missing_files (false)
294 , _bundles (new BundleList)
295 , _bundle_xml_node (0)
299 , click_emphasis_data (0)
301 , click_emphasis_length (0)
302 , _clicks_cleared (0)
303 , _play_range (false)
304 , _range_selection (-1,-1)
305 , _object_selection (-1,-1)
307 , first_file_data_format_reset (true)
308 , first_file_header_format_reset (true)
309 , have_looped (false)
310 , _have_rec_enabled_track (false)
311 , _have_rec_disabled_track (true)
313 , _suspend_timecode_transmission (0)
314 , _speakers (new Speakers)
315 , ignore_route_processor_changes (false)
320 , _vca_manager (new VCAManager (*this))
324 created_with = string_compose ("%1 %2", PROGRAM_NAME, revision);
326 pthread_mutex_init (&_rt_emit_mutex, 0);
327 pthread_cond_init (&_rt_emit_cond, 0);
329 pthread_mutex_init (&_auto_connect_mutex, 0);
330 pthread_cond_init (&_auto_connect_cond, 0);
332 init_name_id_counter (1); // reset for new sessions, start at 1
333 VCA::set_next_vca_number (1); // reset for new sessions, start at 1
335 pre_engine_init (fullpath);
341 Stateful::loading_state_version = CURRENT_SESSION_FILE_VERSION;
343 #ifdef USE_TRACKS_CODE_FEATURES
344 sr = EngineStateController::instance()->get_current_sample_rate();
346 if (ensure_engine (sr, true)) {
348 throw SessionException (_("Cannot connect to audio/midi engine"));
351 // set samplerate for plugins added early
352 // e.g from templates or MB channelstrip
353 set_block_size (_engine.samples_per_cycle());
354 set_frame_rate (_engine.sample_rate());
356 if (create (mix_template, bus_profile)) {
358 throw SessionException (_("Session initialization failed"));
361 /* if a mix template was provided, then ::create() will
362 * have copied it into the session and we need to load it
363 * so that we have the state ready for ::set_state()
364 * after the engine is started.
366 * Note that we do NOT try to get the sample rate from
367 * the template at this time, though doing so would
368 * be easy if we decided this was an appropriate part
372 if (!mix_template.empty()) {
373 if (load_state (_current_snapshot_name)) {
374 throw SessionException (_("Failed to load template/snapshot state"));
376 store_recent_templates (mix_template);
379 /* load default session properties - if any */
384 if (load_state (_current_snapshot_name)) {
385 throw SessionException (_("Failed to load state"));
388 /* try to get sample rate from XML state so that we
389 * can influence the SR if we set up the audio
394 XMLProperty const * prop;
395 XMLNode const * root (state_tree->root());
396 if ((prop = root->property (X_("sample-rate"))) != 0) {
397 sr = atoi (prop->value());
401 if (ensure_engine (sr, false)) {
403 throw SessionException (_("Cannot connect to audio/midi engine"));
407 if (post_engine_init ()) {
409 throw SessionException (_("Cannot configure audio/midi engine with session parameters"));
412 store_recent_sessions (_name, _path);
414 bool was_dirty = dirty();
416 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
418 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
419 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
422 DirtyChanged (); /* EMIT SIGNAL */
425 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
426 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
428 emit_thread_start ();
429 auto_connect_thread_start ();
431 /* hook us up to the engine since we are now completely constructed */
433 BootMessage (_("Connect to engine"));
435 _engine.set_session (this);
436 _engine.reset_timebase ();
438 #ifdef USE_TRACKS_CODE_FEATURES
440 EngineStateController::instance()->set_session(this);
443 if ( ARDOUR::Profile->get_trx () ) {
445 /* Waves Tracks: fill session with tracks basing on the amount of inputs.
446 * each available input must have corresponding track when session starts.
449 uint32_t how_many (0);
451 std::vector<std::string> inputs;
452 EngineStateController::instance()->get_physical_audio_inputs(inputs);
454 how_many = inputs.size();
456 list<boost::shared_ptr<AudioTrack> > tracks;
458 // Track names after driver
459 if (Config->get_tracks_auto_naming() == NameAfterDriver) {
460 string track_name = "";
461 for (std::vector<string>::size_type i = 0; i < inputs.size(); ++i) {
463 track_name = inputs[i];
464 replace_all (track_name, "system:capture", "");
466 list<boost::shared_ptr<AudioTrack> > single_track = new_audio_track (1, 1, Normal, 0, 1, track_name);
467 tracks.insert(tracks.begin(), single_track.front());
469 } else { // Default track names
470 tracks = new_audio_track (1, 1, Normal, 0, how_many, string());
473 if (tracks.size() != how_many) {
475 throw failed_constructor ();
484 BootMessage (_("Session loading complete"));
496 Session::next_name_id ()
498 return g_atomic_int_add (&_name_id_counter, 1);
502 Session::name_id_counter ()
504 return g_atomic_int_get (&_name_id_counter);
508 Session::init_name_id_counter (guint n)
510 g_atomic_int_set (&_name_id_counter, n);
514 Session::ensure_engine (uint32_t desired_sample_rate, bool isnew)
516 if (_engine.current_backend() == 0) {
517 /* backend is unknown ... */
518 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
519 if (r.get_value_or (-1) != 0) {
522 } else if (!isnew && _engine.running() && _engine.sample_rate () == desired_sample_rate) {
524 } else if (_engine.setup_required()) {
525 /* backend is known, but setup is needed */
526 boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
527 if (r.get_value_or (-1) != 0) {
530 } else if (!_engine.running()) {
531 if (_engine.start()) {
536 /* at this point the engine should be running */
538 if (!_engine.running()) {
542 return immediately_post_engine ();
547 Session::immediately_post_engine ()
549 /* Do various initializations that should take place directly after we
550 * know that the engine is running, but before we either create a
551 * session or set state for an existing one.
554 if (how_many_dsp_threads () > 1) {
555 /* For now, only create the graph if we are using >1 DSP threads, as
556 it is a bit slower than the old code with 1 thread.
558 _process_graph.reset (new Graph (*this));
561 /* every time we reconnect, recompute worst case output latencies */
563 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
565 if (synced_to_engine()) {
566 _engine.transport_stop ();
569 if (config.get_jack_time_master()) {
570 _engine.transport_locate (_transport_frame);
575 BootMessage (_("Set up LTC"));
577 BootMessage (_("Set up Click"));
579 BootMessage (_("Set up standard connections"));
583 catch (failed_constructor& err) {
587 /* TODO, connect in different thread. (PortRegisteredOrUnregistered may be in RT context)
589 _engine.PortRegisteredOrUnregistered.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
597 vector<void*> debug_pointers;
599 /* if we got to here, leaving pending capture state around
603 remove_pending_capture_state ();
607 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
609 /* stop autoconnecting */
610 auto_connect_thread_terminate ();
612 /* disconnect from any and all signals that we are connected to */
614 Port::PortSignalDrop (); /* EMIT SIGNAL */
617 /* shutdown control surface protocols while we still have ports
618 and the engine to move data to any devices.
621 ControlProtocolManager::instance().drop_protocols ();
623 MIDI::Name::MidiPatchManager::instance().remove_search_path(session_directory().midi_patch_path());
625 _engine.remove_session ();
627 #ifdef USE_TRACKS_CODE_FEATURES
628 EngineStateController::instance()->remove_session();
631 /* deregister all ports - there will be no process or any other
632 * callbacks from the engine any more.
635 Port::PortDrop (); /* EMIT SIGNAL */
639 /* clear history so that no references to objects are held any more */
643 /* clear state tree so that no references to objects are held any more */
648 // unregister all lua functions, drop held references (if any)
650 lua.do_command ("Session = nil");
658 lua.collect_garbage ();
660 /* reset dynamic state version back to default */
661 Stateful::loading_state_version = 0;
663 _butler->drop_references ();
667 delete _all_route_group;
669 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
670 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
674 if (click_data != default_click) {
675 delete [] click_data;
678 if (click_emphasis_data != default_click_emphasis) {
679 delete [] click_emphasis_data;
684 /* need to remove auditioner before monitoring section
685 * otherwise it is re-connected */
688 /* drop references to routes held by the monitoring section
689 * specifically _monitor_out aux/listen references */
690 remove_monitor_section();
692 /* clear out any pending dead wood from RCU managed objects */
697 AudioDiskstream::free_working_buffers();
699 /* tell everyone who is still standing that we're about to die */
702 /* tell everyone to drop references and delete objects as we go */
704 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
705 RegionFactory::delete_all_regions ();
707 /* Do this early so that VCAs no longer hold references to routes */
709 DEBUG_TRACE (DEBUG::Destruction, "delete vcas\n");
712 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
714 /* reset these three references to special routes before we do the usual route delete thing */
716 _master_out.reset ();
717 _monitor_out.reset ();
720 RCUWriter<RouteList> writer (routes);
721 boost::shared_ptr<RouteList> r = writer.get_copy ();
723 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
724 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
725 (*i)->drop_references ();
729 /* writer goes out of scope and updates master */
734 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
735 Glib::Threads::Mutex::Lock lm (source_lock);
736 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
737 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
738 i->second->drop_references ();
744 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
747 emit_thread_terminate ();
749 pthread_cond_destroy (&_rt_emit_cond);
750 pthread_mutex_destroy (&_rt_emit_mutex);
752 pthread_cond_destroy (&_auto_connect_cond);
753 pthread_mutex_destroy (&_auto_connect_mutex);
755 delete _scene_changer; _scene_changer = 0;
756 delete midi_control_ui; midi_control_ui = 0;
758 delete _mmc; _mmc = 0;
759 delete _midi_ports; _midi_ports = 0;
760 delete _locations; _locations = 0;
765 /* clear event queue, the session is gone, nobody is interested in
766 * those anymore, but they do leak memory if not removed
768 while (!immediate_events.empty ()) {
769 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
770 SessionEvent *ev = immediate_events.front ();
771 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Drop event: %1\n", enum_2_string (ev->type)));
772 immediate_events.pop_front ();
776 case SessionEvent::AutoLoop:
777 case SessionEvent::AutoLoopDeclick:
778 case SessionEvent::Skip:
779 case SessionEvent::PunchIn:
780 case SessionEvent::PunchOut:
781 case SessionEvent::StopOnce:
782 case SessionEvent::RangeStop:
783 case SessionEvent::RangeLocate:
787 case SessionEvent::RealTimeOperation:
794 del = del && !_remove_event (ev);
801 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
803 BOOST_SHOW_POINTERS ();
807 Session::setup_ltc ()
811 _ltc_input.reset (new IO (*this, X_("LTC In"), IO::Input));
812 _ltc_output.reset (new IO (*this, X_("LTC Out"), IO::Output));
814 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC In"))) != 0) {
815 _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
818 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
819 _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
821 reconnect_ltc_input ();
824 if (state_tree && (child = find_named_node (*state_tree->root(), X_("LTC Out"))) != 0) {
825 _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
828 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
829 _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
831 reconnect_ltc_output ();
834 /* fix up names of LTC ports because we don't want the normal
835 * IO style of NAME/TYPE-{in,out}N
838 _ltc_input->nth (0)->set_name (X_("LTC-in"));
839 _ltc_output->nth (0)->set_name (X_("LTC-out"));
843 Session::setup_click ()
847 boost::shared_ptr<AutomationList> gl (new AutomationList (Evoral::Parameter (GainAutomation)));
848 boost::shared_ptr<GainControl> gain_control = boost::shared_ptr<GainControl> (new GainControl (*this, Evoral::Parameter(GainAutomation), gl));
850 _click_io.reset (new ClickIO (*this, X_("Click")));
851 _click_gain.reset (new Amp (*this, _("Fader"), gain_control, true));
852 _click_gain->activate ();
854 setup_click_state (state_tree->root());
856 setup_click_state (0);
861 Session::setup_click_state (const XMLNode* node)
863 const XMLNode* child = 0;
865 if (node && (child = find_named_node (*node, "Click")) != 0) {
867 /* existing state for Click */
870 if (Stateful::loading_state_version < 3000) {
871 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
873 const XMLNodeList& children (child->children());
874 XMLNodeList::const_iterator i = children.begin();
875 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
877 if (i != children.end()) {
878 c = _click_gain->set_state (**i, Stateful::loading_state_version);
884 _clicking = Config->get_clicking ();
888 error << _("could not setup Click I/O") << endmsg;
895 /* default state for Click: dual-mono to first 2 physical outputs */
898 _engine.get_physical_outputs (DataType::AUDIO, outs);
900 for (uint32_t physport = 0; physport < 2; ++physport) {
901 if (outs.size() > physport) {
902 if (_click_io->add_port (outs[physport], this)) {
903 // relax, even though its an error
908 if (_click_io->n_ports () > ChanCount::ZERO) {
909 _clicking = Config->get_clicking ();
915 Session::get_physical_ports (vector<string>& inputs, vector<string>& outputs, DataType type, bool excluding)
917 _engine.get_physical_inputs (type, inputs);
920 /* rip out ControlOnly ports, and ALSA MIDI Through ports */
922 for (vector<string>::iterator si = inputs.begin(); si != inputs.end(); ) {
923 if (PortManager::port_is_control_only (*si)) {
924 si = inputs.erase (si);
925 } else if ((*si).find (X_("Midi Through")) != string::npos || (*si).find (X_("Midi-Through")) != string::npos) {
926 si = inputs.erase (si);
932 _engine.get_physical_outputs (type, outputs);
935 /* rip out ControlOnly ports, and ALSA MIDI Through ports */
937 for (vector<string>::iterator si = outputs.begin(); si != outputs.end(); ) {
938 if (PortManager::port_is_control_only (*si)) {
939 si = outputs.erase (si);
940 } else if ((*si).find (X_("Midi Through")) != string::npos || (*si).find (X_("Midi-Through")) != string::npos) {
941 si = outputs.erase (si);
950 Session::setup_bundles ()
954 RCUWriter<BundleList> writer (_bundles);
955 boost::shared_ptr<BundleList> b = writer.get_copy ();
956 for (BundleList::iterator i = b->begin(); i != b->end();) {
957 if (boost::dynamic_pointer_cast<UserBundle>(*i)) {
965 vector<string> inputs[DataType::num_types];
966 vector<string> outputs[DataType::num_types];
968 for (uint32_t i = 0; i < DataType::num_types; ++i) {
969 get_physical_ports (inputs[i], outputs[i], DataType (DataType::Symbol (i)), true);
972 /* Create a set of Bundle objects that map
973 to the physical I/O currently available. We create both
974 mono and stereo bundles, so that the common cases of mono
975 and stereo tracks get bundles to put in their mixer strip
976 in / out menus. There may be a nicer way of achieving that;
977 it doesn't really scale that well to higher channel counts
980 /* mono output bundles */
982 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
984 std::string pn = _engine.get_pretty_name_by_name (outputs[DataType::AUDIO][np]);
986 snprintf (buf, sizeof (buf), _("out %s"), pn.c_str());
988 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
991 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
992 c->add_channel (_("mono"), DataType::AUDIO);
993 c->set_port (0, outputs[DataType::AUDIO][np]);
995 add_bundle (c, false);
998 /* stereo output bundles */
1000 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
1001 if (np + 1 < outputs[DataType::AUDIO].size()) {
1003 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
1004 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
1005 c->add_channel (_("L"), DataType::AUDIO);
1006 c->set_port (0, outputs[DataType::AUDIO][np]);
1007 c->add_channel (_("R"), DataType::AUDIO);
1008 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
1010 add_bundle (c, false);
1014 /* mono input bundles */
1016 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
1018 std::string pn = _engine.get_pretty_name_by_name (inputs[DataType::AUDIO][np]);
1020 snprintf (buf, sizeof (buf), _("in %s"), pn.c_str());
1022 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
1025 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
1026 c->add_channel (_("mono"), DataType::AUDIO);
1027 c->set_port (0, inputs[DataType::AUDIO][np]);
1029 add_bundle (c, false);
1032 /* stereo input bundles */
1034 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
1035 if (np + 1 < inputs[DataType::AUDIO].size()) {
1037 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
1039 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
1040 c->add_channel (_("L"), DataType::AUDIO);
1041 c->set_port (0, inputs[DataType::AUDIO][np]);
1042 c->add_channel (_("R"), DataType::AUDIO);
1043 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
1045 add_bundle (c, false);
1049 /* MIDI input bundles */
1051 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
1052 string n = inputs[DataType::MIDI][np];
1053 std::string pn = _engine.get_pretty_name_by_name (n);
1057 boost::erase_first (n, X_("alsa_pcm:"));
1059 boost::shared_ptr<Bundle> c (new Bundle (n, false));
1060 c->add_channel ("", DataType::MIDI);
1061 c->set_port (0, inputs[DataType::MIDI][np]);
1062 add_bundle (c, false);
1065 /* MIDI output bundles */
1067 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
1068 string n = outputs[DataType::MIDI][np];
1069 std::string pn = _engine.get_pretty_name_by_name (n);
1073 boost::erase_first (n, X_("alsa_pcm:"));
1075 boost::shared_ptr<Bundle> c (new Bundle (n, true));
1076 c->add_channel ("", DataType::MIDI);
1077 c->set_port (0, outputs[DataType::MIDI][np]);
1078 add_bundle (c, false);
1081 // we trust the backend to only calls us if there's a change
1082 BundleAddedOrRemoved (); /* EMIT SIGNAL */
1086 Session::auto_connect_master_bus ()
1088 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
1092 // Waves Tracks: Do not connect master bas for Tracks if AutoConnectMaster option is not set
1093 // In this case it means "Multi Out" output mode
1094 if (ARDOUR::Profile->get_trx() && !(Config->get_output_auto_connect() & AutoConnectMaster) ) {
1098 /* if requested auto-connect the outputs to the first N physical ports.
1101 uint32_t limit = _master_out->n_outputs().n_total();
1102 vector<string> outputs[DataType::num_types];
1104 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1105 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1108 for (uint32_t n = 0; n < limit; ++n) {
1109 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
1111 if (outputs[p->type()].size() > n) {
1112 connect_to = outputs[p->type()][n];
1115 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
1116 if (_master_out->output()->connect (p, connect_to, this)) {
1117 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
1126 Session::remove_monitor_section ()
1128 if (!_monitor_out || Profile->get_trx()) {
1132 /* force reversion to Solo-In-Place */
1133 Config->set_solo_control_is_listen_control (false);
1135 /* if we are auditioning, cancel it ... this is a workaround
1136 to a problem (auditioning does not execute the process graph,
1137 which is needed to remove routes when using >1 core for processing)
1142 /* Hold process lock while doing this so that we don't hear bits and
1143 * pieces of audio as we work on each route.
1146 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1148 /* Connect tracks to monitor section. Note that in an
1149 existing session, the internal sends will already exist, but we want the
1150 routes to notice that they connect to the control out specifically.
1154 boost::shared_ptr<RouteList> r = routes.reader ();
1155 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
1157 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
1159 if ((*x)->is_monitor()) {
1161 } else if ((*x)->is_master()) {
1164 (*x)->remove_aux_or_listen (_monitor_out);
1169 remove_route (_monitor_out);
1170 if (_state_of_the_state & Deletion) {
1174 auto_connect_master_bus ();
1177 auditioner->connect ();
1180 Config->ParameterChanged ("use-monitor-bus");
1184 Session::add_monitor_section ()
1188 if (_monitor_out || !_master_out || Profile->get_trx()) {
1192 boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), PresentationInfo::MonitorOut, DataType::AUDIO));
1198 BOOST_MARK_ROUTE(r);
1201 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1202 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
1203 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
1205 error << _("Cannot create monitor section. 'Monitor' Port name is not unique.") << endmsg;
1210 add_routes (rl, false, false, false, 0);
1212 assert (_monitor_out);
1214 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
1215 are undefined, at best.
1218 uint32_t limit = _monitor_out->n_inputs().n_audio();
1222 /* connect the inputs to the master bus outputs. this
1223 * represents a separate data feed from the internal sends from
1224 * each route. as of jan 2011, it allows the monitor section to
1225 * conditionally ignore either the internal sends or the normal
1226 * input feed, but we should really find a better way to do
1230 _master_out->output()->disconnect (this);
1232 for (uint32_t n = 0; n < limit; ++n) {
1233 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1234 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1237 string connect_to = o->name();
1238 if (_monitor_out->input()->connect (p, connect_to, this)) {
1239 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1247 /* if monitor section is not connected, connect it to physical outs
1250 if ((Config->get_auto_connect_standard_busses () || Profile->get_mixbus ()) && !_monitor_out->output()->connected ()) {
1252 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1254 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1257 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1259 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1260 Config->get_monitor_bus_preferred_bundle())
1266 /* Monitor bus is audio only */
1268 vector<string> outputs[DataType::num_types];
1270 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1271 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1274 uint32_t mod = outputs[DataType::AUDIO].size();
1275 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1279 for (uint32_t n = 0; n < limit; ++n) {
1281 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1283 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1284 connect_to = outputs[DataType::AUDIO][n % mod];
1287 if (!connect_to.empty()) {
1288 if (_monitor_out->output()->connect (p, connect_to, this)) {
1289 error << string_compose (
1290 _("cannot connect control output %1 to %2"),
1301 /* Hold process lock while doing this so that we don't hear bits and
1302 * pieces of audio as we work on each route.
1305 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1307 /* Connect tracks to monitor section. Note that in an
1308 existing session, the internal sends will already exist, but we want the
1309 routes to notice that they connect to the control out specifically.
1313 boost::shared_ptr<RouteList> rls = routes.reader ();
1315 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
1317 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1319 if ((*x)->is_monitor()) {
1321 } else if ((*x)->is_master()) {
1324 (*x)->enable_monitor_send ();
1329 auditioner->connect ();
1331 Config->ParameterChanged ("use-monitor-bus");
1335 Session::reset_monitor_section ()
1337 /* Process lock should be held by the caller.*/
1339 if (!_monitor_out || Profile->get_trx()) {
1343 uint32_t limit = _master_out->n_outputs().n_audio();
1345 /* connect the inputs to the master bus outputs. this
1346 * represents a separate data feed from the internal sends from
1347 * each route. as of jan 2011, it allows the monitor section to
1348 * conditionally ignore either the internal sends or the normal
1349 * input feed, but we should really find a better way to do
1353 _master_out->output()->disconnect (this);
1354 _monitor_out->output()->disconnect (this);
1356 // monitor section follow master bus - except midi
1357 ChanCount mon_chn (_master_out->output()->n_ports());
1358 mon_chn.set_midi (0);
1360 _monitor_out->input()->ensure_io (mon_chn, false, this);
1361 _monitor_out->output()->ensure_io (mon_chn, false, this);
1363 for (uint32_t n = 0; n < limit; ++n) {
1364 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1365 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1368 string connect_to = o->name();
1369 if (_monitor_out->input()->connect (p, connect_to, this)) {
1370 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1377 /* connect monitor section to physical outs
1380 if (Config->get_auto_connect_standard_busses()) {
1382 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1384 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1387 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1389 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1390 Config->get_monitor_bus_preferred_bundle())
1396 /* Monitor bus is audio only */
1398 vector<string> outputs[DataType::num_types];
1400 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1401 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1404 uint32_t mod = outputs[DataType::AUDIO].size();
1405 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1409 for (uint32_t n = 0; n < limit; ++n) {
1411 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1413 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1414 connect_to = outputs[DataType::AUDIO][n % mod];
1417 if (!connect_to.empty()) {
1418 if (_monitor_out->output()->connect (p, connect_to, this)) {
1419 error << string_compose (
1420 _("cannot connect control output %1 to %2"),
1431 /* Connect tracks to monitor section. Note that in an
1432 existing session, the internal sends will already exist, but we want the
1433 routes to notice that they connect to the control out specifically.
1437 boost::shared_ptr<RouteList> rls = routes.reader ();
1439 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
1441 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1443 if ((*x)->is_monitor()) {
1445 } else if ((*x)->is_master()) {
1448 (*x)->enable_monitor_send ();
1454 Session::hookup_io ()
1456 /* stop graph reordering notifications from
1457 causing resorts, etc.
1460 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
1464 /* we delay creating the auditioner till now because
1465 it makes its own connections to ports.
1469 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
1471 throw failed_constructor ();
1473 a->use_new_diskstream ();
1477 catch (failed_constructor& err) {
1478 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
1482 /* load bundles, which we may have postponed earlier on */
1483 if (_bundle_xml_node) {
1484 load_bundles (*_bundle_xml_node);
1485 delete _bundle_xml_node;
1488 /* Tell all IO objects to connect themselves together */
1490 IO::enable_connecting ();
1492 /* Now tell all "floating" ports to connect to whatever
1493 they should be connected to.
1496 AudioEngine::instance()->reconnect_ports ();
1498 /* Anyone who cares about input state, wake up and do something */
1500 IOConnectionsComplete (); /* EMIT SIGNAL */
1502 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
1504 /* now handle the whole enchilada as if it was one
1505 graph reorder event.
1510 /* update the full solo state, which can't be
1511 correctly determined on a per-route basis, but
1512 needs the global overview that only the session
1516 update_route_solo_state ();
1520 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
1522 boost::shared_ptr<Track> track = wp.lock ();
1527 boost::shared_ptr<Playlist> playlist;
1529 if ((playlist = track->playlist()) != 0) {
1530 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
1531 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
1532 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
1537 Session::record_enabling_legal () const
1539 /* this used to be in here, but survey says.... we don't need to restrict it */
1540 // if (record_status() == Recording) {
1544 if (Config->get_all_safe()) {
1551 Session::set_track_monitor_input_status (bool yn)
1553 boost::shared_ptr<RouteList> rl = routes.reader ();
1554 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1555 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
1556 if (tr && tr->rec_enable_control()->get_value()) {
1557 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1558 tr->request_input_monitoring (yn);
1564 Session::auto_punch_start_changed (Location* location)
1566 replace_event (SessionEvent::PunchIn, location->start());
1568 if (get_record_enabled() && config.get_punch_in()) {
1569 /* capture start has been changed, so save new pending state */
1570 save_state ("", true);
1575 Session::auto_punch_end_changed (Location* location)
1577 framepos_t when_to_stop = location->end();
1578 // when_to_stop += _worst_output_latency + _worst_input_latency;
1579 replace_event (SessionEvent::PunchOut, when_to_stop);
1583 Session::auto_punch_changed (Location* location)
1585 framepos_t when_to_stop = location->end();
1587 replace_event (SessionEvent::PunchIn, location->start());
1588 //when_to_stop += _worst_output_latency + _worst_input_latency;
1589 replace_event (SessionEvent::PunchOut, when_to_stop);
1592 /** @param loc A loop location.
1593 * @param pos Filled in with the start time of the required fade-out (in session frames).
1594 * @param length Filled in with the length of the required fade-out.
1597 Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
1599 pos = max (loc->start(), loc->end() - 64);
1600 length = loc->end() - pos;
1604 Session::auto_loop_changed (Location* location)
1606 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
1609 auto_loop_declick_range (location, dcp, dcl);
1611 if (transport_rolling() && play_loop) {
1613 replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
1615 // if (_transport_frame > location->end()) {
1617 if (_transport_frame < location->start() || _transport_frame > location->end()) {
1618 // relocate to beginning of loop
1619 clear_events (SessionEvent::LocateRoll);
1621 request_locate (location->start(), true);
1624 else if (Config->get_seamless_loop() && !loop_changing) {
1626 // schedule a locate-roll to refill the diskstreams at the
1627 // previous loop end
1628 loop_changing = true;
1630 if (location->end() > last_loopend) {
1631 clear_events (SessionEvent::LocateRoll);
1632 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
1638 clear_events (SessionEvent::AutoLoopDeclick);
1639 clear_events (SessionEvent::AutoLoop);
1642 /* possibly move playhead if not rolling; if we are rolling we'll move
1643 to the loop start on stop if that is appropriate.
1648 if (!transport_rolling() && select_playhead_priority_target (pos)) {
1649 if (pos == location->start()) {
1650 request_locate (pos);
1655 last_loopend = location->end();
1660 Session::set_auto_punch_location (Location* location)
1664 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1665 punch_connections.drop_connections();
1666 existing->set_auto_punch (false, this);
1667 remove_event (existing->start(), SessionEvent::PunchIn);
1668 clear_events (SessionEvent::PunchOut);
1669 auto_punch_location_changed (0);
1674 if (location == 0) {
1678 if (location->end() <= location->start()) {
1679 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1683 punch_connections.drop_connections ();
1685 location->StartChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, location));
1686 location->EndChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, location));
1687 location->Changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, location));
1689 location->set_auto_punch (true, this);
1691 auto_punch_changed (location);
1693 auto_punch_location_changed (location);
1697 Session::set_session_extents (framepos_t start, framepos_t end)
1700 if ((existing = _locations->session_range_location()) == 0) {
1701 //if there is no existing session, we need to make a new session location (should never happen)
1702 existing = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1706 error << _("Session: you can't use that location for session start/end)") << endmsg;
1710 existing->set( start, end );
1716 Session::set_auto_loop_location (Location* location)
1720 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1721 loop_connections.drop_connections ();
1722 existing->set_auto_loop (false, this);
1723 remove_event (existing->end(), SessionEvent::AutoLoop);
1726 auto_loop_declick_range (existing, dcp, dcl);
1727 remove_event (dcp, SessionEvent::AutoLoopDeclick);
1728 auto_loop_location_changed (0);
1733 if (location == 0) {
1737 if (location->end() <= location->start()) {
1738 error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
1742 last_loopend = location->end();
1744 loop_connections.drop_connections ();
1746 location->StartChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1747 location->EndChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1748 location->Changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1749 location->FlagsChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1751 location->set_auto_loop (true, this);
1753 if (Config->get_loop_is_mode() && play_loop && Config->get_seamless_loop()) {
1754 // set all tracks to use internal looping
1755 boost::shared_ptr<RouteList> rl = routes.reader ();
1756 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1757 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1758 if (tr && !tr->hidden()) {
1759 tr->set_loop (location);
1764 /* take care of our stuff first */
1766 auto_loop_changed (location);
1768 /* now tell everyone else */
1770 auto_loop_location_changed (location);
1774 Session::update_marks (Location*)
1780 Session::update_skips (Location* loc, bool consolidate)
1782 if (_ignore_skips_updates) {
1786 Locations::LocationList skips;
1789 PBD::Unwinder<bool> uw (_ignore_skips_updates, true);
1790 consolidate_skips (loc);
1793 sync_locations_to_skips ();
1799 Session::consolidate_skips (Location* loc)
1801 Locations::LocationList all_locations = _locations->list ();
1803 for (Locations::LocationList::iterator l = all_locations.begin(); l != all_locations.end(); ) {
1805 if (!(*l)->is_skip ()) {
1810 /* don't test against self */
1817 switch (Evoral::coverage ((*l)->start(), (*l)->end(), loc->start(), loc->end())) {
1818 case Evoral::OverlapInternal:
1819 case Evoral::OverlapExternal:
1820 case Evoral::OverlapStart:
1821 case Evoral::OverlapEnd:
1822 /* adjust new location to cover existing one */
1823 loc->set_start (min (loc->start(), (*l)->start()));
1824 loc->set_end (max (loc->end(), (*l)->end()));
1825 /* we don't need this one any more */
1826 _locations->remove (*l);
1827 /* the location has been deleted, so remove reference to it in our local list */
1828 l = all_locations.erase (l);
1831 case Evoral::OverlapNone:
1839 Session::sync_locations_to_skips ()
1841 /* This happens asynchronously (in the audioengine thread). After the clear is done, we will call
1842 * Session::_sync_locations_to_skips() from the audioengine thread.
1844 clear_events (SessionEvent::Skip, boost::bind (&Session::_sync_locations_to_skips, this));
1848 Session::_sync_locations_to_skips ()
1850 /* called as a callback after existing Skip events have been cleared from a realtime audioengine thread */
1852 Locations::LocationList const & locs (_locations->list());
1854 for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) {
1856 Location* location = *i;
1858 if (location->is_skip() && location->is_skipping()) {
1859 SessionEvent* ev = new SessionEvent (SessionEvent::Skip, SessionEvent::Add, location->start(), location->end(), 1.0);
1867 Session::location_added (Location *location)
1869 if (location->is_auto_punch()) {
1870 set_auto_punch_location (location);
1873 if (location->is_auto_loop()) {
1874 set_auto_loop_location (location);
1877 if (location->is_session_range()) {
1878 /* no need for any signal handling or event setting with the session range,
1879 because we keep a direct reference to it and use its start/end directly.
1881 _session_range_location = location;
1884 if (location->is_mark()) {
1885 /* listen for per-location signals that require us to do any * global updates for marks */
1887 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1888 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1889 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1890 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1893 if (location->is_skip()) {
1894 /* listen for per-location signals that require us to update skip-locate events */
1896 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1897 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1898 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1899 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, false));
1901 update_skips (location, true);
1908 Session::location_removed (Location *location)
1910 if (location->is_auto_loop()) {
1911 set_auto_loop_location (0);
1912 set_track_loop (false);
1915 if (location->is_auto_punch()) {
1916 set_auto_punch_location (0);
1919 if (location->is_session_range()) {
1920 /* this is never supposed to happen */
1921 error << _("programming error: session range removed!") << endl;
1924 if (location->is_skip()) {
1926 update_skips (location, false);
1933 Session::locations_changed ()
1935 _locations->apply (*this, &Session::_locations_changed);
1939 Session::_locations_changed (const Locations::LocationList& locations)
1941 /* There was some mass-change in the Locations object.
1943 We might be re-adding a location here but it doesn't actually matter
1944 for all the locations that the Session takes an interest in.
1948 PBD::Unwinder<bool> protect_ignore_skip_updates (_ignore_skips_updates, true);
1949 for (Locations::LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
1950 location_added (*i);
1954 update_skips (NULL, false);
1958 Session::enable_record ()
1960 if (_transport_speed != 0.0 && _transport_speed != 1.0) {
1961 /* no recording at anything except normal speed */
1966 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1968 if (rs == Recording) {
1972 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1974 _last_record_location = _transport_frame;
1975 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1977 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1978 set_track_monitor_input_status (true);
1981 RecordStateChanged ();
1988 Session::set_all_tracks_record_enabled (bool enable )
1990 boost::shared_ptr<RouteList> rl = routes.reader();
1991 set_controls (route_list_to_control_list (rl, &Stripable::rec_enable_control), enable, Controllable::NoGroup);
1995 Session::disable_record (bool rt_context, bool force)
1999 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
2001 if (!Config->get_latched_record_enable () || force) {
2002 g_atomic_int_set (&_record_status, Disabled);
2003 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
2005 if (rs == Recording) {
2006 g_atomic_int_set (&_record_status, Enabled);
2010 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
2011 set_track_monitor_input_status (false);
2014 RecordStateChanged (); /* emit signal */
2017 remove_pending_capture_state ();
2023 Session::step_back_from_record ()
2025 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
2027 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
2028 set_track_monitor_input_status (false);
2031 RecordStateChanged (); /* emit signal */
2036 Session::maybe_enable_record ()
2038 if (_step_editors > 0) {
2042 g_atomic_int_set (&_record_status, Enabled);
2044 /* This function is currently called from somewhere other than an RT thread.
2045 This save_state() call therefore doesn't impact anything. Doing it here
2046 means that we save pending state of which sources the next record will use,
2047 which gives us some chance of recovering from a crash during the record.
2050 save_state ("", true);
2052 if (_transport_speed) {
2053 if (!config.get_punch_in()) {
2057 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
2058 RecordStateChanged (); /* EMIT SIGNAL */
2065 Session::audible_frame () const
2069 frameoffset_t offset = worst_playback_latency (); // - _engine.samples_since_cycle_start ();
2070 offset *= transport_speed ();
2072 if (synced_to_engine()) {
2073 /* Note: this is basically just sync-to-JACK */
2074 ret = _engine.transport_frame();
2076 ret = _transport_frame;
2079 if (transport_rolling()) {
2082 /* Check to see if we have passed the first guaranteed
2083 * audible frame past our last start position. if not,
2084 * return that last start point because in terms
2085 * of audible frames, we have not moved yet.
2087 * `Start position' in this context means the time we last
2088 * either started, located, or changed transport direction.
2091 if (_transport_speed > 0.0f) {
2093 if (!play_loop || !have_looped) {
2094 if (ret < _last_roll_or_reversal_location) {
2095 return _last_roll_or_reversal_location;
2099 Location *location = _locations->auto_loop_location();
2100 frameoffset_t lo = location->start() - ret;
2102 ret = location->end () - lo;
2106 } else if (_transport_speed < 0.0f) {
2108 /* XXX wot? no backward looping? */
2110 if (ret > _last_roll_or_reversal_location) {
2111 return _last_roll_or_reversal_location;
2116 return std::max ((framepos_t)0, ret);
2120 Session::set_frame_rate (framecnt_t frames_per_second)
2122 /** \fn void Session::set_frame_size(framecnt_t)
2123 the AudioEngine object that calls this guarantees
2124 that it will not be called while we are also in
2125 ::process(). Its fine to do things that block
2129 if (_base_frame_rate == 0) {
2130 _base_frame_rate = frames_per_second;
2132 else if (_base_frame_rate != frames_per_second && frames_per_second != _nominal_frame_rate) {
2133 NotifyAboutSampleRateMismatch (_base_frame_rate, frames_per_second);
2135 _nominal_frame_rate = frames_per_second;
2140 reset_write_sources (false);
2142 // XXX we need some equivalent to this, somehow
2143 // SndFileSource::setup_standard_crossfades (frames_per_second);
2147 /* XXX need to reset/reinstantiate all LADSPA plugins */
2151 Session::set_block_size (pframes_t nframes)
2153 /* the AudioEngine guarantees
2154 that it will not be called while we are also in
2155 ::process(). It is therefore fine to do things that block
2160 current_block_size = nframes;
2164 boost::shared_ptr<RouteList> r = routes.reader ();
2166 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2167 (*i)->set_block_size (nframes);
2170 boost::shared_ptr<RouteList> rl = routes.reader ();
2171 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2172 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2174 tr->set_block_size (nframes);
2178 set_worst_io_latencies ();
2184 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
2186 boost::shared_ptr<Route> r2;
2188 if (r1->feeds (rbase) && rbase->feeds (r1)) {
2189 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
2193 /* make a copy of the existing list of routes that feed r1 */
2195 Route::FedBy existing (r1->fed_by());
2197 /* for each route that feeds r1, recurse, marking it as feeding
2201 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
2202 if (!(r2 = i->r.lock ())) {
2203 /* (*i) went away, ignore it */
2207 /* r2 is a route that feeds r1 which somehow feeds base. mark
2208 base as being fed by r2
2211 rbase->add_fed_by (r2, i->sends_only);
2215 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
2219 if (r1->feeds (r2) && r2->feeds (r1)) {
2223 /* now recurse, so that we can mark base as being fed by
2224 all routes that feed r2
2227 trace_terminal (r2, rbase);
2234 Session::resort_routes ()
2236 /* don't do anything here with signals emitted
2237 by Routes during initial setup or while we
2238 are being destroyed.
2241 if (_state_of_the_state & (InitialConnecting | Deletion)) {
2245 if (_route_deletion_in_progress) {
2250 RCUWriter<RouteList> writer (routes);
2251 boost::shared_ptr<RouteList> r = writer.get_copy ();
2252 resort_routes_using (r);
2253 /* writer goes out of scope and forces update */
2257 if (DEBUG_ENABLED(DEBUG::Graph)) {
2258 boost::shared_ptr<RouteList> rl = routes.reader ();
2259 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2260 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
2262 const Route::FedBy& fb ((*i)->fed_by());
2264 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
2265 boost::shared_ptr<Route> sf = f->r.lock();
2267 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
2276 /** This is called whenever we need to rebuild the graph of how we will process
2278 * @param r List of routes, in any order.
2282 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
2284 /* We are going to build a directed graph of our routes;
2285 this is where the edges of that graph are put.
2290 /* Go through all routes doing two things:
2292 * 1. Collect the edges of the route graph. Each of these edges
2293 * is a pair of routes, one of which directly feeds the other
2294 * either by a JACK connection or by an internal send.
2296 * 2. Begin the process of making routes aware of which other
2297 * routes directly or indirectly feed them. This information
2298 * is used by the solo code.
2301 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2303 /* Clear out the route's list of direct or indirect feeds */
2304 (*i)->clear_fed_by ();
2306 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
2308 bool via_sends_only;
2310 /* See if this *j feeds *i according to the current state of the JACK
2311 connections and internal sends.
2313 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
2314 /* add the edge to the graph (part #1) */
2315 edges.add (*j, *i, via_sends_only);
2316 /* tell the route (for part #2) */
2317 (*i)->add_fed_by (*j, via_sends_only);
2322 /* Attempt a topological sort of the route graph */
2323 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
2325 if (sorted_routes) {
2326 /* We got a satisfactory topological sort, so there is no feedback;
2329 Note: the process graph rechain does not require a
2330 topologically-sorted list, but hey ho.
2332 if (_process_graph) {
2333 _process_graph->rechain (sorted_routes, edges);
2336 _current_route_graph = edges;
2338 /* Complete the building of the routes' lists of what directly
2339 or indirectly feeds them.
2341 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2342 trace_terminal (*i, *i);
2345 *r = *sorted_routes;
2348 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
2349 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2350 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 presentation order %2\n", (*i)->name(), (*i)->presentation_info().order()));
2354 SuccessfulGraphSort (); /* EMIT SIGNAL */
2357 /* The topological sort failed, so we have a problem. Tell everyone
2358 and stick to the old graph; this will continue to be processed, so
2359 until the feedback is fixed, what is played back will not quite
2360 reflect what is actually connected. Note also that we do not
2361 do trace_terminal here, as it would fail due to an endless recursion,
2362 so the solo code will think that everything is still connected
2366 FeedbackDetected (); /* EMIT SIGNAL */
2371 /** Find a route name starting with \a base, maybe followed by the
2372 * lowest \a id. \a id will always be added if \a definitely_add_number
2373 * is true on entry; otherwise it will only be added if required
2374 * to make the name unique.
2376 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
2377 * The available route name with the lowest ID will be used, and \a id
2378 * will be set to the ID.
2380 * \return false if a route name could not be found, and \a track_name
2381 * and \a id do not reflect a free route name.
2384 Session::find_route_name (string const & base, uint32_t& id, string& name, bool definitely_add_number)
2386 /* the base may conflict with ports that do not belong to existing
2387 routes, but hidden objects like the click track. So check port names
2388 before anything else.
2391 for (vector<string>::const_iterator reserved = reserved_io_names.begin(); reserved != reserved_io_names.end(); ++reserved) {
2392 if (base == *reserved) {
2393 /* Check if this reserved name already exists, and if
2394 so, disallow it without a numeric suffix.
2396 if (route_by_name (*reserved)) {
2397 definitely_add_number = true;
2406 if (!definitely_add_number && route_by_name (base) == 0) {
2407 /* juse use the base */
2413 name = string_compose ("%1 %2", base, id);
2415 if (route_by_name (name) == 0) {
2421 } while (id < (UINT_MAX-1));
2426 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
2428 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
2430 in = ChanCount::ZERO;
2431 out = ChanCount::ZERO;
2433 boost::shared_ptr<RouteList> r = routes.reader ();
2435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2436 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2437 if (tr && !tr->is_auditioner()) {
2438 in += tr->n_inputs();
2439 out += tr->n_outputs();
2445 Session::default_track_name_pattern (DataType t)
2448 case DataType::AUDIO:
2449 if (Profile->get_trx()) {
2456 case DataType::MIDI:
2463 /** Caller must not hold process lock
2464 * @param name_template string to use for the start of the name, or "" to use "MIDI".
2465 * @param instrument plugin info for the instrument to insert pre-fader, if any
2467 list<boost::shared_ptr<MidiTrack> >
2468 Session::new_midi_track (const ChanCount& input, const ChanCount& output,
2469 boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
2470 RouteGroup* route_group, uint32_t how_many, string name_template, PresentationInfo::order_t order,
2474 uint32_t track_id = 0;
2476 RouteList new_routes;
2477 list<boost::shared_ptr<MidiTrack> > ret;
2479 const string name_pattern = default_track_name_pattern (DataType::MIDI);
2480 bool const use_number = (how_many != 1) || name_template.empty () || (name_template == name_pattern);
2483 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, use_number)) {
2484 error << "cannot find name for new midi track" << endmsg;
2488 boost::shared_ptr<MidiTrack> track;
2491 track.reset (new MidiTrack (*this, track_name, mode));
2493 if (track->init ()) {
2497 if (Profile->get_mixbus ()) {
2498 track->set_strict_io (true);
2501 track->use_new_diskstream();
2503 BOOST_MARK_TRACK (track);
2506 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2507 if (track->input()->ensure_io (input, false, this)) {
2508 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
2512 if (track->output()->ensure_io (output, false, this)) {
2513 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
2518 track->non_realtime_input_change();
2521 route_group->add (track);
2524 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
2526 new_routes.push_back (track);
2527 ret.push_back (track);
2530 catch (failed_constructor &err) {
2531 error << _("Session: could not create new midi track.") << endmsg;
2535 catch (AudioEngine::PortRegistrationFailure& pfe) {
2537 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;
2545 if (!new_routes.empty()) {
2546 StateProtector sp (this);
2547 if (Profile->get_trx()) {
2548 add_routes (new_routes, false, false, false, order);
2550 add_routes (new_routes, true, true, false, order);
2554 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
2555 PluginPtr plugin = instrument->load (*this);
2557 plugin->load_preset (*pset);
2559 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
2560 (*r)->add_processor (p, PreFader);
2570 Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
2571 PresentationInfo::Flag flag, PresentationInfo::order_t order)
2574 uint32_t bus_id = 0;
2578 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Midi Bus");
2581 if (!find_route_name (name_template.empty () ? _("Midi Bus") : name_template, ++bus_id, bus_name, use_number)) {
2582 error << "cannot find name for new midi bus" << endmsg;
2587 boost::shared_ptr<Route> bus (new Route (*this, bus_name, flag, DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
2593 if (Profile->get_mixbus ()) {
2594 bus->set_strict_io (true);
2597 BOOST_MARK_ROUTE(bus);
2600 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2602 if (bus->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
2603 error << _("cannot configure new midi bus input") << endmsg;
2608 if (bus->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
2609 error << _("cannot configure new midi bus output") << endmsg;
2615 route_group->add (bus);
2618 bus->add_internal_return ();
2619 ret.push_back (bus);
2622 catch (failed_constructor &err) {
2623 error << _("Session: could not create new audio route.") << endmsg;
2627 catch (AudioEngine::PortRegistrationFailure& pfe) {
2628 error << pfe.what() << endmsg;
2638 StateProtector sp (this);
2639 add_routes (ret, false, false, false, order);
2642 for (RouteList::iterator r = ret.begin(); r != ret.end(); ++r) {
2643 PluginPtr plugin = instrument->load (*this);
2645 plugin->load_preset (*pset);
2647 boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
2648 (*r)->add_processor (p, PreFader);
2659 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
2661 boost::shared_ptr<Route> midi_track (wmt.lock());
2667 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
2669 if (change.after.n_audio() <= change.before.n_audio()) {
2673 /* new audio ports: make sure the audio goes somewhere useful,
2674 * unless the user has no-auto-connect selected.
2676 * The existing ChanCounts don't matter for this call as they are only
2677 * to do with matching input and output indices, and we are only changing
2680 auto_connect_route (midi_track, false, ChanCount(), change.before);
2684 #ifdef USE_TRACKS_CODE_FEATURES
2687 compare_routes_by_remote_id (const boost::shared_ptr<Route>& route1, const boost::shared_ptr<Route>& route2)
2689 return route1->remote_control_id() < route2->remote_control_id();
2693 Session::reconnect_existing_routes (bool withLock, bool reconnect_master, bool reconnect_inputs, bool reconnect_outputs)
2695 // it is not allowed to perform connection
2696 if (!IO::connecting_legal) {
2700 // if we are deleting routes we will call this once at the end
2701 if (_route_deletion_in_progress) {
2705 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
2711 // We need to disconnect the route's inputs and outputs first
2712 // basing on autoconnect configuration
2713 bool reconnectIputs = !(Config->get_input_auto_connect() & ManualConnect) && reconnect_inputs;
2714 bool reconnectOutputs = !(Config->get_output_auto_connect() & ManualConnect) && reconnect_outputs;
2716 ChanCount existing_inputs;
2717 ChanCount existing_outputs;
2718 count_existing_track_channels (existing_inputs, existing_outputs);
2720 //ChanCount inputs = ChanCount::ZERO;
2721 //ChanCount outputs = ChanCount::ZERO;
2723 RouteList existing_routes = *routes.reader ();
2724 existing_routes.sort (compare_routes_by_remote_id);
2727 PBD::Unwinder<bool> protect_ignore_changes (_reconnecting_routes_in_progress, true);
2729 vector<string> physinputs;
2730 vector<string> physoutputs;
2732 EngineStateController::instance()->get_physical_audio_outputs(physoutputs);
2733 EngineStateController::instance()->get_physical_audio_inputs(physinputs);
2735 uint32_t input_n = 0;
2736 uint32_t output_n = 0;
2737 RouteList::iterator rIter = existing_routes.begin();
2738 const AutoConnectOption current_input_auto_connection (Config->get_input_auto_connect());
2739 const AutoConnectOption current_output_auto_connection (Config->get_output_auto_connect());
2740 for (; rIter != existing_routes.end(); ++rIter) {
2741 if (*rIter == _master_out || *rIter == _monitor_out ) {
2745 if (current_output_auto_connection == AutoConnectPhysical) {
2746 (*rIter)->amp()->deactivate();
2747 } else if (current_output_auto_connection == AutoConnectMaster) {
2748 (*rIter)->amp()->activate();
2751 if (reconnectIputs) {
2752 (*rIter)->input()->disconnect (this); //GZ: check this; could be heavy
2754 for (uint32_t route_input_n = 0; route_input_n < (*rIter)->n_inputs().get(DataType::AUDIO); ++route_input_n) {
2756 if (current_input_auto_connection & AutoConnectPhysical) {
2758 if ( input_n == physinputs.size() ) {
2762 string port = physinputs[input_n];
2764 if (port.empty() ) {
2765 error << "Physical Input number "<< input_n << " is unavailable and cannot be connected" << endmsg;
2768 //GZ: check this; could be heavy
2769 (*rIter)->input()->connect ((*rIter)->input()->ports().port(DataType::AUDIO, route_input_n), port, this);
2775 if (reconnectOutputs) {
2777 //normalize route ouptuts: reduce the amount outputs to be equal to the amount of inputs
2778 if (current_output_auto_connection & AutoConnectPhysical) {
2780 //GZ: check this; could be heavy
2781 (*rIter)->output()->disconnect (this);
2782 size_t route_inputs_count = (*rIter)->n_inputs().get(DataType::AUDIO);
2784 //GZ: check this; could be heavy
2785 (*rIter)->output()->ensure_io(ChanCount(DataType::AUDIO, route_inputs_count), false, this );
2787 } else if (current_output_auto_connection & AutoConnectMaster){
2789 if (!reconnect_master) {
2793 //GZ: check this; could be heavy
2794 (*rIter)->output()->disconnect (this);
2797 uint32_t master_inputs_count = _master_out->n_inputs().get(DataType::AUDIO);
2798 (*rIter)->output()->ensure_io(ChanCount(DataType::AUDIO, master_inputs_count), false, this );
2800 error << error << "Master bus is not available" << endmsg;
2805 for (uint32_t route_output_n = 0; route_output_n < (*rIter)->n_outputs().get(DataType::AUDIO); ++route_output_n) {
2806 if (current_output_auto_connection & AutoConnectPhysical) {
2808 if ( output_n == physoutputs.size() ) {
2812 string port = physoutputs[output_n];
2814 if (port.empty() ) {
2815 error << "Physical Output number "<< output_n << " is unavailable and cannot be connected" << endmsg;
2818 //GZ: check this; could be heavy
2819 (*rIter)->output()->connect ((*rIter)->output()->ports().port(DataType::AUDIO, route_output_n), port, this);
2822 } else if (current_output_auto_connection & AutoConnectMaster) {
2824 if ( route_output_n == _master_out->n_inputs().get(DataType::AUDIO) ) {
2828 // connect to master bus
2829 string port = _master_out->input()->ports().port(DataType::AUDIO, route_output_n)->name();
2831 if (port.empty() ) {
2832 error << "MasterBus Input number "<< route_output_n << " is unavailable and cannot be connected" << endmsg;
2836 //GZ: check this; could be heavy
2837 (*rIter)->output()->connect ((*rIter)->output()->ports().port(DataType::AUDIO, route_output_n), port, this);
2844 _master_out->output()->disconnect (this);
2845 auto_connect_master_bus ();
2850 session_routes_reconnected (); /* EMIT SIGNAL */
2854 Session::reconnect_midi_scene_ports(bool inputs)
2858 boost::shared_ptr<MidiPort> scene_in_ptr = scene_in();
2860 scene_in_ptr->disconnect_all ();
2862 std::vector<EngineStateController::MidiPortState> midi_port_states;
2863 EngineStateController::instance()->get_physical_midi_input_states (midi_port_states);
2865 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2867 for (; state_iter != midi_port_states.end(); ++state_iter) {
2868 if (state_iter->active && state_iter->available && state_iter->scene_connected) {
2869 scene_in_ptr->connect (state_iter->name);
2876 boost::shared_ptr<MidiPort> scene_out_ptr = scene_out();
2878 if (scene_out_ptr ) {
2879 scene_out_ptr->disconnect_all ();
2881 std::vector<EngineStateController::MidiPortState> midi_port_states;
2882 EngineStateController::instance()->get_physical_midi_output_states (midi_port_states);
2884 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2886 for (; state_iter != midi_port_states.end(); ++state_iter) {
2887 if (state_iter->active && state_iter->available && state_iter->scene_connected) {
2888 scene_out_ptr->connect (state_iter->name);
2896 Session::reconnect_mtc_ports ()
2898 boost::shared_ptr<MidiPort> mtc_in_ptr = _midi_ports->mtc_input_port();
2904 mtc_in_ptr->disconnect_all ();
2906 std::vector<EngineStateController::MidiPortState> midi_port_states;
2907 EngineStateController::instance()->get_physical_midi_input_states (midi_port_states);
2909 std::vector<EngineStateController::MidiPortState>::iterator state_iter = midi_port_states.begin();
2911 for (; state_iter != midi_port_states.end(); ++state_iter) {
2912 if (state_iter->available && state_iter->mtc_in) {
2913 mtc_in_ptr->connect (state_iter->name);
2917 if (!_midi_ports->mtc_input_port ()->connected () &&
2918 config.get_external_sync () &&
2919 (Config->get_sync_source () == MTC) ) {
2920 config.set_external_sync (false);
2923 if ( ARDOUR::Profile->get_trx () ) {
2924 // Tracks need this signal to update timecode_source_dropdown
2925 MtcOrLtcInputPortChanged (); //emit signal
2930 Session::reconnect_mmc_ports(bool inputs)
2932 if (inputs ) { // get all enabled midi input ports
2934 boost::shared_ptr<MidiPort> mmc_in_ptr = _midi_ports->mmc_in();
2936 mmc_in_ptr->disconnect_all ();
2937 std::vector<std::string> enabled_midi_inputs;
2938 EngineStateController::instance()->get_physical_midi_inputs (enabled_midi_inputs);
2940 std::vector<std::string>::iterator port_iter = enabled_midi_inputs.begin();
2942 for (; port_iter != enabled_midi_inputs.end(); ++port_iter) {
2943 mmc_in_ptr->connect (*port_iter);
2947 } else { // get all enabled midi output ports
2949 boost::shared_ptr<MidiPort> mmc_out_ptr = _midi_ports->mmc_out();
2951 mmc_out_ptr->disconnect_all ();
2952 std::vector<std::string> enabled_midi_outputs;
2953 EngineStateController::instance()->get_physical_midi_outputs (enabled_midi_outputs);
2955 std::vector<std::string>::iterator port_iter = enabled_midi_outputs.begin();
2957 for (; port_iter != enabled_midi_outputs.end(); ++port_iter) {
2958 mmc_out_ptr->connect (*port_iter);
2967 Session::ensure_route_presentation_info_gap (PresentationInfo::order_t first_new_order, uint32_t how_many)
2969 if (first_new_order == PresentationInfo::max_order) {
2970 /* adding at end, no worries */
2974 /* create a gap in the presentation info to accomodate @param how_many
2978 get_stripables (sl);
2980 for (StripableList::iterator si = sl.begin(); si != sl.end(); ++si) {
2981 boost::shared_ptr<Stripable> s (*si);
2983 if (s->is_monitor() || s->is_auditioner()) {
2987 if (s->presentation_info().order () >= first_new_order) {
2988 s->set_presentation_order (s->presentation_info().order () + how_many);
2993 /** Caller must not hold process lock
2994 * @param name_template string to use for the start of the name, or "" to use "Audio".
2996 list< boost::shared_ptr<AudioTrack> >
2997 Session::new_audio_track (int input_channels, int output_channels, RouteGroup* route_group,
2998 uint32_t how_many, string name_template, PresentationInfo::order_t order,
3002 uint32_t track_id = 0;
3004 RouteList new_routes;
3005 list<boost::shared_ptr<AudioTrack> > ret;
3007 const string name_pattern = default_track_name_pattern (DataType::AUDIO);
3008 bool const use_number = (how_many != 1) || name_template.empty () || (name_template == name_pattern);
3012 if (!find_route_name (name_template.empty() ? _(name_pattern.c_str()) : name_template, ++track_id, track_name, use_number)) {
3013 error << "cannot find name for new audio track" << endmsg;
3017 boost::shared_ptr<AudioTrack> track;
3020 track.reset (new AudioTrack (*this, track_name, mode));
3022 if (track->init ()) {
3026 if (Profile->get_mixbus ()) {
3027 track->set_strict_io (true);
3030 if (ARDOUR::Profile->get_trx ()) {
3031 // TRACKS considers it's not a USE CASE, it's
3032 // a piece of behavior of the session model:
3034 // Gain for a newly created route depends on
3035 // the current output_auto_connect mode:
3037 // 0 for Stereo Out mode
3039 if (Config->get_output_auto_connect() & AutoConnectMaster) {
3040 track->gain_control()->set_value (dB_to_coefficient (0), Controllable::NoGroup);
3044 track->use_new_diskstream();
3046 BOOST_MARK_TRACK (track);
3049 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3051 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
3052 error << string_compose (
3053 _("cannot configure %1 in/%2 out configuration for new audio track"),
3054 input_channels, output_channels)
3059 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
3060 error << string_compose (
3061 _("cannot configure %1 in/%2 out configuration for new audio track"),
3062 input_channels, output_channels)
3069 route_group->add (track);
3072 track->non_realtime_input_change();
3074 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
3076 new_routes.push_back (track);
3077 ret.push_back (track);
3080 catch (failed_constructor &err) {
3081 error << _("Session: could not create new audio track.") << endmsg;
3085 catch (AudioEngine::PortRegistrationFailure& pfe) {
3087 error << pfe.what() << endmsg;
3095 if (!new_routes.empty()) {
3096 StateProtector sp (this);
3097 if (Profile->get_trx()) {
3098 add_routes (new_routes, false, false, false, order);
3100 add_routes (new_routes, true, true, false, order);
3107 /** Caller must not hold process lock.
3108 * @param name_template string to use for the start of the name, or "" to use "Bus".
3111 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template,
3112 PresentationInfo::Flag flags, PresentationInfo::order_t order)
3115 uint32_t bus_id = 0;
3119 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
3122 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, use_number)) {
3123 error << "cannot find name for new audio bus" << endmsg;
3128 boost::shared_ptr<Route> bus (new Route (*this, bus_name, flags, DataType::AUDIO));
3134 if (Profile->get_mixbus ()) {
3135 bus->set_strict_io (true);
3138 BOOST_MARK_ROUTE(bus);
3141 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3143 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
3144 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
3145 input_channels, output_channels)
3151 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
3152 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
3153 input_channels, output_channels)
3160 route_group->add (bus);
3163 bus->add_internal_return ();
3164 ret.push_back (bus);
3167 catch (failed_constructor &err) {
3168 error << _("Session: could not create new audio route.") << endmsg;
3172 catch (AudioEngine::PortRegistrationFailure& pfe) {
3173 error << pfe.what() << endmsg;
3183 StateProtector sp (this);
3184 if (Profile->get_trx()) {
3185 add_routes (ret, false, false, false, order);
3187 add_routes (ret, false, true, true, order); // autoconnect // outputs only
3196 Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t insert_at, const std::string& template_path, const std::string& name_base,
3197 PlaylistDisposition pd)
3201 if (!tree.read (template_path.c_str())) {
3205 return new_route_from_template (how_many, insert_at, *tree.root(), name_base, pd);
3209 Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t insert_at, XMLNode& node, const std::string& name_base, PlaylistDisposition pd)
3212 uint32_t number = 0;
3213 const uint32_t being_added = how_many;
3214 /* This will prevent the use of any existing XML-provided PBD::ID
3217 Stateful::ForceIDRegeneration force_ids;
3218 IO::disable_connecting ();
3222 /* We're going to modify the node contents a bit so take a
3223 * copy. The node may be re-used when duplicating more than once.
3226 XMLNode node_copy (node);
3231 if (!name_base.empty()) {
3233 /* if we're adding more than one routes, force
3234 * all the names of the new routes to be
3235 * numbered, via the final parameter.
3238 if (!find_route_name (name_base.c_str(), ++number, name, (being_added > 1))) {
3239 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
3245 string const route_name = node_copy.property(X_("name"))->value ();
3247 /* generate a new name by adding a number to the end of the template name */
3248 if (!find_route_name (route_name.c_str(), ++number, name, true)) {
3249 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
3250 abort(); /*NOTREACHED*/
3254 /* set this name in the XML description that we are about to use */
3256 bool rename_playlist;
3259 rename_playlist = true;
3264 rename_playlist = false;
3267 Route::set_name_in_state (node_copy, name, rename_playlist);
3269 /* trim bitslots from listen sends so that new ones are used */
3270 XMLNodeList children = node_copy.children ();
3271 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
3272 if ((*i)->name() == X_("Processor")) {
3273 /* ForceIDRegeneration does not catch the following */
3274 XMLProperty const * role = (*i)->property (X_("role"));
3275 XMLProperty const * type = (*i)->property (X_("type"));
3276 if (role && role->value() == X_("Aux")) {
3277 /* check if the target bus exists.
3278 * we should not save aux-sends in templates.
3280 XMLProperty const * target = (*i)->property (X_("target"));
3282 (*i)->add_property ("type", "dangling-aux-send");
3285 boost::shared_ptr<Route> r = route_by_id (target->value());
3286 if (!r || boost::dynamic_pointer_cast<Track>(r)) {
3287 (*i)->add_property ("type", "dangling-aux-send");
3291 if (role && role->value() == X_("Listen")) {
3292 (*i)->remove_property (X_("bitslot"));
3294 else if (role && (role->value() == X_("Send") || role->value() == X_("Aux"))) {
3296 Delivery::Role xrole;
3297 uint32_t bitslot = 0;
3298 xrole = Delivery::Role (string_2_enum (role->value(), xrole));
3299 std::string name = Send::name_and_id_new_send(*this, xrole, bitslot, false);
3300 snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
3301 (*i)->remove_property (X_("bitslot"));
3302 (*i)->remove_property (X_("name"));
3303 (*i)->add_property ("bitslot", buf);
3304 (*i)->add_property ("name", name);
3306 else if (type && type->value() == X_("intreturn")) {
3307 (*i)->remove_property (X_("bitslot"));
3308 (*i)->add_property ("ignore-bitslot", "1");
3310 else if (type && type->value() == X_("return")) {
3311 // Return::set_state() generates a new one
3312 (*i)->remove_property (X_("bitslot"));
3314 else if (type && type->value() == X_("port")) {
3315 // PortInsert::set_state() handles the bitslot
3316 (*i)->remove_property (X_("bitslot"));
3317 (*i)->add_property ("ignore-name", "1");
3322 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
3325 error << _("Session: cannot create track/bus from template description") << endmsg;
3329 if (boost::dynamic_pointer_cast<Track>(route)) {
3330 /* force input/output change signals so that the new diskstream
3331 picks up the configuration of the route. During session
3332 loading this normally happens in a different way.
3335 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3337 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
3338 change.after = route->input()->n_ports();
3339 route->input()->changed (change, this);
3340 change.after = route->output()->n_ports();
3341 route->output()->changed (change, this);
3344 boost::shared_ptr<Track> track;
3346 if ((track = boost::dynamic_pointer_cast<Track> (route))) {
3349 track->use_new_playlist ();
3352 track->use_copy_playlist ();
3359 ret.push_back (route);
3362 catch (failed_constructor &err) {
3363 error << _("Session: could not create new route from template") << endmsg;
3367 catch (AudioEngine::PortRegistrationFailure& pfe) {
3368 error << pfe.what() << endmsg;
3377 StateProtector sp (this);
3378 if (Profile->get_trx()) {
3379 add_routes (ret, false, false, false, insert_at);
3381 add_routes (ret, true, true, false, insert_at);
3383 IO::enable_connecting ();
3390 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save, PresentationInfo::order_t order)
3393 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
3394 add_routes_inner (new_routes, input_auto_connect, output_auto_connect, order);
3397 error << _("Adding new tracks/busses failed") << endmsg;
3402 update_latency (true);
3403 update_latency (false);
3408 save_state (_current_snapshot_name);
3411 update_route_record_state ();
3413 RouteAdded (new_routes); /* EMIT SIGNAL */
3417 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t order)
3419 ChanCount existing_inputs;
3420 ChanCount existing_outputs;
3424 count_existing_track_channels (existing_inputs, existing_outputs);
3427 RCUWriter<RouteList> writer (routes);
3428 boost::shared_ptr<RouteList> r = writer.get_copy ();
3429 r->insert (r->end(), new_routes.begin(), new_routes.end());
3430 n_routes = r->size();
3432 /* if there is no control out and we're not in the middle of loading,
3433 * resort the graph here. if there is a control out, we will resort
3434 * toward the end of this method. if we are in the middle of loading,
3435 * we will resort when done.
3438 if (!_monitor_out && IO::connecting_legal) {
3439 resort_routes_using (r);
3443 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("ensure order gap starting at %1 for %2\n", order, new_routes.size()));
3444 ensure_route_presentation_info_gap (order, new_routes.size());
3446 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x, ++added) {
3448 boost::weak_ptr<Route> wpr (*x);
3449 boost::shared_ptr<Route> r (*x);
3451 r->solo_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2,wpr));
3452 r->solo_isolate_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr));
3453 r->mute_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this));
3455 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
3456 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
3457 r->processor_latency_changed.connect_same_thread (*this, boost::bind (&Session::queue_latency_recompute, this));
3459 if (r->is_master()) {
3463 if (r->is_monitor()) {
3467 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
3469 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
3470 track_playlist_changed (boost::weak_ptr<Track> (tr));
3471 tr->rec_enable_control()->Changed.connect_same_thread (*this, boost::bind (&Session::update_route_record_state, this));
3473 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
3475 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
3476 mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
3480 if (!r->presentation_info().special()) {
3482 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("checking PI state for %1\n", r->name()));
3484 /* presentation info order may already have been set from XML */
3486 if (!r->presentation_info().order_set()) {
3488 if (order == PresentationInfo::max_order) {
3489 /* just add to the end */
3490 r->set_presentation_order (n_routes + added, false);
3491 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to NR %1 + %2 = %3\n", n_routes, added, n_routes + added));
3493 r->set_presentation_order (order + added);
3494 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to %1 + %2 = %3\n", order, added, order + added));
3497 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order already set to %1\n", r->presentation_info().order()));
3501 #if !defined(__APPLE__) && !defined(__FreeBSD__)
3502 /* clang complains: 'operator<<' should be declared prior to the call site or in an associated namespace of one of its
3503 * arguments std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid)"
3505 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("added route %1, group order %2 type %3 (summary: %4)\n",
3507 r->presentation_info().order(),
3508 enum_2_string (r->presentation_info().flags()),
3509 r->presentation_info()));
3513 if (input_auto_connect || output_auto_connect) {
3514 auto_connect_route (r, input_auto_connect, ChanCount (), ChanCount (), existing_inputs, existing_outputs);
3515 existing_inputs += r->n_inputs();
3516 existing_outputs += r->n_outputs();
3522 if (_monitor_out && IO::connecting_legal) {
3523 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
3525 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
3526 if ((*x)->is_monitor()) {
3528 } else if ((*x)->is_master()) {
3531 (*x)->enable_monitor_send ();
3536 reassign_track_numbers ();
3540 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
3542 boost::shared_ptr<RouteList> r = routes.reader ();
3543 boost::shared_ptr<Send> s;
3545 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3546 if ((s = (*i)->internal_send_for (dest)) != 0) {
3547 s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO, Controllable::NoGroup);
3553 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
3555 boost::shared_ptr<RouteList> r = routes.reader ();
3556 boost::shared_ptr<Send> s;
3558 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3559 if ((s = (*i)->internal_send_for (dest)) != 0) {
3560 s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY, Controllable::NoGroup);
3566 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
3568 boost::shared_ptr<RouteList> r = routes.reader ();
3569 boost::shared_ptr<Send> s;
3571 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3572 if ((s = (*i)->internal_send_for (dest)) != 0) {
3573 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value(), Controllable::NoGroup);
3578 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
3580 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
3582 boost::shared_ptr<RouteList> r = routes.reader ();
3583 boost::shared_ptr<RouteList> t (new RouteList);
3585 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3586 /* no MIDI sends because there are no MIDI busses yet */
3587 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
3592 add_internal_sends (dest, p, t);
3596 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
3598 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
3599 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
3604 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
3606 add_internal_send (dest, sender->before_processor_for_index (index), sender);
3610 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
3612 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
3616 if (!dest->internal_return()) {
3617 dest->add_internal_return ();
3620 sender->add_aux_send (dest, before);
3626 Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
3628 { // RCU Writer scope
3629 PBD::Unwinder<bool> uw_flag (_route_deletion_in_progress, true);
3630 RCUWriter<RouteList> writer (routes);
3631 boost::shared_ptr<RouteList> rs = writer.get_copy ();
3634 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3636 if (*iter == _master_out) {
3640 (*iter)->solo_control()->set_value (0.0, Controllable::NoGroup);
3644 /* deleting the master out seems like a dumb
3645 idea, but its more of a UI policy issue
3649 if (*iter == _master_out) {
3650 _master_out = boost::shared_ptr<Route> ();
3653 if (*iter == _monitor_out) {
3654 _monitor_out.reset ();
3657 // We need to disconnect the route's inputs and outputs
3659 (*iter)->input()->disconnect (0);
3660 (*iter)->output()->disconnect (0);
3662 /* if the route had internal sends sending to it, remove them */
3663 if ((*iter)->internal_return()) {
3665 boost::shared_ptr<RouteList> r = routes.reader ();
3666 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3667 boost::shared_ptr<Send> s = (*i)->internal_send_for (*iter);
3669 (*i)->remove_processor (s);
3674 /* if the monitoring section had a pointer to this route, remove it */
3675 if (_monitor_out && !(*iter)->is_master() && !(*iter)->is_monitor()) {
3676 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3677 PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
3678 (*iter)->remove_aux_or_listen (_monitor_out);
3681 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*iter);
3682 if (mt && mt->step_editing()) {
3683 if (_step_editors > 0) {
3689 /* writer goes out of scope, forces route list update */
3691 } // end of RCU Writer scope
3693 update_route_solo_state ();
3694 update_latency_compensation ();
3697 /* Re-sort routes to remove the graph's current references to the one that is
3698 * going away, then flush old references out of the graph.
3699 * Wave Tracks: reconnect routes
3702 #ifdef USE_TRACKS_CODE_FEATURES
3703 reconnect_existing_routes(true, false);
3705 routes.flush (); // maybe unsafe, see below.
3709 if (_process_graph && !(_state_of_the_state & Deletion)) {
3710 _process_graph->clear_other_chain ();
3713 /* get rid of it from the dead wood collection in the route list manager */
3714 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
3718 /* try to cause everyone to drop their references
3719 * and unregister ports from the backend
3722 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3723 cerr << "Drop references to " << (*iter)->name() << endl;
3724 (*iter)->drop_references ();
3727 if (_state_of_the_state & Deletion) {
3731 PresentationInfo::Change(); /* EMIT SIGNAL */
3733 /* save the new state of the world */
3735 if (save_state (_current_snapshot_name)) {
3736 save_history (_current_snapshot_name);
3739 update_route_record_state ();
3743 Session::remove_route (boost::shared_ptr<Route> route)
3745 boost::shared_ptr<RouteList> rl (new RouteList);
3746 rl->push_back (route);
3751 Session::route_mute_changed ()
3757 Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
3759 boost::shared_ptr<Route> route (wpr.lock());
3765 assert (Config->get_solo_control_is_listen_control());
3767 if (route->solo_control()->soloed_by_self_or_masters()) {
3769 if (Config->get_exclusive_solo()) {
3771 RouteGroup* rg = route->route_group ();
3772 const bool group_already_accounted_for = (group_override == Controllable::ForGroup);
3774 boost::shared_ptr<RouteList> r = routes.reader ();
3776 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3777 if ((*i) == route) {
3778 /* already changed */
3782 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3783 /* route does not get solo propagated to it */
3787 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3788 /* this route is a part of the same solo group as the route
3789 * that was changed. Changing that route did change or will
3790 * change all group members appropriately, so we can ignore it
3795 (*i)->solo_control()->set_value (0.0, Controllable::NoGroup);
3801 } else if (_listen_cnt > 0) {
3806 update_route_solo_state ();
3810 Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr)
3812 boost::shared_ptr<Route> route (wpr.lock());
3818 bool send_changed = false;
3820 if (route->solo_isolate_control()->solo_isolated()) {
3821 if (_solo_isolated_cnt == 0) {
3822 send_changed = true;
3824 _solo_isolated_cnt++;
3825 } else if (_solo_isolated_cnt > 0) {
3826 _solo_isolated_cnt--;
3827 if (_solo_isolated_cnt == 0) {
3828 send_changed = true;
3833 IsolatedChanged (); /* EMIT SIGNAL */
3838 Session::route_solo_changed (bool self_solo_changed, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
3840 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_changed));
3842 boost::shared_ptr<Route> route (wpr.lock());
3848 if (Config->get_solo_control_is_listen_control()) {
3849 route_listen_changed (group_override, wpr);
3853 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()));
3855 if (route->solo_control()->transitioned_into_solo() == 0) {
3856 /* route solo changed by upstream/downstream; not interesting
3859 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()));
3863 if (route->solo_control()->transitioned_into_solo() == 0) {
3864 /* reason for being soloed changed (e.g. master went away, we
3865 * took over the master state), but actual status did
3866 * not. nothing to do.
3868 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: solo change was change in reason, not status\n", route->name()));
3871 boost::shared_ptr<RouteList> r = routes.reader ();
3872 int32_t delta = route->solo_control()->transitioned_into_solo ();
3874 /* the route may be a member of a group that has shared-solo
3875 * semantics. If so, then all members of that group should follow the
3876 * solo of the changed route. But ... this is optional, controlled by a
3877 * Controllable::GroupControlDisposition.
3879 * The first argument to the signal that this method is connected to is the
3880 * GroupControlDisposition value that was used to change solo.
3882 * If the solo change was done with group semantics (either InverseGroup
3883 * (force the entire group to change even if the group shared solo is
3884 * disabled) or UseGroup (use the group, which may or may not have the
3885 * shared solo property enabled)) then as we propagate the change to
3886 * the entire session we should IGNORE THE GROUP that the changed route
3890 RouteGroup* rg = route->route_group ();
3891 const bool group_already_accounted_for = (group_override == Controllable::ForGroup);
3893 if (delta == 1 && Config->get_exclusive_solo()) {
3895 /* new solo: disable all other solos, but not the group if its solo-enabled */
3897 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3899 if ((*i) == route) {
3900 /* already changed */
3904 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3905 /* route does not get solo propagated to it */
3909 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3910 /* this route is a part of the same solo group as the route
3911 * that was changed. Changing that route did change or will
3912 * change all group members appropriately, so we can ignore it
3918 (*i)->solo_control()->set_value (0.0, group_override);
3922 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
3924 RouteList uninvolved;
3926 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
3928 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3929 bool via_sends_only;
3930 bool in_signal_flow;
3932 if ((*i) == route) {
3933 /* already changed */
3937 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3938 /* route does not get solo propagated to it */
3939 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(),
3944 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3945 /* this route is a part of the same solo group as the route
3946 * that was changed. Changing that route did change or will
3947 * change all group members appropriately, so we can ignore it
3953 in_signal_flow = false;
3955 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
3957 if ((*i)->feeds (route, &via_sends_only)) {
3958 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
3959 if (!via_sends_only) {
3960 if (!route->soloed_by_others_upstream()) {
3961 (*i)->solo_control()->mod_solo_by_others_downstream (delta);
3963 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others upstream\n");
3966 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
3968 in_signal_flow = true;
3970 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
3973 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
3975 if (route->feeds (*i, &via_sends_only)) {
3976 /* propagate solo upstream only if routing other than
3977 sends is involved, but do consider the other route
3978 (*i) to be part of the signal flow even if only
3981 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
3985 route->soloed_by_others_downstream(),
3986 route->soloed_by_others_upstream()));
3987 if (!via_sends_only) {
3988 //NB. Triggers Invert Push, which handles soloed by downstream
3989 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
3990 (*i)->solo_control()->mod_solo_by_others_upstream (delta);
3992 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
3994 in_signal_flow = true;
3996 DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
3999 if (!in_signal_flow) {
4000 uninvolved.push_back (*i);
4004 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
4006 update_route_solo_state (r);
4008 /* now notify that the mute state of the routes not involved in the signal
4009 pathway of the just-solo-changed route may have altered.
4012 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
4013 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
4014 (*i)->act_on_mute ();
4015 (*i)->mute_control()->Changed (false, Controllable::NoGroup);
4018 SoloChanged (); /* EMIT SIGNAL */
4023 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
4025 /* now figure out if anything that matters is soloed (or is "listening")*/
4027 bool something_soloed = false;
4028 bool something_listening = false;
4029 uint32_t listeners = 0;
4030 uint32_t isolated = 0;
4033 r = routes.reader();
4036 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4037 if ((*i)->can_solo()) {
4038 if (Config->get_solo_control_is_listen_control()) {
4039 if ((*i)->self_soloed() || (*i)->solo_control()->get_masters_value()) {
4041 something_listening = true;
4044 (*i)->set_listen (false);
4045 if ((*i)->can_solo() && ((*i)->self_soloed() || (*i)->solo_control()->get_masters_value())) {
4046 something_soloed = true;
4051 if ((*i)->solo_isolate_control()->solo_isolated()) {
4056 if (something_soloed != _non_soloed_outs_muted) {
4057 _non_soloed_outs_muted = something_soloed;
4058 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
4061 if (something_listening != _listening) {
4062 _listening = something_listening;
4063 SoloActive (_listening);
4066 _listen_cnt = listeners;
4068 if (isolated != _solo_isolated_cnt) {
4069 _solo_isolated_cnt = isolated;
4070 IsolatedChanged (); /* EMIT SIGNAL */
4073 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
4074 something_soloed, listeners, isolated));
4078 Session::get_stripables (StripableList& sl) const
4080 boost::shared_ptr<RouteList> r = routes.reader ();
4081 sl.insert (sl.end(), r->begin(), r->end());
4083 VCAList v = _vca_manager->vcas ();
4084 sl.insert (sl.end(), v.begin(), v.end());
4087 boost::shared_ptr<RouteList>
4088 Session::get_routes_with_internal_returns() const
4090 boost::shared_ptr<RouteList> r = routes.reader ();
4091 boost::shared_ptr<RouteList> rl (new RouteList);
4093 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4094 if ((*i)->internal_return ()) {
4102 Session::io_name_is_legal (const std::string& name) const
4104 boost::shared_ptr<RouteList> r = routes.reader ();
4106 for (vector<string>::const_iterator reserved = reserved_io_names.begin(); reserved != reserved_io_names.end(); ++reserved) {
4107 if (name == *reserved) {
4108 if (!route_by_name (*reserved)) {
4109 /* first instance of a reserved name is allowed */
4112 /* all other instances of a reserved name are not allowed */
4117 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4118 if ((*i)->name() == name) {
4122 if ((*i)->has_io_processor_named (name)) {
4131 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
4134 vector<string> connections;
4136 /* if we are passed only a single route and we're not told to turn
4137 * others off, then just do the simple thing.
4140 if (flip_others == false && rl->size() == 1) {
4141 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
4143 mt->set_input_active (onoff);
4148 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
4150 PortSet& ps ((*rt)->input()->ports());
4152 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
4153 p->get_connections (connections);
4156 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
4157 routes_using_input_from (*s, rl2);
4160 /* scan all relevant routes to see if others are on or off */
4162 bool others_are_already_on = false;
4164 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
4166 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
4172 if ((*r) != (*rt)) {
4173 if (mt->input_active()) {
4174 others_are_already_on = true;
4177 /* this one needs changing */
4178 mt->set_input_active (onoff);
4184 /* globally reverse other routes */
4186 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
4187 if ((*r) != (*rt)) {
4188 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
4190 mt->set_input_active (!others_are_already_on);
4199 Session::routes_using_input_from (const string& str, RouteList& rl)
4201 boost::shared_ptr<RouteList> r = routes.reader();
4203 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4204 if ((*i)->input()->connected_to (str)) {
4210 boost::shared_ptr<Route>
4211 Session::route_by_name (string name) const
4213 boost::shared_ptr<RouteList> r = routes.reader ();
4215 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4216 if ((*i)->name() == name) {
4221 return boost::shared_ptr<Route> ((Route*) 0);
4224 boost::shared_ptr<Route>
4225 Session::route_by_id (PBD::ID id) const
4227 boost::shared_ptr<RouteList> r = routes.reader ();
4229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4230 if ((*i)->id() == id) {
4235 return boost::shared_ptr<Route> ((Route*) 0);
4238 boost::shared_ptr<Processor>
4239 Session::processor_by_id (PBD::ID id) const
4241 boost::shared_ptr<RouteList> r = routes.reader ();
4243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4244 boost::shared_ptr<Processor> p = (*i)->Route::processor_by_id (id);
4250 return boost::shared_ptr<Processor> ();
4253 boost::shared_ptr<Track>
4254 Session::track_by_diskstream_id (PBD::ID id) const
4256 boost::shared_ptr<RouteList> r = routes.reader ();
4258 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4259 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
4260 if (t && t->using_diskstream_id (id)) {
4265 return boost::shared_ptr<Track> ();
4268 boost::shared_ptr<Route>
4269 Session::get_remote_nth_route (PresentationInfo::order_t n) const
4271 return boost::dynamic_pointer_cast<Route> (get_remote_nth_stripable (n, PresentationInfo::Route));
4274 boost::shared_ptr<Stripable>
4275 Session::get_remote_nth_stripable (PresentationInfo::order_t n, PresentationInfo::Flag flags) const
4278 PresentationInfo::order_t match_cnt = 0;
4280 get_stripables (sl);
4281 sl.sort (Stripable::PresentationOrderSorter());
4283 for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
4285 if ((*s)->presentation_info().hidden()) {
4286 /* if the caller didn't explicitly ask for hidden
4287 stripables, ignore hidden ones. This matches
4288 the semantics of the pre-PresentationOrder
4289 "get by RID" logic of Ardour 4.x and earlier.
4291 XXX at some point we should likely reverse
4292 the logic of the flags, because asking for "the
4293 hidden stripables" is not going to be common,
4294 whereas asking for visible ones is normal.
4297 if (! (flags & PresentationInfo::Hidden)) {
4302 if ((*s)->presentation_info().flag_match (flags)) {
4303 if (match_cnt++ == n) {
4309 /* there is no nth stripable that matches the given flags */
4310 return boost::shared_ptr<Stripable>();
4313 boost::shared_ptr<Route>
4314 Session::route_by_selected_count (uint32_t id) const
4316 boost::shared_ptr<RouteList> r = routes.reader ();
4318 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4319 /* NOT IMPLEMENTED */
4322 return boost::shared_ptr<Route> ((Route*) 0);
4325 struct PresentationOrderSorter {
4326 bool operator() (boost::shared_ptr<Stripable> a, boost::shared_ptr<Stripable> b) {
4327 if (a->presentation_info().special() && !b->presentation_info().special()) {
4328 /* a is not ordered, b is; b comes before a */
4330 } else if (!b->presentation_info().order_set() && a->presentation_info().order_set()) {
4331 /* b is not ordered, a is; a comes before b */
4334 return a->presentation_info().order() < b->presentation_info().order();
4340 Session::reassign_track_numbers ()
4344 RouteList r (*(routes.reader ()));
4345 PresentationOrderSorter sorter;
4348 StateProtector sp (this);
4350 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
4351 if (boost::dynamic_pointer_cast<Track> (*i)) {
4352 (*i)->set_track_number(++tn);
4354 else if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
4355 (*i)->set_track_number(--bn);
4358 const uint32_t decimals = ceilf (log10f (tn + 1));
4359 const bool decimals_changed = _track_number_decimals != decimals;
4360 _track_number_decimals = decimals;
4362 if (decimals_changed && config.get_track_name_number ()) {
4363 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
4364 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
4366 t->resync_track_name();
4369 // trigger GUI re-layout
4370 config.ParameterChanged("track-name-number");
4374 if (DEBUG_ENABLED(DEBUG::OrderKeys)) {
4375 boost::shared_ptr<RouteList> rl = routes.reader ();
4376 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4377 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 numbered %2\n", (*i)->name(), (*i)->track_number()));
4385 Session::playlist_region_added (boost::weak_ptr<Region> w)
4387 boost::shared_ptr<Region> r = w.lock ();
4392 /* These are the operations that are currently in progress... */
4393 list<GQuark> curr = _current_trans_quarks;
4396 /* ...and these are the operations during which we want to update
4397 the session range location markers.
4400 ops.push_back (Operations::capture);
4401 ops.push_back (Operations::paste);
4402 ops.push_back (Operations::duplicate_region);
4403 ops.push_back (Operations::insert_file);
4404 ops.push_back (Operations::insert_region);
4405 ops.push_back (Operations::drag_region_brush);
4406 ops.push_back (Operations::region_drag);
4407 ops.push_back (Operations::selection_grab);
4408 ops.push_back (Operations::region_fill);
4409 ops.push_back (Operations::fill_selection);
4410 ops.push_back (Operations::create_region);
4411 ops.push_back (Operations::region_copy);
4412 ops.push_back (Operations::fixed_time_region_copy);
4415 /* See if any of the current operations match the ones that we want */
4417 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
4419 /* If so, update the session range markers */
4421 maybe_update_session_range (r->position (), r->last_frame ());
4425 /** Update the session range markers if a is before the current start or
4426 * b is after the current end.
4429 Session::maybe_update_session_range (framepos_t a, framepos_t b)
4431 if (_state_of_the_state & Loading) {
4435 framepos_t session_end_marker_shift_samples = session_end_shift * _nominal_frame_rate;
4437 if (_session_range_location == 0) {
4439 set_session_range_location (a, b + session_end_marker_shift_samples);
4443 if (a < _session_range_location->start()) {
4444 _session_range_location->set_start (a);
4447 if (_session_range_end_is_free && (b > _session_range_location->end())) {
4448 _session_range_location->set_end (b);
4454 Session::set_end_is_free (bool yn)
4456 _session_range_end_is_free = yn;
4460 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
4462 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
4463 maybe_update_session_range (i->to, i->to + i->length);
4468 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
4470 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
4471 maybe_update_session_range (i->from, i->to);
4475 /* Region management */
4477 boost::shared_ptr<Region>
4478 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
4480 const RegionFactory::RegionMap& regions (RegionFactory::regions());
4481 RegionFactory::RegionMap::const_iterator i;
4482 boost::shared_ptr<Region> region;
4484 Glib::Threads::Mutex::Lock lm (region_lock);
4486 for (i = regions.begin(); i != regions.end(); ++i) {
4490 if (region->whole_file()) {
4492 if (child->source_equivalent (region)) {
4498 return boost::shared_ptr<Region> ();
4502 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
4504 set<boost::shared_ptr<Region> > relevant_regions;
4506 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
4507 RegionFactory::get_regions_using_source (*s, relevant_regions);
4510 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
4511 set<boost::shared_ptr<Region> >::iterator tmp;
4516 playlists->destroy_region (*r);
4517 RegionFactory::map_remove (*r);
4519 (*r)->drop_sources ();
4520 (*r)->drop_references ();
4522 relevant_regions.erase (r);
4527 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
4530 Glib::Threads::Mutex::Lock ls (source_lock);
4531 /* remove from the main source list */
4532 sources.erase ((*s)->id());
4535 (*s)->mark_for_remove ();
4536 (*s)->drop_references ();
4545 Session::remove_last_capture ()
4547 list<boost::shared_ptr<Source> > srcs;
4549 boost::shared_ptr<RouteList> rl = routes.reader ();
4550 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4551 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4556 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
4559 srcs.insert (srcs.end(), l.begin(), l.end());
4564 destroy_sources (srcs);
4566 save_state (_current_snapshot_name);
4571 /* Source Management */
4574 Session::add_source (boost::shared_ptr<Source> source)
4576 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
4577 pair<SourceMap::iterator,bool> result;
4579 entry.first = source->id();
4580 entry.second = source;
4583 Glib::Threads::Mutex::Lock lm (source_lock);
4584 result = sources.insert (entry);
4587 if (result.second) {
4589 /* yay, new source */
4591 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
4594 if (!fs->within_session()) {
4595 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
4601 boost::shared_ptr<AudioFileSource> afs;
4603 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
4604 if (Config->get_auto_analyse_audio()) {
4605 Analyser::queue_source_for_analysis (source, false);
4609 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
4614 Session::remove_source (boost::weak_ptr<Source> src)
4616 if (_state_of_the_state & Deletion) {
4620 SourceMap::iterator i;
4621 boost::shared_ptr<Source> source = src.lock();
4628 Glib::Threads::Mutex::Lock lm (source_lock);
4630 if ((i = sources.find (source->id())) != sources.end()) {
4635 if (!(_state_of_the_state & StateOfTheState (InCleanup|Loading))) {
4637 /* save state so we don't end up with a session file
4638 referring to non-existent sources.
4641 save_state (_current_snapshot_name);
4645 boost::shared_ptr<Source>
4646 Session::source_by_id (const PBD::ID& id)
4648 Glib::Threads::Mutex::Lock lm (source_lock);
4649 SourceMap::iterator i;
4650 boost::shared_ptr<Source> source;
4652 if ((i = sources.find (id)) != sources.end()) {
4659 boost::shared_ptr<AudioFileSource>
4660 Session::audio_source_by_path_and_channel (const string& path, uint16_t chn) const
4662 /* Restricted to audio files because only audio sources have channel
4666 Glib::Threads::Mutex::Lock lm (source_lock);
4668 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4669 boost::shared_ptr<AudioFileSource> afs
4670 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
4672 if (afs && afs->path() == path && chn == afs->channel()) {
4677 return boost::shared_ptr<AudioFileSource>();
4680 boost::shared_ptr<MidiSource>
4681 Session::midi_source_by_path (const std::string& path) const
4683 /* Restricted to MIDI files because audio sources require a channel
4684 for unique identification, in addition to a path.
4687 Glib::Threads::Mutex::Lock lm (source_lock);
4689 for (SourceMap::const_iterator s = sources.begin(); s != sources.end(); ++s) {
4690 boost::shared_ptr<MidiSource> ms
4691 = boost::dynamic_pointer_cast<MidiSource>(s->second);
4692 boost::shared_ptr<FileSource> fs
4693 = boost::dynamic_pointer_cast<FileSource>(s->second);
4695 if (ms && fs && fs->path() == path) {
4700 return boost::shared_ptr<MidiSource>();
4704 Session::count_sources_by_origin (const string& path)
4707 Glib::Threads::Mutex::Lock lm (source_lock);
4709 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
4710 boost::shared_ptr<FileSource> fs
4711 = boost::dynamic_pointer_cast<FileSource>(i->second);
4713 if (fs && fs->origin() == path) {
4722 peak_file_helper (const string& peak_path, const string& file_path, const string& file_base, bool hash) {
4724 std::string checksum = Glib::Checksum::compute_checksum(Glib::Checksum::CHECKSUM_SHA1, file_path + G_DIR_SEPARATOR + file_base);
4725 return Glib::build_filename (peak_path, checksum + peakfile_suffix);
4727 return Glib::build_filename (peak_path, file_base + peakfile_suffix);
4732 Session::construct_peak_filepath (const string& filepath, const bool in_session, const bool old_peak_name) const
4734 string interchange_dir_string = string (interchange_dir_name) + G_DIR_SEPARATOR;
4736 if (Glib::path_is_absolute (filepath)) {
4738 /* rip the session dir from the audiofile source */
4740 string session_path;
4741 bool in_another_session = true;
4743 if (filepath.find (interchange_dir_string) != string::npos) {
4745 session_path = Glib::path_get_dirname (filepath); /* now ends in audiofiles */
4746 session_path = Glib::path_get_dirname (session_path); /* now ends in session name */
4747 session_path = Glib::path_get_dirname (session_path); /* now ends in interchange */
4748 session_path = Glib::path_get_dirname (session_path); /* now has session path */
4750 /* see if it is within our session */
4752 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4753 if (i->path == session_path) {
4754 in_another_session = false;
4759 in_another_session = false;
4763 if (in_another_session) {
4764 SessionDirectory sd (session_path);
4765 return peak_file_helper (sd.peak_path(), "", Glib::path_get_basename (filepath), !old_peak_name);
4769 /* 1) if file belongs to this session
4770 * it may be a relative path (interchange/...)
4771 * or just basename (session_state, remove source)
4772 * -> just use the basename
4774 std::string filename = Glib::path_get_basename (filepath);
4777 /* 2) if the file is outside our session dir:
4778 * (imported but not copied) add the path for check-summming */
4780 path = Glib::path_get_dirname (filepath);
4783 return peak_file_helper (_session_dir->peak_path(), path, Glib::path_get_basename (filepath), !old_peak_name);
4787 Session::new_audio_source_path_for_embedded (const std::string& path)
4791 * we know that the filename is already unique because it exists
4792 * out in the filesystem.
4794 * However, when we bring it into the session, we could get a
4797 * Eg. two embedded files:
4802 * When merged into session, these collide.
4804 * There will not be a conflict with in-memory sources
4805 * because when the source was created we already picked
4806 * a unique name for it.
4808 * This collision is not likely to be common, but we have to guard
4809 * against it. So, if there is a collision, take the md5 hash of the
4810 * the path, and use that as the filename instead.
4813 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4814 string base = Glib::path_get_basename (path);
4815 string newpath = Glib::build_filename (sdir.sound_path(), base);
4817 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4821 md5.digestString (path.c_str());
4822 md5.writeToString ();
4823 base = md5.digestChars;
4825 string ext = get_suffix (path);
4832 newpath = Glib::build_filename (sdir.sound_path(), base);
4834 /* if this collides, we're screwed */
4836 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4837 error << string_compose (_("Merging embedded file %1: name collision AND md5 hash collision!"), path) << endmsg;
4846 /** Return true if there are no audio file sources that use @param name as
4847 * the filename component of their path.
4849 * Return false otherwise.
4851 * This method MUST ONLY be used to check in-session, mono files since it
4852 * hard-codes the channel of the audio file source we are looking for as zero.
4854 * If/when Ardour supports native files in non-mono formats, the logic here
4855 * will need to be revisited.
4858 Session::audio_source_name_is_unique (const string& name)
4860 std::vector<string> sdirs = source_search_path (DataType::AUDIO);
4861 vector<space_and_path>::iterator i;
4862 uint32_t existing = 0;
4864 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4866 /* note that we search *without* the extension so that
4867 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
4868 in the event that this new name is required for
4869 a file format change.
4872 const string spath = *i;
4874 if (matching_unsuffixed_filename_exists_in (spath, name)) {
4879 /* it is possible that we have the path already
4880 * assigned to a source that has not yet been written
4881 * (ie. the write source for a diskstream). we have to
4882 * check this in order to make sure that our candidate
4883 * path isn't used again, because that can lead to
4884 * two Sources point to the same file with different
4885 * notions of their removability.
4889 string possible_path = Glib::build_filename (spath, name);
4891 if (audio_source_by_path_and_channel (possible_path, 0)) {
4897 return (existing == 0);
4901 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)
4904 const string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
4906 if (Profile->get_trx() && destructive) {
4908 sstr << setfill ('0') << setw (4) << cnt;
4909 sstr << legalized_base;
4911 sstr << legalized_base;
4913 if (take_required || related_exists) {
4925 } else if (nchan > 2) {
4930 /* XXX what? more than 26 channels! */
4941 /** Return a unique name based on \a base for a new internal audio source */
4943 Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required)
4946 string possible_name;
4947 const uint32_t limit = 9999; // arbitrary limit on number of files with the same basic name
4949 bool some_related_source_name_exists = false;
4951 legalized = legalize_for_path (base);
4953 // Find a "version" of the base name that doesn't exist in any of the possible directories.
4955 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
4957 possible_name = format_audio_source_name (legalized, nchan, chan, destructive, take_required, cnt, some_related_source_name_exists);
4959 if (audio_source_name_is_unique (possible_name)) {
4963 some_related_source_name_exists = true;
4966 error << string_compose(
4967 _("There are already %1 recordings for %2, which I consider too many."),
4968 limit, base) << endmsg;
4970 throw failed_constructor();
4974 /* We've established that the new name does not exist in any session
4975 * directory, so now find out which one we should use for this new
4979 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4981 std::string s = Glib::build_filename (sdir.sound_path(), possible_name);
4986 /** Return a unique name based on `base` for a new internal MIDI source */
4988 Session::new_midi_source_path (const string& base)
4991 char buf[PATH_MAX+1];
4992 const uint32_t limit = 10000;
4994 string possible_path;
4995 string possible_name;
4998 legalized = legalize_for_path (base);
5000 // Find a "version" of the file name that doesn't exist in any of the possible directories.
5001 std::vector<string> sdirs = source_search_path(DataType::MIDI);
5003 /* - the main session folder is the first in the vector.
5004 * - after checking all locations for file-name uniqueness,
5005 * we keep the one from the last iteration as new file name
5006 * - midi files are small and should just be kept in the main session-folder
5008 * -> reverse the array, check main session folder last and use that as location
5011 std::reverse(sdirs.begin(), sdirs.end());
5013 for (cnt = 1; cnt <= limit; ++cnt) {
5015 vector<space_and_path>::iterator i;
5016 uint32_t existing = 0;
5018 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
5020 snprintf (buf, sizeof(buf), "%s-%u.mid", legalized.c_str(), cnt);
5021 possible_name = buf;
5023 possible_path = Glib::build_filename (*i, possible_name);
5025 if (Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
5029 if (midi_source_by_path (possible_path)) {
5034 if (existing == 0) {
5039 error << string_compose(
5040 _("There are already %1 recordings for %2, which I consider too many."),
5041 limit, base) << endmsg;
5047 /* No need to "find best location" for software/app-based RAID, because
5048 MIDI is so small that we always put it in the same place.
5051 return possible_path;
5055 /** Create a new within-session audio source */
5056 boost::shared_ptr<AudioFileSource>
5057 Session::create_audio_source_for_session (size_t n_chans, string const & base, uint32_t chan, bool destructive)
5059 const string path = new_audio_source_path (base, n_chans, chan, destructive, true);
5061 if (!path.empty()) {
5062 return boost::dynamic_pointer_cast<AudioFileSource> (
5063 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate(), true, true));
5065 throw failed_constructor ();
5069 /** Create a new within-session MIDI source */
5070 boost::shared_ptr<MidiSource>
5071 Session::create_midi_source_for_session (string const & basic_name)
5073 const string path = new_midi_source_path (basic_name);
5075 if (!path.empty()) {
5076 return boost::dynamic_pointer_cast<SMFSource> (
5077 SourceFactory::createWritable (
5078 DataType::MIDI, *this, path, false, frame_rate()));
5080 throw failed_constructor ();
5084 /** Create a new within-session MIDI source */
5085 boost::shared_ptr<MidiSource>
5086 Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
5088 /* the caller passes in the track the source will be used in,
5089 so that we can keep the numbering sane.
5091 Rationale: a track with the name "Foo" that has had N
5092 captures carried out so far will ALREADY have a write source
5093 named "Foo-N+1.mid" waiting to be used for the next capture.
5095 If we call new_midi_source_name() we will get "Foo-N+2". But
5096 there is no region corresponding to "Foo-N+1", so when
5097 "Foo-N+2" appears in the track, the gap presents the user
5098 with odd behaviour - why did it skip past Foo-N+1?
5100 We could explain this to the user in some odd way, but
5101 instead we rename "Foo-N+1.mid" as "Foo-N+2.mid", and then
5104 If that attempted rename fails, we get "Foo-N+2.mid" anyway.
5107 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (track);
5109 std::string name = track->steal_write_source_name ();
5112 return boost::shared_ptr<MidiSource>();
5115 /* MIDI files are small, just put them in the first location of the
5116 session source search path.
5119 const string path = Glib::build_filename (source_search_path (DataType::MIDI).front(), name);
5121 return boost::dynamic_pointer_cast<SMFSource> (
5122 SourceFactory::createWritable (
5123 DataType::MIDI, *this, path, false, frame_rate()));
5128 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
5130 if (playlist->hidden()) {
5134 playlists->add (playlist);
5137 playlist->release();
5144 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
5146 if (_state_of_the_state & Deletion) {
5150 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
5156 playlists->remove (playlist);
5162 Session::set_audition (boost::shared_ptr<Region> r)
5164 pending_audition_region = r;
5165 add_post_transport_work (PostTransportAudition);
5166 _butler->schedule_transport_work ();
5170 Session::audition_playlist ()
5172 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
5173 ev->region.reset ();
5179 Session::register_lua_function (
5180 const std::string& name,
5181 const std::string& script,
5182 const LuaScriptParamList& args
5185 Glib::Threads::Mutex::Lock lm (lua_lock);
5187 lua_State* L = lua.getState();
5189 const std::string& bytecode = LuaScripting::get_factory_bytecode (script);
5190 luabridge::LuaRef tbl_arg (luabridge::newTable(L));
5191 for (LuaScriptParamList::const_iterator i = args.begin(); i != args.end(); ++i) {
5192 if ((*i)->optional && !(*i)->is_set) { continue; }
5193 tbl_arg[(*i)->name] = (*i)->value;
5195 (*_lua_add)(name, bytecode, tbl_arg); // throws luabridge::LuaException
5200 Session::unregister_lua_function (const std::string& name)
5202 Glib::Threads::Mutex::Lock lm (lua_lock);
5203 (*_lua_del)(name); // throws luabridge::LuaException
5204 lua.collect_garbage ();
5208 std::vector<std::string>
5209 Session::registered_lua_functions ()
5211 Glib::Threads::Mutex::Lock lm (lua_lock);
5212 std::vector<std::string> rv;
5215 luabridge::LuaRef list ((*_lua_list)());
5216 for (luabridge::Iterator i (list); !i.isNil (); ++i) {
5217 if (!i.key ().isString ()) { assert(0); continue; }
5218 rv.push_back (i.key ().cast<std::string> ());
5220 } catch (luabridge::LuaException const& e) { }
5225 static void _lua_print (std::string s) {
5226 std::cout << "SessionLua: " << s << "\n";
5231 Session::try_run_lua (pframes_t nframes)
5233 if (_n_lua_scripts == 0) return;
5234 Glib::Threads::Mutex::Lock tm (lua_lock, Glib::Threads::TRY_LOCK);
5236 try { (*_lua_run)(nframes); } catch (luabridge::LuaException const& e) { }
5237 lua.collect_garbage_step ();
5242 Session::setup_lua ()
5245 lua.Print.connect (&_lua_print);
5249 "function ArdourSession ()"
5250 " local self = { scripts = {}, instances = {} }"
5252 " local remove = function (n)"
5253 " self.scripts[n] = nil"
5254 " self.instances[n] = nil"
5255 " Session:scripts_changed()" // call back
5258 " local addinternal = function (n, f, a)"
5259 " assert(type(n) == 'string', 'function-name must be string')"
5260 " assert(type(f) == 'function', 'Given script is a not a function')"
5261 " assert(type(a) == 'table' or type(a) == 'nil', 'Given argument is invalid')"
5262 " assert(self.scripts[n] == nil, 'Callback \"'.. n ..'\" already exists.')"
5263 " self.scripts[n] = { ['f'] = f, ['a'] = a }"
5264 " 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"
5265 " 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 }"
5266 " self.instances[n] = load (string.dump(f, true), nil, nil, env)(a)"
5267 " Session:scripts_changed()" // call back
5270 " local add = function (n, b, a)"
5271 " assert(type(b) == 'string', 'ByteCode must be string')"
5272 " load (b)()" // assigns f
5273 " assert(type(f) == 'string', 'Assigned ByteCode must be string')"
5274 " addinternal (n, load(f), a)"
5277 " local run = function (...)"
5278 " for n, s in pairs (self.instances) do"
5279 " local status, err = pcall (s, ...)"
5280 " if not status then"
5281 " print ('fn \"'.. n .. '\": ', err)"
5288 " local cleanup = function ()"
5289 " self.scripts = nil"
5290 " self.instances = nil"
5293 " local list = function ()"
5295 " for n, _ in pairs (self.scripts) do"
5301 " local function basic_serialize (o)"
5302 " if type(o) == \"number\" then"
5303 " return tostring(o)"
5305 " return string.format(\"%q\", o)"
5309 " local function serialize (name, value)"
5310 " local rv = name .. ' = '"
5312 " if type(value) == \"number\" or type(value) == \"string\" or type(value) == \"nil\" then"
5313 " return rv .. basic_serialize(value) .. ' '"
5314 " elseif type(value) == \"table\" then"
5316 " for k,v in pairs(value) do"
5317 " local fieldname = string.format(\"%s[%s]\", name, basic_serialize(k))"
5318 " rv = rv .. serialize(fieldname, v) .. ' '"
5319 " collectgarbage()" // string concatenation allocates a new string :(
5322 " elseif type(value) == \"function\" then"
5323 " return rv .. string.format(\"%q\", string.dump(value, true))"
5325 " error('cannot save a ' .. type(value))"
5330 " local save = function ()"
5331 " return (serialize('scripts', self.scripts))"
5334 " local restore = function (state)"
5335 " self.scripts = {}"
5337 " for n, s in pairs (scripts) do"
5338 " addinternal (n, load(s['f']), s['a'])"
5342 " return { run = run, add = add, remove = remove,"
5343 " list = list, restore = restore, save = save, cleanup = cleanup}"
5346 " sess = ArdourSession ()"
5347 " ArdourSession = nil"
5349 "function ardour () end"
5352 lua_State* L = lua.getState();
5355 luabridge::LuaRef lua_sess = luabridge::getGlobal (L, "sess");
5356 lua.do_command ("sess = nil"); // hide it.
5357 lua.do_command ("collectgarbage()");
5359 _lua_run = new luabridge::LuaRef(lua_sess["run"]);
5360 _lua_add = new luabridge::LuaRef(lua_sess["add"]);
5361 _lua_del = new luabridge::LuaRef(lua_sess["remove"]);
5362 _lua_list = new luabridge::LuaRef(lua_sess["list"]);
5363 _lua_save = new luabridge::LuaRef(lua_sess["save"]);
5364 _lua_load = new luabridge::LuaRef(lua_sess["restore"]);
5365 _lua_cleanup = new luabridge::LuaRef(lua_sess["cleanup"]);
5366 } catch (luabridge::LuaException const& e) {
5367 fatal << string_compose (_("programming error: %1"),
5368 X_("Failed to setup Lua interpreter"))
5370 abort(); /*NOTREACHED*/
5373 LuaBindings::stddef (L);
5374 LuaBindings::common (L);
5375 LuaBindings::dsp (L);
5376 luabridge::push <Session *> (L, this);
5377 lua_setglobal (L, "Session");
5381 Session::scripts_changed ()
5383 assert (!lua_lock.trylock()); // must hold lua_lock
5386 luabridge::LuaRef list ((*_lua_list)());
5388 for (luabridge::Iterator i (list); !i.isNil (); ++i) {
5389 if (!i.key ().isString ()) { assert(0); continue; }
5392 _n_lua_scripts = cnt;
5393 } catch (luabridge::LuaException const& e) {
5394 fatal << string_compose (_("programming error: %1"),
5395 X_("Indexing Lua Session Scripts failed."))
5397 abort(); /*NOTREACHED*/
5402 Session::non_realtime_set_audition ()
5404 assert (pending_audition_region);
5405 auditioner->audition_region (pending_audition_region);
5406 pending_audition_region.reset ();
5407 AuditionActive (true); /* EMIT SIGNAL */
5411 Session::audition_region (boost::shared_ptr<Region> r)
5413 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
5419 Session::cancel_audition ()
5424 if (auditioner->auditioning()) {
5425 auditioner->cancel_audition ();
5426 AuditionActive (false); /* EMIT SIGNAL */
5431 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
5433 if (a->is_monitor()) {
5436 if (b->is_monitor()) {
5439 return a->presentation_info().order() < b->presentation_info().order();
5443 Session::is_auditioning () const
5445 /* can be called before we have an auditioner object */
5447 return auditioner->auditioning();
5454 Session::graph_reordered ()
5456 /* don't do this stuff if we are setting up connections
5457 from a set_state() call or creating new tracks. Ditto for deletion.
5460 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress || _reconnecting_routes_in_progress || _route_deletion_in_progress) {
5464 /* every track/bus asked for this to be handled but it was deferred because
5465 we were connecting. do it now.
5468 request_input_change_handling ();
5472 /* force all diskstreams to update their capture offset values to
5473 reflect any changes in latencies within the graph.
5476 boost::shared_ptr<RouteList> rl = routes.reader ();
5477 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5478 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5480 tr->set_capture_offset ();
5485 /** @return Number of frames that there is disk space available to write,
5488 boost::optional<framecnt_t>
5489 Session::available_capture_duration ()
5491 Glib::Threads::Mutex::Lock lm (space_lock);
5493 if (_total_free_4k_blocks_uncertain) {
5494 return boost::optional<framecnt_t> ();
5497 float sample_bytes_on_disk = 4.0; // keep gcc happy
5499 switch (config.get_native_file_data_format()) {
5501 sample_bytes_on_disk = 4.0;
5505 sample_bytes_on_disk = 3.0;
5509 sample_bytes_on_disk = 2.0;
5513 /* impossible, but keep some gcc versions happy */
5514 fatal << string_compose (_("programming error: %1"),
5515 X_("illegal native file data format"))
5517 abort(); /*NOTREACHED*/
5520 double scale = 4096.0 / sample_bytes_on_disk;
5522 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
5523 return max_framecnt;
5526 return (framecnt_t) floor (_total_free_4k_blocks * scale);
5530 Session::add_bundle (boost::shared_ptr<Bundle> bundle, bool emit_signal)
5533 RCUWriter<BundleList> writer (_bundles);
5534 boost::shared_ptr<BundleList> b = writer.get_copy ();
5535 b->push_back (bundle);
5539 BundleAddedOrRemoved (); /* EMIT SIGNAL */
5546 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
5548 bool removed = false;
5551 RCUWriter<BundleList> writer (_bundles);
5552 boost::shared_ptr<BundleList> b = writer.get_copy ();
5553 BundleList::iterator i = find (b->begin(), b->end(), bundle);
5555 if (i != b->end()) {
5562 BundleAddedOrRemoved (); /* EMIT SIGNAL */
5568 boost::shared_ptr<Bundle>
5569 Session::bundle_by_name (string name) const
5571 boost::shared_ptr<BundleList> b = _bundles.reader ();
5573 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
5574 if ((*i)->name() == name) {
5579 return boost::shared_ptr<Bundle> ();
5583 Session::tempo_map_changed (const PropertyChange&)
5587 playlists->update_after_tempo_map_change ();
5589 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
5595 Session::gui_tempo_map_changed ()
5599 playlists->update_after_tempo_map_change ();
5601 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
5605 Session::update_locations_after_tempo_map_change (const Locations::LocationList& loc)
5607 for (Locations::LocationList::const_iterator i = loc.begin(); i != loc.end(); ++i) {
5608 (*i)->recompute_frames_from_bbt ();
5612 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
5613 * the given count with the current block size.
5616 Session::ensure_buffers (ChanCount howmany)
5618 BufferManager::ensure_buffers (howmany, bounce_processing() ? bounce_chunk_size : 0);
5622 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
5624 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
5625 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
5630 Session::next_insert_id ()
5632 /* this doesn't really loop forever. just think about it */
5635 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < insert_bitset.size(); ++n) {
5636 if (!insert_bitset[n]) {
5637 insert_bitset[n] = true;
5643 /* none available, so resize and try again */
5645 insert_bitset.resize (insert_bitset.size() + 16, false);
5650 Session::next_send_id ()
5652 /* this doesn't really loop forever. just think about it */
5655 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < send_bitset.size(); ++n) {
5656 if (!send_bitset[n]) {
5657 send_bitset[n] = true;
5663 /* none available, so resize and try again */
5665 send_bitset.resize (send_bitset.size() + 16, false);
5670 Session::next_aux_send_id ()
5672 /* this doesn't really loop forever. just think about it */
5675 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < aux_send_bitset.size(); ++n) {
5676 if (!aux_send_bitset[n]) {
5677 aux_send_bitset[n] = true;
5683 /* none available, so resize and try again */
5685 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
5690 Session::next_return_id ()
5692 /* this doesn't really loop forever. just think about it */
5695 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < return_bitset.size(); ++n) {
5696 if (!return_bitset[n]) {
5697 return_bitset[n] = true;
5703 /* none available, so resize and try again */
5705 return_bitset.resize (return_bitset.size() + 16, false);
5710 Session::mark_send_id (uint32_t id)
5712 if (id >= send_bitset.size()) {
5713 send_bitset.resize (id+16, false);
5715 if (send_bitset[id]) {
5716 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
5718 send_bitset[id] = true;
5722 Session::mark_aux_send_id (uint32_t id)
5724 if (id >= aux_send_bitset.size()) {
5725 aux_send_bitset.resize (id+16, false);
5727 if (aux_send_bitset[id]) {
5728 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
5730 aux_send_bitset[id] = true;
5734 Session::mark_return_id (uint32_t id)
5736 if (id >= return_bitset.size()) {
5737 return_bitset.resize (id+16, false);
5739 if (return_bitset[id]) {
5740 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
5742 return_bitset[id] = true;
5746 Session::mark_insert_id (uint32_t id)
5748 if (id >= insert_bitset.size()) {
5749 insert_bitset.resize (id+16, false);
5751 if (insert_bitset[id]) {
5752 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
5754 insert_bitset[id] = true;
5758 Session::unmark_send_id (uint32_t id)
5760 if (id < send_bitset.size()) {
5761 send_bitset[id] = false;
5766 Session::unmark_aux_send_id (uint32_t id)
5768 if (id < aux_send_bitset.size()) {
5769 aux_send_bitset[id] = false;
5774 Session::unmark_return_id (uint32_t id)
5776 if (_state_of_the_state & Deletion) { return; }
5777 if (id < return_bitset.size()) {
5778 return_bitset[id] = false;
5783 Session::unmark_insert_id (uint32_t id)
5785 if (id < insert_bitset.size()) {
5786 insert_bitset[id] = false;
5791 Session::reset_native_file_format ()
5793 boost::shared_ptr<RouteList> rl = routes.reader ();
5795 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5796 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5798 /* don't save state as we do this, there's no point
5800 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
5801 tr->reset_write_sources (false);
5802 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
5808 Session::route_name_unique (string n) const
5810 boost::shared_ptr<RouteList> r = routes.reader ();
5812 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5813 if ((*i)->name() == n) {
5822 Session::route_name_internal (string n) const
5824 if (auditioner && auditioner->name() == n) {
5828 if (_click_io && _click_io->name() == n) {
5836 Session::freeze_all (InterThreadInfo& itt)
5838 boost::shared_ptr<RouteList> r = routes.reader ();
5840 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5842 boost::shared_ptr<Track> t;
5844 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
5845 /* XXX this is wrong because itt.progress will keep returning to zero at the start
5855 boost::shared_ptr<Region>
5856 Session::write_one_track (Track& track, framepos_t start, framepos_t end,
5857 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
5858 InterThreadInfo& itt,
5859 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
5860 bool for_export, bool for_freeze)
5862 boost::shared_ptr<Region> result;
5863 boost::shared_ptr<Playlist> playlist;
5864 boost::shared_ptr<Source> source;
5865 ChanCount diskstream_channels (track.n_channels());
5866 framepos_t position;
5867 framecnt_t this_chunk;
5869 framepos_t latency_skip;
5871 framepos_t len = end - start;
5872 bool need_block_size_reset = false;
5873 ChanCount const max_proc = track.max_processor_streams ();
5874 string legal_playlist_name;
5875 string possible_path;
5878 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
5879 end, start) << endmsg;
5883 diskstream_channels = track.bounce_get_output_streams (diskstream_channels, endpoint,
5884 include_endpoint, for_export, for_freeze);
5886 if (diskstream_channels.n(track.data_type()) < 1) {
5887 error << _("Cannot write a range with no data.") << endmsg;
5891 // block all process callback handling
5893 block_processing ();
5896 // synchronize with AudioEngine::process_callback()
5897 // make sure processing is not currently running
5898 // and processing_blocked() is honored before
5899 // acquiring thread buffers
5900 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
5903 _bounce_processing_active = true;
5905 /* call tree *MUST* hold route_lock */
5907 if ((playlist = track.playlist()) == 0) {
5911 legal_playlist_name = legalize_for_path (playlist->name());
5913 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n(track.data_type()); ++chan_n) {
5915 string base_name = string_compose ("%1-%2-bounce", playlist->name(), chan_n);
5916 string path = ((track.data_type() == DataType::AUDIO)
5917 ? new_audio_source_path (legal_playlist_name, diskstream_channels.n_audio(), chan_n, false, true)
5918 : new_midi_source_path (legal_playlist_name));
5925 source = SourceFactory::createWritable (track.data_type(), *this, path, false, frame_rate());
5928 catch (failed_constructor& err) {
5929 error << string_compose (_("cannot create new file \"%1\" for %2"), path, track.name()) << endmsg;
5933 srcs.push_back (source);
5936 /* tell redirects that care that we are about to use a much larger
5937 * blocksize. this will flush all plugins too, so that they are ready
5938 * to be used for this process.
5941 need_block_size_reset = true;
5942 track.set_block_size (bounce_chunk_size);
5943 _engine.main_thread()->get_buffers ();
5947 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
5949 /* create a set of reasonably-sized buffers */
5950 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
5951 buffers.ensure_buffers(*t, max_proc.get(*t), bounce_chunk_size);
5953 buffers.set_count (max_proc);
5955 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
5956 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5957 boost::shared_ptr<MidiSource> ms;
5959 afs->prepare_for_peakfile_writes ();
5960 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
5961 Source::Lock lock(ms->mutex());
5962 ms->mark_streaming_write_started(lock);
5966 while (to_do && !itt.cancel) {
5968 this_chunk = min (to_do, bounce_chunk_size);
5970 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze)) {
5974 start += this_chunk;
5975 to_do -= this_chunk;
5976 itt.progress = (float) (1.0 - ((double) to_do / len));
5978 if (latency_skip >= bounce_chunk_size) {
5979 latency_skip -= bounce_chunk_size;
5983 const framecnt_t current_chunk = this_chunk - latency_skip;
5986 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
5987 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5988 boost::shared_ptr<MidiSource> ms;
5991 if (afs->write (buffers.get_audio(n).data(latency_skip), current_chunk) != current_chunk) {
5994 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
5995 Source::Lock lock(ms->mutex());
5997 const MidiBuffer& buf = buffers.get_midi(0);
5998 for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
5999 Evoral::Event<framepos_t> ev = *i;
6000 ev.set_time(ev.time() - position);
6001 ms->append_event_frames(lock, ev, ms->timeline_position());
6008 /* post-roll, pick up delayed processor output */
6009 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
6011 while (latency_skip && !itt.cancel) {
6012 this_chunk = min (latency_skip, bounce_chunk_size);
6013 latency_skip -= this_chunk;
6015 buffers.silence (this_chunk, 0);
6016 track.bounce_process (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze);
6019 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
6020 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
6023 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
6035 xnow = localtime (&now);
6037 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
6038 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
6039 boost::shared_ptr<MidiSource> ms;
6042 afs->update_header (position, *xnow, now);
6043 afs->flush_header ();
6044 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
6045 Source::Lock lock(ms->mutex());
6046 ms->mark_streaming_write_completed(lock);
6050 /* construct a region to represent the bounced material */
6054 plist.add (Properties::start, 0);
6055 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
6056 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
6058 result = RegionFactory::create (srcs, plist);
6064 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
6065 (*src)->mark_for_remove ();
6066 (*src)->drop_references ();
6070 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
6071 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
6074 afs->done_with_peakfile_writes ();
6078 _bounce_processing_active = false;
6080 if (need_block_size_reset) {
6081 _engine.main_thread()->drop_buffers ();
6082 track.set_block_size (get_block_size());
6085 unblock_processing ();
6091 Session::gain_automation_buffer() const
6093 return ProcessThread::gain_automation_buffer ();
6097 Session::trim_automation_buffer() const
6099 return ProcessThread::trim_automation_buffer ();
6103 Session::send_gain_automation_buffer() const
6105 return ProcessThread::send_gain_automation_buffer ();
6109 Session::pan_automation_buffer() const
6111 return ProcessThread::pan_automation_buffer ();
6115 Session::get_silent_buffers (ChanCount count)
6117 return ProcessThread::get_silent_buffers (count);
6121 Session::get_scratch_buffers (ChanCount count, bool silence)
6123 return ProcessThread::get_scratch_buffers (count, silence);
6127 Session::get_noinplace_buffers (ChanCount count)
6129 return ProcessThread::get_noinplace_buffers (count);
6133 Session::get_route_buffers (ChanCount count, bool silence)
6135 return ProcessThread::get_route_buffers (count, silence);
6140 Session::get_mix_buffers (ChanCount count)
6142 return ProcessThread::get_mix_buffers (count);
6146 Session::ntracks () const
6149 boost::shared_ptr<RouteList> r = routes.reader ();
6151 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
6152 if (boost::dynamic_pointer_cast<Track> (*i)) {
6161 Session::nbusses () const
6164 boost::shared_ptr<RouteList> r = routes.reader ();
6166 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
6167 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
6176 Session::add_automation_list(AutomationList *al)
6178 automation_lists[al->id()] = al;
6181 /** @return true if there is at least one record-enabled track, otherwise false */
6183 Session::have_rec_enabled_track () const
6185 return g_atomic_int_get (const_cast<gint*>(&_have_rec_enabled_track)) == 1;
6189 Session::have_rec_disabled_track () const
6191 return g_atomic_int_get (const_cast<gint*>(&_have_rec_disabled_track)) == 1;
6194 /** Update the state of our rec-enabled tracks flag */
6196 Session::update_route_record_state ()
6198 boost::shared_ptr<RouteList> rl = routes.reader ();
6199 RouteList::iterator i = rl->begin();
6200 while (i != rl->end ()) {
6202 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6203 if (tr && tr->rec_enable_control()->get_value()) {
6210 int const old = g_atomic_int_get (&_have_rec_enabled_track);
6212 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
6214 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
6215 RecordStateChanged (); /* EMIT SIGNAL */
6218 for (i = rl->begin(); i != rl->end (); ++i) {
6219 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6220 if (tr && !tr->rec_enable_control()->get_value()) {
6225 g_atomic_int_set (&_have_rec_disabled_track, i != rl->end () ? 1 : 0);
6227 bool record_arm_state_changed = (old != g_atomic_int_get (&_have_rec_enabled_track) );
6229 if (record_status() == Recording && record_arm_state_changed ) {
6230 RecordArmStateChanged ();
6236 Session::listen_position_changed ()
6238 boost::shared_ptr<RouteList> r = routes.reader ();
6240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6241 (*i)->listen_position_changed ();
6246 Session::solo_control_mode_changed ()
6248 if (soloing() || listening()) {
6249 /* We can't use ::clear_all_solo_state() here because during
6250 session loading at program startup, that will queue a call
6251 to rt_clear_all_solo_state() that will not execute until
6252 AFTER solo states have been established (thus throwing away
6253 the session's saved solo state). So just explicitly turn
6256 set_controls (route_list_to_control_list (get_routes(), &Stripable::solo_control), 0.0, Controllable::NoGroup);
6260 /** Called when a property of one of our route groups changes */
6262 Session::route_group_property_changed (RouteGroup* rg)
6264 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
6267 /** Called when a route is added to one of our route groups */
6269 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
6271 RouteAddedToRouteGroup (rg, r);
6274 /** Called when a route is removed from one of our route groups */
6276 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
6278 update_route_record_state ();
6279 RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */
6282 boost::shared_ptr<RouteList>
6283 Session::get_tracks () const
6285 boost::shared_ptr<RouteList> rl = routes.reader ();
6286 boost::shared_ptr<RouteList> tl (new RouteList);
6288 for (RouteList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
6289 if (boost::dynamic_pointer_cast<Track> (*r)) {
6290 if (!(*r)->is_auditioner()) {
6298 boost::shared_ptr<RouteList>
6299 Session::get_routes_with_regions_at (framepos_t const p) const
6301 boost::shared_ptr<RouteList> r = routes.reader ();
6302 boost::shared_ptr<RouteList> rl (new RouteList);
6304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6305 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6310 boost::shared_ptr<Playlist> pl = tr->playlist ();
6315 if (pl->has_region_at (p)) {
6324 Session::goto_end ()
6326 if (_session_range_location) {
6327 request_locate (_session_range_location->end(), false);
6329 request_locate (0, false);
6334 Session::goto_start (bool and_roll)
6336 if (_session_range_location) {
6337 request_locate (_session_range_location->start(), and_roll);
6339 request_locate (0, and_roll);
6344 Session::current_start_frame () const
6346 return _session_range_location ? _session_range_location->start() : 0;
6350 Session::current_end_frame () const
6352 return _session_range_location ? _session_range_location->end() : 0;
6356 Session::set_session_range_location (framepos_t start, framepos_t end)
6358 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
6359 _locations->add (_session_range_location);
6363 Session::step_edit_status_change (bool yn)
6369 send = (_step_editors == 0);
6374 send = (_step_editors == 1);
6377 if (_step_editors > 0) {
6383 StepEditStatusChange (val);
6389 Session::start_time_changed (framepos_t old)
6391 /* Update the auto loop range to match the session range
6392 (unless the auto loop range has been changed by the user)
6395 Location* s = _locations->session_range_location ();
6400 Location* l = _locations->auto_loop_location ();
6402 if (l && l->start() == old) {
6403 l->set_start (s->start(), true);
6409 Session::end_time_changed (framepos_t old)
6411 /* Update the auto loop range to match the session range
6412 (unless the auto loop range has been changed by the user)
6415 Location* s = _locations->session_range_location ();
6420 Location* l = _locations->auto_loop_location ();
6422 if (l && l->end() == old) {
6423 l->set_end (s->end(), true);
6428 std::vector<std::string>
6429 Session::source_search_path (DataType type) const
6433 if (session_dirs.size() == 1) {
6435 case DataType::AUDIO:
6436 sp.push_back (_session_dir->sound_path());
6438 case DataType::MIDI:
6439 sp.push_back (_session_dir->midi_path());
6443 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
6444 SessionDirectory sdir (i->path);
6446 case DataType::AUDIO:
6447 sp.push_back (sdir.sound_path());
6449 case DataType::MIDI:
6450 sp.push_back (sdir.midi_path());
6456 if (type == DataType::AUDIO) {
6457 const string sound_path_2X = _session_dir->sound_path_2X();
6458 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
6459 if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) {
6460 sp.push_back (sound_path_2X);
6465 // now check the explicit (possibly user-specified) search path
6468 case DataType::AUDIO:
6469 sp += Searchpath(config.get_audio_search_path ());
6471 case DataType::MIDI:
6472 sp += Searchpath(config.get_midi_search_path ());
6480 Session::ensure_search_path_includes (const string& path, DataType type)
6489 case DataType::AUDIO:
6490 sp += Searchpath(config.get_audio_search_path ());
6492 case DataType::MIDI:
6493 sp += Searchpath (config.get_midi_search_path ());
6497 for (vector<std::string>::iterator i = sp.begin(); i != sp.end(); ++i) {
6498 /* No need to add this new directory if it has the same inode as
6499 an existing one; checking inode rather than name prevents duplicated
6500 directories when we are using symlinks.
6502 On Windows, I think we could just do if (*i == path) here.
6504 if (PBD::equivalent_paths (*i, path)) {
6512 case DataType::AUDIO:
6513 config.set_audio_search_path (sp.to_string());
6515 case DataType::MIDI:
6516 config.set_midi_search_path (sp.to_string());
6522 Session::remove_dir_from_search_path (const string& dir, DataType type)
6527 case DataType::AUDIO:
6528 sp = Searchpath(config.get_audio_search_path ());
6530 case DataType::MIDI:
6531 sp = Searchpath (config.get_midi_search_path ());
6538 case DataType::AUDIO:
6539 config.set_audio_search_path (sp.to_string());
6541 case DataType::MIDI:
6542 config.set_midi_search_path (sp.to_string());
6548 boost::shared_ptr<Speakers>
6549 Session::get_speakers()
6555 Session::unknown_processors () const
6559 boost::shared_ptr<RouteList> r = routes.reader ();
6560 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6561 list<string> t = (*i)->unknown_processors ();
6562 copy (t.begin(), t.end(), back_inserter (p));
6572 Session::update_latency (bool playback)
6575 DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
6577 if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress || _route_deletion_in_progress) {
6581 boost::shared_ptr<RouteList> r = routes.reader ();
6582 framecnt_t max_latency = 0;
6585 /* reverse the list so that we work backwards from the last route to run to the first */
6586 RouteList* rl = routes.reader().get();
6587 r.reset (new RouteList (*rl));
6588 reverse (r->begin(), r->end());
6591 /* compute actual latency values for the given direction and store them all in per-port
6592 structures. this will also publish the same values (to JACK) so that computation of latency
6593 for routes can consistently use public latency values.
6596 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6597 max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
6600 /* because we latency compensate playback, our published playback latencies should
6601 be the same for all output ports - all material played back by ardour has
6602 the same latency, whether its caused by plugins or by latency compensation. since
6603 these may differ from the values computed above, reset all playback port latencies
6607 DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
6609 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6610 (*i)->set_public_port_latencies (max_latency, playback);
6615 post_playback_latency ();
6619 post_capture_latency ();
6622 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
6626 Session::post_playback_latency ()
6628 set_worst_playback_latency ();
6630 boost::shared_ptr<RouteList> r = routes.reader ();
6632 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6633 if (!(*i)->is_auditioner() && ((*i)->active())) {
6634 _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
6638 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6639 (*i)->set_latency_compensation (_worst_track_latency);
6644 Session::post_capture_latency ()
6646 set_worst_capture_latency ();
6648 /* reflect any changes in capture latencies into capture offsets
6651 boost::shared_ptr<RouteList> rl = routes.reader();
6652 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
6653 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6655 tr->set_capture_offset ();
6661 Session::initialize_latencies ()
6664 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
6665 update_latency (false);
6666 update_latency (true);
6669 set_worst_io_latencies ();
6673 Session::set_worst_io_latencies ()
6675 set_worst_playback_latency ();
6676 set_worst_capture_latency ();
6680 Session::set_worst_playback_latency ()
6682 if (_state_of_the_state & (InitialConnecting|Deletion)) {
6686 _worst_output_latency = 0;
6688 if (!_engine.connected()) {
6692 boost::shared_ptr<RouteList> r = routes.reader ();
6694 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6695 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
6698 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
6702 Session::set_worst_capture_latency ()
6704 if (_state_of_the_state & (InitialConnecting|Deletion)) {
6708 _worst_input_latency = 0;
6710 if (!_engine.connected()) {
6714 boost::shared_ptr<RouteList> r = routes.reader ();
6716 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6717 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
6720 DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
6724 Session::update_latency_compensation (bool force_whole_graph)
6726 bool some_track_latency_changed = false;
6728 if (_state_of_the_state & (InitialConnecting|Deletion)) {
6732 DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
6734 _worst_track_latency = 0;
6736 boost::shared_ptr<RouteList> r = routes.reader ();
6738 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6739 if (!(*i)->is_auditioner() && ((*i)->active())) {
6741 if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
6742 some_track_latency_changed = true;
6744 _worst_track_latency = max (tl, _worst_track_latency);
6748 DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
6749 (some_track_latency_changed ? "yes" : "no")));
6751 DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
6753 if (some_track_latency_changed || force_whole_graph) {
6754 _engine.update_latencies ();
6758 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6759 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6763 tr->set_capture_offset ();
6768 Session::session_name_is_legal (const string& path)
6770 char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
6772 for (int i = 0; illegal_chars[i]; ++i) {
6773 if (path.find (illegal_chars[i]) != string::npos) {
6774 return illegal_chars[i];
6782 Session::notify_presentation_info_change ()
6784 if (deletion_in_progress()) {
6788 PresentationInfo::Change (); /* EMIT SIGNAL */
6789 reassign_track_numbers();
6791 #ifdef USE_TRACKS_CODE_FEATURES
6792 /* Waves Tracks: for Waves Tracks session it's required to reconnect their IOs
6793 * if track order has been changed by user
6795 reconnect_existing_routes(true, true);
6801 Session::operation_in_progress (GQuark op) const
6803 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
6806 boost::shared_ptr<Port>
6807 Session::ltc_input_port () const
6809 return _ltc_input->nth (0);
6812 boost::shared_ptr<Port>
6813 Session::ltc_output_port () const
6815 return _ltc_output->nth (0);
6819 Session::reconnect_ltc_input ()
6823 string src = Config->get_ltc_source_port();
6825 _ltc_input->disconnect (this);
6827 if (src != _("None") && !src.empty()) {
6828 _ltc_input->nth (0)->connect (src);
6831 if ( ARDOUR::Profile->get_trx () ) {
6832 // Tracks need this signal to update timecode_source_dropdown
6833 MtcOrLtcInputPortChanged (); //emit signal
6839 Session::reconnect_ltc_output ()
6843 string src = Config->get_ltc_output_port();
6845 _ltc_output->disconnect (this);
6847 if (src != _("None") && !src.empty()) {
6848 _ltc_output->nth (0)->connect (src);
6854 Session::set_range_selection (framepos_t start, framepos_t end)
6856 _range_selection = Evoral::Range<framepos_t> (start, end);
6857 #ifdef USE_TRACKS_CODE_FEATURES
6858 follow_playhead_priority ();
6863 Session::set_object_selection (framepos_t start, framepos_t end)
6865 _object_selection = Evoral::Range<framepos_t> (start, end);
6866 #ifdef USE_TRACKS_CODE_FEATURES
6867 follow_playhead_priority ();
6872 Session::clear_range_selection ()
6874 _range_selection = Evoral::Range<framepos_t> (-1,-1);
6875 #ifdef USE_TRACKS_CODE_FEATURES
6876 follow_playhead_priority ();
6881 Session::clear_object_selection ()
6883 _object_selection = Evoral::Range<framepos_t> (-1,-1);
6884 #ifdef USE_TRACKS_CODE_FEATURES
6885 follow_playhead_priority ();
6890 Session::auto_connect_route (boost::shared_ptr<Route> route, bool connect_inputs,
6891 const ChanCount& input_start,
6892 const ChanCount& output_start,
6893 const ChanCount& input_offset,
6894 const ChanCount& output_offset)
6896 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
6897 _auto_connect_queue.push (AutoConnectRequest (route, connect_inputs,
6898 input_start, output_start,
6899 input_offset, output_offset));
6901 auto_connect_thread_wakeup ();
6905 Session::auto_connect_thread_wakeup ()
6907 if (pthread_mutex_trylock (&_auto_connect_mutex) == 0) {
6908 pthread_cond_signal (&_auto_connect_cond);
6909 pthread_mutex_unlock (&_auto_connect_mutex);
6914 Session::queue_latency_recompute ()
6916 g_atomic_int_inc (&_latency_recompute_pending);
6917 auto_connect_thread_wakeup ();
6921 Session::auto_connect (const AutoConnectRequest& ar)
6923 boost::shared_ptr<Route> route = ar.route.lock();
6925 if (!route) { return; }
6927 if (!IO::connecting_legal) {
6931 /* If both inputs and outputs are auto-connected to physical ports,
6932 * use the max of input and output offsets to ensure auto-connected
6933 * port numbers always match up (e.g. the first audio input and the
6934 * first audio output of the route will have the same physical
6935 * port number). Otherwise just use the lowest input or output
6939 const bool in_out_physical =
6940 (Config->get_input_auto_connect() & AutoConnectPhysical)
6941 && (Config->get_output_auto_connect() & AutoConnectPhysical)
6942 && ar.connect_inputs;
6944 const ChanCount in_offset = in_out_physical
6945 ? ChanCount::max(ar.input_offset, ar.output_offset)
6948 const ChanCount out_offset = in_out_physical
6949 ? ChanCount::max(ar.input_offset, ar.output_offset)
6952 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
6953 vector<string> physinputs;
6954 vector<string> physoutputs;
6956 get_physical_ports (physinputs, physoutputs, *t, true);
6958 if (!physinputs.empty() && ar.connect_inputs) {
6959 uint32_t nphysical_in = physinputs.size();
6961 for (uint32_t i = ar.input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
6964 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
6965 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
6968 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
6974 if (!physoutputs.empty()) {
6975 uint32_t nphysical_out = physoutputs.size();
6976 for (uint32_t i = ar.output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
6980 * do not create new connections if we reached the limit of physical outputs
6983 if (!(Config->get_output_auto_connect() & AutoConnectMaster) &&
6984 ARDOUR::Profile->get_trx () &&
6985 ar.output_offset.get(*t) == nphysical_out ) {
6989 if ((*t) == DataType::MIDI && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
6990 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
6991 } else if ((*t) == DataType::AUDIO && (Config->get_output_auto_connect() & AutoConnectMaster)) {
6992 /* master bus is audio only */
6993 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
6994 port = _master_out->input()->ports().port(*t,
6995 i % _master_out->input()->n_ports().get(*t))->name();
6999 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
7008 Session::auto_connect_thread_start ()
7010 if (_ac_thread_active) {
7014 while (!_auto_connect_queue.empty ()) {
7015 _auto_connect_queue.pop ();
7018 _ac_thread_active = true;
7019 if (pthread_create (&_auto_connect_thread, NULL, auto_connect_thread, this)) {
7020 _ac_thread_active = false;
7025 Session::auto_connect_thread_terminate ()
7027 if (!_ac_thread_active) {
7030 _ac_thread_active = false;
7033 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
7034 while (!_auto_connect_queue.empty ()) {
7035 _auto_connect_queue.pop ();
7039 auto_connect_thread_wakeup ();
7042 pthread_join (_auto_connect_thread, &status);
7046 Session::auto_connect_thread (void *arg)
7048 Session *s = static_cast<Session *>(arg);
7049 s->auto_connect_thread_run ();
7055 Session::auto_connect_thread_run ()
7057 pthread_set_name (X_("autoconnect"));
7058 SessionEvent::create_per_thread_pool (X_("autoconnect"), 1024);
7059 PBD::notify_event_loops_about_thread_creation (pthread_self(), X_("autoconnect"), 1024);
7060 pthread_mutex_lock (&_auto_connect_mutex);
7061 while (_ac_thread_active) {
7063 if (!_auto_connect_queue.empty ()) {
7064 // Why would we need the process lock ??
7065 // A: if ports are added while we're connecting, the backend's iterator may be invalidated:
7066 // graph_order_callback() -> resort_routes() -> direct_feeds_according_to_reality () -> backend::connected_to()
7067 // All ardour-internal backends use a std::vector xxxAudioBackend::find_port()
7068 // We have control over those, but what does jack do?
7069 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
7071 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
7072 while (!_auto_connect_queue.empty ()) {
7073 const AutoConnectRequest ar (_auto_connect_queue.front());
7074 _auto_connect_queue.pop ();
7081 if (!actively_recording ()) { // might not be needed,
7082 /* this is only used for updating plugin latencies, the
7083 * graph does not change. so it's safe in general.
7085 * .. update_latency_compensation () entails set_capture_offset()
7086 * which calls Diskstream::set_capture_offset () which
7087 * modifies the capture offset... which can be a proplem
7088 * in "prepare_to_stop"
7090 while (g_atomic_int_and (&_latency_recompute_pending, 0)) {
7091 update_latency_compensation ();
7095 AudioEngine::instance()->clear_pending_port_deletions ();
7097 pthread_cond_wait (&_auto_connect_cond, &_auto_connect_mutex);
7099 pthread_mutex_unlock (&_auto_connect_mutex);
7103 Session::cancel_all_solo ()
7107 get_stripables (sl);
7109 set_controls (stripable_list_to_control_list (sl, &Stripable::solo_control), 0.0, Controllable::NoGroup);
7110 clear_all_solo_state (routes.reader());