93db2113ee913a53b390af0d9ed776ab2df3fa77
[ardour.git] / libs / ardour / transport_master_manager.cc
1 /*
2  * Copyright (C) 2018-2019 Paul Davis <paul@linuxaudiosystems.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include "ardour/audioengine.h"
20 #include "ardour/debug.h"
21 #include "ardour/disk_reader.h"
22 #include "ardour/session.h"
23 #include "ardour/rc_configuration.h"
24 #include "ardour/transport_master_manager.h"
25
26 #include "pbd/boost_debug.cc"
27 #include "pbd/i18n.h"
28 #include "pbd/stateful.h"
29
30 using namespace ARDOUR;
31 using namespace PBD;
32
33 const std::string TransportMasterManager::state_node_name = X_("TransportMasters");
34 TransportMasterManager* TransportMasterManager::_instance = 0;
35
36 TransportMasterManager::TransportMasterManager()
37         : _master_speed (0)
38         , _master_position (0)
39         , _session (0)
40         , _master_invalid_this_cycle (false)
41         , master_dll_initstate (0)
42 {
43 }
44
45 TransportMasterManager::~TransportMasterManager ()
46 {
47         clear ();
48 }
49
50 TransportMasterManager&
51 TransportMasterManager::create ()
52 {
53         assert (!_instance);
54
55         cerr << "TMM::create(), Config = " << Config << " size will be " << sizeof (TransportMasterManager) << endl;
56
57         _instance = new TransportMasterManager;
58
59         XMLNode* tmm_node = Config->extra_xml (X_("TransportMasters"));
60         if (tmm_node) {
61                 cerr << " setting state via XML\n";
62                 _instance->set_state (*tmm_node, Stateful::current_state_version);
63         } else {
64                 cerr << " setting default config\n";
65                 _instance->set_default_configuration ();
66         }
67
68         return *_instance;
69 }
70
71 int
72 TransportMasterManager::set_default_configuration ()
73 {
74         try {
75
76                 clear ();
77
78                 /* setup default transport masters. Most people will never need any
79                    others
80                 */
81
82                 add (Engine, X_("JACK Transport"), false);
83                 add (MTC, X_("MTC"), false);
84                 add (LTC, X_("LTC"), false);
85                 add (MIDIClock, X_("MIDI Clock"), false);
86
87         } catch (...) {
88                 return -1;
89         }
90
91         _current_master = _transport_masters.back();
92         cerr << "default current master (back) is " << _current_master->name() << endl;
93         return 0;
94 }
95
96 void
97 TransportMasterManager::set_session (Session* s)
98 {
99         /* Called by AudioEngine in process context, synchronously with it's
100          * own "adoption" of the Session. The call will occur before the first
101          * call to ::pre_process_transport_masters().
102          */
103
104         Glib::Threads::RWLock::ReaderLock lm (lock);
105
106         config_connection.disconnect ();
107
108         _session = s;
109
110         for (TransportMasters::iterator tm = _transport_masters.begin(); tm != _transport_masters.end(); ++tm) {
111                 (*tm)->set_session (s);
112         }
113
114         if (_session) {
115                 _session->config.ParameterChanged.connect_same_thread (config_connection, boost::bind (&TransportMasterManager::parameter_changed, this, _1));
116         }
117
118 }
119
120 void
121 TransportMasterManager::parameter_changed (std::string const & what)
122 {
123         if (what == "external-sync") {
124                 if (!_session->config.get_external_sync()) {
125                         /* disabled */
126                         DiskReader::dec_no_disk_output ();
127                 }
128         }
129 }
130
131 TransportMasterManager&
132 TransportMasterManager::instance()
133 {
134         if (!_instance) {
135                 fatal << string_compose (_("programming error:%1"), X_("TransportMasterManager::instance() called without an instance!")) << endmsg;
136                 /* NOTREACHED */
137         }
138         return *_instance;
139 }
140
141 // Called from AudioEngine::process_callback() BEFORE Session::process() is called. Each transport master has processed any incoming data for this cycle,
142 // and this method computes the transport speed that Ardour should use to get into and remain in sync with the master.
143 //
144 double
145 TransportMasterManager::pre_process_transport_masters (pframes_t nframes, samplepos_t now)
146 {
147         Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK);
148
149         if (!lm.locked()) {
150                 return 1.0;
151         }
152
153         boost::optional<samplepos_t> session_pos;
154
155         if (_session) {
156                 session_pos = _session->audible_sample();
157         }
158
159         if (Config->get_run_all_transport_masters_always()) {
160                 for (TransportMasters::iterator tm = _transport_masters.begin(); tm != _transport_masters.end(); ++tm) {
161                         if ((*tm)->check_collect()) {
162                                 (*tm)->pre_process (nframes, now, session_pos);
163                         }
164                 }
165         }
166
167         if (!_session) {
168                 return 1.0;
169         }
170
171         /* if we're not running ALL transport masters, but still have a current
172          * one, then we should run that one all the time so that we know
173          * precisely where it is when we starting chasing it ...
174          */
175
176         if (!Config->get_run_all_transport_masters_always() && _current_master) {
177                 _current_master->pre_process (nframes, now, session_pos);
178         }
179
180         if (!_session->config.get_external_sync()) {
181                 DEBUG_TRACE (DEBUG::Slave, string_compose ("no external sync, use session actual speed of %1\n", _session->actual_speed() ? _session->actual_speed() : 1.0));
182                 return _session->actual_speed () ? _session->actual_speed() : 1.0;
183         }
184
185         /* --- NOT REACHED UNLESS CHASING (i.e. _session->config.get_external_sync() is true ------*/
186
187         if (!_current_master->ok()) {
188                 /* stop */
189                 _session->request_transport_speed (0.0, false, _current_master->request_type());
190                 DEBUG_TRACE (DEBUG::Slave, "no roll2 - master has failed\n");
191                 _master_invalid_this_cycle = true;
192                 return 1.0;
193         }
194
195         if (!_current_master->locked()) {
196                 DEBUG_TRACE (DEBUG::Slave, "no roll4 - not locked\n");
197                 _master_invalid_this_cycle = true;
198                 return 1.0;
199         }
200
201         double engine_speed;
202         samplepos_t ignore1, ignore2;
203
204         if (!_current_master->speed_and_position (_master_speed, _master_position, ignore1, ignore2, now)) {
205                 return 1.0;
206         }
207
208         if (_master_speed != 0.0) {
209
210                 samplepos_t delta = _master_position;
211
212                 if (_session->compute_audible_delta (delta)) {
213
214                         if (master_dll_initstate == 0) {
215
216                                 init_transport_master_dll (_master_speed, _master_position);
217                                 _master_invalid_this_cycle = true;
218                                 DEBUG_TRACE (DEBUG::Slave, "no roll3 - still initializing master DLL\n");
219                                 master_dll_initstate = _master_speed > 0.0 ? 1 : -1;
220
221                                 return 1.0;
222                         }
223
224                         /* compute delta or "error" between the computed master_position for
225                          * this cycle and the current session position.
226                          *
227                          * Remember: ::speed_and_position() is being called in process context
228                          * but returns the predicted speed+position for the start of this process cycle,
229                          * not just the most recent timestamp received by the current master object.
230                          */
231
232                         DEBUG_TRACE (DEBUG::Slave, string_compose ("master DLL: delta = %1 (%2 vs %3) res: %4\n", delta, _master_position, _session->transport_sample(), _current_master->resolution()));
233
234                         if (delta > _current_master->resolution()) {
235
236                                 // init_transport_master_dll (_master_speed, _master_position);
237
238                                 if (!_session->actively_recording()) {
239                                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave delta %1 greater than slave resolution %2 => no disk output\n", delta, _current_master->resolution()));
240                                         /* run routes as normal, but no disk output */
241                                         DiskReader::inc_no_disk_output ();
242                                 } else {
243                                         DiskReader::dec_no_disk_output ();
244                                 }
245                         } else {
246                                 DiskReader::dec_no_disk_output ();
247                         }
248
249                         /* inject DLL with new data */
250
251                         DEBUG_TRACE (DEBUG::Slave, string_compose ("feed master DLL t0 %1 t1 %2 e %3 %4 e2 %5 sess %6\n", t0, t1, delta, _master_position, e2, _session->transport_sample()));
252
253                         const double e = delta;
254
255                         t0 = t1;
256                         t1 += b * e + e2;
257                         e2 += c * e;
258
259                         engine_speed = (t1 - t0) / nframes;
260
261                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave @ %1 speed %2 cur delta %3 matching speed %4\n", _master_position, _master_speed, delta, engine_speed));
262
263                         /* provide a .1% deadzone to lock the speed */
264                         if (fabs (engine_speed - 1.0) <= 0.001) {
265                                 engine_speed = 1.0;
266                         }
267
268                         if (_current_master->sample_clock_synced() && engine_speed != 0.0f) {
269
270                                 /* if the master is synced to our audio interface via word-clock or similar, then we assume that its speed is binary: 0.0 or 1.0
271                                    (since our sample clock cannot change with respect to it).
272                                 */
273                                 if (engine_speed > 0.0) {
274                                         engine_speed = 1.0;
275                                 } else if (engine_speed < 0.0) {
276                                         engine_speed = -1.0;
277                                 }
278                         }
279
280                         /* speed is set, we're locked, and good to go */
281                         DEBUG_TRACE (DEBUG::Slave, string_compose ("%1: computed speed-to-follow-master as %2\n", _current_master->name(), engine_speed));
282
283                 } else {
284
285                         /* session has not finished with latency compensation yet, so we cannot compute the
286                            difference between the master and the session.
287                         */
288                         engine_speed = 1.0;
289                 }
290
291         } else {
292
293                 engine_speed = 1.0;
294         }
295
296         _master_invalid_this_cycle = false;
297
298         DEBUG_TRACE (DEBUG::Slave, string_compose ("computed resampling ratio as %1 with position = %2 and speed = %3\n", engine_speed, _master_position, _master_speed));
299
300         return engine_speed;
301 }
302
303
304 void
305 TransportMasterManager::init_transport_master_dll (double speed, samplepos_t pos)
306 {
307         /* the bandwidth of the DLL is a trade-off,
308          * because the max-speed of the transport in ardour is
309          * limited to +-8.0, a larger bandwidth would cause oscillations
310          *
311          * But this is only really a problem if the user performs manual
312          * seeks while transport is running and slaved to some timecode-y master.
313          */
314
315         AudioEngine* ae = AudioEngine::instance();
316
317         double const omega = 2.0 * M_PI * double(ae->samples_per_cycle()) / 2.0 / double(ae->sample_rate());
318         b = 1.4142135623730950488 * omega;
319         c = omega * omega;
320
321         const int direction = (speed >= 0.0 ? 1 : -1);
322
323         master_dll_initstate = direction;
324
325         e2 = double (direction * ae->samples_per_cycle());
326         t0 = double (pos);
327         t1 = t0 + e2;
328
329         DEBUG_TRACE (DEBUG::Slave, string_compose ("[re-]init ENGINE DLL %1 %2 %3 from %4 %5\n", t0,  t1, e2, speed, pos));
330 }
331
332 int
333 TransportMasterManager::add (SyncSource type, std::string const & name, bool removeable)
334 {
335         int ret = 0;
336         boost::shared_ptr<TransportMaster> tm;
337
338         DEBUG_TRACE (DEBUG::Slave, string_compose ("adding new transport master, type %1 name %2 removeable %3\n", enum_2_string (type), name, removeable));
339
340         {
341                 Glib::Threads::RWLock::WriterLock lm (lock);
342
343                 for (TransportMasters::const_iterator t = _transport_masters.begin(); t != _transport_masters.end(); ++t) {
344                         if ((*t)->name() == name) {
345                                 error << string_compose (_("There is already a transport master named \"%1\" - not duplicated"), name) << endmsg;
346                                 return -1;
347                         }
348                 }
349
350                 tm = TransportMaster::factory (type, name, removeable);
351
352                 if (!tm) {
353                         return -1;
354                 }
355
356                 boost_debug_shared_ptr_mark_interesting (tm.get(), "tm");
357                 ret = add_locked (tm);
358         }
359
360         if (ret == 0) {
361                 Added (tm);
362         }
363
364         return ret;
365 }
366
367 int
368 TransportMasterManager::add_locked (boost::shared_ptr<TransportMaster> tm)
369 {
370         if (!tm) {
371                 return -1;
372         }
373
374
375         if (_session) {
376                 tm->set_session (_session);
377         }
378
379         _transport_masters.push_back (tm);
380         return 0;
381 }
382
383 int
384 TransportMasterManager::remove (std::string const & name)
385 {
386         int ret = -1;
387         boost::shared_ptr<TransportMaster> tm;
388
389         {
390                 Glib::Threads::RWLock::WriterLock lm (lock);
391
392                 for (TransportMasters::iterator t = _transport_masters.begin(); t != _transport_masters.end(); ++t) {
393                         if ((*t)->name() == name) {
394                                 if (!(*t)->removeable()) {
395                                         return -1;
396                                 }
397                                 tm = *t;
398                                 _transport_masters.erase (t);
399                                 ret = 0;
400                                 break;
401                         }
402                 }
403         }
404
405         if (ret == 0) {
406                 Removed (tm);
407         }
408
409         return ret;
410 }
411
412 int
413 TransportMasterManager::set_current_locked (boost::shared_ptr<TransportMaster> c)
414 {
415         if (c) {
416                 if (find (_transport_masters.begin(), _transport_masters.end(), c) == _transport_masters.end()) {
417                         warning << string_compose (X_("programming error: attempt to use unknown transport master \"%1\"\n"), c->name());
418                         return -1;
419                 }
420         }
421
422         if (!c->usable()) {
423                 return -1;
424         }
425
426         _current_master = c;
427         _master_speed = 0;
428         _master_position = 0;
429
430         master_dll_initstate = 0;
431
432         DEBUG_TRACE (DEBUG::Slave, string_compose ("current transport master set to %1\n", (c ? c->name() : string ("none"))));
433
434         return 0;
435 }
436
437 int
438 TransportMasterManager::set_current (boost::shared_ptr<TransportMaster> c)
439 {
440         int ret = -1;
441         boost::shared_ptr<TransportMaster> old (_current_master);
442
443         {
444                 Glib::Threads::RWLock::WriterLock lm (lock);
445                 ret = set_current_locked (c);
446         }
447
448         if (ret == 0) {
449                 CurrentChanged (old, _current_master); // EMIT SIGNAL
450         }
451
452         return ret;
453 }
454
455 int
456 TransportMasterManager::set_current (SyncSource ss)
457 {
458         int ret = -1;
459         boost::shared_ptr<TransportMaster> old (_current_master);
460
461         {
462                 Glib::Threads::RWLock::WriterLock lm (lock);
463
464                 for (TransportMasters::iterator t = _transport_masters.begin(); t != _transport_masters.end(); ++t) {
465                         if ((*t)->type() == ss) {
466                                 ret = set_current_locked (*t);
467                                 break;
468                         }
469                 }
470         }
471
472         if (ret == 0) {
473                 CurrentChanged (old, _current_master); // EMIT SIGNAL
474         }
475
476         return ret;
477 }
478
479
480 int
481 TransportMasterManager::set_current (std::string const & str)
482 {
483         int ret = -1;
484         boost::shared_ptr<TransportMaster> old (_current_master);
485
486         {
487                 Glib::Threads::RWLock::WriterLock lm (lock);
488
489                 for (TransportMasters::iterator t = _transport_masters.begin(); t != _transport_masters.end(); ++t) {
490                         if ((*t)->name() == str) {
491                                 ret = set_current_locked (*t);
492                                 break;
493                         }
494                 }
495         }
496
497         if (ret == 0) {
498                 CurrentChanged (old, _current_master); // EMIT SIGNAL
499         }
500
501         return ret;
502 }
503
504
505 void
506 TransportMasterManager::clear ()
507 {
508         {
509                 Glib::Threads::RWLock::WriterLock lm (lock);
510                 _current_master.reset ();
511                 _transport_masters.clear ();
512         }
513
514         Removed (boost::shared_ptr<TransportMaster>());
515 }
516
517 int
518 TransportMasterManager::set_state (XMLNode const & node, int version)
519 {
520         PBD::stacktrace (std::cerr, 20);
521         assert (node.name() == state_node_name);
522
523         XMLNodeList const & children = node.children();
524
525         {
526                 Glib::Threads::RWLock::WriterLock lm (lock);
527
528                 _current_master.reset ();
529                 boost_debug_list_ptrs ();
530
531                 /* TramsportMasters live for the entire life of the
532                  * program. TransportMasterManager::set_state() should only be
533                  * called at the start of the program, and there should be no
534                  * transport masters at that time.
535                  */
536
537                 assert (_transport_masters.empty());
538
539                 for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
540
541                         boost::shared_ptr<TransportMaster> tm = TransportMaster::factory (**c);
542
543                         if (!tm) {
544                                 continue;
545                         }
546
547                         boost_debug_shared_ptr_mark_interesting (tm.get(), "tm");
548
549                         if (add_locked (tm)) {
550                                 continue;
551                         }
552
553                         /* we know it is the last thing added to the list of masters */
554
555                         _transport_masters.back()->set_state (**c, version);
556                 }
557         }
558
559         std::string current_master;
560
561         if (node.get_property (X_("current"), current_master)) {
562
563                 /* may fal if current_master is not usable */
564
565                 set_current (current_master);
566
567                 if (!current()) {
568                         set_current (MTC); // always available
569                 }
570
571         } else {
572                 set_current (MTC);
573         }
574
575         return 0;
576 }
577
578 XMLNode&
579 TransportMasterManager::get_state ()
580 {
581         XMLNode* node = new XMLNode (state_node_name);
582
583         if (_current_master) {
584                 node->set_property (X_("current"), _current_master->name());
585         }
586
587         Glib::Threads::RWLock::ReaderLock lm (lock);
588
589         for (TransportMasters::iterator t = _transport_masters.begin(); t != _transport_masters.end(); ++t) {
590                 node->add_child_nocopy ((*t)->get_state());
591         }
592
593         return *node;
594 }
595
596 boost::shared_ptr<TransportMaster>
597 TransportMasterManager::master_by_type (SyncSource src) const
598 {
599         Glib::Threads::RWLock::ReaderLock lm (lock);
600
601         for (TransportMasters::const_iterator tm = _transport_masters.begin(); tm != _transport_masters.end(); ++tm) {
602                 if ((*tm)->type() == src) {
603                         return *tm;
604                 }
605         }
606
607         return boost::shared_ptr<TransportMaster> ();
608 }
609
610 void
611 TransportMasterManager::engine_stopped ()
612 {
613         DEBUG_TRACE (DEBUG::Slave, "engine stopped, reset all transport masters\n");
614         {
615                 Glib::Threads::RWLock::ReaderLock lm (lock);
616
617                 for (TransportMasters::const_iterator tm = _transport_masters.begin(); tm != _transport_masters.end(); ++tm) {
618                         (*tm)->reset (false);
619                 }
620         }
621 }
622
623 void
624 TransportMasterManager::restart ()
625 {
626         XMLNode* node;
627
628         if ((node = Config->transport_master_state()) != 0) {
629
630                 Glib::Threads::RWLock::ReaderLock lm (lock);
631
632                 for (TransportMasters::const_iterator tm = _transport_masters.begin(); tm != _transport_masters.end(); ++tm) {
633                         (*tm)->connect_port_using_state ();
634                         (*tm)->reset (false);
635                 }
636
637         } else {
638                 if (TransportMasterManager::instance().set_default_configuration ()) {
639                         error << _("Cannot initialize transport master manager") << endmsg;
640                         /* XXX now what? */
641                 }
642         }
643 }
644
645 void
646 TransportMasterManager::reconnect_ports ()
647 {
648         DEBUG_TRACE (DEBUG::Slave, "reconnecting all transport master ports\n");
649         {
650                 Glib::Threads::RWLock::ReaderLock lm (lock);
651
652                 for (TransportMasters::const_iterator tm = _transport_masters.begin(); tm != _transport_masters.end(); ++tm) {
653                         (*tm)->connect_port_using_state ();
654                 }
655         }
656 }