1 /*
2 * Copyright (C) 1999-2019 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2006-2007 Jesse Chappell <jesse@essej.net>
4 * Copyright (C) 2006-2009 Sampo Savolainen <v2@iki.fi>
5 * Copyright (C) 2006-2015 David Robillard <d@drobilla.net>
6 * Copyright (C) 2006-2016 Tim Mayberry <mojofunk@gmail.com>
7 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
8 * Copyright (C) 2008-2009 Hans Baier <hansfbaier@googlemail.com>
9 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
10 * Copyright (C) 2013-2017 Nick Mainsbridge <mainsbridge@gmail.com>
11 * Copyright (C) 2014-2019 Ben Loftis <ben@harrisonconsoles.com>
12 * Copyright (C) 2015 GZharun <grygoriiz@wavesglobal.com>
13 * Copyright (C) 2016-2018 Len Ovens <len@ovenwerks.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 */
29
30 #include <stdint.h>
31
32 #include <algorithm>
33 #include <string>
34 #include <vector>
35 #include <sstream>
36 #include <cstdio> /* sprintf(3) ... grrr */
37 #include <cmath>
38 #include <cerrno>
39 #include <unistd.h>
40 #include <limits.h>
41
42 #include <glibmm/datetime.h>
43 #include <glibmm/threads.h>
44 #include <glibmm/miscutils.h>
45 #include <glibmm/fileutils.h>
46
47 #include <boost/algorithm/string/erase.hpp>
48
49 #include "pbd/basename.h"
50 #include "pbd/convert.h"
51 #include "pbd/error.h"
52 #include "pbd/file_utils.h"
53 #include "pbd/md5.h"
54 #include "pbd/pthread_utils.h"
55 #include "pbd/search_path.h"
56 #include "pbd/stl_delete.h"
57 #include "pbd/replace_all.h"
58 #include "pbd/types_convert.h"
59 #include "pbd/unwind.h"
60
61 #include "ardour/amp.h"
62 #include "ardour/analyser.h"
63 #include "ardour/async_midi_port.h"
64 #include "ardour/audio_buffer.h"
65 #include "ardour/audio_port.h"
66 #include "ardour/audio_track.h"
67 #include "ardour/audioengine.h"
68 #include "ardour/audiofilesource.h"
69 #include "ardour/auditioner.h"
70 #include "ardour/boost_debug.h"
71 #include "ardour/buffer_manager.h"
72 #include "ardour/buffer_set.h"
73 #include "ardour/bundle.h"
74 #include "ardour/butler.h"
75 #include "ardour/click.h"
76 #include "ardour/control_protocol_manager.h"
77 #include "ardour/data_type.h"
78 #include "ardour/debug.h"
79 #include "ardour/disk_reader.h"
80 #include "ardour/directory_names.h"
81 #include "ardour/filename_extensions.h"
82 #include "ardour/gain_control.h"
83 #include "ardour/graph.h"
84 #include "ardour/luabindings.h"
85 #include "ardour/midiport_manager.h"
86 #include "ardour/scene_changer.h"
87 #include "ardour/midi_patch_manager.h"
88 #include "ardour/midi_track.h"
89 #include "ardour/midi_ui.h"
90 #include "ardour/operations.h"
91 #include "ardour/playlist.h"
92 #include "ardour/playlist_factory.h"
93 #include "ardour/plugin.h"
94 #include "ardour/plugin_insert.h"
95 #include "ardour/presentation_info.h"
96 #include "ardour/process_thread.h"
97 #include "ardour/profile.h"
98 #include "ardour/rc_configuration.h"
99 #include "ardour/recent_sessions.h"
100 #include "ardour/region.h"
101 #include "ardour/region_factory.h"
102 #include "ardour/revision.h"
103 #include "ardour/route_graph.h"
104 #include "ardour/route_group.h"
105 #include "ardour/rt_tasklist.h"
106 #include "ardour/silentfilesource.h"
107 #include "ardour/send.h"
108 #include "ardour/selection.h"
109 #include "ardour/session.h"
110 #include "ardour/session_directory.h"
111 #include "ardour/session_playlists.h"
112 #include "ardour/session_route.h"
113 #include "ardour/smf_source.h"
114 #include "ardour/solo_isolate_control.h"
115 #include "ardour/source_factory.h"
116 #include "ardour/speakers.h"
117 #include "ardour/tempo.h"
118 #include "ardour/ticker.h"
119 #include "ardour/transport_fsm.h"
120 #include "ardour/transport_master.h"
121 #include "ardour/transport_master_manager.h"
122 #include "ardour/track.h"
123 #include "ardour/types_convert.h"
124 #include "ardour/user_bundle.h"
125 #include "ardour/utils.h"
126 #include "ardour/vca_manager.h"
127 #include "ardour/vca.h"
128
129 #include "midi++/port.h"
130 #include "midi++/mmc.h"
131
132 #include "LuaBridge/LuaBridge.h"
133
134 #include <glibmm/checksum.h>
135
136 #include "pbd/i18n.h"
137
138 namespace ARDOUR {
139 class MidiSource;
140 class Processor;
141 class Speakers;
142 }
143
144 using namespace std;
145 using namespace ARDOUR;
146 using namespace PBD;
147
148 bool Session::_disable_all_loaded_plugins = false;
149 bool Session::_bypass_all_loaded_plugins = false;
150 guint Session::_name_id_counter = 0;
151
152 PBD::Signal1<void,std::string> Session::Dialog;
153 PBD::Signal0<int> Session::AskAboutPendingState;
154 PBD::Signal2<int, samplecnt_t, samplecnt_t> Session::AskAboutSampleRateMismatch;
155 PBD::Signal2<void, samplecnt_t, samplecnt_t> Session::NotifyAboutSampleRateMismatch;
156 PBD::Signal0<void> Session::SendFeedback;
157 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
158
159 PBD::Signal1<void, samplepos_t> Session::StartTimeChanged;
160 PBD::Signal1<void, samplepos_t> Session::EndTimeChanged;
161 PBD::Signal2<void,std::string, std::string> Session::Exported;
162 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
163 PBD::Signal0<void> Session::Quit;
164 PBD::Signal0<void> Session::FeedbackDetected;
165 PBD::Signal0<void> Session::SuccessfulGraphSort;
166 PBD::Signal2<void,std::string,std::string> Session::VersionMismatch;
167
168 const samplecnt_t Session::bounce_chunk_size = 8192;
clean_up_session_event(SessionEvent * ev)169 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
170 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
171 const uint32_t Session::session_end_shift = 0;
172
173 /** @param snapshot_name Snapshot name, without .ardour suffix */
Session(AudioEngine & eng,const string & fullpath,const string & snapshot_name,BusProfile const * bus_profile,string mix_template,bool unnamed)174 Session::Session (AudioEngine &eng,
175 const string& fullpath,
176 const string& snapshot_name,
177 BusProfile const * bus_profile,
178 string mix_template,
179 bool unnamed)
180 : _playlists (new SessionPlaylists)
181 , _engine (eng)
182 , process_function (&Session::process_with_events)
183 , _bounce_processing_active (false)
184 , waiting_for_sync_offset (false)
185 , _base_sample_rate (0)
186 , _nominal_sample_rate (0)
187 , _current_sample_rate (0)
188 , _transport_sample (0)
189 , _session_range_location (0)
190 , _session_range_is_free (true)
191 , _silent (false)
192 , _remaining_latency_preroll (0)
193 , _engine_speed (1.0)
194 , _last_transport_speed (1.0)
195 , _requested_transport_speed (std::numeric_limits<double>::max())
196 , _signalled_varispeed (0)
197 , auto_play_legal (false)
198 , _requested_return_sample (-1)
199 , current_block_size (0)
200 , _worst_output_latency (0)
201 , _worst_input_latency (0)
202 , _worst_route_latency (0)
203 , _send_latency_changes (0)
204 , _have_captured (false)
205 , _capture_duration (0)
206 , _capture_xruns (0)
207 , _export_xruns (0)
208 , _non_soloed_outs_muted (false)
209 , _listening (false)
210 , _listen_cnt (0)
211 , _solo_isolated_cnt (0)
212 , _writable (false)
213 , _under_nsm_control (false)
214 , _xrun_count (0)
215 , master_wait_end (0)
216 , post_export_sync (false)
217 , post_export_position (0)
218 , _exporting (false)
219 , _export_rolling (false)
220 , _realtime_export (false)
221 , _region_export (false)
222 , _export_preroll (0)
223 , _pre_export_mmc_enabled (false)
224 , _name (snapshot_name)
225 , _is_new (true)
226 , _send_qf_mtc (false)
227 , _pframes_since_last_mtc (0)
228 , play_loop (false)
229 , loop_changing (false)
230 , last_loopend (0)
231 , _session_dir (new SessionDirectory (fullpath))
232 , _current_snapshot_name (snapshot_name)
233 , state_tree (0)
234 , state_was_pending (false)
235 , _state_of_the_state (StateOfTheState (CannotSave | InitialConnecting | Loading))
236 , _save_queued (false)
237 , _save_queued_pending (false)
238 , _last_roll_location (0)
239 , _last_roll_or_reversal_location (0)
240 , _last_record_location (0)
241 , pending_auto_loop (false)
242 , _mempool ("Session", 3145728)
243 , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
244 , _n_lua_scripts (0)
245 , _butler (new Butler (*this))
246 , _transport_fsm (new TransportFSM (*this))
247 , _locations (new Locations (*this))
248 , _ignore_skips_updates (false)
249 , _rt_thread_active (false)
250 , _rt_emit_pending (false)
251 , _ac_thread_active (0)
252 , step_speed (0)
253 , outbound_mtc_timecode_frame (0)
254 , next_quarter_frame_to_send (-1)
255 , _samples_per_timecode_frame (0)
256 , _frames_per_hour (0)
257 , _timecode_frames_per_hour (0)
258 , last_timecode_valid (false)
259 , last_timecode_when (0)
260 , _send_timecode_update (false)
261 , ltc_encoder (0)
262 , ltc_enc_buf(0)
263 , ltc_buf_off (0)
264 , ltc_buf_len (0)
265 , ltc_speed (0)
266 , ltc_enc_byte (0)
267 , ltc_enc_pos (0)
268 , ltc_enc_cnt (0)
269 , ltc_enc_off (0)
270 , restarting (false)
271 , ltc_prev_cycle (0)
272 , ltc_timecode_offset (0)
273 , ltc_timecode_negative_offset (false)
274 , midi_control_ui (0)
275 , _tempo_map (0)
276 , _all_route_group (new RouteGroup (*this, "all"))
277 , routes (new RouteList)
278 , _adding_routes_in_progress (false)
279 , _reconnecting_routes_in_progress (false)
280 , _route_deletion_in_progress (false)
281 , _track_number_decimals(1)
282 , default_fade_steepness (0)
283 , default_fade_msecs (0)
284 , _total_free_4k_blocks (0)
285 , _total_free_4k_blocks_uncertain (false)
286 , no_questions_about_missing_files (false)
287 , _bundles (new BundleList)
288 , _bundle_xml_node (0)
289 , _current_trans (0)
290 , _clicking (false)
291 , _click_rec_only (false)
292 , click_data (0)
293 , click_emphasis_data (0)
294 , click_length (0)
295 , click_emphasis_length (0)
296 , _clicks_cleared (0)
297 , _count_in_samples (0)
298 , _play_range (false)
299 , _range_selection (-1,-1)
300 , _object_selection (-1,-1)
301 , _preroll_record_trim_len (0)
302 , _count_in_once (false)
303 , main_outs (0)
304 , first_file_data_format_reset (true)
305 , first_file_header_format_reset (true)
306 , have_looped (false)
307 , _step_editors (0)
308 , _speakers (new Speakers)
309 , _ignore_route_processor_changes (0)
310 , _ignored_a_processor_change (0)
311 , midi_clock (0)
312 , _scene_changer (0)
313 , _midi_ports (0)
314 , _mmc (0)
315 , _vca_manager (new VCAManager (*this))
316 , _selection (new CoreSelection (*this))
317 , _global_locate_pending (false)
318 , _had_destructive_tracks (false)
319 {
320 g_atomic_int_set (&_suspend_save, 0);
321 g_atomic_int_set (&_playback_load, 0);
322 g_atomic_int_set (&_capture_load, 0);
323 g_atomic_int_set (&_post_transport_work, 0);
324 g_atomic_int_set (&_processing_prohibited, Disabled);
325 g_atomic_int_set (&_record_status, Disabled);
326 g_atomic_int_set (&_punch_or_loop, NoConstraint);
327 g_atomic_int_set (&_current_usecs_per_track, 1000);
328 g_atomic_int_set (&_have_rec_enabled_track, 0);
329 g_atomic_int_set (&_have_rec_disabled_track, 1);
330 g_atomic_int_set (&_latency_recompute_pending, 0);
331 g_atomic_int_set (&_suspend_timecode_transmission, 0);
332 g_atomic_int_set (&_update_pretty_names, 0);
333 g_atomic_int_set (&_seek_counter, 0);
334 g_atomic_int_set (&_butler_seek_counter, 0);
335
336 created_with = string_compose ("%1 %2", PROGRAM_NAME, revision);
337
338 pthread_mutex_init (&_rt_emit_mutex, 0);
339 pthread_cond_init (&_rt_emit_cond, 0);
340
341 pthread_mutex_init (&_auto_connect_mutex, 0);
342 pthread_cond_init (&_auto_connect_cond, 0);
343
344 init_name_id_counter (1); // reset for new sessions, start at 1
345 VCA::set_next_vca_number (1); // reset for new sessions, start at 1
346
347 pre_engine_init (fullpath); // sets _is_new
348
349 setup_lua ();
350
351 assert (AudioEngine::instance()->running());
352 immediately_post_engine ();
353
354 bool need_template_resave = false;
355 std::string template_description;
356
357 if (_is_new) {
358
359 Stateful::loading_state_version = CURRENT_SESSION_FILE_VERSION;
360
361 if (create (mix_template, bus_profile, unnamed)) {
362 destroy ();
363 throw SessionException (_("Session initialization failed"));
364 }
365
366 /* if a mix template was provided, then ::create() will
367 * have copied it into the session and we need to load it
368 * so that we have the state ready for ::set_state()
369 * after the engine is started.
370 *
371 * Note that we do NOT try to get the sample rate from
372 * the template at this time, though doing so would
373 * be easy if we decided this was an appropriate part
374 * of a template.
375 */
376
377 if (!mix_template.empty()) {
378 try {
379 if (load_state (_current_snapshot_name, /* from_template = */ true)) {
380 throw SessionException (_("Failed to load template/snapshot state"));
381 }
382 } catch (PBD::unknown_enumeration& e) {
383 throw SessionException (_("Failed to parse template/snapshot state"));
384 }
385
386 if (state_tree && Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
387 need_template_resave = true;
388 XMLNode const & root (*state_tree->root());
389 XMLNode* desc_nd = root.child (X_("description"));
390 if (desc_nd) {
391 template_description = desc_nd->attribute_value();
392 }
393 }
394 store_recent_templates (mix_template);
395 }
396
397 /* load default session properties - if any */
398 config.load_state();
399
400 } else {
401
402 if (load_state (_current_snapshot_name)) {
403 throw SessionException (_("Failed to load state"));
404 }
405 }
406
407 /* apply the loaded state_tree */
408 int err = post_engine_init ();
409
410 if (err) {
411 destroy ();
412 switch (err) {
413 case -1:
414 throw SessionException (string_compose (_("Cannot initialize session/engine: %1"), _("Failed to create background threads.")));
415 break;
416 case -2:
417 case -3:
418 throw SessionException (string_compose (_("Cannot initialize session/engine: %1"), _("Invalid TempoMap in session-file.")));
419 break;
420 case -4:
421 throw SessionException (string_compose (_("Cannot initialize session/engine: %1"), _("Invalid or corrupt session state.")));
422 break;
423 case -5:
424 throw SessionException (string_compose (_("Cannot initialize session/engine: %1"), _("Port registration failed.")));
425 break;
426 default:
427 throw SessionException (string_compose (_("Cannot initialize session/engine: %1"), _("Unexpected exception during session setup, possibly invalid audio/midi engine parameters. Please see stdout/stderr for details")));
428 break;
429 }
430 }
431
432 if (!mix_template.empty()) {
433 /* fixup monitor-sends */
434 if (Config->get_use_monitor_bus ()) {
435 /* Session::config_changed will have set use-monitor-bus to match the template.
436 * search for want_ms, have_ms
437 */
438 assert (_monitor_out);
439 /* ..but sends do not exist, since templated track bitslots are unset */
440 setup_route_monitor_sends (true, true);
441 } else {
442 /* remove any monitor-sends that may be in the template */
443 assert (!_monitor_out);
444 setup_route_monitor_sends (false, true);
445 }
446 }
447
448 if (!unnamed) {
449 store_recent_sessions (_name, _path);
450 }
451
452 bool was_dirty = dirty();
453 unset_dirty ();
454
455 PresentationInfo::Change.connect_same_thread (*this, boost::bind (&Session::notify_presentation_info_change, this));
456
457 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
458 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
459
460 if (was_dirty) {
461 DirtyChanged (); /* EMIT SIGNAL */
462 }
463
464 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
465 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
466
467 LatentSend::ChangedLatency.connect_same_thread (*this, boost::bind (&Session::send_latency_compensation_change, this));
468 Latent::DisableSwitchChanged.connect_same_thread (*this, boost::bind (&Session::queue_latency_recompute, this));
469
470 Controllable::ControlTouched.connect_same_thread (*this, boost::bind (&Session::controllable_touched, this, _1));
471
472 emit_thread_start ();
473 auto_connect_thread_start ();
474
475 /* hook us up to the engine since we are now completely constructed */
476
477 BootMessage (_("Connect to engine"));
478
479 _engine.set_session (this);
480 _engine.reset_timebase ();
481
482 ensure_subdirs (); // archived or zipped sessions may lack peaks/ analysis/ etc
483
484 if (!mix_template.empty ()) {
485 /* ::create() unsets _is_new after creating the session.
486 * But for templated sessions, the sample-rate is initially unset
487 * (not read from template), so we need to save it (again).
488 */
489 _is_new = true;
490 }
491
492 session_loaded ();
493 _is_new = false;
494
495 if (need_template_resave) {
496 save_template (mix_template, template_description, true);
497 }
498
499 BootMessage (_("Session loading complete"));
500 }
501
~Session()502 Session::~Session ()
503 {
504 #ifdef PT_TIMING
505 ST.dump ("ST.dump");
506 #endif
507 destroy ();
508 }
509
510 unsigned int
next_name_id()511 Session::next_name_id ()
512 {
513 return g_atomic_int_add (&_name_id_counter, 1);
514 }
515
516 unsigned int
name_id_counter()517 Session::name_id_counter ()
518 {
519 return g_atomic_int_get (&_name_id_counter);
520 }
521
522 void
init_name_id_counter(guint n)523 Session::init_name_id_counter (guint n)
524 {
525 g_atomic_int_set (&_name_id_counter, n);
526 }
527
528 int
immediately_post_engine()529 Session::immediately_post_engine ()
530 {
531 /* Do various initializations that should take place directly after we
532 * know that the engine is running, but before we either create a
533 * session or set state for an existing one.
534 */
535
536 _rt_tasklist.reset (new RTTaskList ());
537
538 if (how_many_dsp_threads () > 1) {
539 /* For now, only create the graph if we are using >1 DSP threads, as
540 it is a bit slower than the old code with 1 thread.
541 */
542 _process_graph.reset (new Graph (*this));
543 }
544
545 /* every time we reconnect, recompute worst case output latencies */
546
547 _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
548
549 /* Restart transport FSM */
550
551 _transport_fsm->start ();
552
553 /* every time we reconnect, do stuff ... */
554
555 _engine.Running.connect_same_thread (*this, boost::bind (&Session::engine_running, this));
556
557 try {
558 BootMessage (_("Set up LTC"));
559 setup_ltc ();
560 BootMessage (_("Set up Click"));
561 setup_click ();
562 BootMessage (_("Set up standard connections"));
563 setup_bundles ();
564 }
565
566 catch (failed_constructor& err) {
567 return -1;
568 }
569
570 /* TODO, connect in different thread. (PortRegisteredOrUnregistered may be in RT context)
571 * can we do that? */
572 _engine.PortRegisteredOrUnregistered.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
573 _engine.PortPrettyNameChanged.connect_same_thread (*this, boost::bind (&Session::setup_bundles, this));
574
575 // set samplerate for plugins added early
576 // e.g from templates or MB channelstrip
577 set_block_size (_engine.samples_per_cycle());
578 set_sample_rate (_engine.sample_rate());
579
580 return 0;
581 }
582
583 void
destroy()584 Session::destroy ()
585 {
586 vector<void*> debug_pointers;
587
588 /* if we got to here, leaving pending capture state around
589 is a mistake.
590 */
591
592 remove_pending_capture_state ();
593
594 Analyser::flush ();
595
596 _state_of_the_state = StateOfTheState (CannotSave | Deletion);
597
598 {
599 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
600 ltc_tx_cleanup();
601 if (_ltc_output_port) {
602 AudioEngine::instance()->unregister_port (_ltc_output_port);
603 }
604 }
605
606 /* disconnect from any and all signals that we are connected to */
607
608 Port::PortSignalDrop (); /* EMIT SIGNAL */
609 drop_connections ();
610
611 /* shutdown control surface protocols while we still have ports
612 * and the engine to move data to any devices.
613 */
614 ControlProtocolManager::instance().drop_protocols ();
615
616 /* stop auto dis/connecting */
617 auto_connect_thread_terminate ();
618
619 _engine.remove_session ();
620
621 /* deregister all ports - there will be no process or any other
622 * callbacks from the engine any more.
623 */
624
625 Port::PortDrop (); /* EMIT SIGNAL */
626
627 /* remove I/O objects that we (the session) own */
628 _click_io.reset ();
629 _click_io_connection.disconnect ();
630
631 {
632 Glib::Threads::Mutex::Lock lm (controllables_lock);
633 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
634 (*i)->DropReferences (); /* EMIT SIGNAL */
635 }
636 controllables.clear ();
637 }
638
639 /* clear history so that no references to objects are held any more */
640
641 _history.clear ();
642
643 /* clear state tree so that no references to objects are held any more */
644
645 delete state_tree;
646 state_tree = 0;
647
648 {
649 /* unregister all lua functions, drop held references (if any) */
650 Glib::Threads::Mutex::Lock tm (lua_lock, Glib::Threads::TRY_LOCK);
651 (*_lua_cleanup)();
652 lua.do_command ("Session = nil");
653 delete _lua_run;
654 delete _lua_add;
655 delete _lua_del;
656 delete _lua_list;
657 delete _lua_save;
658 delete _lua_load;
659 delete _lua_cleanup;
660 lua.collect_garbage ();
661 }
662
663 /* reset dynamic state version back to default */
664 Stateful::loading_state_version = 0;
665
666 _butler->drop_references ();
667 delete _butler;
668 _butler = 0;
669
670 delete _all_route_group;
671
672 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
673 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
674 delete *i;
675 }
676
677 if (click_data != default_click) {
678 delete [] click_data;
679 }
680
681 if (click_emphasis_data != default_click_emphasis) {
682 delete [] click_emphasis_data;
683 }
684
685 clear_clicks ();
686
687 /* need to remove auditioner before monitoring section
688 * otherwise it is re-connected.
689 * Note: If a session was never successfully loaded, there
690 * may not yet be an auditioner.
691 */
692 if (auditioner) {
693 auditioner->drop_references ();
694 }
695 auditioner.reset ();
696
697 /* drop references to routes held by the monitoring section
698 * specifically _monitor_out aux/listen references */
699 remove_monitor_section();
700
701 /* clear out any pending dead wood from RCU managed objects */
702
703 routes.flush ();
704 _bundles.flush ();
705
706 DiskReader::free_working_buffers();
707
708 /* tell everyone who is still standing that we're about to die */
709 drop_references ();
710
711 /* tell everyone to drop references and delete objects as we go */
712
713 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
714 RegionFactory::delete_all_regions ();
715
716 /* Do this early so that VCAs no longer hold references to routes */
717
718 DEBUG_TRACE (DEBUG::Destruction, "delete vcas\n");
719 delete _vca_manager;
720
721 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
722
723 /* reset these three references to special routes before we do the usual route delete thing */
724
725 _master_out.reset ();
726 _monitor_out.reset ();
727
728 {
729 RCUWriter<RouteList> writer (routes);
730 boost::shared_ptr<RouteList> r = writer.get_copy ();
731
732 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
733 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
734 (*i)->drop_references ();
735 }
736
737 r->clear ();
738 /* writer goes out of scope and updates master */
739 }
740 routes.flush ();
741
742 {
743 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
744 Glib::Threads::Mutex::Lock lm (source_lock);
745 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
746 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
747 i->second->drop_references ();
748 }
749
750 sources.clear ();
751 }
752
753 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
754 _playlists.reset ();
755
756 emit_thread_terminate ();
757
758 pthread_cond_destroy (&_rt_emit_cond);
759 pthread_mutex_destroy (&_rt_emit_mutex);
760
761 pthread_cond_destroy (&_auto_connect_cond);
762 pthread_mutex_destroy (&_auto_connect_mutex);
763
764 delete _scene_changer; _scene_changer = 0;
765 delete midi_control_ui; midi_control_ui = 0;
766
767 delete _mmc; _mmc = 0;
768 delete _midi_ports; _midi_ports = 0;
769 delete _locations; _locations = 0;
770
771 delete midi_clock;
772 delete _tempo_map;
773
774 /* clear event queue, the session is gone, nobody is interested in
775 * those anymore, but they do leak memory if not removed
776 */
777 while (!immediate_events.empty ()) {
778 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
779 SessionEvent *ev = immediate_events.front ();
780 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Drop event: %1\n", enum_2_string (ev->type)));
781 immediate_events.pop_front ();
782 bool remove = true;
783 bool del = true;
784 switch (ev->type) {
785 case SessionEvent::AutoLoop:
786 case SessionEvent::Skip:
787 case SessionEvent::PunchIn:
788 case SessionEvent::PunchOut:
789 case SessionEvent::RangeStop:
790 case SessionEvent::RangeLocate:
791 remove = false;
792 del = false;
793 break;
794 case SessionEvent::RealTimeOperation:
795 process_rtop (ev);
796 del = false;
797 default:
798 break;
799 }
800 if (remove) {
801 del = del && !_remove_event (ev);
802 }
803 if (del) {
804 delete ev;
805 }
806 }
807
808 {
809 /* unregister all dropped ports, process pending port deletion. */
810 // this may call ARDOUR::Port::drop ... jack_port_unregister ()
811 // jack1 cannot cope with removing ports while processing
812 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
813 AudioEngine::instance()->clear_pending_port_deletions ();
814 }
815
816 DEBUG_TRACE (DEBUG::Destruction, "delete selection\n");
817 delete _selection;
818 _selection = 0;
819
820 _transport_fsm->stop ();
821
822 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
823
824 #ifndef NDEBUG
825 Controllable::dump_registry ();
826 #endif
827
828 BOOST_SHOW_POINTERS ();
829 }
830
831 void
setup_ltc()832 Session::setup_ltc ()
833 {
834 _ltc_output_port = AudioEngine::instance()->register_output_port (DataType::AUDIO, X_("LTC-Out"), false, TransportGenerator);
835
836 {
837 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
838 /* TODO use auto-connect thread */
839 reconnect_ltc_output ();
840 }
841 }
842
843 void
setup_click()844 Session::setup_click ()
845 {
846 _clicking = false;
847
848 boost::shared_ptr<AutomationList> gl (new AutomationList (Evoral::Parameter (GainAutomation)));
849 boost::shared_ptr<GainControl> gain_control = boost::shared_ptr<GainControl> (new GainControl (*this, Evoral::Parameter(GainAutomation), gl));
850
851 _click_io.reset (new ClickIO (*this, X_("Click")));
852 _click_gain.reset (new Amp (*this, _("Fader"), gain_control, true));
853 _click_gain->activate ();
854 if (state_tree) {
855 setup_click_state (state_tree->root());
856 } else {
857 setup_click_state (0);
858 }
859 click_io_resync_latency (true);
860 LatencyUpdated.connect_same_thread (_click_io_connection, boost::bind (&Session::click_io_resync_latency, this, _1));
861 }
862
863 void
setup_click_state(const XMLNode * node)864 Session::setup_click_state (const XMLNode* node)
865 {
866 const XMLNode* child = 0;
867
868 if (node && (child = find_named_node (*node, "Click")) != 0) {
869
870 /* existing state for Click */
871 int c = 0;
872
873 if (Stateful::loading_state_version < 3000) {
874 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
875 } else {
876 const XMLNodeList& children (child->children());
877 XMLNodeList::const_iterator i = children.begin();
878 if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
879 ++i;
880 if (i != children.end()) {
881 c = _click_gain->set_state (**i, Stateful::loading_state_version);
882 }
883 }
884 }
885
886 if (c == 0) {
887 _clicking = Config->get_clicking ();
888
889 } else {
890
891 error << _("could not setup Click I/O") << endmsg;
892 _clicking = false;
893 }
894
895
896 } else {
897
898 /* default state for Click: dual-mono to first 2 physical outputs */
899
900 vector<string> outs;
901 _engine.get_physical_outputs (DataType::AUDIO, outs);
902
903 for (uint32_t physport = 0; physport < 2; ++physport) {
904 if (outs.size() > physport) {
905 if (_click_io->add_port (outs[physport], this)) {
906 // relax, even though its an error
907 }
908 }
909 }
910
911 if (_click_io->n_ports () > ChanCount::ZERO) {
912 _clicking = Config->get_clicking ();
913 }
914 }
915 }
916
917 void
get_physical_ports(vector<string> & inputs,vector<string> & outputs,DataType type,MidiPortFlags include,MidiPortFlags exclude)918 Session::get_physical_ports (vector<string>& inputs, vector<string>& outputs, DataType type,
919 MidiPortFlags include, MidiPortFlags exclude)
920 {
921 _engine.get_physical_inputs (type, inputs, include, exclude);
922 _engine.get_physical_outputs (type, outputs, include, exclude);
923 }
924
925
926 void
auto_connect_master_bus()927 Session::auto_connect_master_bus ()
928 {
929 if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
930 return;
931 }
932
933 /* if requested auto-connect the outputs to the first N physical ports.
934 */
935
936 uint32_t limit = _master_out->n_outputs().n_total();
937 vector<string> outputs[DataType::num_types];
938
939 for (uint32_t i = 0; i < DataType::num_types; ++i) {
940 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
941 }
942
943 for (uint32_t n = 0; n < limit; ++n) {
944 boost::shared_ptr<Port> p = _master_out->output()->nth (n);
945 string connect_to;
946 if (outputs[p->type()].size() > n) {
947 connect_to = outputs[p->type()][n];
948 }
949
950 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
951 if (_master_out->output()->connect (p, connect_to, this)) {
952 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
953 << endmsg;
954 break;
955 }
956 }
957 }
958 }
959
960 boost::shared_ptr<GainControl>
master_volume() const961 Session::master_volume () const
962 {
963 if (_master_out) {
964 return _master_out->volume_control ();
965 }
966 return boost::shared_ptr<GainControl> ();
967 }
968
969 void
remove_monitor_section()970 Session::remove_monitor_section ()
971 {
972 if (!_monitor_out) {
973 return;
974 }
975
976 /* allow deletion when session is unloaded */
977 if (!_engine.running() && !deletion_in_progress ()) {
978 error << _("Cannot remove monitor section while the engine is offline.") << endmsg;
979 return;
980 }
981
982 /* force reversion to Solo-In-Place */
983 Config->set_solo_control_is_listen_control (false);
984
985 /* if we are auditioning, cancel it ... this is a workaround
986 to a problem (auditioning does not execute the process graph,
987 which is needed to remove routes when using >1 core for processing)
988 */
989 cancel_audition ();
990
991 if (!deletion_in_progress ()) {
992 setup_route_monitor_sends (false, true);
993 _engine.monitor_port().clear_ports (true);
994 }
995
996 remove_route (_monitor_out);
997 if (deletion_in_progress ()) {
998 return;
999 }
1000
1001 auto_connect_master_bus ();
1002
1003 if (auditioner) {
1004 auditioner->connect ();
1005 }
1006
1007 MonitorBusAddedOrRemoved (); /* EMIT SIGNAL */
1008 }
1009
1010 void
add_monitor_section()1011 Session::add_monitor_section ()
1012 {
1013 RouteList rl;
1014
1015 if (!_engine.running()) {
1016 error << _("Cannot create monitor section while the engine is offline.") << endmsg;
1017 return;
1018 }
1019
1020 if (_monitor_out || !_master_out) {
1021 return;
1022 }
1023
1024 boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), PresentationInfo::MonitorOut, DataType::AUDIO));
1025
1026 if (r->init ()) {
1027 return;
1028 }
1029
1030 BOOST_MARK_ROUTE(r);
1031
1032 try {
1033 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1034 r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
1035 r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
1036 } catch (...) {
1037 error << _("Cannot create monitor section. 'Monitor' Port name is not unique.") << endmsg;
1038 return;
1039 }
1040
1041 rl.push_back (r);
1042 add_routes (rl, false, false, 0);
1043
1044 assert (_monitor_out);
1045
1046 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
1047 are undefined, at best.
1048 */
1049
1050 uint32_t limit = _monitor_out->n_inputs().n_audio();
1051
1052 if (_master_out) {
1053
1054 /* connect the inputs to the master bus outputs. this
1055 * represents a separate data feed from the internal sends from
1056 * each route. as of jan 2011, it allows the monitor section to
1057 * conditionally ignore either the internal sends or the normal
1058 * input feed, but we should really find a better way to do
1059 * this, i think.
1060 */
1061
1062 _master_out->output()->disconnect (this);
1063
1064 for (uint32_t n = 0; n < limit; ++n) {
1065 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1066 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1067
1068 if (o) {
1069 string connect_to = o->name();
1070 if (_monitor_out->input()->connect (p, connect_to, this)) {
1071 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1072 << endmsg;
1073 break;
1074 }
1075 }
1076 }
1077 }
1078
1079 /* if monitor section is not connected, connect it to physical outs */
1080
1081 if ((Config->get_auto_connect_standard_busses () || Profile->get_mixbus ()) && !_monitor_out->output()->connected ()) {
1082
1083 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1084
1085 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1086
1087 if (b) {
1088 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1089 } else {
1090 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1091 Config->get_monitor_bus_preferred_bundle())
1092 << endmsg;
1093 }
1094
1095 } else {
1096
1097 /* Monitor bus is audio only */
1098
1099 vector<string> outputs[DataType::num_types];
1100
1101 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1102 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1103 }
1104
1105 uint32_t mod = outputs[DataType::AUDIO].size();
1106 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1107
1108 if (mod != 0) {
1109
1110 for (uint32_t n = 0; n < limit; ++n) {
1111
1112 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1113 string connect_to;
1114 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1115 connect_to = outputs[DataType::AUDIO][n % mod];
1116 }
1117
1118 if (!connect_to.empty()) {
1119 if (_monitor_out->output()->connect (p, connect_to, this)) {
1120 error << string_compose (
1121 _("cannot connect control output %1 to %2"),
1122 n, connect_to)
1123 << endmsg;
1124 break;
1125 }
1126 }
1127 }
1128 }
1129 }
1130 }
1131
1132 /* Hold process lock while doing this so that we don't hear bits and
1133 * pieces of audio as we work on each route.
1134 */
1135
1136 setup_route_monitor_sends (true, true);
1137
1138 MonitorBusAddedOrRemoved (); /* EMIT SIGNAL */
1139 }
1140
1141 void
setup_route_monitor_sends(bool enable,bool need_process_lock)1142 Session::setup_route_monitor_sends (bool enable, bool need_process_lock)
1143 {
1144 Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
1145 if (need_process_lock) {
1146 /* Hold process lock while doing this so that we don't hear bits and
1147 * pieces of audio as we work on each route.
1148 */
1149 lx.acquire();
1150 }
1151
1152 boost::shared_ptr<RouteList> rls = routes.reader ();
1153 ProcessorChangeBlocker pcb (this, false /* XXX */);
1154
1155 for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
1156 if ((*x)->can_monitor ()) {
1157 if (enable) {
1158 (*x)->enable_monitor_send ();
1159 } else {
1160 (*x)->remove_monitor_send ();
1161 }
1162 }
1163 }
1164
1165 if (auditioner) {
1166 auditioner->connect ();
1167 }
1168 }
1169
1170
1171 void
reset_monitor_section()1172 Session::reset_monitor_section ()
1173 {
1174 /* Process lock should be held by the caller.*/
1175
1176 if (!_monitor_out) {
1177 return;
1178 }
1179
1180 uint32_t limit = _master_out->n_outputs().n_audio();
1181
1182 /* connect the inputs to the master bus outputs. this
1183 * represents a separate data feed from the internal sends from
1184 * each route. as of jan 2011, it allows the monitor section to
1185 * conditionally ignore either the internal sends or the normal
1186 * input feed, but we should really find a better way to do
1187 * this, i think.
1188 */
1189
1190 _master_out->output()->disconnect (this);
1191 _monitor_out->output()->disconnect (this);
1192
1193 // monitor section follow master bus - except midi
1194 ChanCount mon_chn (_master_out->output()->n_ports());
1195 mon_chn.set_midi (0);
1196
1197 _monitor_out->input()->ensure_io (mon_chn, false, this);
1198 _monitor_out->output()->ensure_io (mon_chn, false, this);
1199
1200 for (uint32_t n = 0; n < limit; ++n) {
1201 boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
1202 boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
1203
1204 if (o) {
1205 string connect_to = o->name();
1206 if (_monitor_out->input()->connect (p, connect_to, this)) {
1207 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
1208 << endmsg;
1209 break;
1210 }
1211 }
1212 }
1213
1214 /* connect monitor section to physical outs */
1215
1216 if (Config->get_auto_connect_standard_busses()) {
1217
1218 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
1219
1220 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
1221
1222 if (b) {
1223 _monitor_out->output()->connect_ports_to_bundle (b, true, this);
1224 } else {
1225 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
1226 Config->get_monitor_bus_preferred_bundle())
1227 << endmsg;
1228 }
1229
1230 } else {
1231
1232 /* Monitor bus is audio only */
1233
1234 vector<string> outputs[DataType::num_types];
1235
1236 for (uint32_t i = 0; i < DataType::num_types; ++i) {
1237 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
1238 }
1239
1240 uint32_t mod = outputs[DataType::AUDIO].size();
1241 uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
1242
1243 if (mod != 0) {
1244
1245 for (uint32_t n = 0; n < limit; ++n) {
1246
1247 boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
1248 string connect_to;
1249 if (outputs[DataType::AUDIO].size() > (n % mod)) {
1250 connect_to = outputs[DataType::AUDIO][n % mod];
1251 }
1252
1253 if (!connect_to.empty()) {
1254 if (_monitor_out->output()->connect (p, connect_to, this)) {
1255 error << string_compose (
1256 _("cannot connect control output %1 to %2"),
1257 n, connect_to)
1258 << endmsg;
1259 break;
1260 }
1261 }
1262 }
1263 }
1264 }
1265 }
1266
1267 setup_route_monitor_sends (true, false);
1268 }
1269
1270 int
add_master_bus(ChanCount const & count)1271 Session::add_master_bus (ChanCount const& count)
1272 {
1273 if (master_out ()) {
1274 return -1;
1275 }
1276
1277 RouteList rl;
1278
1279 boost::shared_ptr<Route> r (new Route (*this, _("Master"), PresentationInfo::MasterOut, DataType::AUDIO));
1280 if (r->init ()) {
1281 return -1;
1282 }
1283
1284 BOOST_MARK_ROUTE(r);
1285
1286 {
1287 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1288 r->input()->ensure_io (count, false, this);
1289 r->output()->ensure_io (count, false, this);
1290 }
1291
1292 rl.push_back (r);
1293 add_routes (rl, false, false, PresentationInfo::max_order);
1294 return 0;
1295 }
1296
1297 void
hookup_io()1298 Session::hookup_io ()
1299 {
1300 /* stop graph reordering notifications from
1301 causing resorts, etc.
1302 */
1303
1304 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
1305
1306 if (!auditioner) {
1307
1308 /* we delay creating the auditioner till now because
1309 it makes its own connections to ports.
1310 */
1311
1312 try {
1313 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
1314 if (a->init()) {
1315 throw failed_constructor ();
1316 }
1317 auditioner = a;
1318 }
1319
1320 catch (failed_constructor& err) {
1321 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
1322 }
1323 }
1324
1325 /* load bundles, which we may have postponed earlier on */
1326 if (_bundle_xml_node) {
1327 load_bundles (*_bundle_xml_node);
1328 delete _bundle_xml_node;
1329 }
1330
1331 /* Tell all IO objects to connect themselves together */
1332
1333 IO::enable_connecting ();
1334
1335 /* Now tell all "floating" ports to connect to whatever
1336 they should be connected to.
1337 */
1338
1339 AudioEngine::instance()->reconnect_ports ();
1340 TransportMasterManager::instance().reconnect_ports ();
1341
1342 /* Anyone who cares about input state, wake up and do something */
1343
1344 IOConnectionsComplete (); /* EMIT SIGNAL */
1345
1346 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
1347
1348 /* now handle the whole enchilada as if it was one
1349 graph reorder event.
1350 */
1351
1352 graph_reordered (false);
1353
1354 /* update the full solo state, which can't be
1355 correctly determined on a per-route basis, but
1356 needs the global overview that only the session
1357 has.
1358 */
1359
1360 update_route_solo_state ();
1361 }
1362
1363 void
track_playlist_changed(boost::weak_ptr<Track> wp)1364 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
1365 {
1366 boost::shared_ptr<Track> track = wp.lock ();
1367 if (!track) {
1368 return;
1369 }
1370
1371 boost::shared_ptr<Playlist> playlist;
1372
1373 if ((playlist = track->playlist()) != 0) {
1374 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
1375 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
1376 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
1377 }
1378 }
1379
1380 bool
record_enabling_legal() const1381 Session::record_enabling_legal () const
1382 {
1383 if (Config->get_all_safe()) {
1384 return false;
1385 }
1386 return true;
1387 }
1388
1389 void
set_track_monitor_input_status(bool yn)1390 Session::set_track_monitor_input_status (bool yn)
1391 {
1392 boost::shared_ptr<RouteList> rl = routes.reader ();
1393
1394 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1395 boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
1396 if (tr && tr->rec_enable_control()->get_value()) {
1397 tr->request_input_monitoring (yn);
1398 }
1399 }
1400 }
1401
1402 void
auto_punch_start_changed(Location * location)1403 Session::auto_punch_start_changed (Location* location)
1404 {
1405 replace_event (SessionEvent::PunchIn, location->start());
1406
1407 if (get_record_enabled() && config.get_punch_in() && !actively_recording ()) {
1408 /* capture start has been changed, so save new pending state */
1409 save_state ("", true);
1410 }
1411 }
1412
1413 bool
punch_active() const1414 Session::punch_active () const
1415 {
1416 if (!get_record_enabled ()) {
1417 return false;
1418 }
1419 if (!_locations->auto_punch_location ()) {
1420 return false;
1421 }
1422 return config.get_punch_in () || config.get_punch_out ();
1423 }
1424
1425 bool
punch_is_possible() const1426 Session::punch_is_possible () const
1427 {
1428 return g_atomic_int_get (&_punch_or_loop) != OnlyLoop;
1429 }
1430
1431 bool
loop_is_possible() const1432 Session::loop_is_possible () const
1433 {
1434 #if 0 /* maybe prevent looping even when not rolling ? */
1435 if (get_record_enabled () && punch_active ()) {
1436 return false;
1437 }
1438 }
1439 #endif
1440 return g_atomic_int_get(&_punch_or_loop) != OnlyPunch;
1441 }
1442
1443 void
reset_punch_loop_constraint()1444 Session::reset_punch_loop_constraint ()
1445 {
1446 if (g_atomic_int_get (&_punch_or_loop) == NoConstraint) {
1447 return;
1448 }
1449 g_atomic_int_set (&_punch_or_loop, NoConstraint);
1450 PunchLoopConstraintChange (); /* EMIT SIGNAL */
1451 }
1452
1453 bool
maybe_allow_only_loop(bool play_loop)1454 Session::maybe_allow_only_loop (bool play_loop) {
1455 if (!(get_play_loop () || play_loop)) {
1456 return false;
1457 }
1458 bool rv = g_atomic_int_compare_and_exchange (&_punch_or_loop, NoConstraint, OnlyLoop);
1459 if (rv) {
1460 PunchLoopConstraintChange (); /* EMIT SIGNAL */
1461 }
1462 if (rv || loop_is_possible ()) {
1463 unset_punch ();
1464 return true;
1465 }
1466 return false;
1467 }
1468
1469 bool
maybe_allow_only_punch()1470 Session::maybe_allow_only_punch () {
1471 if (!punch_active ()) {
1472 return false;
1473 }
1474 bool rv = g_atomic_int_compare_and_exchange (&_punch_or_loop, NoConstraint, OnlyPunch);
1475 if (rv) {
1476 PunchLoopConstraintChange (); /* EMIT SIGNAL */
1477 }
1478 return rv || punch_is_possible ();
1479 }
1480
1481 void
unset_punch()1482 Session::unset_punch ()
1483 {
1484 /* used when enabling looping
1485 * -> _punch_or_loop = OnlyLoop;
1486 */
1487 if (config.get_punch_in ()) {
1488 config.set_punch_in (false);
1489 }
1490 if (config.get_punch_out ()) {
1491 config.set_punch_out (false);
1492 }
1493 }
1494
1495 void
auto_punch_end_changed(Location * location)1496 Session::auto_punch_end_changed (Location* location)
1497 {
1498 replace_event (SessionEvent::PunchOut, location->end());
1499 }
1500
1501 void
auto_punch_changed(Location * location)1502 Session::auto_punch_changed (Location* location)
1503 {
1504 auto_punch_start_changed (location);
1505 auto_punch_end_changed (location);
1506 }
1507
1508 void
auto_loop_changed(Location * location)1509 Session::auto_loop_changed (Location* location)
1510 {
1511 if (!location) {
1512 return;
1513 }
1514
1515 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
1516
1517 if (transport_rolling()) {
1518
1519 if (get_play_loop ()) {
1520
1521 if (_transport_sample < location->start() || _transport_sample > location->end()) {
1522
1523 /* new loop range excludes current transport
1524 * sample => relocate to beginning of loop and roll.
1525 */
1526
1527 /* Set this so that when/if we have to stop the
1528 * transport for a locate, we know that it is triggered
1529 * by loop-changing, and we do not cancel play loop
1530 */
1531
1532 loop_changing = true;
1533 request_locate (location->start(), MustRoll);
1534
1535 } else {
1536
1537 // schedule a locate-roll to refill the diskstreams at the
1538 // previous loop end
1539
1540 /* schedule a buffer overwrite to refill buffers with the new loop. */
1541 SessionEvent *ev = new SessionEvent (SessionEvent::OverwriteAll, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0);
1542 ev->overwrite = LoopChanged;
1543 queue_event (ev);
1544 }
1545 }
1546
1547 } else {
1548
1549 /* possibly move playhead if not rolling; if we are rolling we'll move
1550 to the loop start on stop if that is appropriate.
1551 */
1552
1553 samplepos_t pos;
1554
1555 if (select_playhead_priority_target (pos)) {
1556 if (pos == location->start()) {
1557 request_locate (pos);
1558 }
1559 }
1560 }
1561
1562 last_loopend = location->end();
1563 set_dirty ();
1564 }
1565
1566 void
set_auto_punch_location(Location * location)1567 Session::set_auto_punch_location (Location* location)
1568 {
1569 Location* existing;
1570
1571 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
1572 punch_connections.drop_connections();
1573 existing->set_auto_punch (false, this);
1574 clear_events (SessionEvent::PunchIn);
1575 clear_events (SessionEvent::PunchOut);
1576 auto_punch_location_changed (0);
1577 }
1578
1579 set_dirty();
1580
1581 if (location == 0) {
1582 return;
1583 }
1584
1585 if (location->end() <= location->start()) {
1586 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1587 return;
1588 }
1589
1590 punch_connections.drop_connections ();
1591
1592 location->StartChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, location));
1593 location->EndChanged.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, location));
1594 location->Changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, location));
1595
1596 location->set_auto_punch (true, this);
1597
1598 auto_punch_changed (location);
1599
1600 auto_punch_location_changed (location);
1601 }
1602
1603 void
set_session_extents(samplepos_t start,samplepos_t end)1604 Session::set_session_extents (samplepos_t start, samplepos_t end)
1605 {
1606 if (end <= start) {
1607 error << _("Session: you can't use that location for session start/end)") << endmsg;
1608 return;
1609 }
1610
1611 Location* existing;
1612 if ((existing = _locations->session_range_location()) == 0) {
1613 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange, 0);
1614 _locations->add (_session_range_location);
1615 } else {
1616 existing->set( start, end );
1617 }
1618
1619 set_dirty();
1620 }
1621
1622 void
set_auto_loop_location(Location * location)1623 Session::set_auto_loop_location (Location* location)
1624 {
1625 Location* existing;
1626
1627 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
1628 loop_connections.drop_connections ();
1629 existing->set_auto_loop (false, this);
1630 remove_event (existing->end(), SessionEvent::AutoLoop);
1631 auto_loop_location_changed (0);
1632 }
1633
1634 set_dirty();
1635
1636 if (location == 0) {
1637 return;
1638 }
1639
1640 if (location->end() <= location->start()) {
1641 error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
1642 return;
1643 }
1644
1645 last_loopend = location->end();
1646
1647 loop_connections.drop_connections ();
1648
1649 location->StartChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1650 location->EndChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1651 location->Changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1652 location->FlagsChanged.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, location));
1653
1654 location->set_auto_loop (true, this);
1655
1656 if (Config->get_loop_is_mode() && get_play_loop ()) {
1657 /* set all tracks to use internal looping */
1658 set_track_loop (true);
1659 }
1660
1661 /* take care of our stuff first */
1662
1663 auto_loop_changed (location);
1664
1665 /* now tell everyone else */
1666
1667 auto_loop_location_changed (location);
1668 }
1669
1670 void
update_marks(Location *)1671 Session::update_marks (Location*)
1672 {
1673 set_dirty ();
1674 }
1675
1676 void
update_skips(Location * loc,bool consolidate)1677 Session::update_skips (Location* loc, bool consolidate)
1678 {
1679 if (_ignore_skips_updates) {
1680 return;
1681 }
1682
1683 Locations::LocationList skips;
1684
1685 if (consolidate) {
1686 PBD::Unwinder<bool> uw (_ignore_skips_updates, true);
1687 consolidate_skips (loc);
1688 }
1689
1690 sync_locations_to_skips ();
1691
1692 set_dirty ();
1693 }
1694
1695 void
consolidate_skips(Location * loc)1696 Session::consolidate_skips (Location* loc)
1697 {
1698 Locations::LocationList all_locations = _locations->list ();
1699
1700 for (Locations::LocationList::iterator l = all_locations.begin(); l != all_locations.end(); ) {
1701
1702 if (!(*l)->is_skip ()) {
1703 ++l;
1704 continue;
1705 }
1706
1707 /* don't test against self */
1708
1709 if (*l == loc) {
1710 ++l;
1711 continue;
1712 }
1713
1714 switch (Evoral::coverage ((*l)->start(), (*l)->end(), loc->start(), loc->end())) {
1715 case Evoral::OverlapInternal:
1716 case Evoral::OverlapExternal:
1717 case Evoral::OverlapStart:
1718 case Evoral::OverlapEnd:
1719 /* adjust new location to cover existing one */
1720 loc->set_start (min (loc->start(), (*l)->start()));
1721 loc->set_end (max (loc->end(), (*l)->end()));
1722 /* we don't need this one any more */
1723 _locations->remove (*l);
1724 /* the location has been deleted, so remove reference to it in our local list */
1725 l = all_locations.erase (l);
1726 break;
1727
1728 case Evoral::OverlapNone:
1729 ++l;
1730 break;
1731 }
1732 }
1733 }
1734
1735 void
sync_locations_to_skips()1736 Session::sync_locations_to_skips ()
1737 {
1738 /* This happens asynchronously (in the audioengine thread). After the clear is done, we will call
1739 * Session::_sync_locations_to_skips() from the audioengine thread.
1740 */
1741 clear_events (SessionEvent::Skip, boost::bind (&Session::_sync_locations_to_skips, this));
1742 }
1743
1744 void
_sync_locations_to_skips()1745 Session::_sync_locations_to_skips ()
1746 {
1747 /* called as a callback after existing Skip events have been cleared from a realtime audioengine thread */
1748
1749 Locations::LocationList const & locs (_locations->list());
1750
1751 for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) {
1752
1753 Location* location = *i;
1754
1755 if (location->is_skip() && location->is_skipping()) {
1756 SessionEvent* ev = new SessionEvent (SessionEvent::Skip, SessionEvent::Add, location->start(), location->end(), 1.0);
1757 queue_event (ev);
1758 }
1759 }
1760 }
1761
1762
1763 void
location_added(Location * location)1764 Session::location_added (Location *location)
1765 {
1766 if (location->is_auto_punch()) {
1767 set_auto_punch_location (location);
1768 }
1769
1770 if (location->is_auto_loop()) {
1771 set_auto_loop_location (location);
1772 }
1773
1774 if (location->is_session_range()) {
1775 /* no need for any signal handling or event setting with the session range,
1776 because we keep a direct reference to it and use its start/end directly.
1777 */
1778 _session_range_location = location;
1779 }
1780
1781 if (location->is_mark()) {
1782 /* listen for per-location signals that require us to do any * global updates for marks */
1783
1784 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1785 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1786 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1787 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1788 location->PositionLockStyleChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1789 }
1790
1791 if (location->is_range_marker()) {
1792 /* listen for per-location signals that require us to do any * global updates for marks */
1793
1794 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1795 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1796 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1797 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1798 location->PositionLockStyleChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1799 }
1800
1801 if (location->is_skip()) {
1802 /* listen for per-location signals that require us to update skip-locate events */
1803
1804 location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1805 location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1806 location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, true));
1807 location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_skips, this, location, false));
1808 location->PositionLockStyleChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location));
1809
1810 update_skips (location, true);
1811 }
1812
1813 set_dirty ();
1814 }
1815
1816 void
location_removed(Location * location)1817 Session::location_removed (Location *location)
1818 {
1819 if (location->is_auto_loop()) {
1820 set_auto_loop_location (0);
1821 if (!get_play_loop ()) {
1822 set_track_loop (false);
1823 }
1824 unset_play_loop ();
1825 }
1826
1827 if (location->is_auto_punch()) {
1828 set_auto_punch_location (0);
1829 }
1830
1831 if (location->is_session_range()) {
1832 /* this is never supposed to happen */
1833 error << _("programming error: session range removed!") << endl;
1834 }
1835
1836 if (location->is_skip()) {
1837
1838 update_skips (location, false);
1839 }
1840
1841 set_dirty ();
1842 }
1843
1844 void
locations_changed()1845 Session::locations_changed ()
1846 {
1847 _locations->apply (*this, &Session::_locations_changed);
1848 }
1849
1850 void
_locations_changed(const Locations::LocationList & locations)1851 Session::_locations_changed (const Locations::LocationList& locations)
1852 {
1853 /* There was some mass-change in the Locations object.
1854 *
1855 * We might be re-adding a location here but it doesn't actually matter
1856 * for all the locations that the Session takes an interest in.
1857 */
1858
1859 {
1860 PBD::Unwinder<bool> protect_ignore_skip_updates (_ignore_skips_updates, true);
1861 for (Locations::LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
1862 location_added (*i);
1863 }
1864 }
1865
1866 update_skips (NULL, false);
1867 }
1868
1869 void
enable_record()1870 Session::enable_record ()
1871 {
1872 if (_transport_fsm->transport_speed() != 0.0 && _transport_fsm->transport_speed() != 1.0) {
1873 /* no recording at anything except normal speed */
1874 return;
1875 }
1876
1877 while (1) {
1878 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1879
1880 if (rs == Recording) {
1881 break;
1882 }
1883
1884 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1885
1886 _last_record_location = _transport_sample;
1887 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1888
1889 if (Config->get_recording_resets_xrun_count ()) {
1890 reset_xrun_count ();
1891 }
1892 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1893 set_track_monitor_input_status (true);
1894 }
1895
1896 _capture_duration = 0;
1897 _capture_xruns = 0;
1898
1899 RecordStateChanged ();
1900 break;
1901 }
1902 }
1903 }
1904
1905 void
set_all_tracks_record_enabled(bool enable)1906 Session::set_all_tracks_record_enabled (bool enable )
1907 {
1908 boost::shared_ptr<RouteList> rl = routes.reader();
1909 set_controls (route_list_to_control_list (rl, &Stripable::rec_enable_control), enable, Controllable::NoGroup);
1910 }
1911
1912 void
disable_record(bool rt_context,bool force)1913 Session::disable_record (bool rt_context, bool force)
1914 {
1915 RecordState rs;
1916
1917 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1918
1919 if (!Config->get_latched_record_enable () || force) {
1920 g_atomic_int_set (&_record_status, Disabled);
1921 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1922 } else {
1923 if (rs == Recording) {
1924 g_atomic_int_set (&_record_status, Enabled);
1925 }
1926 }
1927
1928 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1929 set_track_monitor_input_status (false);
1930 }
1931
1932 RecordStateChanged (); /* emit signal */
1933 }
1934 }
1935
1936 void
step_back_from_record()1937 Session::step_back_from_record ()
1938 {
1939 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1940
1941 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1942 set_track_monitor_input_status (false);
1943 }
1944
1945 RecordStateChanged (); /* emit signal */
1946 }
1947 }
1948
1949 void
maybe_enable_record(bool rt_context)1950 Session::maybe_enable_record (bool rt_context)
1951 {
1952 if (_step_editors > 0) {
1953 return;
1954 }
1955
1956 g_atomic_int_set (&_record_status, Enabled);
1957
1958 // TODO make configurable, perhaps capture-buffer-seconds dependnet?
1959 bool quick_start = true;
1960
1961 /* Save pending state of which sources the next record will use,
1962 * which gives us some chance of recovering from a crash during the record.
1963 */
1964 if (!rt_context && (!quick_start || _transport_fsm->transport_speed() == 0)) {
1965 save_state ("", true);
1966 }
1967
1968 if (_transport_fsm->transport_speed() != 0) {
1969 maybe_allow_only_punch ();
1970 if (!config.get_punch_in()) {
1971 enable_record ();
1972 }
1973 /* When rolling, start recording immediately.
1974 * Do not wait for .pending state save to complete
1975 * because that may take some time (up to a second
1976 * for huge sessions).
1977 *
1978 * This is potentially dangerous!! If a crash happens
1979 * while recording before the .pending save completed,
1980 * the data until then may be lost or overwritten.
1981 * (However disk-writer buffers are usually longer,
1982 * compared to the time it takes to save a session.
1983 * disk I/O may not be a bottleneck either. Except
1984 * perhaps plugin-state saves taking a lock.
1985 */
1986 if (!rt_context && quick_start) {
1987 save_state ("", true);
1988 }
1989 } else {
1990 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1991 RecordStateChanged (); /* EMIT SIGNAL */
1992 }
1993
1994 set_dirty();
1995 }
1996
1997 samplepos_t
audible_sample(bool * latent_locate) const1998 Session::audible_sample (bool* latent_locate) const
1999 {
2000 if (latent_locate) {
2001 *latent_locate = false;
2002 }
2003
2004 samplepos_t ret;
2005
2006 if (synced_to_engine()) {
2007 /* Note: this is basically just sync-to-JACK */
2008 ret = _engine.transport_sample();
2009 } else {
2010 ret = _transport_sample;
2011 }
2012
2013 assert (ret >= 0);
2014
2015 if (!transport_rolling()) {
2016 return ret;
2017 }
2018
2019 #if 0 // TODO looping
2020 if (_transport_fsm->transport_speed() > 0.0f) {
2021 if (play_loop && have_looped) {
2022 /* the play-position wrapped at the loop-point
2023 * ardour is already playing the beginning of the loop,
2024 * but due to playback latency, the "audible frame"
2025 * is still at the end of the loop.
2026 */
2027 Location *location = _locations->auto_loop_location();
2028 sampleoffset_t lo = location->start() - ret;
2029 if (lo > 0) {
2030 ret = location->end () - lo;
2031 if (latent_locate) {
2032 *latent_locate = true;
2033 }
2034 }
2035 }
2036 } else if (_transport_fsm->transport_speed() < 0.0f) {
2037 /* XXX wot? no backward looping? */
2038 }
2039 #endif
2040
2041 return std::max ((samplepos_t)0, ret);
2042 }
2043
2044 samplecnt_t
preroll_samples(samplepos_t pos) const2045 Session::preroll_samples (samplepos_t pos) const
2046 {
2047 const float pr = Config->get_preroll_seconds();
2048 if (pos >= 0 && pr < 0) {
2049 const Tempo& tempo = _tempo_map->tempo_at_sample (pos);
2050 const Meter& meter = _tempo_map->meter_at_sample (pos);
2051 return meter.samples_per_bar (tempo, sample_rate()) * -pr;
2052 }
2053 if (pr < 0) {
2054 return 0;
2055 }
2056 return pr * sample_rate();
2057 }
2058
2059 void
set_sample_rate(samplecnt_t frames_per_second)2060 Session::set_sample_rate (samplecnt_t frames_per_second)
2061 {
2062 /** \fn void Session::set_sample_size(samplecnt_t)
2063 the AudioEngine object that calls this guarantees
2064 that it will not be called while we are also in
2065 ::process(). Its fine to do things that block
2066 here.
2067 */
2068
2069 if (_base_sample_rate == 0) {
2070 _base_sample_rate = frames_per_second;
2071 }
2072 else if (_base_sample_rate != frames_per_second && frames_per_second != _nominal_sample_rate) {
2073 NotifyAboutSampleRateMismatch (_base_sample_rate, frames_per_second);
2074 }
2075 _nominal_sample_rate = frames_per_second;
2076
2077 sync_time_vars();
2078
2079 clear_clicks ();
2080 reset_write_sources (false);
2081
2082 DiskReader::alloc_loop_declick (nominal_sample_rate());
2083 Location* loc = _locations->auto_loop_location ();
2084 DiskReader::reset_loop_declick (loc, nominal_sample_rate());
2085
2086 // XXX we need some equivalent to this, somehow
2087 // SndFileSource::setup_standard_crossfades (frames_per_second);
2088
2089 set_dirty();
2090
2091 /* XXX need to reset/reinstantiate all LADSPA plugins */
2092 }
2093
2094 void
set_block_size(pframes_t nframes)2095 Session::set_block_size (pframes_t nframes)
2096 {
2097 /* the AudioEngine guarantees
2098 * that it will not be called while we are also in
2099 * ::process(). It is therefore fine to do things that block
2100 * here.
2101 */
2102 current_block_size = nframes;
2103
2104 ensure_buffers ();
2105
2106 foreach_route (&Route::set_block_size, nframes);
2107
2108 DEBUG_TRACE (DEBUG::LatencyCompensation, "Session::set_block_size -> update worst i/o latency\n");
2109 /* when this is called from the auto-connect thread, the process-lock is held */
2110 Glib::Threads::Mutex::Lock lx (_update_latency_lock);
2111 set_worst_output_latency ();
2112 set_worst_input_latency ();
2113 }
2114
2115
2116 static void
trace_terminal(boost::shared_ptr<Route> r1,boost::shared_ptr<Route> rbase,bool sends_only)2117 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase, bool sends_only)
2118 {
2119 boost::shared_ptr<Route> r2;
2120
2121 if (r1->feeds (rbase) && rbase->feeds (r1)) {
2122 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
2123 return;
2124 }
2125
2126 /* make a copy of the existing list of routes that feed r1 */
2127
2128 Route::FedBy existing (r1->fed_by());
2129
2130 /* for each route that feeds r1, recurse, marking it as feeding
2131 rbase as well.
2132 */
2133
2134 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
2135 if (!(r2 = i->r.lock ())) {
2136 /* (*i) went away, ignore it */
2137 continue;
2138 }
2139
2140 /* r2 is a route that feeds r1 which somehow feeds base. mark
2141 base as being fed by r2
2142 */
2143
2144 rbase->add_fed_by (r2, i->sends_only || sends_only);
2145
2146 if (r2 != rbase) {
2147
2148 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
2149 stop here.
2150 */
2151
2152 if (r1->feeds (r2) && r2->feeds (r1)) {
2153 continue;
2154 }
2155
2156 /* now recurse, so that we can mark base as being fed by
2157 all routes that feed r2
2158 */
2159
2160 trace_terminal (r2, rbase, i->sends_only || sends_only);
2161 }
2162
2163 }
2164 }
2165
2166 void
resort_routes()2167 Session::resort_routes ()
2168 {
2169 /* don't do anything here with signals emitted
2170 by Routes during initial setup or while we
2171 are being destroyed.
2172 */
2173
2174 if (inital_connect_or_deletion_in_progress ()) {
2175 return;
2176 }
2177
2178 if (_route_deletion_in_progress) {
2179 return;
2180 }
2181
2182 {
2183 RCUWriter<RouteList> writer (routes);
2184 boost::shared_ptr<RouteList> r = writer.get_copy ();
2185 resort_routes_using (r);
2186 /* writer goes out of scope and forces update */
2187 }
2188
2189 #ifndef NDEBUG
2190 if (DEBUG_ENABLED(DEBUG::Graph)) {
2191 boost::shared_ptr<RouteList> rl = routes.reader ();
2192 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2193 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
2194
2195 const Route::FedBy& fb ((*i)->fed_by());
2196
2197 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
2198 boost::shared_ptr<Route> sf = f->r.lock();
2199 if (sf) {
2200 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
2201 }
2202 }
2203 }
2204 }
2205 #endif
2206
2207 }
2208
2209 /** This is called whenever we need to rebuild the graph of how we will process
2210 * routes.
2211 * @param r List of routes, in any order.
2212 */
2213
2214 void
resort_routes_using(boost::shared_ptr<RouteList> r)2215 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
2216 {
2217 /* We are going to build a directed graph of our routes;
2218 this is where the edges of that graph are put.
2219 */
2220
2221 GraphEdges edges;
2222
2223 /* Go through all routes doing two things:
2224 *
2225 * 1. Collect the edges of the route graph. Each of these edges
2226 * is a pair of routes, one of which directly feeds the other
2227 * either by a JACK connection or by an internal send.
2228 *
2229 * 2. Begin the process of making routes aware of which other
2230 * routes directly or indirectly feed them. This information
2231 * is used by the solo code.
2232 */
2233
2234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2235
2236 /* Clear out the route's list of direct or indirect feeds */
2237 (*i)->clear_fed_by ();
2238
2239 for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
2240
2241 bool via_sends_only = false;
2242
2243 /* See if this *j feeds *i according to the current state of the JACK
2244 connections and internal sends.
2245 */
2246 if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
2247 /* add the edge to the graph (part #1) */
2248 edges.add (*j, *i, via_sends_only);
2249 /* tell the route (for part #2) */
2250 (*i)->add_fed_by (*j, via_sends_only);
2251 }
2252 }
2253 }
2254
2255 /* Attempt a topological sort of the route graph */
2256 boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
2257
2258 if (sorted_routes) {
2259 /* We got a satisfactory topological sort, so there is no feedback;
2260 use this new graph.
2261
2262 Note: the process graph rechain does not require a
2263 topologically-sorted list, but hey ho.
2264 */
2265 if (_process_graph) {
2266 _process_graph->rechain (sorted_routes, edges);
2267 }
2268
2269 _current_route_graph = edges;
2270
2271 /* Complete the building of the routes' lists of what directly
2272 or indirectly feeds them.
2273 */
2274 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2275 trace_terminal (*i, *i, false);
2276 }
2277
2278 *r = *sorted_routes;
2279
2280 #ifndef NDEBUG
2281 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2283 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 presentation order %2\n", (*i)->name(), (*i)->presentation_info().order()));
2284 }
2285 #endif
2286
2287 SuccessfulGraphSort (); /* EMIT SIGNAL */
2288
2289 } else {
2290 /* The topological sort failed, so we have a problem. Tell everyone
2291 and stick to the old graph; this will continue to be processed, so
2292 until the feedback is fixed, what is played back will not quite
2293 reflect what is actually connected. Note also that we do not
2294 do trace_terminal here, as it would fail due to an endless recursion,
2295 so the solo code will think that everything is still connected
2296 as it was before.
2297 */
2298
2299 FeedbackDetected (); /* EMIT SIGNAL */
2300 }
2301
2302 }
2303
2304 /** Find a route name starting with \a base, maybe followed by the
2305 * lowest \a id. \a id will always be added if \a definitely_add_number
2306 * is true on entry; otherwise it will only be added if required
2307 * to make the name unique.
2308 *
2309 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
2310 * The available route name with the lowest ID will be used, and \a id
2311 * will be set to the ID.
2312 *
2313 * \return false if a route name could not be found, and \a track_name
2314 * and \a id do not reflect a free route name.
2315 */
2316 bool
find_route_name(string const & base,uint32_t & id,string & name,bool definitely_add_number)2317 Session::find_route_name (string const & base, uint32_t& id, string& name, bool definitely_add_number)
2318 {
2319 /* the base may conflict with ports that do not belong to existing
2320 routes, but hidden objects like the click track. So check port names
2321 before anything else.
2322 */
2323
2324 for (map<string,bool>::const_iterator reserved = reserved_io_names.begin(); reserved != reserved_io_names.end(); ++reserved) {
2325 if (base == reserved->first) {
2326 /* Check if this reserved name already exists, and if
2327 so, disallow it without a numeric suffix.
2328 */
2329 if (!reserved->second || route_by_name (reserved->first)) {
2330 definitely_add_number = true;
2331 if (id < 1) {
2332 id = 1;
2333 }
2334 }
2335 break;
2336 }
2337 }
2338
2339 /* if we have "base 1" already, it doesn't make sense to add "base"
2340 * if "base 1" has been deleted, adding "base" is no worse than "base 1"
2341 */
2342 if (!definitely_add_number && route_by_name (base) == 0 && (route_by_name (string_compose("%1 1", base)) == 0)) {
2343 /* just use the base */
2344 name = base;
2345 return true;
2346 }
2347
2348 do {
2349 name = string_compose ("%1 %2", base, id);
2350
2351 if (route_by_name (name) == 0) {
2352 return true;
2353 }
2354
2355 ++id;
2356
2357 } while (id < (UINT_MAX-1));
2358
2359 return false;
2360 }
2361
2362 /** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
2363 void
count_existing_track_channels(ChanCount & in,ChanCount & out)2364 Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
2365 {
2366 in = ChanCount::ZERO;
2367 out = ChanCount::ZERO;
2368
2369 boost::shared_ptr<RouteList> r = routes.reader ();
2370
2371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2372 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2373 if (!tr) {
2374 continue;
2375 }
2376 assert (!tr->is_auditioner()); // XXX remove me
2377 in += tr->n_inputs();
2378 out += tr->n_outputs();
2379 }
2380 }
2381
2382 string
default_track_name_pattern(DataType t)2383 Session::default_track_name_pattern (DataType t)
2384 {
2385 switch (t) {
2386 case DataType::AUDIO:
2387 return _("Audio");
2388 break;
2389
2390 case DataType::MIDI:
2391 return _("MIDI");
2392 }
2393
2394 return "";
2395 }
2396
2397 /** Caller must not hold process lock
2398 * @param name_template string to use for the start of the name, or "" to use "MIDI".
2399 * @param instrument plugin info for the instrument to insert pre-fader, if any
2400 */
2401 list<boost::shared_ptr<MidiTrack> >
new_midi_track(const ChanCount & input,const ChanCount & output,bool strict_io,boost::shared_ptr<PluginInfo> instrument,Plugin::PresetRecord * pset,RouteGroup * route_group,uint32_t how_many,string name_template,PresentationInfo::order_t order,TrackMode mode,bool input_auto_connect)2402 Session::new_midi_track (const ChanCount& input, const ChanCount& output, bool strict_io,
2403 boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
2404 RouteGroup* route_group, uint32_t how_many,
2405 string name_template, PresentationInfo::order_t order,
2406 TrackMode mode, bool input_auto_connect)
2407 {
2408 string track_name;
2409 uint32_t track_id = 0;
2410 string port;
2411 RouteList new_routes;
2412 list<boost::shared_ptr<MidiTrack> > ret;
2413
2414 const string name_pattern = default_track_name_pattern (DataType::MIDI);
2415 bool const use_number = (how_many != 1) || name_template.empty () || (name_template == name_pattern);
2416
2417 while (how_many) {
2418 if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, use_number)) {
2419 error << "cannot find name for new midi track" << endmsg;
2420 goto failed;
2421 }
2422
2423 boost::shared_ptr<MidiTrack> track;
2424
2425 try {
2426 track.reset (new MidiTrack (*this, track_name, mode));
2427
2428 if (track->init ()) {
2429 goto failed;
2430 }
2431
2432 if (strict_io) {
2433 track->set_strict_io (true);
2434 }
2435
2436 BOOST_MARK_TRACK (track);
2437
2438 {
2439 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2440 if (track->input()->ensure_io (input, false, this)) {
2441 error << "cannot configure " << input << " out configuration for new midi track" << endmsg;
2442 goto failed;
2443 }
2444
2445 if (track->output()->ensure_io (output, false, this)) {
2446 error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
2447 goto failed;
2448 }
2449 }
2450
2451 if (route_group) {
2452 route_group->add (track);
2453 }
2454
2455 new_routes.push_back (track);
2456 ret.push_back (track);
2457 }
2458
2459 catch (failed_constructor &err) {
2460 error << _("Session: could not create new midi track.") << endmsg;
2461 goto failed;
2462 }
2463
2464 catch (AudioEngine::PortRegistrationFailure& pfe) {
2465
2466 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;
2467 goto failed;
2468 }
2469
2470 --how_many;
2471 }
2472
2473 failed:
2474 if (!new_routes.empty()) {
2475 ChanCount existing_inputs;
2476 ChanCount existing_outputs;
2477 count_existing_track_channels (existing_inputs, existing_outputs);
2478
2479 add_routes (new_routes, input_auto_connect, !instrument, order);
2480 load_and_connect_instruments (new_routes, strict_io, instrument, pset, existing_outputs);
2481 }
2482
2483 return ret;
2484 }
2485
2486 RouteList
new_midi_route(RouteGroup * route_group,uint32_t how_many,string name_template,bool strict_io,boost::shared_ptr<PluginInfo> instrument,Plugin::PresetRecord * pset,PresentationInfo::Flag flag,PresentationInfo::order_t order)2487 Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, bool strict_io,
2488 boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
2489 PresentationInfo::Flag flag, PresentationInfo::order_t order)
2490 {
2491 string bus_name;
2492 uint32_t bus_id = 0;
2493 string port;
2494 RouteList ret;
2495
2496 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Midi Bus");
2497
2498 while (how_many) {
2499 if (!find_route_name (name_template.empty () ? _("Midi Bus") : name_template, ++bus_id, bus_name, use_number)) {
2500 error << "cannot find name for new midi bus" << endmsg;
2501 goto failure;
2502 }
2503
2504 try {
2505 boost::shared_ptr<Route> bus (new Route (*this, bus_name, flag, DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
2506
2507 if (bus->init ()) {
2508 goto failure;
2509 }
2510
2511 if (strict_io) {
2512 bus->set_strict_io (true);
2513 }
2514
2515 BOOST_MARK_ROUTE(bus);
2516
2517 {
2518 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2519
2520 if (bus->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
2521 error << _("cannot configure new midi bus input") << endmsg;
2522 goto failure;
2523 }
2524
2525
2526 if (bus->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
2527 error << _("cannot configure new midi bus output") << endmsg;
2528 goto failure;
2529 }
2530 }
2531
2532 if (route_group) {
2533 route_group->add (bus);
2534 }
2535
2536 bus->add_internal_return ();
2537 ret.push_back (bus);
2538 }
2539
2540 catch (failed_constructor &err) {
2541 error << _("Session: could not create new MIDI bus.") << endmsg;
2542 goto failure;
2543 }
2544
2545 catch (AudioEngine::PortRegistrationFailure& pfe) {
2546 error << pfe.what() << endmsg;
2547 goto failure;
2548 }
2549
2550
2551 --how_many;
2552 }
2553
2554 failure:
2555 if (!ret.empty()) {
2556 ChanCount existing_inputs;
2557 ChanCount existing_outputs;
2558 count_existing_track_channels (existing_inputs, existing_outputs);
2559
2560 add_routes (ret, false, !instrument, order);
2561 load_and_connect_instruments (ret, strict_io, instrument, pset, existing_outputs);
2562 }
2563
2564 return ret;
2565
2566 }
2567
2568
2569 void
midi_output_change_handler(IOChange change,void *,boost::weak_ptr<Route> wr)2570 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wr)
2571 {
2572 boost::shared_ptr<Route> midi_route (wr.lock());
2573
2574 if (!midi_route) {
2575 return;
2576 }
2577
2578 if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
2579
2580 if (change.after.n_audio() <= change.before.n_audio()) {
2581 return;
2582 }
2583
2584 /* new audio ports: make sure the audio goes somewhere useful,
2585 * unless the user has no-auto-connect selected.
2586 *
2587 * The existing ChanCounts don't matter for this call as they are only
2588 * to do with matching input and output indices, and we are only changing
2589 * outputs here.
2590 */
2591 auto_connect_route (midi_route, false, !midi_route->instrument_fanned_out (), ChanCount(), change.before);
2592 }
2593 }
2594
2595 bool
ensure_stripable_sort_order()2596 Session::ensure_stripable_sort_order ()
2597 {
2598 StripableList sl;
2599 get_stripables (sl);
2600 sl.sort (Stripable::Sorter ());
2601
2602 bool change = false;
2603 PresentationInfo::order_t order = 0;
2604
2605 for (StripableList::iterator si = sl.begin(); si != sl.end(); ++si) {
2606 boost::shared_ptr<Stripable> s (*si);
2607 assert (!s->is_auditioner ()); // XXX remove me
2608 if (s->is_monitor ()) {
2609 continue;
2610 }
2611 if (order != s->presentation_info().order()) {
2612 s->set_presentation_order (order);
2613 change = true;
2614 }
2615 ++order;
2616 }
2617 return change;
2618 }
2619
2620 void
ensure_route_presentation_info_gap(PresentationInfo::order_t first_new_order,uint32_t how_many)2621 Session::ensure_route_presentation_info_gap (PresentationInfo::order_t first_new_order, uint32_t how_many)
2622 {
2623 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("ensure order gap starting at %1 for %2\n", first_new_order, how_many));
2624
2625 if (first_new_order == PresentationInfo::max_order) {
2626 /* adding at end, no worries */
2627 return;
2628 }
2629
2630 /* create a gap in the presentation info to accomodate @param how_many
2631 * new objects.
2632 */
2633 StripableList sl;
2634 get_stripables (sl);
2635
2636 for (StripableList::iterator si = sl.begin(); si != sl.end(); ++si) {
2637 boost::shared_ptr<Stripable> s (*si);
2638
2639 if (s->presentation_info().special (false)) {
2640 continue;
2641 }
2642
2643 if (!s->presentation_info().order_set()) {
2644 continue;
2645 }
2646
2647 if (s->presentation_info().order () >= first_new_order) {
2648 s->set_presentation_order (s->presentation_info().order () + how_many);
2649 }
2650 }
2651 }
2652
2653 /** Caller must not hold process lock
2654 * @param name_template string to use for the start of the name, or "" to use "Audio".
2655 */
2656 list< boost::shared_ptr<AudioTrack> >
new_audio_track(int input_channels,int output_channels,RouteGroup * route_group,uint32_t how_many,string name_template,PresentationInfo::order_t order,TrackMode mode,bool input_auto_connect)2657 Session::new_audio_track (int input_channels, int output_channels, RouteGroup* route_group,
2658 uint32_t how_many, string name_template, PresentationInfo::order_t order,
2659 TrackMode mode, bool input_auto_connect)
2660 {
2661 string track_name;
2662 uint32_t track_id = 0;
2663 string port;
2664 RouteList new_routes;
2665 list<boost::shared_ptr<AudioTrack> > ret;
2666
2667 const string name_pattern = default_track_name_pattern (DataType::AUDIO);
2668 bool const use_number = (how_many != 1) || name_template.empty () || (name_template == name_pattern);
2669
2670 while (how_many) {
2671
2672 if (!find_route_name (name_template.empty() ? _(name_pattern.c_str()) : name_template, ++track_id, track_name, use_number)) {
2673 error << "cannot find name for new audio track" << endmsg;
2674 goto failed;
2675 }
2676
2677 boost::shared_ptr<AudioTrack> track;
2678
2679 try {
2680 track.reset (new AudioTrack (*this, track_name, mode));
2681
2682 if (track->init ()) {
2683 goto failed;
2684 }
2685
2686 if (Profile->get_mixbus ()) {
2687 track->set_strict_io (true);
2688 }
2689
2690 BOOST_MARK_TRACK (track);
2691
2692 {
2693 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2694
2695 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
2696 error << string_compose (
2697 _("cannot configure %1 in/%2 out configuration for new audio track"),
2698 input_channels, output_channels)
2699 << endmsg;
2700 goto failed;
2701 }
2702
2703 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
2704 error << string_compose (
2705 _("cannot configure %1 in/%2 out configuration for new audio track"),
2706 input_channels, output_channels)
2707 << endmsg;
2708 goto failed;
2709 }
2710 }
2711
2712 if (route_group) {
2713 route_group->add (track);
2714 }
2715
2716 new_routes.push_back (track);
2717 ret.push_back (track);
2718 }
2719
2720 catch (failed_constructor &err) {
2721 error << _("Session: could not create new audio track.") << endmsg;
2722 goto failed;
2723 }
2724
2725 catch (AudioEngine::PortRegistrationFailure& pfe) {
2726
2727 error << pfe.what() << endmsg;
2728 goto failed;
2729 }
2730
2731 --how_many;
2732 }
2733
2734 failed:
2735 if (!new_routes.empty()) {
2736 add_routes (new_routes, input_auto_connect, true, order);
2737 }
2738
2739 return ret;
2740 }
2741
2742 /** Caller must not hold process lock.
2743 * @param name_template string to use for the start of the name, or "" to use "Bus".
2744 */
2745 RouteList
new_audio_route(int input_channels,int output_channels,RouteGroup * route_group,uint32_t how_many,string name_template,PresentationInfo::Flag flags,PresentationInfo::order_t order)2746 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template,
2747 PresentationInfo::Flag flags, PresentationInfo::order_t order)
2748 {
2749 string bus_name;
2750 uint32_t bus_id = 0;
2751 string port;
2752 RouteList ret;
2753
2754 bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
2755
2756 while (how_many) {
2757 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, use_number)) {
2758 error << "cannot find name for new audio bus" << endmsg;
2759 goto failure;
2760 }
2761
2762 try {
2763 boost::shared_ptr<Route> bus (new Route (*this, bus_name, flags, DataType::AUDIO));
2764
2765 if (bus->init ()) {
2766 goto failure;
2767 }
2768
2769 if (Profile->get_mixbus ()) {
2770 bus->set_strict_io (true);
2771 }
2772
2773 BOOST_MARK_ROUTE(bus);
2774
2775 {
2776 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
2777
2778 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
2779 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2780 input_channels, output_channels)
2781 << endmsg;
2782 goto failure;
2783 }
2784
2785
2786 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
2787 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2788 input_channels, output_channels)
2789 << endmsg;
2790 goto failure;
2791 }
2792 }
2793
2794 if (route_group) {
2795 route_group->add (bus);
2796 }
2797
2798 bus->add_internal_return ();
2799 ret.push_back (bus);
2800 }
2801
2802 catch (failed_constructor &err) {
2803 error << _("Session: could not create new audio bus.") << endmsg;
2804 goto failure;
2805 }
2806
2807 catch (AudioEngine::PortRegistrationFailure& pfe) {
2808 error << pfe.what() << endmsg;
2809 goto failure;
2810 }
2811
2812
2813 --how_many;
2814 }
2815
2816 failure:
2817 if (!ret.empty()) {
2818 if (flags == PresentationInfo::FoldbackBus) {
2819 add_routes (ret, false, false, order); // no autoconnect
2820 } else {
2821 add_routes (ret, false, true, order); // autoconnect // outputs only
2822 }
2823 }
2824
2825 return ret;
2826
2827 }
2828
2829 RouteList
new_route_from_template(uint32_t how_many,PresentationInfo::order_t insert_at,const std::string & template_path,const std::string & name_base,PlaylistDisposition pd)2830 Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t insert_at, const std::string& template_path, const std::string& name_base,
2831 PlaylistDisposition pd)
2832 {
2833 XMLTree tree;
2834
2835 if (!tree.read (template_path.c_str())) {
2836 return RouteList();
2837 }
2838
2839 return new_route_from_template (how_many, insert_at, *tree.root(), name_base, pd);
2840 }
2841
2842 RouteList
new_route_from_template(uint32_t how_many,PresentationInfo::order_t insert_at,XMLNode & node,const std::string & name_base,PlaylistDisposition pd)2843 Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t insert_at, XMLNode& node, const std::string& name_base, PlaylistDisposition pd)
2844 {
2845 RouteList ret;
2846 uint32_t number = 0;
2847 const uint32_t being_added = how_many;
2848 /* This will prevent the use of any existing XML-provided PBD::ID
2849 values by Stateful.
2850 */
2851 Stateful::ForceIDRegeneration force_ids;
2852 IO::disable_connecting ();
2853
2854 /* New v6 templates do have a version in the Route-Template,
2855 * we assume that all older, unversioned templates are
2856 * from Ardour 5.x
2857 * when Stateful::loading_state_version was 3002
2858 */
2859 int version = 3002;
2860 node.get_property (X_("version"), version);
2861
2862 while (how_many) {
2863
2864 /* We're going to modify the node contents a bit so take a
2865 * copy. The node may be re-used when duplicating more than once.
2866 */
2867
2868 XMLNode node_copy (node);
2869 std::vector<boost::shared_ptr<Playlist> > shared_playlists;
2870
2871 try {
2872 string name;
2873
2874 if (!name_base.empty()) {
2875
2876 /* if we're adding more than one routes, force
2877 * all the names of the new routes to be
2878 * numbered, via the final parameter.
2879 */
2880
2881 if (!find_route_name (name_base.c_str(), ++number, name, (being_added > 1))) {
2882 fatal << _("Session: Failed to create unique ID for track from template.") << endmsg;
2883 abort(); /*NOTREACHED*/
2884 }
2885
2886 } else {
2887
2888 string const route_name = node_copy.property(X_("name"))->value ();
2889
2890 /* generate a new name by adding a number to the end of the template name */
2891 if (!find_route_name (route_name.c_str(), ++number, name, true)) {
2892 fatal << _("Session: Failed to generate unique name and ID for track from template.") << endmsg;
2893 abort(); /*NOTREACHED*/
2894 }
2895 }
2896
2897 /* figure out the appropriate playlist setup. The track
2898 * (if the Route we're creating is a track) will find
2899 * playlists via ID.
2900 */
2901
2902 if (pd == CopyPlaylist) {
2903
2904 PBD::ID playlist_id;
2905
2906 if (node_copy.get_property (X_("audio-playlist"), playlist_id)) {
2907 boost::shared_ptr<Playlist> playlist = _playlists->by_id (playlist_id);
2908 playlist = PlaylistFactory::create (playlist, string_compose ("%1.1", name));
2909 playlist->reset_shares ();
2910 node_copy.set_property (X_("audio-playlist"), playlist->id());
2911 }
2912
2913 if (node_copy.get_property (X_("midi-playlist"), playlist_id)) {
2914 boost::shared_ptr<Playlist> playlist = _playlists->by_id (playlist_id);
2915 playlist = PlaylistFactory::create (playlist, string_compose ("%1.1", name));
2916 playlist->reset_shares ();
2917 node_copy.set_property (X_("midi-playlist"), playlist->id());
2918 }
2919
2920 } else if (pd == SharePlaylist) {
2921 PBD::ID playlist_id;
2922
2923 if (node_copy.get_property (X_("audio-playlist"), playlist_id)) {
2924 boost::shared_ptr<Playlist> playlist = _playlists->by_id (playlist_id);
2925 shared_playlists.push_back (playlist);
2926 }
2927
2928 if (node_copy.get_property (X_("midi-playlist"), playlist_id)) {
2929 boost::shared_ptr<Playlist> playlist = _playlists->by_id (playlist_id);
2930 shared_playlists.push_back (playlist);
2931 }
2932
2933 } else { /* NewPlaylist */
2934
2935 PBD::ID pid;
2936 std::string default_type;
2937 node.get_property(X_("default-type"), default_type);
2938
2939 if (node_copy.get_property (X_("audio-playlist"), pid) || (version < 5000 && default_type == "audio")) {
2940 boost::shared_ptr<Playlist> playlist = PlaylistFactory::create (DataType::AUDIO, *this, name, false);
2941 node_copy.set_property (X_("audio-playlist"), playlist->id());
2942 }
2943
2944 if (node_copy.get_property (X_("midi-playlist"), pid) || (version < 5000 && default_type == "midi")) {
2945 boost::shared_ptr<Playlist> playlist = PlaylistFactory::create (DataType::MIDI, *this, name, false);
2946 node_copy.set_property (X_("midi-playlist"), playlist->id());
2947 }
2948 }
2949
2950 /* Fix up new name in the XML node */
2951
2952 Route::set_name_in_state (node_copy, name);
2953
2954 /* trim bitslots from listen sends so that new ones are used */
2955 XMLNodeList children = node_copy.children ();
2956 for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
2957 if ((*i)->name() == X_("Processor")) {
2958 /* ForceIDRegeneration does not catch the following */
2959 XMLProperty const * role = (*i)->property (X_("role"));
2960 XMLProperty const * type = (*i)->property (X_("type"));
2961
2962 if (role && role->value() == X_("Aux")) {
2963 /* Check if the target bus exists.
2964 * This is mainly useful when duplicating tracks
2965 * (aux-sends should not be saved in templates).
2966 */
2967 XMLProperty const * target = (*i)->property (X_("target"));
2968 if (!target) {
2969 (*i)->set_property ("type", "dangling-aux-send");
2970 continue;
2971 }
2972 boost::shared_ptr<Route> r = route_by_id (target->value());
2973 if (!r || boost::dynamic_pointer_cast<Track>(r)) {
2974 (*i)->set_property ("type", "dangling-aux-send");
2975 continue;
2976 }
2977 }
2978
2979 if (role && role->value() == X_("Listen")) {
2980 (*i)->remove_property (X_("bitslot"));
2981 }
2982 else if (role && (role->value() == X_("Send") || role->value() == X_("Aux"))) {
2983 Delivery::Role xrole;
2984 uint32_t bitslot = 0;
2985 xrole = Delivery::Role (string_2_enum (role->value(), xrole));
2986
2987 /* generate new bitslot ID */
2988 std::string name = Send::name_and_id_new_send(*this, xrole, bitslot, false);
2989 (*i)->remove_property (X_("bitslot"));
2990 (*i)->set_property ("bitslot", bitslot);
2991
2992 /* external sends need unique names */
2993 if (role->value() == X_("Send")) {
2994 (*i)->remove_property (X_("name"));
2995 (*i)->set_property ("name", name);
2996
2997 XMLNodeList io_kids = (*i)->children ();
2998 for (XMLNodeList::iterator j = io_kids.begin(); j != io_kids.end(); ++j) {
2999 if ((*j)->name() != X_("IO")) {
3000 continue;
3001 }
3002 (*j)->remove_property (X_("name"));
3003 (*j)->set_property ("name", name);
3004 }
3005 }
3006 }
3007 else if (type && type->value() == X_("intreturn")) {
3008 (*i)->remove_property (X_("bitslot"));
3009 (*i)->set_property ("ignore-bitslot", "1");
3010 }
3011 else if (type && type->value() == X_("return")) {
3012 // Return::set_state() generates a new one
3013 (*i)->remove_property (X_("bitslot"));
3014 }
3015 else if (type && type->value() == X_("port")) {
3016 IOProcessor::prepare_for_reset (**i, name);
3017 }
3018 }
3019 }
3020
3021 /* new routes start off unsoloed to avoid issues related to
3022 upstream / downstream buses.
3023 */
3024 node_copy.remove_node_and_delete (X_("Controllable"), X_("name"), X_("solo"));
3025
3026 boost::shared_ptr<Route> route;
3027
3028 if (version < 3000) {
3029 route = XMLRouteFactory_2X (node_copy, version);
3030 } else if (version < 5000) {
3031 route = XMLRouteFactory_3X (node_copy, version);
3032 } else {
3033 route = XMLRouteFactory (node_copy, version);
3034 }
3035
3036 if (route == 0) {
3037 error << _("Session: cannot create track/bus from template description") << endmsg;
3038 goto out;
3039 }
3040
3041 {
3042 PresentationInfo& rpi = route->presentation_info ();
3043 rpi.set_flags (PresentationInfo::Flag (rpi.flags() & ~PresentationInfo::OrderSet));
3044 }
3045
3046 /* Fix up sharing of playlists with the new Route/Track */
3047
3048 for (vector<boost::shared_ptr<Playlist> >::iterator sp = shared_playlists.begin(); sp != shared_playlists.end(); ++sp) {
3049 (*sp)->share_with (route->id());
3050 }
3051
3052 if (boost::dynamic_pointer_cast<Track>(route)) {
3053 /* force input/output change signals so that the new diskstream
3054 picks up the configuration of the route. During session
3055 loading this normally happens in a different way.
3056 */
3057
3058 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3059
3060 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
3061 change.after = route->input()->n_ports();
3062 route->input()->changed (change, this);
3063 change.after = route->output()->n_ports();
3064 route->output()->changed (change, this);
3065 }
3066
3067 ret.push_back (route);
3068 }
3069
3070 catch (failed_constructor &err) {
3071 error << _("Session: could not create new track/bus from template") << endmsg;
3072 goto out;
3073 }
3074
3075 catch (AudioEngine::PortRegistrationFailure& pfe) {
3076 error << pfe.what() << endmsg;
3077 goto out;
3078 }
3079
3080 catch (...) {
3081 IO::enable_connecting ();
3082 throw;
3083 }
3084
3085 --how_many;
3086 }
3087
3088 out:
3089 if (!ret.empty()) {
3090 add_routes (ret, true, true, insert_at);
3091 }
3092
3093 IO::enable_connecting ();
3094
3095 if (!ret.empty()) {
3096 /* set/unset monitor-send */
3097 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
3098 for (RouteList::iterator x = ret.begin(); x != ret.end(); ++x) {
3099 if ((*x)->can_monitor ()) {
3100 if (_monitor_out) {
3101 (*x)->enable_monitor_send ();
3102 } else {
3103 /* this may happen with old templates */
3104 (*x)->remove_monitor_send ();
3105 }
3106 }
3107 }
3108 }
3109
3110 return ret;
3111 }
3112
3113 void
add_routes(RouteList & new_routes,bool input_auto_connect,bool output_auto_connect,PresentationInfo::order_t order)3114 Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t order)
3115 {
3116 try {
3117 PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
3118 add_routes_inner (new_routes, input_auto_connect, output_auto_connect, order);
3119
3120 } catch (...) {
3121 error << _("Adding new tracks/busses failed") << endmsg;
3122 }
3123
3124 /* During the route additions there will have been potentially several
3125 * signals emitted to indicate the new graph. ::graph_reordered() will
3126 * have ignored all of them because _adding_routes_in_progress was
3127 * true.
3128 *
3129 * We still need the effects of ::graph_reordered(), but we didn't want
3130 * it called multiple times during the addition of multiple routes. Now
3131 * that the addition is done, call it explicitly.
3132 */
3133
3134 graph_reordered (false);
3135
3136 set_dirty();
3137
3138 update_route_record_state ();
3139
3140 RouteAdded (new_routes); /* EMIT SIGNAL */
3141 }
3142
3143 void
add_routes_inner(RouteList & new_routes,bool input_auto_connect,bool output_auto_connect,PresentationInfo::order_t order)3144 Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t order)
3145 {
3146 ChanCount existing_inputs;
3147 ChanCount existing_outputs;
3148 uint32_t n_routes;
3149 uint32_t added = 0;
3150
3151 count_existing_track_channels (existing_inputs, existing_outputs);
3152
3153 {
3154 RCUWriter<RouteList> writer (routes);
3155 boost::shared_ptr<RouteList> r = writer.get_copy ();
3156 n_routes = r->size();
3157 r->insert (r->end(), new_routes.begin(), new_routes.end());
3158
3159 /* if there is no control out and we're not in the middle of loading,
3160 * resort the graph here. if there is a control out, we will resort
3161 * toward the end of this method. if we are in the middle of loading,
3162 * we will resort when done.
3163 */
3164
3165 if (!_monitor_out && IO::connecting_legal) {
3166 resort_routes_using (r);
3167 }
3168 }
3169
3170 /* monitor is not part of the order */
3171 if (_monitor_out) {
3172 assert (n_routes > 0);
3173 --n_routes;
3174 }
3175
3176 {
3177 PresentationInfo::ChangeSuspender cs;
3178 ensure_route_presentation_info_gap (order, new_routes.size());
3179
3180 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x, ++added) {
3181
3182 boost::weak_ptr<Route> wpr (*x);
3183 boost::shared_ptr<Route> r (*x);
3184
3185 r->solo_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2,wpr));
3186 r->solo_isolate_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr));
3187 r->mute_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this));
3188
3189 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
3190 r->processor_latency_changed.connect_same_thread (*this, boost::bind (&Session::queue_latency_recompute, this));
3191
3192 if (r->is_master()) {
3193 _master_out = r;
3194 }
3195
3196 if (r->is_monitor()) {
3197 _monitor_out = r;
3198 }
3199
3200 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
3201 if (tr) {
3202 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
3203 track_playlist_changed (boost::weak_ptr<Track> (tr));
3204 tr->rec_enable_control()->Changed.connect_same_thread (*this, boost::bind (&Session::update_route_record_state, this));
3205
3206 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
3207 if (mt) {
3208 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
3209 mt->presentation_info().PropertyChanged.connect_same_thread (*this, boost::bind (&Session::midi_track_presentation_info_changed, this, _1, boost::weak_ptr<MidiTrack>(mt)));
3210 }
3211 }
3212
3213 if (!r->presentation_info().special (false)) {
3214
3215 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("checking PI state for %1\n", r->name()));
3216
3217 /* presentation info order may already have been set from XML */
3218
3219 if (!r->presentation_info().order_set()) {
3220 if (order == PresentationInfo::max_order) {
3221 /* just add to the end */
3222 r->set_presentation_order (n_routes + added);
3223 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to NR %1 + %2 = %3\n", n_routes, added, n_routes + added));
3224 } else {
3225 r->set_presentation_order (order + added);
3226 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to %1 + %2 = %3\n", order, added, order + added));
3227 }
3228 } else {
3229 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order already set to %1\n", r->presentation_info().order()));
3230 }
3231 }
3232
3233 #if !defined(__APPLE__) && !defined(__FreeBSD__)
3234 /* clang complains: 'operator<<' should be declared prior to the call site or in an associated namespace of one of its
3235 * arguments std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid)"
3236 */
3237 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("added route %1, group order %2 type %3 (summary: %4)\n",
3238 r->name(),
3239 r->presentation_info().order(),
3240 enum_2_string (r->presentation_info().flags()),
3241 r->presentation_info()));
3242 #endif
3243
3244
3245 if (input_auto_connect || output_auto_connect) {
3246 auto_connect_route (r, input_auto_connect, output_auto_connect, ChanCount (), ChanCount (), existing_inputs, existing_outputs);
3247 if (input_auto_connect) {
3248 existing_inputs += r->n_inputs();
3249 }
3250 if (output_auto_connect) {
3251 existing_outputs += r->n_outputs();
3252 }
3253 }
3254
3255 ARDOUR::GUIIdle ();
3256 }
3257 ensure_stripable_sort_order ();
3258 }
3259
3260 if (_monitor_out && IO::connecting_legal) {
3261 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
3262
3263 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
3264 if ((*x)->can_monitor ()) {
3265 (*x)->enable_monitor_send ();
3266 }
3267 }
3268 }
3269
3270 reassign_track_numbers ();
3271 }
3272
3273 void
load_and_connect_instruments(RouteList & new_routes,bool strict_io,boost::shared_ptr<PluginInfo> instrument,Plugin::PresetRecord * pset,ChanCount & existing_outputs)3274 Session::load_and_connect_instruments (RouteList& new_routes, bool strict_io, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset, ChanCount& existing_outputs)
3275 {
3276 if (instrument) {
3277 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
3278 PluginPtr plugin = instrument->load (*this);
3279 if (!plugin) {
3280 warning << "Failed to add Synth Plugin to newly created track." << endmsg;
3281 continue;
3282 }
3283 if (pset) {
3284 plugin->load_preset (*pset);
3285 }
3286 boost::shared_ptr<PluginInsert> pi (new PluginInsert (*this, plugin));
3287 if (strict_io) {
3288 pi->set_strict_io (true);
3289 }
3290
3291 (*r)->add_processor (pi, PreFader);
3292
3293 if (Profile->get_mixbus () && pi->configured () && pi->output_streams().n_audio() > 2) {
3294 (*r)->move_instrument_down (false);
3295 }
3296
3297 /* Route::add_processors -> Delivery::configure_io -> IO::ensure_ports
3298 * should have registered the ports, so now we can call.. */
3299 if (!(*r)->instrument_fanned_out ()) {
3300 auto_connect_route (*r, false, true, ChanCount (), ChanCount (), ChanCount (), existing_outputs);
3301 existing_outputs += (*r)->n_outputs();
3302 }
3303 }
3304 }
3305 for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
3306 (*r)->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(*r)));
3307 }
3308 }
3309
3310 void
globally_set_send_gains_to_zero(boost::shared_ptr<Route> dest)3311 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
3312 {
3313 boost::shared_ptr<RouteList> r = routes.reader ();
3314 boost::shared_ptr<Send> s;
3315
3316 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3317 if ((s = (*i)->internal_send_for (dest)) != 0) {
3318 s->amp()->gain_control()->set_value (GAIN_COEFF_ZERO, Controllable::NoGroup);
3319 }
3320 }
3321 }
3322
3323 void
globally_set_send_gains_to_unity(boost::shared_ptr<Route> dest)3324 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
3325 {
3326 boost::shared_ptr<RouteList> r = routes.reader ();
3327 boost::shared_ptr<Send> s;
3328
3329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3330 if ((s = (*i)->internal_send_for (dest)) != 0) {
3331 s->amp()->gain_control()->set_value (GAIN_COEFF_UNITY, Controllable::NoGroup);
3332 }
3333 }
3334 }
3335
3336 void
globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)3337 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
3338 {
3339 boost::shared_ptr<RouteList> r = routes.reader ();
3340 boost::shared_ptr<Send> s;
3341
3342 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3343 if ((s = (*i)->internal_send_for (dest)) != 0) {
3344 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value(), Controllable::NoGroup);
3345 }
3346 }
3347 }
3348
3349 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
3350 void
globally_add_internal_sends(boost::shared_ptr<Route> dest,Placement p,bool include_buses)3351 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
3352 {
3353 boost::shared_ptr<RouteList> r = routes.reader ();
3354 boost::shared_ptr<RouteList> t (new RouteList);
3355
3356 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3357 /* no MIDI sends because there are no MIDI busses yet */
3358 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
3359 t->push_back (*i);
3360 }
3361 }
3362
3363 add_internal_sends (dest, p, t);
3364 }
3365
3366 void
add_internal_sends(boost::shared_ptr<Route> dest,Placement p,boost::shared_ptr<RouteList> senders)3367 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
3368 {
3369 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
3370 add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
3371 }
3372 }
3373
3374 void
add_internal_send(boost::shared_ptr<Route> dest,int index,boost::shared_ptr<Route> sender)3375 Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
3376 {
3377 add_internal_send (dest, sender->before_processor_for_index (index), sender);
3378 }
3379
3380 void
add_internal_send(boost::shared_ptr<Route> dest,boost::shared_ptr<Processor> before,boost::shared_ptr<Route> sender)3381 Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
3382 {
3383 if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
3384 return;
3385 }
3386
3387 if (!dest->internal_return()) {
3388 dest->add_internal_return ();
3389 }
3390
3391 sender->add_aux_send (dest, before);
3392
3393 graph_reordered (false);
3394 }
3395
3396 void
remove_routes(boost::shared_ptr<RouteList> routes_to_remove)3397 Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
3398 {
3399 bool mute_changed = false;
3400 bool send_selected = false;
3401
3402 { // RCU Writer scope
3403 PBD::Unwinder<bool> uw_flag (_route_deletion_in_progress, true);
3404 RCUWriter<RouteList> writer (routes);
3405 boost::shared_ptr<RouteList> rs = writer.get_copy ();
3406
3407 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3408
3409 if (_selection->selected (*iter)) {
3410 send_selected = true;
3411 }
3412
3413 if (*iter == _master_out) {
3414 continue;
3415 }
3416
3417 /* speed up session deletion, don't do the solo dance */
3418 if (!deletion_in_progress ()) {
3419 (*iter)->solo_control()->set_value (0.0, Controllable::NoGroup);
3420 }
3421
3422 if ((*iter)->mute_control()->muted ()) {
3423 mute_changed = true;
3424 }
3425
3426 rs->remove (*iter);
3427
3428 /* deleting the master out seems like a dumb
3429 idea, but its more of a UI policy issue
3430 than our concern.
3431 */
3432
3433 if (*iter == _master_out) {
3434 _master_out = boost::shared_ptr<Route> ();
3435 }
3436
3437 if (*iter == _monitor_out) {
3438 _monitor_out.reset ();
3439 }
3440
3441 // We need to disconnect the route's inputs and outputs
3442
3443 (*iter)->input()->disconnect (0);
3444 (*iter)->output()->disconnect (0);
3445
3446 /* if the route had internal sends sending to it, remove them */
3447
3448 if (!deletion_in_progress () && (*iter)->internal_return()) {
3449
3450 boost::shared_ptr<RouteList> r = routes.reader ();
3451 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3452 boost::shared_ptr<Send> s = (*i)->internal_send_for (*iter);
3453 if (s) {
3454 (*i)->remove_processor (s);
3455 }
3456 }
3457 }
3458
3459 /* if the monitoring section had a pointer to this route, remove it */
3460 if (!deletion_in_progress () && _monitor_out && (*iter)->can_monitor ()) {
3461 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
3462 ProcessorChangeBlocker pcb (this, false);
3463 (*iter)->remove_monitor_send ();
3464 }
3465
3466 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*iter);
3467 if (mt && mt->step_editing()) {
3468 if (_step_editors > 0) {
3469 _step_editors--;
3470 }
3471 }
3472 }
3473
3474 /* writer goes out of scope, forces route list update */
3475
3476 } // end of RCU Writer scope
3477
3478 if (mute_changed) {
3479 MuteChanged (); /* EMIT SIGNAL */
3480 }
3481
3482 update_route_solo_state ();
3483 update_latency_compensation (false, false);
3484 set_dirty();
3485
3486 /* Re-sort routes to remove the graph's current references to the one that is
3487 * going away, then flush old references out of the graph.
3488 */
3489
3490 routes.flush (); // maybe unsafe, see below.
3491 resort_routes ();
3492
3493 if (_process_graph && !deletion_in_progress() && _engine.running()) {
3494 _process_graph->clear_other_chain ();
3495 }
3496
3497 /* get rid of it from the dead wood collection in the route list manager */
3498 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
3499
3500 routes.flush ();
3501
3502 /* remove these routes from the selection if appropriate, and signal
3503 * the change *before* we call DropReferences for them.
3504 */
3505
3506 if (send_selected && !deletion_in_progress()) {
3507 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3508 _selection->remove_stripable_by_id ((*iter)->id());
3509 }
3510 PropertyChange pc;
3511 pc.add (Properties::selected);
3512 PresentationInfo::Change (pc);
3513 }
3514
3515 /* try to cause everyone to drop their references
3516 * and unregister ports from the backend
3517 */
3518
3519 for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
3520 (*iter)->drop_references ();
3521 }
3522
3523 if (deletion_in_progress()) {
3524 return;
3525 }
3526
3527 PropertyChange pc;
3528 pc.add (Properties::order);
3529 PresentationInfo::Change (pc);
3530
3531 update_route_record_state ();
3532 }
3533
3534 void
remove_route(boost::shared_ptr<Route> route)3535 Session::remove_route (boost::shared_ptr<Route> route)
3536 {
3537 boost::shared_ptr<RouteList> rl (new RouteList);
3538 rl->push_back (route);
3539 remove_routes (rl);
3540 }
3541
3542 void
route_mute_changed()3543 Session::route_mute_changed ()
3544 {
3545 MuteChanged (); /* EMIT SIGNAL */
3546 set_dirty ();
3547 }
3548
3549 void
route_listen_changed(Controllable::GroupControlDisposition group_override,boost::weak_ptr<Route> wpr)3550 Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
3551 {
3552 boost::shared_ptr<Route> route (wpr.lock());
3553
3554 if (!route) {
3555 return;
3556 }
3557
3558 assert (Config->get_solo_control_is_listen_control());
3559
3560 if (route->solo_control()->soloed_by_self_or_masters()) {
3561
3562 if (Config->get_exclusive_solo()) {
3563
3564 _engine.monitor_port().clear_ports (false);
3565
3566 RouteGroup* rg = route->route_group ();
3567 const bool group_already_accounted_for = (group_override == Controllable::ForGroup);
3568
3569 boost::shared_ptr<RouteList> r = routes.reader ();
3570
3571 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3572 if ((*i) == route) {
3573 /* already changed */
3574 continue;
3575 }
3576
3577 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_monitor()) {
3578 /* route does not get solo propagated to it */
3579 continue;
3580 }
3581
3582 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3583 /* this route is a part of the same solo group as the route
3584 * that was changed. Changing that route did change or will
3585 * change all group members appropriately, so we can ignore it
3586 * here
3587 */
3588 continue;
3589 }
3590 (*i)->solo_control()->set_value (0.0, Controllable::NoGroup);
3591 }
3592 }
3593
3594 _listen_cnt++;
3595
3596 } else if (_listen_cnt > 0) {
3597
3598 _listen_cnt--;
3599 }
3600 }
3601
3602 void
route_solo_isolated_changed(boost::weak_ptr<Route> wpr)3603 Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr)
3604 {
3605 boost::shared_ptr<Route> route (wpr.lock());
3606
3607 if (!route) {
3608 return;
3609 }
3610
3611 bool send_changed = false;
3612
3613 if (route->solo_isolate_control()->solo_isolated()) {
3614 if (_solo_isolated_cnt == 0) {
3615 send_changed = true;
3616 }
3617 _solo_isolated_cnt++;
3618 } else if (_solo_isolated_cnt > 0) {
3619 _solo_isolated_cnt--;
3620 if (_solo_isolated_cnt == 0) {
3621 send_changed = true;
3622 }
3623 }
3624
3625 if (send_changed) {
3626 IsolatedChanged (); /* EMIT SIGNAL */
3627 }
3628 }
3629
3630 void
route_solo_changed(bool self_solo_changed,Controllable::GroupControlDisposition group_override,boost::weak_ptr<Route> wpr)3631 Session::route_solo_changed (bool self_solo_changed, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
3632 {
3633 DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1, update\n", self_solo_changed));
3634
3635 boost::shared_ptr<Route> route (wpr.lock());
3636
3637 if (!route) {
3638 return;
3639 }
3640
3641 if (Config->get_solo_control_is_listen_control()) {
3642 route_listen_changed (group_override, wpr);
3643 return;
3644 }
3645
3646 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()));
3647
3648 if (route->solo_control()->transitioned_into_solo() == 0) {
3649 /* route solo changed by upstream/downstream or clear all solo state; not interesting
3650 to Session.
3651 */
3652 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()));
3653 return;
3654 }
3655
3656 boost::shared_ptr<RouteList> r = routes.reader ();
3657 int32_t delta = route->solo_control()->transitioned_into_solo ();
3658
3659 /* the route may be a member of a group that has shared-solo
3660 * semantics. If so, then all members of that group should follow the
3661 * solo of the changed route. But ... this is optional, controlled by a
3662 * Controllable::GroupControlDisposition.
3663 *
3664 * The first argument to the signal that this method is connected to is the
3665 * GroupControlDisposition value that was used to change solo.
3666 *
3667 * If the solo change was done with group semantics (either InverseGroup
3668 * (force the entire group to change even if the group shared solo is
3669 * disabled) or UseGroup (use the group, which may or may not have the
3670 * shared solo property enabled)) then as we propagate the change to
3671 * the entire session we should IGNORE THE GROUP that the changed route
3672 * belongs to.
3673 */
3674
3675 RouteGroup* rg = route->route_group ();
3676 const bool group_already_accounted_for = (group_override == Controllable::ForGroup);
3677
3678 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate to session, group accounted for ? %1\n", group_already_accounted_for));
3679
3680 if (delta == 1 && Config->get_exclusive_solo()) {
3681
3682 /* new solo: disable all other solos, but not the group if its solo-enabled */
3683 _engine.monitor_port().clear_ports (false);
3684
3685 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3686
3687 if ((*i) == route) {
3688 /* already changed */
3689 continue;
3690 }
3691
3692 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3693 /* route does not get solo propagated to it */
3694 continue;
3695 }
3696
3697 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3698 /* this route is a part of the same solo group as the route
3699 * that was changed. Changing that route did change or will
3700 * change all group members appropriately, so we can ignore it
3701 * here
3702 */
3703 continue;
3704 }
3705
3706 (*i)->solo_control()->set_value (0.0, group_override);
3707 }
3708 }
3709
3710 DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
3711
3712 RouteList uninvolved;
3713
3714 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
3715
3716 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3717 bool in_signal_flow;
3718
3719 if ((*i) == route) {
3720 /* already changed */
3721 continue;
3722 }
3723
3724 if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) {
3725 /* route does not get solo propagated to it */
3726 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(),
3727 (*i)->can_solo()));
3728 continue;
3729 }
3730
3731 if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
3732 /* this route is a part of the same solo group as the route
3733 * that was changed. Changing that route did change or will
3734 * change all group members appropriately, so we can ignore it
3735 * here
3736 */
3737 continue;
3738 }
3739
3740 in_signal_flow = false;
3741
3742 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
3743
3744 if ((*i)->feeds (route)) {
3745 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
3746 if (!route->soloed_by_others_upstream()) {
3747 (*i)->solo_control()->mod_solo_by_others_downstream (delta);
3748 } else {
3749 DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others upstream\n");
3750 }
3751 in_signal_flow = true;
3752 } else {
3753 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
3754 }
3755
3756 DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
3757
3758 if (route->feeds (*i)) {
3759 DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 sboD %3 sboU %4\n",
3760 route->name(),
3761 (*i)->name(),
3762 route->soloed_by_others_downstream(),
3763 route->soloed_by_others_upstream()));
3764 //NB. Triggers Invert Push, which handles soloed by downstream
3765 DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
3766 (*i)->solo_control()->mod_solo_by_others_upstream (delta);
3767 in_signal_flow = true;
3768 } else {
3769 DEBUG_TRACE (DEBUG::Solo, string_compose("\tno feed to %1\n", (*i)->name()) );
3770 }
3771
3772 if (!in_signal_flow) {
3773 uninvolved.push_back (*i);
3774 }
3775 }
3776
3777 DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
3778
3779 /* now notify that the mute state of the routes not involved in the signal
3780 pathway of the just-solo-changed route may have altered.
3781 */
3782
3783 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
3784 DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
3785 (*i)->act_on_mute ();
3786 /* Session will emit SoloChanged() after all solo changes are
3787 * complete, which should be used by UIs to update mute status
3788 */
3789 }
3790 }
3791
3792 void
update_route_solo_state(boost::shared_ptr<RouteList> r)3793 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
3794 {
3795 /* now figure out if anything that matters is soloed (or is "listening")*/
3796
3797 bool something_soloed = false;
3798 bool something_listening = false;
3799 uint32_t listeners = 0;
3800 uint32_t isolated = 0;
3801
3802 if (!r) {
3803 r = routes.reader();
3804 }
3805
3806 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3807 if ((*i)->can_monitor() && Config->get_solo_control_is_listen_control()) {
3808 if ((*i)->solo_control()->soloed_by_self_or_masters()) {
3809 listeners++;
3810 something_listening = true;
3811 }
3812 } else if ((*i)->can_solo()) {
3813 (*i)->set_listen (false);
3814 if ((*i)->can_solo() && (*i)->solo_control()->soloed_by_self_or_masters()) {
3815 something_soloed = true;
3816 }
3817 }
3818
3819 if ((*i)->solo_isolate_control()->solo_isolated()) {
3820 isolated++;
3821 }
3822 }
3823
3824 if (something_soloed != _non_soloed_outs_muted) {
3825 _non_soloed_outs_muted = something_soloed;
3826 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
3827 }
3828
3829 if (something_listening != _listening) {
3830 _listening = something_listening;
3831 SoloActive (_listening);
3832 }
3833
3834 _listen_cnt = listeners;
3835
3836 if (isolated != _solo_isolated_cnt) {
3837 _solo_isolated_cnt = isolated;
3838 IsolatedChanged (); /* EMIT SIGNAL */
3839 }
3840
3841 DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
3842 something_soloed, listeners, isolated));
3843
3844
3845 SoloChanged (); /* EMIT SIGNAL */
3846 set_dirty();
3847 }
3848
3849 bool
muted() const3850 Session::muted () const
3851 {
3852 // TODO consider caching the value on every MuteChanged signal,
3853 // Note that API users may also subscribe to MuteChanged and hence
3854 // this method needs to be called first.
3855 bool muted = false;
3856 StripableList all;
3857 get_stripables (all);
3858 for (StripableList::const_iterator i = all.begin(); i != all.end(); ++i) {
3859 assert (!(*i)->is_auditioner()); // XXX remove me
3860 if ((*i)->is_monitor()) {
3861 continue;
3862 }
3863 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(*i);
3864 if (r && !r->active()) {
3865 continue;
3866 }
3867 boost::shared_ptr<MuteControl> mc = (*i)->mute_control();
3868 if (mc && mc->muted ()) {
3869 muted = true;
3870 break;
3871 }
3872 }
3873 return muted;
3874 }
3875
3876 std::vector<boost::weak_ptr<AutomationControl> >
cancel_all_mute()3877 Session::cancel_all_mute ()
3878 {
3879 StripableList all;
3880 get_stripables (all);
3881 std::vector<boost::weak_ptr<AutomationControl> > muted;
3882 boost::shared_ptr<ControlList> cl (new ControlList);
3883 for (StripableList::const_iterator i = all.begin(); i != all.end(); ++i) {
3884 assert (!(*i)->is_auditioner());
3885 if ((*i)->is_monitor()) {
3886 continue;
3887 }
3888 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (*i);
3889 if (r && !r->active()) {
3890 continue;
3891 }
3892 boost::shared_ptr<AutomationControl> ac = (*i)->mute_control();
3893 if (ac && ac->get_value () > 0) {
3894 cl->push_back (ac);
3895 muted.push_back (boost::weak_ptr<AutomationControl>(ac));
3896 }
3897 }
3898 if (!cl->empty ()) {
3899 set_controls (cl, 0.0, PBD::Controllable::UseGroup);
3900 }
3901 return muted;
3902 }
3903
3904 void
get_stripables(StripableList & sl,PresentationInfo::Flag fl) const3905 Session::get_stripables (StripableList& sl, PresentationInfo::Flag fl) const
3906 {
3907 boost::shared_ptr<RouteList> r = routes.reader ();
3908 for (RouteList::iterator it = r->begin(); it != r->end(); ++it) {
3909 if ((*it)->presentation_info ().flags () & fl) {
3910 sl.push_back (*it);
3911 }
3912 }
3913
3914 if (fl & PresentationInfo::VCA) {
3915 VCAList v = _vca_manager->vcas ();
3916 sl.insert (sl.end(), v.begin(), v.end());
3917 }
3918 }
3919
3920 StripableList
get_stripables() const3921 Session::get_stripables () const
3922 {
3923 PresentationInfo::Flag fl = PresentationInfo::AllStripables;
3924 StripableList rv;
3925 Session::get_stripables (rv, fl);
3926 rv.sort (Stripable::Sorter ());
3927 return rv;
3928 }
3929
3930 RouteList
get_routelist(bool mixer_order,PresentationInfo::Flag fl) const3931 Session::get_routelist (bool mixer_order, PresentationInfo::Flag fl) const
3932 {
3933 boost::shared_ptr<RouteList> r = routes.reader ();
3934 RouteList rv;
3935 for (RouteList::iterator it = r->begin(); it != r->end(); ++it) {
3936 if ((*it)->presentation_info ().flags () & fl) {
3937 rv.push_back (*it);
3938 }
3939 }
3940 rv.sort (Stripable::Sorter (mixer_order));
3941 return rv;
3942 }
3943
3944 boost::shared_ptr<RouteList>
get_routes_with_internal_returns() const3945 Session::get_routes_with_internal_returns() const
3946 {
3947 boost::shared_ptr<RouteList> r = routes.reader ();
3948 boost::shared_ptr<RouteList> rl (new RouteList);
3949
3950 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3951 if ((*i)->internal_return ()) {
3952 rl->push_back (*i);
3953 }
3954 }
3955 return rl;
3956 }
3957
3958 bool
io_name_is_legal(const std::string & name) const3959 Session::io_name_is_legal (const std::string& name) const
3960 {
3961 boost::shared_ptr<RouteList> r = routes.reader ();
3962
3963 for (map<string,bool>::const_iterator reserved = reserved_io_names.begin(); reserved != reserved_io_names.end(); ++reserved) {
3964 if (name == reserved->first) {
3965 if (!route_by_name (reserved->first)) {
3966 /* first instance of a reserved name is allowed for some */
3967 return reserved->second;
3968 }
3969 /* all other instances of a reserved name are not allowed */
3970 return false;
3971 }
3972 }
3973
3974 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3975 if ((*i)->name() == name) {
3976 return false;
3977 }
3978
3979 if ((*i)->has_io_processor_named (name)) {
3980 return false;
3981 }
3982 }
3983
3984 return true;
3985 }
3986
3987 void
set_exclusive_input_active(boost::shared_ptr<RouteList> rl,bool onoff,bool flip_others)3988 Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
3989 {
3990 RouteList rl2;
3991 vector<string> connections;
3992
3993 /* if we are passed only a single route and we're not told to turn
3994 * others off, then just do the simple thing.
3995 */
3996
3997 if (flip_others == false && rl->size() == 1) {
3998 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
3999 if (mt) {
4000 mt->set_input_active (onoff);
4001 return;
4002 }
4003 }
4004
4005 for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
4006
4007 PortSet& ps ((*rt)->input()->ports());
4008
4009 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
4010 p->get_connections (connections);
4011 }
4012
4013 for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
4014 routes_using_input_from (*s, rl2);
4015 }
4016
4017 /* scan all relevant routes to see if others are on or off */
4018
4019 bool others_are_already_on = false;
4020
4021 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
4022
4023 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
4024
4025 if (!mt) {
4026 continue;
4027 }
4028
4029 if ((*r) != (*rt)) {
4030 if (mt->input_active()) {
4031 others_are_already_on = true;
4032 }
4033 } else {
4034 /* this one needs changing */
4035 mt->set_input_active (onoff);
4036 }
4037 }
4038
4039 if (flip_others) {
4040
4041 /* globally reverse other routes */
4042
4043 for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
4044 if ((*r) != (*rt)) {
4045 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
4046 if (mt) {
4047 mt->set_input_active (!others_are_already_on);
4048 }
4049 }
4050 }
4051 }
4052 }
4053 }
4054
4055 void
routes_using_input_from(const string & str,RouteList & rl)4056 Session::routes_using_input_from (const string& str, RouteList& rl)
4057 {
4058 boost::shared_ptr<RouteList> r = routes.reader();
4059
4060 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4061 if ((*i)->input()->connected_to (str)) {
4062 rl.push_back (*i);
4063 }
4064 }
4065 }
4066
4067 boost::shared_ptr<Route>
route_by_name(string name) const4068 Session::route_by_name (string name) const
4069 {
4070 boost::shared_ptr<RouteList> r = routes.reader ();
4071
4072 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4073 if ((*i)->name() == name) {
4074 return *i;
4075 }
4076 }
4077
4078 return boost::shared_ptr<Route> ((Route*) 0);
4079 }
4080
4081 boost::shared_ptr<Route>
route_by_id(PBD::ID id) const4082 Session::route_by_id (PBD::ID id) const
4083 {
4084 boost::shared_ptr<RouteList> r = routes.reader ();
4085
4086 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4087 if ((*i)->id() == id) {
4088 return *i;
4089 }
4090 }
4091
4092 return boost::shared_ptr<Route> ((Route*) 0);
4093 }
4094
4095
4096 boost::shared_ptr<Stripable>
stripable_by_id(PBD::ID id) const4097 Session::stripable_by_id (PBD::ID id) const
4098 {
4099 StripableList sl;
4100 get_stripables (sl);
4101
4102 for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
4103 if ((*s)->id() == id) {
4104 return *s;
4105 }
4106 }
4107
4108 return boost::shared_ptr<Stripable>();
4109 }
4110
4111 boost::shared_ptr<Processor>
processor_by_id(PBD::ID id) const4112 Session::processor_by_id (PBD::ID id) const
4113 {
4114 boost::shared_ptr<RouteList> r = routes.reader ();
4115
4116 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4117 boost::shared_ptr<Processor> p = (*i)->Route::processor_by_id (id);
4118 if (p) {
4119 return p;
4120 }
4121 }
4122
4123 return boost::shared_ptr<Processor> ();
4124 }
4125
4126 boost::shared_ptr<Route>
get_remote_nth_route(PresentationInfo::order_t n) const4127 Session::get_remote_nth_route (PresentationInfo::order_t n) const
4128 {
4129 return boost::dynamic_pointer_cast<Route> (get_remote_nth_stripable (n, PresentationInfo::Route));
4130 }
4131
4132 boost::shared_ptr<Stripable>
get_remote_nth_stripable(PresentationInfo::order_t n,PresentationInfo::Flag flags) const4133 Session::get_remote_nth_stripable (PresentationInfo::order_t n, PresentationInfo::Flag flags) const
4134 {
4135 StripableList sl;
4136 PresentationInfo::order_t match_cnt = 0;
4137
4138 get_stripables (sl);
4139 sl.sort (Stripable::Sorter());
4140
4141 for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
4142
4143 if ((*s)->presentation_info().hidden()) {
4144 /* if the caller didn't explicitly ask for hidden
4145 stripables, ignore hidden ones. This matches
4146 the semantics of the pre-PresentationOrder
4147 "get by RID" logic of Ardour 4.x and earlier.
4148
4149 XXX at some point we should likely reverse
4150 the logic of the flags, because asking for "the
4151 hidden stripables" is not going to be common,
4152 whereas asking for visible ones is normal.
4153 */
4154
4155 if (! (flags & PresentationInfo::Hidden)) {
4156 continue;
4157 }
4158 }
4159
4160 if ((*s)->presentation_info().flag_match (flags)) {
4161 if (match_cnt++ == n) {
4162 return *s;
4163 }
4164 }
4165 }
4166
4167 /* there is no nth stripable that matches the given flags */
4168 return boost::shared_ptr<Stripable>();
4169 }
4170
4171 boost::shared_ptr<Route>
route_by_selected_count(uint32_t id) const4172 Session::route_by_selected_count (uint32_t id) const
4173 {
4174 RouteList r (*(routes.reader ()));
4175 r.sort (Stripable::Sorter());
4176
4177 RouteList::iterator i;
4178
4179 for (i = r.begin(); i != r.end(); ++i) {
4180 if ((*i)->is_selected()) {
4181 if (id == 0) {
4182 return *i;
4183 }
4184 --id;
4185 }
4186 }
4187
4188 return boost::shared_ptr<Route> ();
4189 }
4190
4191 void
reassign_track_numbers()4192 Session::reassign_track_numbers ()
4193 {
4194 int64_t tn = 0;
4195 int64_t bn = 0;
4196 RouteList r (*(routes.reader ()));
4197 r.sort (Stripable::Sorter());
4198
4199 StateProtector sp (this);
4200
4201 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
4202 assert (!(*i)->is_auditioner());
4203 if (boost::dynamic_pointer_cast<Track> (*i)) {
4204 (*i)->set_track_number(++tn);
4205 }
4206 else if (!(*i)->is_master() && !(*i)->is_monitor()) {
4207 (*i)->set_track_number(--bn);
4208 }
4209 }
4210 const uint32_t decimals = ceilf (log10f (tn + 1));
4211 const bool decimals_changed = _track_number_decimals != decimals;
4212 _track_number_decimals = decimals;
4213
4214 if (decimals_changed && config.get_track_name_number ()) {
4215 for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
4216 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
4217 if (t) {
4218 t->resync_take_name ();
4219 }
4220 }
4221 // trigger GUI re-layout
4222 config.ParameterChanged("track-name-number");
4223 }
4224
4225 #ifndef NDEBUG
4226 if (DEBUG_ENABLED(DEBUG::OrderKeys)) {
4227 boost::shared_ptr<RouteList> rl = routes.reader ();
4228 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4229 DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 numbered %2\n", (*i)->name(), (*i)->track_number()));
4230 }
4231 }
4232 #endif /* NDEBUG */
4233
4234 }
4235
4236 void
playlist_region_added(boost::weak_ptr<Region> w)4237 Session::playlist_region_added (boost::weak_ptr<Region> w)
4238 {
4239 boost::shared_ptr<Region> r = w.lock ();
4240 if (!r) {
4241 return;
4242 }
4243
4244 /* These are the operations that are currently in progress... */
4245 list<GQuark> curr = _current_trans_quarks;
4246 curr.sort ();
4247
4248 /* ...and these are the operations during which we want to update
4249 the session range location markers.
4250 */
4251 list<GQuark> ops;
4252 ops.push_back (Operations::capture);
4253 ops.push_back (Operations::paste);
4254 ops.push_back (Operations::duplicate_region);
4255 ops.push_back (Operations::insert_file);
4256 ops.push_back (Operations::insert_region);
4257 ops.push_back (Operations::drag_region_brush);
4258 ops.push_back (Operations::region_drag);
4259 ops.push_back (Operations::selection_grab);
4260 ops.push_back (Operations::region_fill);
4261 ops.push_back (Operations::fill_selection);
4262 ops.push_back (Operations::create_region);
4263 ops.push_back (Operations::region_copy);
4264 ops.push_back (Operations::fixed_time_region_copy);
4265 ops.sort ();
4266
4267 /* See if any of the current operations match the ones that we want */
4268 list<GQuark> in;
4269 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
4270
4271 /* If so, update the session range markers */
4272 if (!in.empty ()) {
4273 maybe_update_session_range (r->position (), r->last_sample ());
4274 }
4275 }
4276
4277 /** Update the session range markers if a is before the current start or
4278 * b is after the current end.
4279 */
4280 void
maybe_update_session_range(samplepos_t a,samplepos_t b)4281 Session::maybe_update_session_range (samplepos_t a, samplepos_t b)
4282 {
4283 if (loading ()) {
4284 return;
4285 }
4286
4287 samplepos_t session_end_marker_shift_samples = session_end_shift * _nominal_sample_rate;
4288
4289 if (_session_range_location == 0) {
4290
4291 set_session_extents (a, b + session_end_marker_shift_samples);
4292
4293 } else {
4294
4295 if (_session_range_is_free && (a < _session_range_location->start())) {
4296 _session_range_location->set_start (a);
4297 }
4298
4299 if (_session_range_is_free && (b > _session_range_location->end())) {
4300 _session_range_location->set_end (b);
4301 }
4302 }
4303 }
4304
4305 void
set_session_range_is_free(bool yn)4306 Session::set_session_range_is_free (bool yn)
4307 {
4308 _session_range_is_free = yn;
4309 }
4310
4311 void
playlist_ranges_moved(list<Evoral::RangeMove<samplepos_t>> const & ranges)4312 Session::playlist_ranges_moved (list<Evoral::RangeMove<samplepos_t> > const & ranges)
4313 {
4314 for (list<Evoral::RangeMove<samplepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
4315 maybe_update_session_range (i->to, i->to + i->length);
4316 }
4317 }
4318
4319 void
playlist_regions_extended(list<Evoral::Range<samplepos_t>> const & ranges)4320 Session::playlist_regions_extended (list<Evoral::Range<samplepos_t> > const & ranges)
4321 {
4322 for (list<Evoral::Range<samplepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
4323 maybe_update_session_range (i->from, i->to);
4324 }
4325 }
4326
4327 /* Region management */
4328
4329 boost::shared_ptr<Region>
find_whole_file_parent(boost::shared_ptr<Region const> child) const4330 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
4331 {
4332 const RegionFactory::RegionMap& regions (RegionFactory::regions());
4333 RegionFactory::RegionMap::const_iterator i;
4334 boost::shared_ptr<Region> region;
4335
4336 Glib::Threads::Mutex::Lock lm (region_lock);
4337
4338 for (i = regions.begin(); i != regions.end(); ++i) {
4339
4340 region = i->second;
4341
4342 if (region->whole_file()) {
4343
4344 if (child->source_equivalent (region)) {
4345 return region;
4346 }
4347 }
4348 }
4349
4350 return boost::shared_ptr<Region> ();
4351 }
4352
4353 int
destroy_sources(list<boost::shared_ptr<Source>> const & srcs)4354 Session::destroy_sources (list<boost::shared_ptr<Source> > const& srcs)
4355 {
4356 set<boost::shared_ptr<Region> > relevant_regions;
4357
4358 for (list<boost::shared_ptr<Source> >::const_iterator s = srcs.begin(); s != srcs.end(); ++s) {
4359 RegionFactory::get_regions_using_source (*s, relevant_regions);
4360 }
4361
4362 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
4363 set<boost::shared_ptr<Region> >::iterator tmp;
4364
4365 tmp = r;
4366 ++tmp;
4367
4368 _playlists->destroy_region (*r);
4369 RegionFactory::map_remove (*r);
4370
4371 (*r)->drop_sources ();
4372 (*r)->drop_references ();
4373
4374 relevant_regions.erase (r);
4375
4376 r = tmp;
4377 }
4378
4379 for (list<boost::shared_ptr<Source> >::const_iterator s = srcs.begin(); s != srcs.end(); ++s) {
4380
4381 {
4382 Glib::Threads::Mutex::Lock ls (source_lock);
4383 /* remove from the main source list */
4384 sources.erase ((*s)->id());
4385 }
4386
4387 (*s)->mark_for_remove ();
4388 (*s)->drop_references ();
4389 SourceRemoved (boost::weak_ptr<Source> (*s)); /* EMIT SIGNAL */
4390 }
4391
4392 return 0;
4393 }
4394
4395 int
remove_last_capture()4396 Session::remove_last_capture ()
4397 {
4398 list<boost::shared_ptr<Source> > srcs;
4399
4400 boost::shared_ptr<RouteList> rl = routes.reader ();
4401 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4402 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4403 if (!tr) {
4404 continue;
4405 }
4406
4407 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
4408
4409 if (!l.empty()) {
4410 srcs.insert (srcs.end(), l.begin(), l.end());
4411 l.clear ();
4412 }
4413 }
4414
4415 destroy_sources (srcs);
4416
4417 /* save state so we don't end up with a session file
4418 * referring to non-existent sources.
4419 */
4420
4421 save_state ();
4422
4423 return 0;
4424 }
4425
4426 void
get_last_capture_sources(std::list<boost::shared_ptr<Source>> & srcs)4427 Session::get_last_capture_sources (std::list<boost::shared_ptr<Source> >& srcs)
4428 {
4429 boost::shared_ptr<RouteList> rl = routes.reader ();
4430 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
4431 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4432 if (!tr) {
4433 continue;
4434 }
4435
4436 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
4437
4438 if (!l.empty()) {
4439 srcs.insert (srcs.end(), l.begin(), l.end());
4440 l.clear ();
4441 }
4442 }
4443 }
4444
4445 /* Source Management */
4446
4447 void
add_source(boost::shared_ptr<Source> source)4448 Session::add_source (boost::shared_ptr<Source> source)
4449 {
4450 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
4451 pair<SourceMap::iterator,bool> result;
4452
4453 entry.first = source->id();
4454 entry.second = source;
4455
4456 {
4457 Glib::Threads::Mutex::Lock lm (source_lock);
4458 result = sources.insert (entry);
4459 }
4460
4461 if (result.second) {
4462
4463 /* yay, new source */
4464
4465 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
4466
4467 if (fs) {
4468 if (!fs->within_session()) {
4469 ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
4470 }
4471 }
4472
4473 set_dirty();
4474
4475 boost::shared_ptr<AudioFileSource> afs;
4476
4477 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
4478 if (Config->get_auto_analyse_audio()) {
4479 Analyser::queue_source_for_analysis (source, false);
4480 }
4481 }
4482
4483 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
4484
4485 SourceAdded (boost::weak_ptr<Source> (source)); /* EMIT SIGNAL */
4486 }
4487 }
4488
4489 void
remove_source(boost::weak_ptr<Source> src)4490 Session::remove_source (boost::weak_ptr<Source> src)
4491 {
4492 if (deletion_in_progress ()) {
4493 return;
4494 }
4495
4496 SourceMap::iterator i;
4497 boost::shared_ptr<Source> source = src.lock();
4498
4499 if (!source) {
4500 return;
4501 }
4502
4503 {
4504 Glib::Threads::Mutex::Lock lm (source_lock);
4505
4506 if ((i = sources.find (source->id())) != sources.end()) {
4507 sources.erase (i);
4508 SourceRemoved (src); /* EMIT SIGNAL */
4509 } else {
4510 return;
4511 }
4512 }
4513
4514 if (source->empty ()) {
4515 /* No need to save when empty sources are removed.
4516 * This is likely due to disk-writer initial dummies
4517 * where files don't even exist on disk.
4518 */
4519 return;
4520 }
4521
4522 if (!in_cleanup () && !loading ()) {
4523 /* save state so we don't end up with a session file
4524 * referring to non-existent sources.
4525 */
4526 save_state ();
4527 }
4528 }
4529
4530 boost::shared_ptr<Source>
source_by_id(const PBD::ID & id)4531 Session::source_by_id (const PBD::ID& id)
4532 {
4533 Glib::Threads::Mutex::Lock lm (source_lock);
4534 SourceMap::iterator i;
4535 boost::shared_ptr<Source> source;
4536
4537 if ((i = sources.find (id)) != sources.end()) {
4538 source = i->second;
4539 }
4540
4541 return source;
4542 }
4543
4544 boost::shared_ptr<AudioFileSource>
audio_source_by_path_and_channel(const string & path,uint16_t chn) const4545 Session::audio_source_by_path_and_channel (const string& path, uint16_t chn) const
4546 {
4547 /* Restricted to audio files because only audio sources have channel
4548 as a property.
4549 */
4550
4551 Glib::Threads::Mutex::Lock lm (source_lock);
4552
4553 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4554 boost::shared_ptr<AudioFileSource> afs
4555 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
4556
4557 if (afs && afs->path() == path && chn == afs->channel()) {
4558 return afs;
4559 }
4560 }
4561
4562 return boost::shared_ptr<AudioFileSource>();
4563 }
4564
4565 boost::shared_ptr<MidiSource>
midi_source_by_path(const std::string & path,bool need_source_lock) const4566 Session::midi_source_by_path (const std::string& path, bool need_source_lock) const
4567 {
4568 /* Restricted to MIDI files because audio sources require a channel
4569 for unique identification, in addition to a path.
4570 */
4571
4572 Glib::Threads::Mutex::Lock lm (source_lock, Glib::Threads::NOT_LOCK);
4573 if (need_source_lock) {
4574 lm.acquire ();
4575 }
4576
4577 for (SourceMap::const_iterator s = sources.begin(); s != sources.end(); ++s) {
4578 boost::shared_ptr<MidiSource> ms
4579 = boost::dynamic_pointer_cast<MidiSource>(s->second);
4580 boost::shared_ptr<FileSource> fs
4581 = boost::dynamic_pointer_cast<FileSource>(s->second);
4582
4583 if (ms && fs && fs->path() == path) {
4584 return ms;
4585 }
4586 }
4587
4588 return boost::shared_ptr<MidiSource>();
4589 }
4590
4591 uint32_t
count_sources_by_origin(const string & path)4592 Session::count_sources_by_origin (const string& path)
4593 {
4594 uint32_t cnt = 0;
4595 Glib::Threads::Mutex::Lock lm (source_lock);
4596
4597 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4598 boost::shared_ptr<FileSource> fs
4599 = boost::dynamic_pointer_cast<FileSource>(i->second);
4600
4601 if (fs && fs->origin() == path) {
4602 ++cnt;
4603 }
4604 }
4605
4606 return cnt;
4607 }
4608
4609 static string
peak_file_helper(const string & peak_path,const string & file_path,const string & file_base,bool hash)4610 peak_file_helper (const string& peak_path, const string& file_path, const string& file_base, bool hash) {
4611 if (hash) {
4612 std::string checksum = Glib::Checksum::compute_checksum(Glib::Checksum::CHECKSUM_SHA1, file_path + G_DIR_SEPARATOR + file_base);
4613 return Glib::build_filename (peak_path, checksum + peakfile_suffix);
4614 } else {
4615 return Glib::build_filename (peak_path, file_base + peakfile_suffix);
4616 }
4617 }
4618
4619 string
construct_peak_filepath(const string & filepath,const bool in_session,const bool old_peak_name) const4620 Session::construct_peak_filepath (const string& filepath, const bool in_session, const bool old_peak_name) const
4621 {
4622 string interchange_dir_string = string (interchange_dir_name) + G_DIR_SEPARATOR;
4623
4624 if (Glib::path_is_absolute (filepath)) {
4625
4626 /* rip the session dir from the audiofile source */
4627
4628 string session_path;
4629 bool in_another_session = true;
4630
4631 if (filepath.find (interchange_dir_string) != string::npos) {
4632
4633 session_path = Glib::path_get_dirname (filepath); /* now ends in audiofiles */
4634 session_path = Glib::path_get_dirname (session_path); /* now ends in session name */
4635 session_path = Glib::path_get_dirname (session_path); /* now ends in interchange */
4636 session_path = Glib::path_get_dirname (session_path); /* now has session path */
4637
4638 /* see if it is within our session */
4639
4640 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4641 if (i->path == session_path) {
4642 in_another_session = false;
4643 break;
4644 }
4645 }
4646 } else {
4647 in_another_session = false;
4648 }
4649
4650
4651 if (in_another_session) {
4652 SessionDirectory sd (session_path);
4653 return peak_file_helper (sd.peak_path(), "", Glib::path_get_basename (filepath), !old_peak_name);
4654 }
4655 }
4656
4657 /* 1) if file belongs to this session
4658 * it may be a relative path (interchange/...)
4659 * or just basename (session_state, remove source)
4660 * -> just use the basename
4661 */
4662 std::string filename = Glib::path_get_basename (filepath);
4663 std::string path;
4664
4665 /* 2) if the file is outside our session dir:
4666 * (imported but not copied) add the path for check-summming */
4667 if (!in_session) {
4668 path = Glib::path_get_dirname (filepath);
4669 }
4670
4671 return peak_file_helper (_session_dir->peak_path(), path, Glib::path_get_basename (filepath), !old_peak_name);
4672 }
4673
4674 string
new_audio_source_path_for_embedded(const std::string & path)4675 Session::new_audio_source_path_for_embedded (const std::string& path)
4676 {
4677 /* embedded source:
4678 *
4679 * we know that the filename is already unique because it exists
4680 * out in the filesystem.
4681 *
4682 * However, when we bring it into the session, we could get a
4683 * collision.
4684 *
4685 * Eg. two embedded files:
4686 *
4687 * /foo/bar/baz.wav
4688 * /frob/nic/baz.wav
4689 *
4690 * When merged into session, these collide.
4691 *
4692 * There will not be a conflict with in-memory sources
4693 * because when the source was created we already picked
4694 * a unique name for it.
4695 *
4696 * This collision is not likely to be common, but we have to guard
4697 * against it. So, if there is a collision, take the md5 hash of the
4698 * the path, and use that as the filename instead.
4699 */
4700
4701 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4702 string base = Glib::path_get_basename (path);
4703 string newpath = Glib::build_filename (sdir.sound_path(), base);
4704
4705 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4706
4707 MD5 md5;
4708
4709 md5.digestString (path.c_str());
4710 md5.writeToString ();
4711 base = md5.digestChars;
4712
4713 string ext = get_suffix (path);
4714
4715 if (!ext.empty()) {
4716 base += '.';
4717 base += ext;
4718 }
4719
4720 newpath = Glib::build_filename (sdir.sound_path(), base);
4721
4722 /* if this collides, we're screwed */
4723
4724 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4725 error << string_compose (_("Merging embedded file %1: name collision AND md5 hash collision!"), path) << endmsg;
4726 return string();
4727 }
4728
4729 }
4730
4731 return newpath;
4732 }
4733
4734 /** Return true if there are no audio file sources that use @param name as
4735 * the filename component of their path.
4736 *
4737 * Return false otherwise.
4738 *
4739 * This method MUST ONLY be used to check in-session, mono files since it
4740 * hard-codes the channel of the audio file source we are looking for as zero.
4741 *
4742 * If/when Ardour supports native files in non-mono formats, the logic here
4743 * will need to be revisited.
4744 */
4745 bool
audio_source_name_is_unique(const string & name)4746 Session::audio_source_name_is_unique (const string& name)
4747 {
4748 std::vector<string> sdirs = source_search_path (DataType::AUDIO);
4749 uint32_t existing = 0;
4750
4751 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4752
4753 /* note that we search *without* the extension so that
4754 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
4755 in the event that this new name is required for
4756 a file format change.
4757 */
4758
4759 const string spath = *i;
4760
4761 if (matching_unsuffixed_filename_exists_in (spath, name)) {
4762 existing++;
4763 break;
4764 }
4765
4766 /* it is possible that we have the path already
4767 * assigned to a source that has not yet been written
4768 * (ie. the write source for a diskstream). we have to
4769 * check this in order to make sure that our candidate
4770 * path isn't used again, because that can lead to
4771 * two Sources point to the same file with different
4772 * notions of their removability.
4773 */
4774
4775
4776 string possible_path = Glib::build_filename (spath, name);
4777
4778 if (audio_source_by_path_and_channel (possible_path, 0)) {
4779 existing++;
4780 break;
4781 }
4782 }
4783
4784 return (existing == 0);
4785 }
4786
4787 string
format_audio_source_name(const string & legalized_base,uint32_t nchan,uint32_t chan,bool take_required,uint32_t cnt,bool related_exists)4788 Session::format_audio_source_name (const string& legalized_base, uint32_t nchan, uint32_t chan, bool take_required, uint32_t cnt, bool related_exists)
4789 {
4790 ostringstream sstr;
4791 const string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
4792
4793 sstr << legalized_base;
4794
4795 if (take_required || related_exists) {
4796 sstr << '-';
4797 sstr << cnt;
4798 }
4799
4800 if (nchan == 2) {
4801 if (chan == 0) {
4802 sstr << "%L";
4803 } else {
4804 sstr << "%R";
4805 }
4806 } else if (nchan > 2) {
4807 if (nchan < 26) {
4808 sstr << '%';
4809 sstr << 'a' + chan;
4810 } else {
4811 /* XXX what? more than 26 channels! */
4812 sstr << '%';
4813 sstr << chan+1;
4814 }
4815 }
4816
4817 sstr << ext;
4818
4819 return sstr.str();
4820 }
4821
4822 /** Return a unique name based on \a base for a new internal audio source */
4823 string
new_audio_source_path(const string & base,uint32_t nchan,uint32_t chan,bool take_required)4824 Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t chan, bool take_required)
4825 {
4826 uint32_t cnt;
4827 string possible_name;
4828 const uint32_t limit = 9999; // arbitrary limit on number of files with the same basic name
4829 string legalized;
4830 bool some_related_source_name_exists = false;
4831
4832 legalized = legalize_for_path (base);
4833
4834 // Find a "version" of the base name that doesn't exist in any of the possible directories.
4835
4836 for (cnt = 1; cnt <= limit; ++cnt) {
4837
4838 possible_name = format_audio_source_name (legalized, nchan, chan, take_required, cnt, some_related_source_name_exists);
4839
4840 if (audio_source_name_is_unique (possible_name)) {
4841 break;
4842 }
4843
4844 some_related_source_name_exists = true;
4845
4846 if (cnt > limit) {
4847 error << string_compose(
4848 _("There are already %1 recordings for %2, which I consider too many."),
4849 limit, base) << endmsg;
4850 destroy ();
4851 throw failed_constructor();
4852 }
4853 }
4854
4855 /* We've established that the new name does not exist in any session
4856 * directory, so now find out which one we should use for this new
4857 * audio source.
4858 */
4859
4860 SessionDirectory sdir (get_best_session_directory_for_new_audio());
4861
4862 std::string s = Glib::build_filename (sdir.sound_path(), possible_name);
4863
4864 return s;
4865 }
4866
4867 /** Return a unique name based on `base` for a new internal MIDI source */
4868 string
new_midi_source_path(const string & base,bool need_lock)4869 Session::new_midi_source_path (const string& base, bool need_lock)
4870 {
4871 string possible_path;
4872 string possible_name;
4873
4874 possible_name = legalize_for_path (base);
4875
4876 // Find a "version" of the file name that doesn't exist in any of the possible directories.
4877 std::vector<string> sdirs = source_search_path(DataType::MIDI);
4878
4879 /* - the main session folder is the first in the vector.
4880 * - after checking all locations for file-name uniqueness,
4881 * we keep the one from the last iteration as new file name
4882 * - midi files are small and should just be kept in the main session-folder
4883 *
4884 * -> reverse the array, check main session folder last and use that as location
4885 * for MIDI files.
4886 */
4887 std::reverse(sdirs.begin(), sdirs.end());
4888
4889 while (true) {
4890 possible_name = bump_name_once (possible_name, '-');
4891
4892 uint32_t existing = 0;
4893
4894 for (vector<string>::const_iterator i = sdirs.begin(); i != sdirs.end(); ++i) {
4895
4896 possible_path = Glib::build_filename (*i, possible_name + ".mid");
4897
4898 if (Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
4899 existing++;
4900 }
4901
4902 if (midi_source_by_path (possible_path, need_lock)) {
4903 existing++;
4904 }
4905 }
4906
4907 if (possible_path.size () >= PATH_MAX) {
4908 error << string_compose(
4909 _("There are already many recordings for %1, resulting in a too long file-path %2."),
4910 base, possible_path) << endmsg;
4911 destroy ();
4912 return 0;
4913 }
4914
4915 if (existing == 0) {
4916 break;
4917 }
4918 }
4919
4920 /* No need to "find best location" for software/app-based RAID, because
4921 MIDI is so small that we always put it in the same place.
4922 */
4923
4924 return possible_path;
4925 }
4926
4927
4928 /** Create a new within-session audio source */
4929 boost::shared_ptr<AudioFileSource>
create_audio_source_for_session(size_t n_chans,string const & base,uint32_t chan)4930 Session::create_audio_source_for_session (size_t n_chans, string const & base, uint32_t chan)
4931 {
4932 const string path = new_audio_source_path (base, n_chans, chan, true);
4933
4934 if (!path.empty()) {
4935 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, *this, path, sample_rate(), true, true));
4936 } else {
4937 throw failed_constructor ();
4938 }
4939 }
4940
4941 /** Create a new within-session MIDI source */
4942 boost::shared_ptr<MidiSource>
create_midi_source_for_session(string const & basic_name)4943 Session::create_midi_source_for_session (string const & basic_name)
4944 {
4945 const string path = new_midi_source_path (basic_name);
4946
4947 if (!path.empty()) {
4948 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, path, sample_rate()));
4949 } else {
4950 throw failed_constructor ();
4951 }
4952 }
4953
4954 /** Create a new within-session MIDI source */
4955 boost::shared_ptr<MidiSource>
create_midi_source_by_stealing_name(boost::shared_ptr<Track> track)4956 Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
4957 {
4958 /* the caller passes in the track the source will be used in,
4959 so that we can keep the numbering sane.
4960
4961 Rationale: a track with the name "Foo" that has had N
4962 captures carried out so far will ALREADY have a write source
4963 named "Foo-N+1.mid" waiting to be used for the next capture.
4964
4965 If we call new_midi_source_name() we will get "Foo-N+2". But
4966 there is no region corresponding to "Foo-N+1", so when
4967 "Foo-N+2" appears in the track, the gap presents the user
4968 with odd behaviour - why did it skip past Foo-N+1?
4969
4970 We could explain this to the user in some odd way, but
4971 instead we rename "Foo-N+1.mid" as "Foo-N+2.mid", and then
4972 use "Foo-N+1" here.
4973
4974 If that attempted rename fails, we get "Foo-N+2.mid" anyway.
4975 */
4976
4977 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (track);
4978 assert (mt);
4979 std::string name = track->steal_write_source_name ();
4980
4981 if (name.empty()) {
4982 return boost::shared_ptr<MidiSource>();
4983 }
4984
4985 /* MIDI files are small, just put them in the first location of the
4986 session source search path.
4987 */
4988
4989 const string path = Glib::build_filename (source_search_path (DataType::MIDI).front(), name);
4990
4991 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, path, sample_rate()));
4992 }
4993
4994 bool
playlist_is_active(boost::shared_ptr<Playlist> playlist)4995 Session::playlist_is_active (boost::shared_ptr<Playlist> playlist)
4996 {
4997 Glib::Threads::Mutex::Lock lm (_playlists->lock);
4998 for (SessionPlaylists::List::iterator i = _playlists->playlists.begin(); i != _playlists->playlists.end(); i++) {
4999 if ( (*i) == playlist ) {
5000 return true;
5001 }
5002 }
5003 return false;
5004 }
5005
5006 void
add_playlist(boost::shared_ptr<Playlist> playlist,bool unused)5007 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
5008 {
5009 if (playlist->hidden()) {
5010 return;
5011 }
5012
5013 _playlists->add (playlist);
5014
5015 if (unused) {
5016 playlist->release();
5017 }
5018
5019 set_dirty();
5020 }
5021
5022 void
remove_playlist(boost::weak_ptr<Playlist> weak_playlist)5023 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
5024 {
5025 if (deletion_in_progress ()) {
5026 return;
5027 }
5028
5029 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
5030
5031 if (!playlist) {
5032 return;
5033 }
5034
5035 _playlists->remove (playlist);
5036
5037 set_dirty();
5038 }
5039
5040 void
set_audition(boost::shared_ptr<Region> r)5041 Session::set_audition (boost::shared_ptr<Region> r)
5042 {
5043 pending_audition_region = r;
5044 add_post_transport_work (PostTransportAudition);
5045 _butler->schedule_transport_work ();
5046 }
5047
5048 void
audition_playlist()5049 Session::audition_playlist ()
5050 {
5051 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
5052 ev->region.reset ();
5053 queue_event (ev);
5054 }
5055
5056
5057 void
register_lua_function(const std::string & name,const std::string & script,const LuaScriptParamList & args)5058 Session::register_lua_function (
5059 const std::string& name,
5060 const std::string& script,
5061 const LuaScriptParamList& args
5062 )
5063 {
5064 Glib::Threads::Mutex::Lock lm (lua_lock);
5065
5066 lua_State* L = lua.getState();
5067
5068 const std::string& bytecode = LuaScripting::get_factory_bytecode (script);
5069 luabridge::LuaRef tbl_arg (luabridge::newTable(L));
5070 for (LuaScriptParamList::const_iterator i = args.begin(); i != args.end(); ++i) {
5071 if ((*i)->optional && !(*i)->is_set) { continue; }
5072 tbl_arg[(*i)->name] = (*i)->value;
5073 }
5074 (*_lua_add)(name, bytecode, tbl_arg); // throws luabridge::LuaException
5075 lm.release();
5076
5077 LuaScriptsChanged (); /* EMIT SIGNAL */
5078 set_dirty();
5079 }
5080
5081 void
unregister_lua_function(const std::string & name)5082 Session::unregister_lua_function (const std::string& name)
5083 {
5084 Glib::Threads::Mutex::Lock lm (lua_lock);
5085 (*_lua_del)(name); // throws luabridge::LuaException
5086 lua.collect_garbage ();
5087 lm.release();
5088
5089 LuaScriptsChanged (); /* EMIT SIGNAL */
5090 set_dirty();
5091 }
5092
5093 std::vector<std::string>
registered_lua_functions()5094 Session::registered_lua_functions ()
5095 {
5096 Glib::Threads::Mutex::Lock lm (lua_lock);
5097 std::vector<std::string> rv;
5098
5099 try {
5100 luabridge::LuaRef list ((*_lua_list)());
5101 for (luabridge::Iterator i (list); !i.isNil (); ++i) {
5102 if (!i.key ().isString ()) { assert(0); continue; }
5103 rv.push_back (i.key ().cast<std::string> ());
5104 }
5105 } catch (...) { }
5106 return rv;
5107 }
5108
_lua_print(std::string s)5109 static void _lua_print (std::string s) {
5110 #ifndef NDEBUG
5111 std::cout << "LuaSession: " << s << "\n";
5112 #endif
5113 PBD::info << "LuaSession: " << s << endmsg;
5114 }
5115
5116 void
try_run_lua(pframes_t nframes)5117 Session::try_run_lua (pframes_t nframes)
5118 {
5119 if (_n_lua_scripts == 0) return;
5120 Glib::Threads::Mutex::Lock tm (lua_lock, Glib::Threads::TRY_LOCK);
5121 if (tm.locked ()) {
5122 try { (*_lua_run)(nframes); } catch (...) { }
5123 lua.collect_garbage_step ();
5124 }
5125 }
5126
5127 void
setup_lua()5128 Session::setup_lua ()
5129 {
5130 lua.Print.connect (&_lua_print);
5131 lua.sandbox (true);
5132 lua.do_command (
5133 "function ArdourSession ()"
5134 " local self = { scripts = {}, instances = {} }"
5135 ""
5136 " local remove = function (n)"
5137 " self.scripts[n] = nil"
5138 " self.instances[n] = nil"
5139 " Session:scripts_changed()" // call back
5140 " end"
5141 ""
5142 " local addinternal = function (n, f, a)"
5143 " assert(type(n) == 'string', 'function-name must be string')"
5144 " assert(type(f) == 'function', 'Given script is a not a function')"
5145 " assert(type(a) == 'table' or type(a) == 'nil', 'Given argument is invalid')"
5146 " assert(self.scripts[n] == nil, 'Callback \"'.. n ..'\" already exists.')"
5147 " self.scripts[n] = { ['f'] = f, ['a'] = a }"
5148 " 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, bit32=bit32, Session = Session, PBD = PBD, Timecode = Timecode, Evoral = Evoral, C = C, ARDOUR = ARDOUR }"
5149 " self.instances[n] = load (string.dump(f, true), nil, nil, env)(a)"
5150 " Session:scripts_changed()" // call back
5151 " end"
5152 ""
5153 " local add = function (n, b, a)"
5154 " assert(type(b) == 'string', 'ByteCode must be string')"
5155 " load (b)()" // assigns f
5156 " assert(type(f) == 'string', 'Assigned ByteCode must be string')"
5157 " addinternal (n, load(f), a)"
5158 " end"
5159 ""
5160 " local run = function (...)"
5161 " for n, s in pairs (self.instances) do"
5162 " local status, err = pcall (s, ...)"
5163 " if not status then"
5164 " print ('fn \"'.. n .. '\": ', err)"
5165 " remove (n)"
5166 " end"
5167 " end"
5168 " collectgarbage(\"step\")"
5169 " end"
5170 ""
5171 " local cleanup = function ()"
5172 " self.scripts = nil"
5173 " self.instances = nil"
5174 " end"
5175 ""
5176 " local list = function ()"
5177 " local rv = {}"
5178 " for n, _ in pairs (self.scripts) do"
5179 " rv[n] = true"
5180 " end"
5181 " return rv"
5182 " end"
5183 ""
5184 " local function basic_serialize (o)"
5185 " if type(o) == \"number\" then"
5186 " return tostring(o)"
5187 " else"
5188 " return string.format(\"%q\", o)"
5189 " end"
5190 " end"
5191 ""
5192 " local function serialize (name, value)"
5193 " local rv = name .. ' = '"
5194 " collectgarbage()"
5195 " if type(value) == \"number\" or type(value) == \"string\" or type(value) == \"nil\" then"
5196 " return rv .. basic_serialize(value) .. ' '"
5197 " elseif type(value) == \"table\" then"
5198 " rv = rv .. '{} '"
5199 " for k,v in pairs(value) do"
5200 " local fieldname = string.format(\"%s[%s]\", name, basic_serialize(k))"
5201 " rv = rv .. serialize(fieldname, v) .. ' '"
5202 " collectgarbage()" // string concatenation allocates a new string :(
5203 " end"
5204 " return rv;"
5205 " elseif type(value) == \"function\" then"
5206 " return rv .. string.format(\"%q\", string.dump(value, true))"
5207 " else"
5208 " error('cannot save a ' .. type(value))"
5209 " end"
5210 " end"
5211 ""
5212 ""
5213 " local save = function ()"
5214 " return (serialize('scripts', self.scripts))"
5215 " end"
5216 ""
5217 " local restore = function (state)"
5218 " self.scripts = {}"
5219 " load (state)()"
5220 " for n, s in pairs (scripts) do"
5221 " addinternal (n, load(s['f']), s['a'])"
5222 " end"
5223 " end"
5224 ""
5225 " return { run = run, add = add, remove = remove,"
5226 " list = list, restore = restore, save = save, cleanup = cleanup}"
5227 " end"
5228 " "
5229 " sess = ArdourSession ()"
5230 " ArdourSession = nil"
5231 " "
5232 "function ardour () end"
5233 );
5234
5235 lua_State* L = lua.getState();
5236
5237 try {
5238 luabridge::LuaRef lua_sess = luabridge::getGlobal (L, "sess");
5239 lua.do_command ("sess = nil"); // hide it.
5240 lua.do_command ("collectgarbage()");
5241
5242 _lua_run = new luabridge::LuaRef(lua_sess["run"]);
5243 _lua_add = new luabridge::LuaRef(lua_sess["add"]);
5244 _lua_del = new luabridge::LuaRef(lua_sess["remove"]);
5245 _lua_list = new luabridge::LuaRef(lua_sess["list"]);
5246 _lua_save = new luabridge::LuaRef(lua_sess["save"]);
5247 _lua_load = new luabridge::LuaRef(lua_sess["restore"]);
5248 _lua_cleanup = new luabridge::LuaRef(lua_sess["cleanup"]);
5249 } catch (luabridge::LuaException const& e) {
5250 fatal << string_compose (_("programming error: %1"),
5251 std::string ("Failed to setup session Lua interpreter") + e.what ())
5252 << endmsg;
5253 abort(); /*NOTREACHED*/
5254 } catch (...) {
5255 fatal << string_compose (_("programming error: %1"),
5256 X_("Failed to setup session Lua interpreter"))
5257 << endmsg;
5258 abort(); /*NOTREACHED*/
5259 }
5260
5261 lua_mlock (L, 1);
5262 LuaBindings::stddef (L);
5263 LuaBindings::common (L);
5264 LuaBindings::dsp (L);
5265 lua_mlock (L, 0);
5266 luabridge::push <Session *> (L, this);
5267 lua_setglobal (L, "Session");
5268 }
5269
5270 void
scripts_changed()5271 Session::scripts_changed ()
5272 {
5273 assert (!lua_lock.trylock()); // must hold lua_lock
5274
5275 try {
5276 luabridge::LuaRef list ((*_lua_list)());
5277 int cnt = 0;
5278 for (luabridge::Iterator i (list); !i.isNil (); ++i) {
5279 if (!i.key ().isString ()) { assert(0); continue; }
5280 ++cnt;
5281 }
5282 _n_lua_scripts = cnt;
5283 } catch (luabridge::LuaException const& e) {
5284 fatal << string_compose (_("programming error: %1"),
5285 std::string ("Indexing Lua Session Scripts failed.") + e.what ())
5286 << endmsg;
5287 abort(); /*NOTREACHED*/
5288 } catch (...) {
5289 fatal << string_compose (_("programming error: %1"),
5290 X_("Indexing Lua Session Scripts failed."))
5291 << endmsg;
5292 abort(); /*NOTREACHED*/
5293 }
5294 }
5295
5296 void
non_realtime_set_audition()5297 Session::non_realtime_set_audition ()
5298 {
5299 assert (pending_audition_region);
5300 auditioner->audition_region (pending_audition_region);
5301 pending_audition_region.reset ();
5302 AuditionActive (true); /* EMIT SIGNAL */
5303 }
5304
5305 void
audition_region(boost::shared_ptr<Region> r)5306 Session::audition_region (boost::shared_ptr<Region> r)
5307 {
5308 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
5309 ev->region = r;
5310 queue_event (ev);
5311 }
5312
5313 void
cancel_audition()5314 Session::cancel_audition ()
5315 {
5316 if (!auditioner) {
5317 return;
5318 }
5319 if (auditioner->auditioning()) {
5320 auditioner->cancel_audition ();
5321 AuditionActive (false); /* EMIT SIGNAL */
5322 }
5323 }
5324
5325 bool
is_auditioning() const5326 Session::is_auditioning () const
5327 {
5328 /* can be called before we have an auditioner object */
5329 if (auditioner) {
5330 return auditioner->auditioning();
5331 } else {
5332 return false;
5333 }
5334 }
5335
5336 void
graph_reordered(bool called_from_backend)5337 Session::graph_reordered (bool called_from_backend)
5338 {
5339 /* don't do this stuff if we are setting up connections
5340 from a set_state() call or creating new tracks. Ditto for deletion.
5341 */
5342
5343 if (inital_connect_or_deletion_in_progress () || _adding_routes_in_progress || _reconnecting_routes_in_progress || _route_deletion_in_progress) {
5344 return;
5345 }
5346
5347 resort_routes ();
5348
5349 /* force all diskstreams to update their capture offset values to
5350 * reflect any changes in latencies within the graph.
5351 */
5352 update_latency_compensation (true, called_from_backend);
5353 }
5354
5355 /** @return Number of samples that there is disk space available to write,
5356 * if known.
5357 */
5358 boost::optional<samplecnt_t>
available_capture_duration()5359 Session::available_capture_duration ()
5360 {
5361 Glib::Threads::Mutex::Lock lm (space_lock);
5362
5363 if (_total_free_4k_blocks_uncertain) {
5364 return boost::optional<samplecnt_t> ();
5365 }
5366
5367 float sample_bytes_on_disk = 4.0; // keep gcc happy
5368
5369 switch (config.get_native_file_data_format()) {
5370 case FormatFloat:
5371 sample_bytes_on_disk = 4.0;
5372 break;
5373
5374 case FormatInt24:
5375 sample_bytes_on_disk = 3.0;
5376 break;
5377
5378 case FormatInt16:
5379 sample_bytes_on_disk = 2.0;
5380 break;
5381
5382 default:
5383 /* impossible, but keep some gcc versions happy */
5384 fatal << string_compose (_("programming error: %1"),
5385 X_("illegal native file data format"))
5386 << endmsg;
5387 abort(); /*NOTREACHED*/
5388 }
5389
5390 double scale = 4096.0 / sample_bytes_on_disk;
5391
5392 if (_total_free_4k_blocks * scale > (double) max_samplecnt) {
5393 return max_samplecnt;
5394 }
5395
5396 return (samplecnt_t) floor (_total_free_4k_blocks * scale);
5397 }
5398
5399 void
tempo_map_changed(const PropertyChange &)5400 Session::tempo_map_changed (const PropertyChange&)
5401 {
5402 clear_clicks ();
5403
5404 _playlists->update_after_tempo_map_change ();
5405
5406 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
5407
5408 set_dirty ();
5409 }
5410
5411 void
update_locations_after_tempo_map_change(const Locations::LocationList & loc)5412 Session::update_locations_after_tempo_map_change (const Locations::LocationList& loc)
5413 {
5414 for (Locations::LocationList::const_iterator i = loc.begin(); i != loc.end(); ++i) {
5415 (*i)->recompute_samples_from_beat ();
5416 }
5417 }
5418
5419 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
5420 * the given count with the current block size.
5421 */
5422 void
ensure_buffers(ChanCount howmany)5423 Session::ensure_buffers (ChanCount howmany)
5424 {
5425 BufferManager::ensure_buffers (howmany, bounce_processing() ? bounce_chunk_size : 0);
5426 }
5427
5428 void
ensure_buffer_set(BufferSet & buffers,const ChanCount & count)5429 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
5430 {
5431 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
5432 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
5433 }
5434 }
5435
5436 uint32_t
next_insert_id()5437 Session::next_insert_id ()
5438 {
5439 /* this doesn't really loop forever. just think about it */
5440
5441 while (true) {
5442 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < insert_bitset.size(); ++n) {
5443 if (!insert_bitset[n]) {
5444 insert_bitset[n] = true;
5445 return n;
5446
5447 }
5448 }
5449
5450 /* none available, so resize and try again */
5451
5452 insert_bitset.resize (insert_bitset.size() + 16, false);
5453 }
5454 }
5455
5456 uint32_t
next_send_id()5457 Session::next_send_id ()
5458 {
5459 /* this doesn't really loop forever. just think about it */
5460
5461 while (true) {
5462 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < send_bitset.size(); ++n) {
5463 if (!send_bitset[n]) {
5464 send_bitset[n] = true;
5465 return n;
5466
5467 }
5468 }
5469
5470 /* none available, so resize and try again */
5471
5472 send_bitset.resize (send_bitset.size() + 16, false);
5473 }
5474 }
5475
5476 uint32_t
next_aux_send_id()5477 Session::next_aux_send_id ()
5478 {
5479 /* this doesn't really loop forever. just think about it */
5480
5481 while (true) {
5482 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < aux_send_bitset.size(); ++n) {
5483 if (!aux_send_bitset[n]) {
5484 aux_send_bitset[n] = true;
5485 return n;
5486
5487 }
5488 }
5489
5490 /* none available, so resize and try again */
5491
5492 aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
5493 }
5494 }
5495
5496 uint32_t
next_return_id()5497 Session::next_return_id ()
5498 {
5499 /* this doesn't really loop forever. just think about it */
5500
5501 while (true) {
5502 for (boost::dynamic_bitset<uint32_t>::size_type n = 1; n < return_bitset.size(); ++n) {
5503 if (!return_bitset[n]) {
5504 return_bitset[n] = true;
5505 return n;
5506
5507 }
5508 }
5509
5510 /* none available, so resize and try again */
5511
5512 return_bitset.resize (return_bitset.size() + 16, false);
5513 }
5514 }
5515
5516 void
mark_send_id(uint32_t id)5517 Session::mark_send_id (uint32_t id)
5518 {
5519 if (id >= send_bitset.size()) {
5520 send_bitset.resize (id+16, false);
5521 }
5522 if (send_bitset[id]) {
5523 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
5524 }
5525 send_bitset[id] = true;
5526 }
5527
5528 void
mark_aux_send_id(uint32_t id)5529 Session::mark_aux_send_id (uint32_t id)
5530 {
5531 if (id >= aux_send_bitset.size()) {
5532 aux_send_bitset.resize (id+16, false);
5533 }
5534 if (aux_send_bitset[id]) {
5535 warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
5536 }
5537 aux_send_bitset[id] = true;
5538 }
5539
5540 void
mark_return_id(uint32_t id)5541 Session::mark_return_id (uint32_t id)
5542 {
5543 if (id >= return_bitset.size()) {
5544 return_bitset.resize (id+16, false);
5545 }
5546 if (return_bitset[id]) {
5547 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
5548 }
5549 return_bitset[id] = true;
5550 }
5551
5552 void
mark_insert_id(uint32_t id)5553 Session::mark_insert_id (uint32_t id)
5554 {
5555 if (id >= insert_bitset.size()) {
5556 insert_bitset.resize (id+16, false);
5557 }
5558 if (insert_bitset[id]) {
5559 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
5560 }
5561 insert_bitset[id] = true;
5562 }
5563
5564 void
unmark_send_id(uint32_t id)5565 Session::unmark_send_id (uint32_t id)
5566 {
5567 if (deletion_in_progress ()) {
5568 return;
5569 }
5570 if (id < send_bitset.size()) {
5571 send_bitset[id] = false;
5572 }
5573 }
5574
5575 void
unmark_aux_send_id(uint32_t id)5576 Session::unmark_aux_send_id (uint32_t id)
5577 {
5578 if (deletion_in_progress ()) {
5579 return;
5580 }
5581 if (id < aux_send_bitset.size()) {
5582 aux_send_bitset[id] = false;
5583 }
5584 }
5585
5586 void
unmark_return_id(uint32_t id)5587 Session::unmark_return_id (uint32_t id)
5588 {
5589 if (deletion_in_progress ()) {
5590 return;
5591 }
5592 if (id < return_bitset.size()) {
5593 return_bitset[id] = false;
5594 }
5595 }
5596
5597 void
unmark_insert_id(uint32_t id)5598 Session::unmark_insert_id (uint32_t id)
5599 {
5600 if (deletion_in_progress ()) {
5601 return;
5602 }
5603 if (id < insert_bitset.size()) {
5604 insert_bitset[id] = false;
5605 }
5606 }
5607
5608 void
reset_native_file_format()5609 Session::reset_native_file_format ()
5610 {
5611 boost::shared_ptr<RouteList> rl = routes.reader ();
5612
5613 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
5614 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
5615 if (tr) {
5616 /* don't save state as we do this, there's no point */
5617 _state_of_the_state = StateOfTheState (_state_of_the_state | InCleanup);
5618 tr->reset_write_sources (false);
5619 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
5620 }
5621 }
5622 }
5623
5624 bool
route_name_unique(string n) const5625 Session::route_name_unique (string n) const
5626 {
5627 boost::shared_ptr<RouteList> r = routes.reader ();
5628
5629 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5630 if ((*i)->name() == n) {
5631 return false;
5632 }
5633 }
5634
5635 return true;
5636 }
5637
5638 bool
route_name_internal(string n) const5639 Session::route_name_internal (string n) const
5640 {
5641 if (auditioner && auditioner->name() == n) {
5642 return true;
5643 }
5644
5645 if (_click_io && _click_io->name() == n) {
5646 return true;
5647 }
5648
5649 return false;
5650 }
5651
5652 int
freeze_all(InterThreadInfo & itt)5653 Session::freeze_all (InterThreadInfo& itt)
5654 {
5655 boost::shared_ptr<RouteList> r = routes.reader ();
5656
5657 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
5658
5659 boost::shared_ptr<Track> t;
5660
5661 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
5662 /* XXX this is wrong because itt.progress will keep returning to zero at the start
5663 of every track.
5664 */
5665 t->freeze_me (itt);
5666 }
5667 }
5668
5669 return 0;
5670 }
5671
5672 struct MidiSourceLockMap
5673 {
5674 boost::shared_ptr<MidiSource> src;
5675 Source::Lock lock;
5676
MidiSourceLockMapMidiSourceLockMap5677 MidiSourceLockMap (boost::shared_ptr<MidiSource> midi_source) : src (midi_source), lock (src->mutex()) {}
5678 };
5679
5680 boost::shared_ptr<Region>
write_one_track(Track & track,samplepos_t start,samplepos_t end,bool,vector<boost::shared_ptr<Source>> & srcs,InterThreadInfo & itt,boost::shared_ptr<Processor> endpoint,bool include_endpoint,bool for_export,bool for_freeze,std::string const & name)5681 Session::write_one_track (Track& track, samplepos_t start, samplepos_t end,
5682 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
5683 InterThreadInfo& itt,
5684 boost::shared_ptr<Processor> endpoint, bool include_endpoint,
5685 bool for_export, bool for_freeze, std::string const& name)
5686 {
5687 boost::shared_ptr<Region> result;
5688 boost::shared_ptr<Playlist> playlist;
5689 boost::shared_ptr<Source> source;
5690 ChanCount diskstream_channels (track.n_channels());
5691 samplepos_t position;
5692 samplecnt_t this_chunk;
5693 samplepos_t to_do;
5694 samplepos_t latency_skip;
5695 samplepos_t out_pos;
5696 BufferSet buffers;
5697 samplepos_t len = end - start;
5698 bool need_block_size_reset = false;
5699 ChanCount const max_proc = track.max_processor_streams ();
5700 string legal_playlist_name;
5701 string possible_path;
5702 MidiBuffer resolved (256);
5703 MidiStateTracker tracker;
5704 DataType data_type = track.data_type();
5705 std::vector<MidiSourceLockMap*> midi_source_locks;
5706
5707 if (end <= start) {
5708 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
5709 end, start) << endmsg;
5710 return result;
5711 }
5712
5713 diskstream_channels = track.bounce_get_output_streams (diskstream_channels, endpoint,
5714 include_endpoint, for_export, for_freeze);
5715
5716 if (data_type == DataType::MIDI && endpoint && !for_export && !for_freeze && diskstream_channels.n(DataType::AUDIO) > 0) {
5717 data_type = DataType::AUDIO;
5718 }
5719
5720 if (diskstream_channels.n(data_type) < 1) {
5721 error << _("Cannot write a range with no data.") << endmsg;
5722 return result;
5723 }
5724
5725 // block all process callback handling
5726
5727 block_processing ();
5728
5729 {
5730 // synchronize with AudioEngine::process_callback()
5731 // make sure processing is not currently running
5732 // and processing_blocked() is honored before
5733 // acquiring thread buffers
5734 Glib::Threads::Mutex::Lock lm (_engine.process_lock());
5735 }
5736
5737 _bounce_processing_active = true;
5738
5739 /* call tree *MUST* hold route_lock */
5740
5741 if ((playlist = track.playlist()) == 0) {
5742 goto out;
5743 }
5744
5745 if (name.length() > 0) {
5746 /*if the user passed in a name, we will use it, and also prepend the resulting sources with that name*/
5747 legal_playlist_name.append(legalize_for_path (name) + "-");
5748 }
5749
5750 legal_playlist_name.append(legalize_for_path(playlist->name()));
5751
5752 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n(data_type); ++chan_n) {
5753
5754 string path = ((data_type == DataType::AUDIO)
5755 ? new_audio_source_path (legal_playlist_name, diskstream_channels.n_audio(), chan_n, true)
5756 : new_midi_source_path (legal_playlist_name));
5757
5758 if (path.empty()) {
5759 goto out;
5760 }
5761
5762 try {
5763 source = SourceFactory::createWritable (data_type, *this, path, sample_rate());
5764 }
5765
5766 catch (failed_constructor& err) {
5767 error << string_compose (_("cannot create new file \"%1\" for %2"), path, track.name()) << endmsg;
5768 goto out;
5769 }
5770
5771 source->set_captured_for(track.name());
5772
5773 time_t now;
5774 time (&now);
5775 Glib::DateTime tm (Glib::DateTime::create_now_local (now));
5776 source->set_take_id (tm.format ("%F %H.%M.%S"));
5777
5778 srcs.push_back (source);
5779 }
5780
5781 /* tell redirects that care that we are about to use a much larger
5782 * blocksize. this will flush all plugins too, so that they are ready
5783 * to be used for this process.
5784 */
5785
5786 need_block_size_reset = true;
5787 track.set_block_size (bounce_chunk_size);
5788 _engine.main_thread()->get_buffers ();
5789
5790 position = start;
5791 to_do = len;
5792 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
5793
5794 /* create a set of reasonably-sized buffers */
5795 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
5796 buffers.ensure_buffers(*t, max_proc.get(*t), bounce_chunk_size);
5797 }
5798 buffers.set_count (max_proc);
5799
5800 /* prepare MIDI files */
5801
5802 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
5803
5804 boost::shared_ptr<MidiSource> ms = boost::dynamic_pointer_cast<MidiSource>(*src);
5805
5806 if (ms) {
5807 midi_source_locks.push_back (new MidiSourceLockMap (ms));
5808 ms->mark_streaming_write_started (midi_source_locks.back()->lock);
5809 }
5810 }
5811
5812 /* prepare audio files */
5813
5814 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
5815 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5816 if (afs) {
5817 afs->prepare_for_peakfile_writes ();
5818 }
5819 }
5820
5821 /* process */
5822 out_pos = start;
5823
5824 while (to_do && !itt.cancel) {
5825
5826 this_chunk = min (to_do, bounce_chunk_size);
5827
5828 if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze, tracker)) {
5829 goto out;
5830 }
5831
5832 start += this_chunk;
5833 to_do -= this_chunk;
5834 itt.progress = (float) (1.0 - ((double) to_do / len));
5835
5836 if (latency_skip >= bounce_chunk_size) {
5837 latency_skip -= bounce_chunk_size;
5838 continue;
5839 }
5840
5841 const samplecnt_t current_chunk = this_chunk - latency_skip;
5842
5843 uint32_t n = 0;
5844 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
5845 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5846 boost::shared_ptr<MidiSource> ms;
5847
5848 if (afs) {
5849 if (afs->write (buffers.get_audio(n).data(latency_skip), current_chunk) != current_chunk) {
5850 goto out;
5851 }
5852 }
5853 }
5854
5855 /* XXX NUTEMPO fix this to not use samples */
5856
5857 for (vector<MidiSourceLockMap*>::iterator m = midi_source_locks.begin(); m != midi_source_locks.end(); ++m) {
5858 const MidiBuffer& buf = buffers.get_midi(0);
5859 for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
5860 Evoral::Event<samplepos_t> ev = *i;
5861 if (!endpoint || for_export) {
5862 ev.set_time(ev.time() - position);
5863 } else {
5864 /* MidiTrack::export_stuff moves event to the current cycle */
5865 ev.set_time(ev.time() + out_pos - position);
5866 }
5867 (*m)->src->append_event_samples ((*m)->lock, ev, (*m)->src->natural_position());
5868 }
5869 }
5870 out_pos += current_chunk;
5871 latency_skip = 0;
5872 }
5873
5874 /* post-roll, pick up delayed processor output */
5875 latency_skip = track.bounce_get_latency (endpoint, include_endpoint, for_export, for_freeze);
5876
5877 while (latency_skip && !itt.cancel) {
5878 this_chunk = min (latency_skip, bounce_chunk_size);
5879 latency_skip -= this_chunk;
5880
5881 buffers.silence (this_chunk, 0);
5882 track.bounce_process (buffers, start, this_chunk, endpoint, include_endpoint, for_export, for_freeze);
5883
5884 start += this_chunk;
5885
5886 uint32_t n = 0;
5887 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
5888 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5889
5890 if (afs) {
5891 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
5892 goto out;
5893 }
5894 }
5895 }
5896
5897 /* XXX NUTEMPO fix this to not use samples */
5898
5899 for (vector<MidiSourceLockMap*>::iterator m = midi_source_locks.begin(); m != midi_source_locks.end(); ++m) {
5900 const MidiBuffer& buf = buffers.get_midi(0);
5901 for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
5902 Evoral::Event<samplepos_t> ev = *i;
5903 if (!endpoint || for_export) {
5904 ev.set_time(ev.time() - position);
5905 } else {
5906 ev.set_time(ev.time() + out_pos - position);
5907 }
5908 (*m)->src->append_event_samples ((*m)->lock, ev, (*m)->src->natural_position());
5909 }
5910 }
5911 out_pos += this_chunk;
5912 }
5913
5914 tracker.resolve_notes (resolved, end-1);
5915
5916 if (!resolved.empty()) {
5917
5918 for (vector<MidiSourceLockMap*>::iterator m = midi_source_locks.begin(); m != midi_source_locks.end(); ++m) {
5919
5920 for (MidiBuffer::iterator i = resolved.begin(); i != resolved.end(); ++i) {
5921 Evoral::Event<samplepos_t> ev = *i;
5922 if (!endpoint || for_export) {
5923 ev.set_time(ev.time() - position);
5924 } else {
5925 ev.set_time(ev.time() + out_pos - position);
5926 }
5927 (*m)->src->append_event_samples ((*m)->lock, ev, (*m)->src->natural_position());
5928 }
5929 }
5930 }
5931
5932 for (vector<MidiSourceLockMap*>::iterator m = midi_source_locks.begin(); m != midi_source_locks.end(); ++m) {
5933 delete *m;
5934 }
5935
5936 midi_source_locks.clear ();
5937
5938 if (!itt.cancel) {
5939
5940 time_t now;
5941 struct tm* xnow;
5942 time (&now);
5943 xnow = localtime (&now);
5944
5945 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
5946 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5947 boost::shared_ptr<MidiSource> ms;
5948
5949 if (afs) {
5950 afs->update_header (position, *xnow, now);
5951 afs->flush_header ();
5952 } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(*src))) {
5953 Source::Lock lock(ms->mutex());
5954 ms->mark_streaming_write_completed(lock);
5955 }
5956 }
5957
5958 /* construct a whole-file region to represent the bounced material */
5959
5960 PropertyList plist;
5961
5962 plist.add (Properties::start, 0);
5963 plist.add (Properties::whole_file, true);
5964 plist.add (Properties::length, len); //ToDo: in nutempo, if the Range is snapped to bbt, this should be in bbt (?)
5965 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
5966 plist.add (Properties::tags, "(bounce)");
5967
5968 result = RegionFactory::create (srcs, plist, true);
5969
5970 result->set_name(legal_playlist_name); /*setting name in the properties didn't seem to work, but this does*/
5971 }
5972
5973 out:
5974 if (!result) {
5975 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
5976 (*src)->mark_for_remove ();
5977 (*src)->drop_references ();
5978 }
5979
5980 } else {
5981 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
5982 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
5983
5984 if (afs)
5985 afs->done_with_peakfile_writes ();
5986 }
5987 }
5988
5989 _bounce_processing_active = false;
5990
5991 if (need_block_size_reset) {
5992 _engine.main_thread()->drop_buffers ();
5993 track.set_block_size (get_block_size());
5994 }
5995
5996 unblock_processing ();
5997
5998 return result;
5999 }
6000
6001 gain_t*
gain_automation_buffer() const6002 Session::gain_automation_buffer() const
6003 {
6004 return ProcessThread::gain_automation_buffer ();
6005 }
6006
6007 gain_t*
trim_automation_buffer() const6008 Session::trim_automation_buffer() const
6009 {
6010 return ProcessThread::trim_automation_buffer ();
6011 }
6012
6013 gain_t*
send_gain_automation_buffer() const6014 Session::send_gain_automation_buffer() const
6015 {
6016 return ProcessThread::send_gain_automation_buffer ();
6017 }
6018
6019 gain_t*
scratch_automation_buffer() const6020 Session::scratch_automation_buffer() const
6021 {
6022 return ProcessThread::scratch_automation_buffer ();
6023 }
6024
6025 pan_t**
pan_automation_buffer() const6026 Session::pan_automation_buffer() const
6027 {
6028 return ProcessThread::pan_automation_buffer ();
6029 }
6030
6031 BufferSet&
get_silent_buffers(ChanCount count)6032 Session::get_silent_buffers (ChanCount count)
6033 {
6034 return ProcessThread::get_silent_buffers (count);
6035 }
6036
6037 BufferSet&
get_scratch_buffers(ChanCount count,bool silence)6038 Session::get_scratch_buffers (ChanCount count, bool silence)
6039 {
6040 return ProcessThread::get_scratch_buffers (count, silence);
6041 }
6042
6043 BufferSet&
get_noinplace_buffers(ChanCount count)6044 Session::get_noinplace_buffers (ChanCount count)
6045 {
6046 return ProcessThread::get_noinplace_buffers (count);
6047 }
6048
6049 BufferSet&
get_route_buffers(ChanCount count,bool silence)6050 Session::get_route_buffers (ChanCount count, bool silence)
6051 {
6052 return ProcessThread::get_route_buffers (count, silence);
6053 }
6054
6055
6056 BufferSet&
get_mix_buffers(ChanCount count)6057 Session::get_mix_buffers (ChanCount count)
6058 {
6059 return ProcessThread::get_mix_buffers (count);
6060 }
6061
6062 uint32_t
ntracks() const6063 Session::ntracks () const
6064 {
6065 /* XXX Could be optimized by caching */
6066
6067 uint32_t n = 0;
6068 boost::shared_ptr<RouteList> r = routes.reader ();
6069
6070 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
6071 if (boost::dynamic_pointer_cast<Track> (*i)) {
6072 ++n;
6073 }
6074 }
6075
6076 return n;
6077 }
6078
6079 uint32_t
naudiotracks() const6080 Session::naudiotracks () const
6081 {
6082 /* XXX Could be optimized by caching */
6083
6084 uint32_t n = 0;
6085 boost::shared_ptr<RouteList> r = routes.reader ();
6086
6087 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
6088 if (boost::dynamic_pointer_cast<AudioTrack> (*i)) {
6089 ++n;
6090 }
6091 }
6092
6093 return n;
6094 }
6095
6096 uint32_t
nbusses() const6097 Session::nbusses () const
6098 {
6099 uint32_t n = 0;
6100 boost::shared_ptr<RouteList> r = routes.reader ();
6101
6102 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
6103 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
6104 ++n;
6105 }
6106 }
6107
6108 return n;
6109 }
6110
6111 uint32_t
nstripables(bool with_monitor) const6112 Session::nstripables (bool with_monitor) const
6113 {
6114 uint32_t rv = routes.reader()->size ();
6115 rv += _vca_manager->vcas ().size ();
6116
6117 if (with_monitor) {
6118 return rv;
6119 }
6120
6121 if (_monitor_out) {
6122 assert (rv > 0);
6123 --rv;
6124 }
6125 return rv;
6126 }
6127
6128 bool
plot_process_graph(std::string const & file_name) const6129 Session::plot_process_graph (std::string const& file_name) const {
6130 return _process_graph ? _process_graph->plot (file_name) : false;
6131 }
6132
6133 void
add_automation_list(AutomationList * al)6134 Session::add_automation_list(AutomationList *al)
6135 {
6136 automation_lists[al->id()] = al;
6137 }
6138
6139 /** @return true if there is at least one record-enabled track, otherwise false */
6140 bool
have_rec_enabled_track() const6141 Session::have_rec_enabled_track () const
6142 {
6143 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
6144 }
6145
6146 bool
have_rec_disabled_track() const6147 Session::have_rec_disabled_track () const
6148 {
6149 return g_atomic_int_get (&_have_rec_disabled_track) == 1;
6150 }
6151
6152 /** Update the state of our rec-enabled tracks flag */
6153 void
update_route_record_state()6154 Session::update_route_record_state ()
6155 {
6156 boost::shared_ptr<RouteList> rl = routes.reader ();
6157 RouteList::iterator i = rl->begin();
6158 while (i != rl->end ()) {
6159
6160 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6161 if (tr && tr->rec_enable_control()->get_value()) {
6162 break;
6163 }
6164
6165 ++i;
6166 }
6167
6168 int const old = g_atomic_int_get (&_have_rec_enabled_track);
6169
6170 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
6171
6172 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
6173 RecordStateChanged (); /* EMIT SIGNAL */
6174 }
6175
6176 for (i = rl->begin(); i != rl->end (); ++i) {
6177 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6178 if (tr && !tr->rec_enable_control()->get_value()) {
6179 break;
6180 }
6181 }
6182
6183 g_atomic_int_set (&_have_rec_disabled_track, i != rl->end () ? 1 : 0);
6184
6185 bool record_arm_state_changed = (old != g_atomic_int_get (&_have_rec_enabled_track) );
6186
6187 if (record_status() == Recording && record_arm_state_changed ) {
6188 RecordArmStateChanged ();
6189 }
6190
6191 UpdateRouteRecordState ();
6192 }
6193
6194 void
listen_position_changed()6195 Session::listen_position_changed ()
6196 {
6197 if (loading ()) {
6198 /* skip duing session restore (already taken care of) */
6199 return;
6200 }
6201 ProcessorChangeBlocker pcb (this);
6202 boost::shared_ptr<RouteList> r = routes.reader ();
6203 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6204 (*i)->listen_position_changed ();
6205 }
6206 }
6207
6208 void
solo_control_mode_changed()6209 Session::solo_control_mode_changed ()
6210 {
6211 if (soloing() || listening()) {
6212 if (loading()) {
6213 /* We can't use ::clear_all_solo_state() here because during
6214 session loading at program startup, that will queue a call
6215 to rt_clear_all_solo_state() that will not execute until
6216 AFTER solo states have been established (thus throwing away
6217 the session's saved solo state). So just explicitly turn
6218 them all off.
6219 */
6220 set_controls (route_list_to_control_list (get_routes(), &Stripable::solo_control), 0.0, Controllable::NoGroup);
6221 } else {
6222 clear_all_solo_state (get_routes());
6223 }
6224 }
6225 }
6226
6227 /** Called when a property of one of our route groups changes */
6228 void
route_group_property_changed(RouteGroup * rg)6229 Session::route_group_property_changed (RouteGroup* rg)
6230 {
6231 RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
6232 }
6233
6234 /** Called when a route is added to one of our route groups */
6235 void
route_added_to_route_group(RouteGroup * rg,boost::weak_ptr<Route> r)6236 Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
6237 {
6238 RouteAddedToRouteGroup (rg, r);
6239 }
6240
6241 /** Called when a route is removed from one of our route groups */
6242 void
route_removed_from_route_group(RouteGroup * rg,boost::weak_ptr<Route> r)6243 Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
6244 {
6245 update_route_record_state ();
6246 RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */
6247
6248 if (!rg->has_control_master () && !rg->has_subgroup () && rg->empty()) {
6249 remove_route_group (*rg);
6250 }
6251 }
6252
6253 boost::shared_ptr<AudioTrack>
get_nth_audio_track(uint32_t nth) const6254 Session::get_nth_audio_track (uint32_t nth) const
6255 {
6256 boost::shared_ptr<RouteList> rl = routes.reader ();
6257 rl->sort (Stripable::Sorter ());
6258
6259 for (RouteList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
6260 boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack> (*r);
6261 if (!at) {
6262 continue;
6263 }
6264 if (nth-- == 0) {
6265 return at;
6266 }
6267 }
6268 return boost::shared_ptr<AudioTrack> ();
6269 }
6270
6271 boost::shared_ptr<RouteList>
get_tracks() const6272 Session::get_tracks () const
6273 {
6274 boost::shared_ptr<RouteList> rl = routes.reader ();
6275 boost::shared_ptr<RouteList> tl (new RouteList);
6276
6277 for (RouteList::const_iterator r = rl->begin(); r != rl->end(); ++r) {
6278 if (boost::dynamic_pointer_cast<Track> (*r)) {
6279 assert (!(*r)->is_auditioner()); // XXX remove me
6280 tl->push_back (*r);
6281 }
6282 }
6283 return tl;
6284 }
6285
6286 boost::shared_ptr<RouteList>
get_routes_with_regions_at(samplepos_t const p) const6287 Session::get_routes_with_regions_at (samplepos_t const p) const
6288 {
6289 boost::shared_ptr<RouteList> r = routes.reader ();
6290 boost::shared_ptr<RouteList> rl (new RouteList);
6291
6292 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6293 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
6294 if (!tr) {
6295 continue;
6296 }
6297
6298 boost::shared_ptr<Playlist> pl = tr->playlist ();
6299 if (!pl) {
6300 continue;
6301 }
6302
6303 if (pl->has_region_at (p)) {
6304 rl->push_back (*i);
6305 }
6306 }
6307
6308 return rl;
6309 }
6310
6311 void
goto_end()6312 Session::goto_end ()
6313 {
6314 if (_session_range_location) {
6315 request_locate (_session_range_location->end(), MustStop);
6316 } else {
6317 request_locate (0, MustStop);
6318 }
6319 }
6320
6321 void
goto_start(bool and_roll)6322 Session::goto_start (bool and_roll)
6323 {
6324 if (_session_range_location) {
6325 request_locate (_session_range_location->start(), and_roll ? MustRoll : RollIfAppropriate);
6326 } else {
6327 request_locate (0, and_roll ? MustRoll : RollIfAppropriate);
6328 }
6329 }
6330
6331 samplepos_t
current_start_sample() const6332 Session::current_start_sample () const
6333 {
6334 return _session_range_location ? _session_range_location->start() : 0;
6335 }
6336
6337 samplepos_t
current_end_sample() const6338 Session::current_end_sample () const
6339 {
6340 return _session_range_location ? _session_range_location->end() : 0;
6341 }
6342
6343 void
step_edit_status_change(bool yn)6344 Session::step_edit_status_change (bool yn)
6345 {
6346 bool send = false;
6347
6348 bool val = false;
6349 if (yn) {
6350 send = (_step_editors == 0);
6351 val = true;
6352
6353 _step_editors++;
6354 } else {
6355 send = (_step_editors == 1);
6356 val = false;
6357
6358 if (_step_editors > 0) {
6359 _step_editors--;
6360 }
6361 }
6362
6363 if (send) {
6364 StepEditStatusChange (val);
6365 }
6366 }
6367
6368
6369 void
start_time_changed(samplepos_t old)6370 Session::start_time_changed (samplepos_t old)
6371 {
6372 /* Update the auto loop range to match the session range
6373 (unless the auto loop range has been changed by the user)
6374 */
6375
6376 Location* s = _locations->session_range_location ();
6377 if (s == 0) {
6378 return;
6379 }
6380
6381 Location* l = _locations->auto_loop_location ();
6382
6383 if (l && l->start() == old) {
6384 l->set_start (s->start(), true);
6385 }
6386 set_dirty ();
6387 }
6388
6389 void
end_time_changed(samplepos_t old)6390 Session::end_time_changed (samplepos_t old)
6391 {
6392 /* Update the auto loop range to match the session range
6393 (unless the auto loop range has been changed by the user)
6394 */
6395
6396 Location* s = _locations->session_range_location ();
6397 if (s == 0) {
6398 return;
6399 }
6400
6401 Location* l = _locations->auto_loop_location ();
6402
6403 if (l && l->end() == old) {
6404 l->set_end (s->end(), true);
6405 }
6406 set_dirty ();
6407 }
6408
6409 std::vector<std::string>
source_search_path(DataType type) const6410 Session::source_search_path (DataType type) const
6411 {
6412 Searchpath sp;
6413
6414 if (session_dirs.size() == 1) {
6415 switch (type) {
6416 case DataType::AUDIO:
6417 sp.push_back (_session_dir->sound_path());
6418 break;
6419 case DataType::MIDI:
6420 sp.push_back (_session_dir->midi_path());
6421 break;
6422 }
6423 } else {
6424 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
6425 SessionDirectory sdir (i->path);
6426 switch (type) {
6427 case DataType::AUDIO:
6428 sp.push_back (sdir.sound_path());
6429 break;
6430 case DataType::MIDI:
6431 sp.push_back (sdir.midi_path());
6432 break;
6433 }
6434 }
6435 }
6436
6437 if (type == DataType::AUDIO) {
6438 const string sound_path_2X = _session_dir->sound_path_2X();
6439 if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
6440 if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) {
6441 sp.push_back (sound_path_2X);
6442 }
6443 }
6444 }
6445
6446 // now check the explicit (possibly user-specified) search path
6447
6448 switch (type) {
6449 case DataType::AUDIO:
6450 sp += Searchpath(config.get_audio_search_path ());
6451 break;
6452 case DataType::MIDI:
6453 sp += Searchpath(config.get_midi_search_path ());
6454 break;
6455 }
6456
6457 return sp;
6458 }
6459
6460 void
ensure_search_path_includes(const string & path,DataType type)6461 Session::ensure_search_path_includes (const string& path, DataType type)
6462 {
6463 Searchpath sp;
6464
6465 if (path == ".") {
6466 return;
6467 }
6468
6469 switch (type) {
6470 case DataType::AUDIO:
6471 sp += Searchpath(config.get_audio_search_path ());
6472 break;
6473 case DataType::MIDI:
6474 sp += Searchpath (config.get_midi_search_path ());
6475 break;
6476 }
6477
6478 for (vector<std::string>::iterator i = sp.begin(); i != sp.end(); ++i) {
6479 /* No need to add this new directory if it has the same inode as
6480 an existing one; checking inode rather than name prevents duplicated
6481 directories when we are using symlinks.
6482
6483 On Windows, I think we could just do if (*i == path) here.
6484 */
6485 if (PBD::equivalent_paths (*i, path)) {
6486 return;
6487 }
6488 }
6489
6490 sp += path;
6491
6492 switch (type) {
6493 case DataType::AUDIO:
6494 config.set_audio_search_path (sp.to_string());
6495 break;
6496 case DataType::MIDI:
6497 config.set_midi_search_path (sp.to_string());
6498 break;
6499 }
6500 }
6501
6502 void
remove_dir_from_search_path(const string & dir,DataType type)6503 Session::remove_dir_from_search_path (const string& dir, DataType type)
6504 {
6505 Searchpath sp;
6506
6507 switch (type) {
6508 case DataType::AUDIO:
6509 sp = Searchpath(config.get_audio_search_path ());
6510 break;
6511 case DataType::MIDI:
6512 sp = Searchpath (config.get_midi_search_path ());
6513 break;
6514 }
6515
6516 sp -= dir;
6517
6518 switch (type) {
6519 case DataType::AUDIO:
6520 config.set_audio_search_path (sp.to_string());
6521 break;
6522 case DataType::MIDI:
6523 config.set_midi_search_path (sp.to_string());
6524 break;
6525 }
6526
6527 }
6528
6529 boost::shared_ptr<Speakers>
get_speakers()6530 Session::get_speakers()
6531 {
6532 return _speakers;
6533 }
6534
6535 list<string>
unknown_processors() const6536 Session::unknown_processors () const
6537 {
6538 list<string> p;
6539
6540 boost::shared_ptr<RouteList> r = routes.reader ();
6541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6542 list<string> t = (*i)->unknown_processors ();
6543 copy (t.begin(), t.end(), back_inserter (p));
6544 }
6545
6546 p.sort ();
6547 p.unique ();
6548
6549 return p;
6550 }
6551
6552 list<string>
missing_filesources(DataType dt) const6553 Session::missing_filesources (DataType dt) const
6554 {
6555 list<string> p;
6556 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
6557 if (dt == DataType::AUDIO && 0 != boost::dynamic_pointer_cast<SilentFileSource> (i->second)) {
6558 p.push_back (i->second->name());
6559 }
6560 else if (dt == DataType::MIDI && 0 != boost::dynamic_pointer_cast<SMFSource> (i->second) && (i->second->flags() & Source::Missing) != 0) {
6561 p.push_back (i->second->name());
6562 }
6563 }
6564 p.sort ();
6565 return p;
6566 }
6567
6568 void
initialize_latencies()6569 Session::initialize_latencies ()
6570 {
6571 update_latency (false);
6572 update_latency (true);
6573 }
6574
6575 void
send_latency_compensation_change()6576 Session::send_latency_compensation_change ()
6577 {
6578 /* As a result of Send::set_output_latency()
6579 * or InternalReturn::set_playback_offset ()
6580 * the send's own latency can change (source track
6581 * is aligned with target bus).
6582 *
6583 * This can only happen be triggered by
6584 * Route::update_signal_latency ()
6585 * when updating the processor latency.
6586 *
6587 * We need to walk the graph again to take those changes into account
6588 * (we should probably recurse or process the graph in a 2 step process).
6589 */
6590 ++_send_latency_changes;
6591 }
6592
6593 bool
update_route_latency(bool playback,bool apply_to_delayline,bool * delayline_update_needed)6594 Session::update_route_latency (bool playback, bool apply_to_delayline, bool* delayline_update_needed)
6595 {
6596 /* apply_to_delayline can no be called concurrently with processing
6597 * caller must hold process lock when apply_to_delayline == true */
6598 assert (!apply_to_delayline || !AudioEngine::instance()->process_lock().trylock());
6599
6600 DEBUG_TRACE (DEBUG::LatencyCompensation , string_compose ("update_route_latency: %1 apply_to_delayline? %2)\n", (playback ? "PLAYBACK" : "CAPTURE"), (apply_to_delayline ? "yes" : "no")));
6601
6602 /* Note: RouteList is process-graph sorted */
6603 boost::shared_ptr<RouteList> r = routes.reader ();
6604
6605 if (playback) {
6606 /* reverse the list so that we work backwards from the last route to run to the first,
6607 * this is not needed, but can help to reduce the iterations for aux-sends.
6608 */
6609 RouteList* rl = routes.reader().get();
6610 r.reset (new RouteList (*rl));
6611 reverse (r->begin(), r->end());
6612 }
6613
6614 bool changed = false;
6615 int bailout = 0;
6616 restart:
6617 _send_latency_changes = 0;
6618 _worst_route_latency = 0;
6619
6620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6621 // if (!(*i)->active()) { continue ; } // TODO
6622 samplecnt_t l;
6623 if ((*i)->signal_latency () != (l = (*i)->update_signal_latency (apply_to_delayline, delayline_update_needed))) {
6624 changed = true;
6625 }
6626 _worst_route_latency = std::max (l, _worst_route_latency);
6627 }
6628
6629 if (_send_latency_changes > 0) {
6630 /* One extra iteration might be needed since we allow u level of aux-sends.
6631 * Except mixbus that allows up to 3 (aux-sends, sends to mixbusses 1-8, sends to mixbusses 9-12,
6632 * and then there's JACK */
6633 if (++bailout < 5) {
6634 cerr << "restarting Session::update_latency. # of send changes: " << _send_latency_changes << " iteration: " << bailout << endl;
6635 goto restart;
6636 }
6637 }
6638
6639 DEBUG_TRACE (DEBUG::LatencyCompensation , string_compose ("update_route_latency: worst proc latency: %1 (changed? %2) recursions: %3\n", _worst_route_latency, (changed ? "yes" : "no"), bailout));
6640
6641 return changed;
6642 }
6643
6644 void
update_latency(bool playback)6645 Session::update_latency (bool playback)
6646 {
6647 /* called only from AudioEngine::latency_callback.
6648 * but may indirectly be triggered from
6649 * Session::update_latency_compensation -> _engine.update_latencies
6650 */
6651 DEBUG_TRACE (DEBUG::LatencyCompensation, string_compose ("Engine latency callback: %1 (initial/deletion: %2 adding: %3 deletion: %4)\n",
6652 (playback ? "PLAYBACK" : "CAPTURE"),
6653 inital_connect_or_deletion_in_progress(),
6654 _adding_routes_in_progress,
6655 _route_deletion_in_progress
6656 ));
6657
6658 if (inital_connect_or_deletion_in_progress () || _adding_routes_in_progress || _route_deletion_in_progress) {
6659 _engine.queue_latency_update (playback);
6660 return;
6661 }
6662 if (!_engine.running() || _exporting) {
6663 return;
6664 }
6665
6666 /* Session::new_midi_track -> Route::add_processors -> Delivery::configure_io
6667 * -> IO::ensure_ports -> PortManager::register_output_port
6668 * may run currently (adding many ports) while the backend
6669 * already emits AudioEngine::latency_callback() for previously
6670 * added ports.
6671 *
6672 * Route::set_public_port_latencies() -> IO::latency may try
6673 * to lookup ports that don't yet exist.
6674 * IO::* uses BLOCK_PROCESS_CALLBACK to prevent concurrency,
6675 * so the same has to be done here to prevent a race.
6676 */
6677 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::TRY_LOCK);
6678 if (!lm.locked()) {
6679 /* IO::ensure_ports() calls jack_port_register() while holding the process-lock,
6680 * JACK2 may block and call JACKAudioBackend::_latency_callback() which
6681 * ends up here. https://pastebin.com/mitGBwpq
6682 *
6683 * This is a stopgap to be able to use 6.0 with JACK2's insane threading.
6684 * Yes JACK can also concurrently process (using the old graph) yet emit
6685 * a latency-callback (for which we do need the lock).
6686 *
6687 * One alternative is to use _adding_routes_in_progress and
6688 * call graph_reordered (false); however various entry-points
6689 * to ensure_io don't originate from Session.
6690 *
6691 * Eventually Ardour will probably need to be changed to
6692 * register ports lock-free, and mark those ports as "pending",
6693 * and skip them during process and all other callbacks.
6694 *
6695 * Then clear the pending flags in the rt-process context after
6696 * a port-registraion callback.
6697 */
6698 DEBUG_TRACE (DEBUG::LatencyCompensation, "Engine latency callback: called with process-lock held. queue for later.\n");
6699 queue_latency_recompute ();
6700 return;
6701 }
6702
6703 /* Note; RouteList is sorted as process-graph */
6704 boost::shared_ptr<RouteList> r = routes.reader ();
6705
6706 if (playback) {
6707 /* reverse the list so that we work backwards from the last route to run to the first */
6708 RouteList* rl = routes.reader().get();
6709 r.reset (new RouteList (*rl));
6710 reverse (r->begin(), r->end());
6711 }
6712 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6713 samplecnt_t latency = (*i)->set_private_port_latencies (playback);
6714 (*i)->set_public_port_latencies (latency, playback);
6715 }
6716
6717 if (playback) {
6718 /* Processing needs to be blocked while re-configuring delaylines.
6719 *
6720 * With internal backends, AudioEngine::latency_callback () -> this method
6721 * is called from the main_process_thread (so the lock is not contended).
6722 * However jack2 can concurrently process and reconfigure port latencies.
6723 * -> keep the process-lock.
6724 */
6725
6726 /* prevent any concurrent latency updates */
6727 Glib::Threads::Mutex::Lock lx (_update_latency_lock);
6728 set_worst_output_latency ();
6729 update_route_latency (true, /*apply_to_delayline*/ true, NULL);
6730
6731 /* relese before emiting signals */
6732 lm.release ();
6733
6734 } else {
6735 /* process lock is not needed to update worst-case latency */
6736 lm.release ();
6737 Glib::Threads::Mutex::Lock lx (_update_latency_lock);
6738 set_worst_input_latency ();
6739 update_route_latency (false, false, NULL);
6740 }
6741
6742 DEBUG_TRACE (DEBUG::LatencyCompensation, "Engine latency callback: DONE\n");
6743 LatencyUpdated (playback); /* EMIT SIGNAL */
6744 }
6745
6746 void
set_worst_output_latency()6747 Session::set_worst_output_latency ()
6748 {
6749 if (inital_connect_or_deletion_in_progress ()) {
6750 return;
6751 }
6752
6753 _worst_output_latency = 0;
6754
6755 if (!_engine.running()) {
6756 return;
6757 }
6758
6759 boost::shared_ptr<RouteList> r = routes.reader ();
6760
6761 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6762 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
6763 }
6764
6765 _worst_output_latency = max (_worst_output_latency, _click_io->latency());
6766
6767 DEBUG_TRACE (DEBUG::LatencyCompensation, string_compose ("Worst output latency: %1\n", _worst_output_latency));
6768 }
6769
6770 void
set_worst_input_latency()6771 Session::set_worst_input_latency ()
6772 {
6773 if (inital_connect_or_deletion_in_progress ()) {
6774 return;
6775 }
6776
6777 _worst_input_latency = 0;
6778
6779 if (!_engine.running()) {
6780 return;
6781 }
6782
6783 boost::shared_ptr<RouteList> r = routes.reader ();
6784
6785 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6786 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
6787 }
6788
6789 DEBUG_TRACE (DEBUG::LatencyCompensation, string_compose ("Worst input latency: %1\n", _worst_input_latency));
6790 }
6791
6792 void
update_latency_compensation(bool force_whole_graph,bool called_from_backend)6793 Session::update_latency_compensation (bool force_whole_graph, bool called_from_backend)
6794 {
6795 /* Called to update Ardour's internal latency values and compensation
6796 * planning. Typically case is from within ::graph_reordered()
6797 */
6798
6799 if (inital_connect_or_deletion_in_progress ()) {
6800 return;
6801 }
6802
6803 /* this lock is not usually contended, but under certain conditions,
6804 * update_latency_compensation may be called concurrently.
6805 * e.g. drag/drop copy a latent plugin while rolling.
6806 * GUI thread (via route_processors_changed) and
6807 * auto_connect_thread_run may race.
6808 */
6809 Glib::Threads::Mutex::Lock lx (_update_latency_lock, Glib::Threads::TRY_LOCK);
6810 if (!lx.locked()) {
6811 /* no need to do this twice */
6812 return;
6813 }
6814
6815 DEBUG_TRACE (DEBUG::LatencyCompensation, string_compose ("update_latency_compensation%1.\n", (force_whole_graph ? " of whole graph" : "")));
6816
6817 bool delayline_update_needed = false;
6818 bool some_track_latency_changed = update_route_latency (false, false, &delayline_update_needed);
6819
6820 if (some_track_latency_changed || force_whole_graph) {
6821
6822 /* cannot hold lock while engine initiates a full latency callback */
6823
6824 lx.release ();
6825
6826 /* next call will ask the backend up update its latencies.
6827 *
6828 * The semantics of how the backend does this are not well
6829 * defined (Oct 2019).
6830 *
6831 * In all cases, eventually AudioEngine::latency_callback() is
6832 * invoked, which will call Session::update_latency().
6833 *
6834 * Some backends will do that asynchronously with respect to
6835 * this call. Others (JACK1) will do so synchronously, and in
6836 * those cases this call will return until the backend latency
6837 * callback is complete.
6838 *
6839 * Further, if this is called as part of a backend callback,
6840 * then we have to follow the JACK1 rule that we cannot call
6841 * back into the backend during such a callback (otherwise
6842 * deadlock ensues).
6843 */
6844
6845 if (!called_from_backend) {
6846 DEBUG_TRACE (DEBUG::LatencyCompensation, "update_latency_compensation: delegate to engine\n");
6847 _engine.update_latencies ();
6848 } else {
6849 DEBUG_TRACE (DEBUG::LatencyCompensation, "update_latency_compensation called from engine, don't call back into engine\n");
6850 }
6851 } else if (delayline_update_needed) {
6852 DEBUG_TRACE (DEBUG::LatencyCompensation, "update_latency_compensation: directly apply to routes\n");
6853 lx.release (); // XXX cannot hold this lock when acquiring process_lock ?!
6854 #ifndef MIXBUS
6855 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
6856 #endif
6857 lm.acquire ();
6858
6859 boost::shared_ptr<RouteList> r = routes.reader ();
6860 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
6861 (*i)->apply_latency_compensation ();
6862 }
6863 }
6864 DEBUG_TRACE (DEBUG::LatencyCompensation, "update_latency_compensation: complete\n");
6865 }
6866
6867 const std::string
session_name_is_legal(const string & path)6868 Session::session_name_is_legal (const string& path)
6869 {
6870 static const char illegal_chars[] = { '/', '\\', ':', ';' };
6871
6872 for (size_t i = 0; i < sizeof (illegal_chars); ++i) {
6873 if (path.find (illegal_chars[i]) != string::npos) {
6874 return std::string (1, illegal_chars[i]);
6875 }
6876 }
6877
6878 for (size_t i = 0; i < path.length(); ++i) {
6879 if (iscntrl (path[i])) {
6880 return _("Control Char");
6881 }
6882 }
6883 return std::string ();
6884 }
6885
6886 void
notify_presentation_info_change()6887 Session::notify_presentation_info_change ()
6888 {
6889 if (deletion_in_progress()) {
6890 return;
6891 }
6892
6893 reassign_track_numbers();
6894 }
6895
6896 void
controllable_touched(boost::weak_ptr<PBD::Controllable> c)6897 Session::controllable_touched (boost::weak_ptr<PBD::Controllable> c)
6898 {
6899 _recently_touched_controllable = c;
6900 }
6901
6902 boost::shared_ptr<PBD::Controllable>
recently_touched_controllable() const6903 Session::recently_touched_controllable () const
6904 {
6905 return _recently_touched_controllable.lock ();
6906 }
6907
6908 bool
operation_in_progress(GQuark op) const6909 Session::operation_in_progress (GQuark op) const
6910 {
6911 return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
6912 }
6913
6914 void
reconnect_ltc_output()6915 Session::reconnect_ltc_output ()
6916 {
6917 if (_ltc_output_port) {
6918 string src = Config->get_ltc_output_port();
6919
6920 _ltc_output_port->disconnect_all ();
6921
6922 if (src != _("None") && !src.empty()) {
6923 _ltc_output_port->connect (src);
6924 }
6925 }
6926 }
6927
6928 void
set_range_selection(samplepos_t start,samplepos_t end)6929 Session::set_range_selection (samplepos_t start, samplepos_t end)
6930 {
6931 _range_selection = Evoral::Range<samplepos_t> (start, end);
6932 }
6933
6934 void
set_object_selection(samplepos_t start,samplepos_t end)6935 Session::set_object_selection (samplepos_t start, samplepos_t end)
6936 {
6937 _object_selection = Evoral::Range<samplepos_t> (start, end);
6938 }
6939
6940 void
clear_range_selection()6941 Session::clear_range_selection ()
6942 {
6943 _range_selection = Evoral::Range<samplepos_t> (-1,-1);
6944 }
6945
6946 void
clear_object_selection()6947 Session::clear_object_selection ()
6948 {
6949 _object_selection = Evoral::Range<samplepos_t> (-1,-1);
6950 }
6951
6952 void
auto_connect_route(boost::shared_ptr<Route> route,bool connect_inputs,bool connect_outputs,const ChanCount & input_start,const ChanCount & output_start,const ChanCount & input_offset,const ChanCount & output_offset)6953 Session::auto_connect_route (boost::shared_ptr<Route> route,
6954 bool connect_inputs,
6955 bool connect_outputs,
6956 const ChanCount& input_start,
6957 const ChanCount& output_start,
6958 const ChanCount& input_offset,
6959 const ChanCount& output_offset)
6960 {
6961 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
6962
6963 DEBUG_TRACE (DEBUG::PortConnectAuto,
6964 string_compose ("Session::auto_connect_route '%1' ci: %2 co: %3 is=(%4) os=(%5) io=(%6) oo=(%7)\n",
6965 route->name(), connect_inputs, connect_outputs,
6966 input_start, output_start, input_offset, output_offset));
6967
6968 _auto_connect_queue.push (AutoConnectRequest (route,
6969 connect_inputs, connect_outputs,
6970 input_start, output_start,
6971 input_offset, output_offset));
6972
6973 lx.release (); // XXX check try-lock + pthread_cond_wait
6974 auto_connect_thread_wakeup ();
6975 }
6976
6977 void
auto_connect_thread_wakeup()6978 Session::auto_connect_thread_wakeup ()
6979 {
6980 if (pthread_mutex_trylock (&_auto_connect_mutex) == 0) {
6981 pthread_cond_signal (&_auto_connect_cond);
6982 pthread_mutex_unlock (&_auto_connect_mutex);
6983 }
6984 }
6985
6986 void
queue_latency_recompute()6987 Session::queue_latency_recompute ()
6988 {
6989 g_atomic_int_inc (&_latency_recompute_pending);
6990 auto_connect_thread_wakeup ();
6991 }
6992
6993 void
auto_connect(const AutoConnectRequest & ar)6994 Session::auto_connect (const AutoConnectRequest& ar)
6995 {
6996 boost::shared_ptr<Route> route = ar.route.lock();
6997
6998 if (!route) { return; }
6999
7000 if (!IO::connecting_legal) {
7001 return;
7002 }
7003
7004 /* If both inputs and outputs are auto-connected to physical ports,
7005 * use the max of input and output offsets to ensure auto-connected
7006 * port numbers always match up (e.g. the first audio input and the
7007 * first audio output of the route will have the same physical
7008 * port number). Otherwise just use the lowest input or output
7009 * offset possible.
7010 */
7011
7012 const bool in_out_physical =
7013 (Config->get_input_auto_connect() & AutoConnectPhysical)
7014 && (Config->get_output_auto_connect() & AutoConnectPhysical)
7015 && ar.connect_inputs;
7016
7017 const ChanCount in_offset = in_out_physical
7018 ? ChanCount::max(ar.input_offset, ar.output_offset)
7019 : ar.input_offset;
7020
7021 const ChanCount out_offset = in_out_physical
7022 ? ChanCount::max(ar.input_offset, ar.output_offset)
7023 : ar.output_offset;
7024
7025 DEBUG_TRACE (DEBUG::PortConnectAuto,
7026 string_compose ("Session::auto_connect '%1' iop: %2 is=(%3) os=(%4) Eio=(%5) Eoo=(%6)\n",
7027 route->name(), in_out_physical, ar.input_start, ar.output_start, in_offset, out_offset));
7028
7029 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
7030 vector<string> physinputs;
7031 vector<string> physoutputs;
7032
7033
7034 /* for connecting track inputs we only want MIDI ports marked
7035 * for "music".
7036 */
7037
7038 get_physical_ports (physinputs, physoutputs, *t, MidiPortMusic);
7039
7040 DEBUG_TRACE (DEBUG::PortConnectAuto,
7041 string_compose ("Physical MidiPortMusic %1 Ports count in: %2 out %3\n",
7042 (*t).to_string(), physinputs.size(), physoutputs.size()));
7043
7044 if (!physinputs.empty() && ar.connect_inputs) {
7045 uint32_t nphysical_in = physinputs.size();
7046
7047 for (uint32_t i = ar.input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
7048 string port;
7049
7050 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
7051 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
7052 }
7053
7054 if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
7055 DEBUG_TRACE (DEBUG::PortConnectAuto, "Failed to auto-connect input.");
7056 break;
7057 }
7058 }
7059 }
7060
7061 if (!physoutputs.empty() && ar.connect_outputs) {
7062 DEBUG_TRACE (DEBUG::PortConnectAuto,
7063 string_compose ("Connect %1 outputs # %2 .. %3\n",
7064 (*t).to_string(), ar.output_start.get(*t), route->n_outputs().get(*t)));
7065
7066 uint32_t nphysical_out = physoutputs.size();
7067 for (uint32_t i = ar.output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
7068 string port;
7069
7070 if ((*t) == DataType::MIDI && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
7071 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
7072 } else if ((*t) == DataType::AUDIO && (Config->get_output_auto_connect() & AutoConnectMaster)) {
7073 /* master bus is audio only */
7074 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
7075 port = _master_out->input()->ports().port(*t,
7076 i % _master_out->input()->n_ports().get(*t))->name();
7077 }
7078 }
7079
7080 if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
7081 DEBUG_TRACE (DEBUG::PortConnectAuto, "Failed to auto-connect ouput.");
7082 break;
7083 }
7084 }
7085 }
7086 }
7087 }
7088
7089 void
auto_connect_thread_start()7090 Session::auto_connect_thread_start ()
7091 {
7092 if (g_atomic_int_get (&_ac_thread_active)) {
7093 return;
7094 }
7095
7096 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
7097 while (!_auto_connect_queue.empty ()) {
7098 _auto_connect_queue.pop ();
7099 }
7100 lx.release ();
7101
7102 g_atomic_int_set (&_ac_thread_active, 1);
7103 if (pthread_create (&_auto_connect_thread, NULL, auto_connect_thread, this)) {
7104 g_atomic_int_set (&_ac_thread_active, 0);
7105 }
7106 }
7107
7108 void
auto_connect_thread_terminate()7109 Session::auto_connect_thread_terminate ()
7110 {
7111 if (!g_atomic_int_get (&_ac_thread_active)) {
7112 return;
7113 }
7114
7115 {
7116 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
7117 while (!_auto_connect_queue.empty ()) {
7118 _auto_connect_queue.pop ();
7119 }
7120 }
7121
7122 /* cannot use auto_connect_thread_wakeup() because that is allowed to
7123 * fail to wakeup the thread.
7124 */
7125
7126 pthread_mutex_lock (&_auto_connect_mutex);
7127 g_atomic_int_set (&_ac_thread_active, 0);
7128 pthread_cond_signal (&_auto_connect_cond);
7129 pthread_mutex_unlock (&_auto_connect_mutex);
7130
7131 void *status;
7132 pthread_join (_auto_connect_thread, &status);
7133 }
7134
7135 void *
auto_connect_thread(void * arg)7136 Session::auto_connect_thread (void *arg)
7137 {
7138 Session *s = static_cast<Session *>(arg);
7139 pthread_set_name (X_("autoconnect"));
7140 s->auto_connect_thread_run ();
7141 pthread_exit (0);
7142 return 0;
7143 }
7144
7145 void
auto_connect_thread_run()7146 Session::auto_connect_thread_run ()
7147 {
7148 SessionEvent::create_per_thread_pool (X_("autoconnect"), 1024);
7149 PBD::notify_event_loops_about_thread_creation (pthread_self(), X_("autoconnect"), 1024);
7150 pthread_mutex_lock (&_auto_connect_mutex);
7151
7152 Glib::Threads::Mutex::Lock lx (_auto_connect_queue_lock);
7153 while (g_atomic_int_get (&_ac_thread_active)) {
7154
7155 if (!_auto_connect_queue.empty ()) {
7156 /* Why would we need the process lock?
7157 *
7158 * A: if ports are added while connections change,
7159 * the backend's iterator may be invalidated:
7160 * graph_order_callback() -> resort_routes() -> direct_feeds_according_to_reality () -> backend::connected_to()
7161 * Ardour::IO uses the process-lock to avoid concurrency, too
7162 */
7163 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
7164
7165 while (!_auto_connect_queue.empty ()) {
7166 const AutoConnectRequest ar (_auto_connect_queue.front());
7167 _auto_connect_queue.pop ();
7168 lx.release ();
7169 auto_connect (ar);
7170 lx.acquire ();
7171 }
7172 }
7173 lx.release ();
7174
7175 if (!actively_recording ()) { // might not be needed,
7176 /* this is only used for updating plugin latencies, the
7177 * graph does not change. so it's safe in general.
7178 * BUT..
7179 * update_latency_compensation ()
7180 * calls DiskWriter::set_capture_offset () which
7181 * modifies the capture-offset, which can be a problem.
7182 */
7183 while (g_atomic_int_and (&_latency_recompute_pending, 0)) {
7184 update_latency_compensation (false, false);
7185 if (g_atomic_int_get (&_latency_recompute_pending)) {
7186 Glib::usleep (1000);
7187 }
7188 }
7189 }
7190
7191 if (_midi_ports && g_atomic_int_get (&_update_pretty_names)) {
7192 boost::shared_ptr<Port> ap = boost::dynamic_pointer_cast<Port> (vkbd_output_port ());
7193 if (ap->pretty_name () != _("Virtual Keyboard")) {
7194 ap->set_pretty_name (_("Virtual Keyboard"));
7195 }
7196 g_atomic_int_set (&_update_pretty_names, 0);
7197 }
7198
7199 if (_engine.port_deletions_pending ().read_space () > 0) {
7200 // this may call ARDOUR::Port::drop ... jack_port_unregister ()
7201 // jack1 cannot cope with removing ports while processing
7202 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
7203 _engine.clear_pending_port_deletions ();
7204 }
7205
7206 lx.acquire ();
7207 if (_auto_connect_queue.empty ()) {
7208 lx.release ();
7209 pthread_cond_wait (&_auto_connect_cond, &_auto_connect_mutex);
7210 lx.acquire ();
7211 }
7212 }
7213 lx.release ();
7214 pthread_mutex_unlock (&_auto_connect_mutex);
7215 }
7216
7217 void
cancel_all_solo()7218 Session::cancel_all_solo ()
7219 {
7220 StripableList sl;
7221
7222 get_stripables (sl);
7223
7224 set_controls (stripable_list_to_control_list (sl, &Stripable::solo_control), 0.0, Controllable::NoGroup);
7225 clear_all_solo_state (routes.reader());
7226
7227 _engine.monitor_port().clear_ports (false);
7228 }
7229
7230 bool
listening() const7231 Session::listening () const
7232 {
7233 if (_listen_cnt > 0) {
7234 return true;
7235 }
7236
7237 if (_monitor_out && _engine.monitor_port().monitoring ()) {
7238 return true;
7239 }
7240
7241 return false;
7242 }
7243
7244 void
maybe_update_tempo_from_midiclock_tempo(float bpm)7245 Session::maybe_update_tempo_from_midiclock_tempo (float bpm)
7246 {
7247 if (_tempo_map->n_tempos() == 1) {
7248 TempoSection& ts (_tempo_map->tempo_section_at_sample (0));
7249 if (fabs (ts.note_types_per_minute() - bpm) > (0.01 * ts.note_types_per_minute())) {
7250 const Tempo tempo (bpm, 4.0, bpm);
7251 _tempo_map->replace_tempo (ts, tempo, 0.0, 0.0, AudioTime);
7252 }
7253 }
7254 }
7255
7256 void
send_mclk_for_cycle(samplepos_t start_sample,samplepos_t end_sample,pframes_t n_samples,samplecnt_t pre_roll)7257 Session::send_mclk_for_cycle (samplepos_t start_sample, samplepos_t end_sample, pframes_t n_samples, samplecnt_t pre_roll)
7258 {
7259 midi_clock->tick (start_sample, end_sample, n_samples, pre_roll);
7260 }
7261
7262 void
set_had_destructive_tracks(bool yn)7263 Session::set_had_destructive_tracks (bool yn)
7264 {
7265 _had_destructive_tracks = yn;
7266 }
7267
7268 bool
had_destructive_tracks() const7269 Session::had_destructive_tracks() const
7270 {
7271 return _had_destructive_tracks;
7272 }
7273