NO-OP: <tab> after <space> fixes in libs
[ardour.git] / libs / ardour / ardour / transport_master.h
1 /*
2     Copyright (C) 2002 Paul Davis
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
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __ardour_transport_master_h__
21 #define __ardour_transport_master_h__
22
23 #include <vector>
24
25 #include <boost/optional.hpp>
26 #include <boost/atomic.hpp>
27
28 #include <glibmm/threads.h>
29 #include <glibmm/timer.h>
30
31 #include <ltc.h>
32
33 #include "pbd/i18n.h"
34 #include "pbd/properties.h"
35 #include "pbd/signals.h"
36 #include "pbd/statefuldestructible.h"
37
38 #include "temporal/time.h"
39
40 #include "ardour/libardour_visibility.h"
41 #include "ardour/region.h" /* for Properties::locked */
42 #include "ardour/types.h"
43
44 #include "midi++/parser.h"
45 #include "midi++/types.h"
46
47 /* used for delta_string(): */
48 #define PLUSMINUS(A) ( ((A)<0) ? "-" : (((A)>0) ? "+" : "\u00B1") )
49 #define LEADINGZERO(A) ( (A)<10 ? "   " : (A)<100 ? "  " : (A)<1000 ? " " : "" )
50
51 namespace ARDOUR {
52
53 class TempoMap;
54 class Session;
55 class AudioEngine;
56 class Location;
57 class MidiPort;
58 class AudioPort;
59 class Port;
60
61 namespace Properties {
62         LIBARDOUR_API extern PBD::PropertyDescriptor<bool> fr2997;
63         LIBARDOUR_API extern PBD::PropertyDescriptor<bool> collect;
64         LIBARDOUR_API extern PBD::PropertyDescriptor<bool> connected;
65         LIBARDOUR_API extern PBD::PropertyDescriptor<bool> sclock_synced;
66         LIBARDOUR_API extern PBD::PropertyDescriptor<ARDOUR::TransportRequestType> allowed_transport_requests;
67 };
68
69 struct LIBARDOUR_API SafeTime {
70
71         /* This object uses memory fences to provide psuedo-atomic updating of
72          * non-atomic data. If after reading guard1 and guard2 with correct
73          * memory fencing they have the same value, then we know that the other
74          * members are all internally consistent.
75          *
76          * Traditionally, one might do this with a mutex, but this object
77          * provides lock-free write update. The reader might block while
78          * waiting for consistency, but this is extraordinarily unlikely. In
79          * this sense, the design is similar to a spinlock.
80          *
81          * any update starts by incrementing guard1, with a memory fence to
82          * ensure no reordering of this w.r.t later operations.
83          *
84          * then we update the "non-atomic" data members.
85          *
86          * then we update guard2, with another memory fence to prevent
87          * reordering.
88          *
89          * ergo, if guard1 == guard2, the update of the non-atomic members is
90          * complete and the values stored there are consistent.
91          */
92
93         boost::atomic<int> guard1;
94         samplepos_t        position;
95         samplepos_t        timestamp;
96         double             speed;
97         boost::atomic<int> guard2;
98
99         SafeTime() {
100                 guard1.store (0);
101                 position = 0;
102                 timestamp = 0;
103                 speed = 0;
104                 guard2.store (0);
105         }
106
107         void reset () {
108                 guard1.store (0);
109                 position = 0;
110                 timestamp  = 0;
111                 speed = 0;
112                 guard2.store (0);
113         }
114
115         void update (samplepos_t p, samplepos_t t, double s) {
116                 guard1.fetch_add (1, boost::memory_order_acquire);
117                 position = p;
118                 timestamp = t;
119                 speed = s;
120                 guard2.fetch_add (1, boost::memory_order_acquire);
121         }
122
123         void safe_read (SafeTime& dst) const {
124                 int tries = 0;
125
126                 do {
127                         if (tries == 10) {
128                                 std::cerr << X_("SafeTime: atomic read of current time failed, sleeping!") << std::endl;
129                                 Glib::usleep (20);
130                                 tries = 0;
131                         }
132                         dst.guard1.store (guard1.load (boost::memory_order_seq_cst), boost::memory_order_seq_cst);
133                         dst.position = position;
134                         dst.timestamp = timestamp;
135                         dst.speed = speed;
136                         dst.guard2.store (guard2.load (boost::memory_order_seq_cst), boost::memory_order_seq_cst);
137                         tries++;
138
139                 } while (dst.guard1.load (boost::memory_order_seq_cst) != dst.guard2.load (boost::memory_order_seq_cst));
140         }
141 };
142
143 /**
144  * @class TransportMaster
145  *
146  * @brief The TransportMaster interface can be used to sync ARDOURs tempo to an external source
147  * like MTC, MIDI Clock, etc. as well as a single internal pseudo master we
148  * call "UI" because it is controlled from any of the user interfaces for
149  * Ardour (GUI, control surfaces, OSC, etc.)
150  *
151  */
152 class LIBARDOUR_API TransportMaster : public PBD::Stateful {
153   public:
154
155         TransportMaster (SyncSource t, std::string const & name);
156         virtual ~TransportMaster();
157
158         static boost::shared_ptr<TransportMaster> factory (SyncSource, std::string const &, bool removeable);
159         static boost::shared_ptr<TransportMaster> factory (XMLNode const &);
160
161         virtual void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>) = 0;
162
163         /**
164          * This is the most important function to implement:
165          * Each process cycle, Session::follow_slave will call this method.
166          *  and after the method call they should
167          *
168          * Session::follow_slave will then try to follow the given
169          * <em>position</em> using a delay locked loop (DLL),
170          * starting with the first given transport speed.
171          * If the values of speed and position contradict each other,
172          * ARDOUR will always follow the position and disregard the speed.
173          * Although, a correct speed is important so that ARDOUR
174          * can sync to the master time source quickly.
175          *
176          * For background information on delay locked loops,
177          * see http://www.kokkinizita.net/papers/usingdll.pdf
178          *
179          * The method has the following precondition:
180          * <ul>
181          *   <li>
182          *       TransportMaster::ok() should return true, otherwise playback will stop
183          *       immediately and the method will not be called
184          *   </li>
185          *   <li>
186          *     when the references speed and position are passed into the TransportMaster
187          *     they are uninitialized
188          *   </li>
189          * </ul>
190          *
191          * After the method call the following postconditions should be met:
192          * <ul>
193          *    <li>
194          *       The first position value on transport start should be 0,
195          *       otherwise ARDOUR will try to locate to the new position
196          *       rather than move to it
197          *    </li>
198          *    <li>
199          *      the references speed and position should be assigned
200          *      to the TransportMasters current requested transport speed
201          *      and transport position.
202          *    </li>
203          *   <li>
204          *     TransportMaster::resolution() should be greater than the maximum distance of
205          *     ARDOURs transport position to the slaves requested transport position.
206          *   </li>
207          *   <li>TransportMaster::locked() should return true, otherwise Session::no_roll will be called</li>
208          *   <li>TransportMaster::starting() should be false, otherwise the transport will not move until it becomes true</li>
209          * </ul>
210          *
211          * @param speed - The transport speed requested
212          * @param position - The transport position requested
213          * @return - The return value is currently ignored (see Session::follow_slave)
214          */
215         virtual bool speed_and_position (double& speed, samplepos_t& position, samplepos_t & lp, samplepos_t & when, samplepos_t now);
216
217         virtual void reset (bool with_position) = 0;
218
219         /**
220          * reports to ARDOUR whether the TransportMaster is currently synced to its external
221          * time source.
222          *
223          * @return - when returning false, the transport will stop rolling
224          */
225         virtual bool locked() const = 0;
226
227         /**
228          * reports to ARDOUR whether the slave is in a sane state
229          *
230          * @return - when returning false, the transport will be stopped and the slave
231          * disconnected from ARDOUR.
232          */
233         virtual bool ok() const = 0;
234
235         /**
236          * reports to ARDOUR whether the slave is in the process of starting
237          * to roll
238          *
239          * @return - when returning false, transport will not move until this method returns true
240          */
241         virtual bool starting() const { return false; }
242
243         /**
244          * @return - the timing resolution of the TransportMaster - If the distance of ARDOURs transport
245          * to the slave becomes greater than the resolution, sound will stop
246          */
247         virtual samplecnt_t resolution() const = 0;
248
249         /**
250          * @return - the expected update interval for the data source used by
251          * this transport master. Even if the data is effectively continuous,
252          * this number indicates how long it is between changes to the known
253          * position of the master.
254          */
255         virtual samplecnt_t update_interval() const = 0;
256
257         /**
258          * @return - when returning true, ARDOUR will wait for seekahead_distance() before transport
259          * starts rolling
260          */
261         virtual bool requires_seekahead () const = 0;
262
263         /**
264          * @return the number of samples that this slave wants to seek ahead. Relevant
265          * only if requires_seekahead() returns true.
266          */
267
268         virtual samplecnt_t seekahead_distance() const { return 0; }
269
270         /**
271          * @return - when returning true, ARDOUR will use transport speed 1.0 no matter what
272          *           the slave returns
273          */
274         virtual bool sample_clock_synced() const { return _sclock_synced; }
275         virtual void set_sample_clock_synced (bool);
276
277         /**
278          * @return - current time-delta between engine and sync-source
279          */
280         virtual std::string delta_string() const { return ""; }
281
282         sampleoffset_t current_delta() const { return _current_delta; }
283
284         /* this is intended to be used by a UI and polled from a timeout. it should
285            return a string describing the current position of the TC source. it
286            should NOT do any computation, but should use a cached value
287            of the TC source position.
288         */
289         virtual std::string position_string() const = 0;
290
291         virtual bool can_loop() const { return false; }
292
293         virtual Location* loop_location() const { return 0; }
294         bool has_loop() const { return loop_location() != 0; }
295
296         SyncSource type() const { return _type; }
297         TransportRequestSource request_type() const {
298                 switch (_type) {
299                 case Engine: /* also JACK */
300                         return TRS_Engine;
301                 case MTC:
302                         return TRS_MTC;
303                 case LTC:
304                         return TRS_LTC;
305                 case MIDIClock:
306                         break;
307                 }
308                 return TRS_MIDIClock;
309         }
310
311         std::string name() const { return _name; }
312         void set_name (std::string const &);
313
314         int set_state (XMLNode const &, int);
315         XMLNode& get_state();
316
317         static const std::string state_node_name;
318         static void make_property_quarks ();
319
320         virtual void set_session (Session*);
321
322         boost::shared_ptr<Port> port() const { return _port; }
323
324         bool check_collect();
325         virtual void set_collect (bool);
326         bool collect() const { return _collect; }
327
328         /* called whenever the manager starts collecting (processing) this
329            transport master. Typically will re-initialize any state used to
330            deal with incoming data.
331         */
332         virtual void init() = 0;
333
334         virtual void check_backend() {}
335         virtual bool allow_request (TransportRequestSource, TransportRequestType) const;
336
337         TransportRequestType request_mask() const { return _request_mask; }
338         void set_request_mask (TransportRequestType);
339
340         void get_current (double&, samplepos_t&, samplepos_t);
341
342         /* this is set at construction, and not changeable later, so it is not
343          * a property
344          */
345
346         bool removeable () const { return _removeable; }
347         void set_removeable (bool yn) { _removeable = yn; }
348
349         std::string display_name (bool sh/*ort*/ = true) const;
350
351         virtual void unregister_port ();
352
353   protected:
354         SyncSource      _type;
355         PBD::Property<std::string>   _name;
356         Session*        _session;
357         sampleoffset_t  _current_delta;
358         bool            _pending_collect;
359         bool            _removeable;
360         PBD::Property<TransportRequestType> _request_mask; /* lists transport requests still accepted when we're in control */
361         PBD::Property<bool> _sclock_synced;
362         PBD::Property<bool> _collect;
363         PBD::Property<bool> _connected;
364
365         SafeTime current;
366
367         /* DLL - chase incoming data */
368
369         int    transport_direction;
370         int    dll_initstate;
371
372         double t0;
373         double t1;
374         double e2;
375         double b, c;
376
377         boost::shared_ptr<Port>  _port;
378
379         PBD::ScopedConnection port_connection;
380         bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
381
382         PBD::ScopedConnection backend_connection;
383
384         virtual void register_properties ();
385 };
386
387 /** a helper class for any TransportMaster that receives its input via a MIDI
388  * port
389  */
390 class LIBARDOUR_API TransportMasterViaMIDI {
391   public:
392         boost::shared_ptr<MidiPort> midi_port() const { return _midi_port; }
393         boost::shared_ptr<Port> create_midi_port (std::string const & port_name);
394
395   protected:
396         TransportMasterViaMIDI () {};
397
398         MIDI::Parser                 parser;
399         boost::shared_ptr<MidiPort> _midi_port;
400 };
401
402 class LIBARDOUR_API TimecodeTransportMaster : public TransportMaster {
403   public:
404         TimecodeTransportMaster (std::string const & name, SyncSource type);
405
406         virtual Timecode::TimecodeFormat apparent_timecode_format() const = 0;
407         samplepos_t        timecode_offset;
408         bool              timecode_negative_offset;
409
410         bool fr2997() const { return _fr2997; }
411         void set_fr2997 (bool);
412
413   protected:
414         void register_properties ();
415
416   private:
417         PBD::Property<bool> _fr2997;
418 };
419
420 class LIBARDOUR_API MTC_TransportMaster : public TimecodeTransportMaster, public TransportMasterViaMIDI {
421   public:
422         MTC_TransportMaster (std::string const &);
423         ~MTC_TransportMaster ();
424
425         void set_session (Session*);
426
427         void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>);
428
429         void unregister_port ();
430
431         void reset (bool with_pos);
432         bool locked() const;
433         bool ok() const;
434         void handle_locate (const MIDI::byte*);
435
436         samplecnt_t update_interval () const;
437         samplecnt_t resolution () const;
438         bool requires_seekahead () const { return false; }
439         samplecnt_t seekahead_distance() const;
440         void init ();
441
442         Timecode::TimecodeFormat apparent_timecode_format() const;
443         std::string position_string() const;
444         std::string delta_string() const;
445
446   private:
447         PBD::ScopedConnectionList port_connections;
448         PBD::ScopedConnection     config_connection;
449         bool        can_notify_on_unknown_rate;
450
451         static const int sample_tolerance;
452
453         samplepos_t    mtc_frame;               /* current time */
454         double         mtc_frame_dll;
455         samplepos_t    last_inbound_frame;      /* when we got it; audio clocked */
456         MIDI::byte     last_mtc_fps_byte;
457         samplepos_t    window_begin;
458         samplepos_t    window_end;
459         samplepos_t    first_mtc_timestamp;
460         bool           did_reset_tc_format;
461         Timecode::TimecodeFormat saved_tc_format;
462         Glib::Threads::Mutex    reset_lock;
463         uint32_t       reset_pending;
464         bool           reset_position;
465         int            transport_direction;
466         int            busy_guard1;
467         int            busy_guard2;
468
469         double         speedup_due_to_tc_mismatch;
470         double         quarter_frame_duration;
471         Timecode::TimecodeFormat mtc_timecode;
472         Timecode::TimecodeFormat a3e_timecode;
473         Timecode::Time timecode;
474         bool           printed_timecode_warning;
475
476         void queue_reset (bool with_pos);
477         void maybe_reset ();
478
479         void update_mtc_qtr (MIDI::Parser&, int, samplepos_t);
480         void update_mtc_time (const MIDI::byte *, bool, samplepos_t);
481         void update_mtc_status (MIDI::MTC_Status);
482         void reset_window (samplepos_t);
483         bool outside_window (samplepos_t) const;
484         void init_mtc_dll(samplepos_t, double);
485         void parse_timecode_offset();
486         void parameter_changed(std::string const & p);
487 };
488
489 class LIBARDOUR_API LTC_TransportMaster : public TimecodeTransportMaster {
490 public:
491         LTC_TransportMaster (std::string const &);
492         ~LTC_TransportMaster ();
493
494         void set_session (Session*);
495
496         void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>);
497
498         void reset (bool with_pos);
499         bool locked() const;
500         bool ok() const;
501
502         samplecnt_t update_interval () const;
503         samplecnt_t resolution () const;
504         bool requires_seekahead () const { return false; }
505         samplecnt_t seekahead_distance () const { return 0; }
506         void init ();
507
508         Timecode::TimecodeFormat apparent_timecode_format() const;
509         std::string position_string() const;
510         std::string delta_string() const;
511
512   private:
513         void parse_ltc(const pframes_t, const Sample* const, const samplecnt_t);
514         void process_ltc(samplepos_t const);
515         void init_dll (samplepos_t, int32_t);
516         bool detect_discontinuity(LTCFrameExt *, int, bool);
517         bool detect_ltc_fps(int, bool);
518         bool equal_ltc_sample_time(LTCFrame *a, LTCFrame *b);
519         void resync_xrun();
520         void resync_latency();
521         void parse_timecode_offset();
522         void parameter_changed(std::string const & p);
523
524         bool           did_reset_tc_format;
525         Timecode::TimecodeFormat saved_tc_format;
526
527         LTCDecoder *   decoder;
528         double         samples_per_ltc_frame;
529         Timecode::Time timecode;
530         LTCFrameExt    prev_frame;
531         bool           fps_detected;
532
533         samplecnt_t    monotonic_cnt;
534         uint64_t       frames_since_reset;
535         int            delayedlocked;
536
537         int            ltc_detect_fps_cnt;
538         int            ltc_detect_fps_max;
539         bool           printed_timecode_warning;
540         bool           sync_lock_broken;
541         Timecode::TimecodeFormat ltc_timecode;
542         Timecode::TimecodeFormat a3e_timecode;
543         double         samples_per_timecode_frame;
544
545         PBD::ScopedConnectionList port_connections;
546         PBD::ScopedConnection     config_connection;
547         LatencyRange  ltc_slave_latency;
548 };
549
550 class LIBARDOUR_API MIDIClock_TransportMaster : public TransportMaster, public TransportMasterViaMIDI {
551   public:
552         MIDIClock_TransportMaster (std::string const & name, int ppqn = 24);
553
554         /// Constructor for unit tests
555         ~MIDIClock_TransportMaster ();
556
557         void set_session (Session*);
558
559         void unregister_port ();
560
561         void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>);
562
563         void rebind (MidiPort&);
564
565         void reset (bool with_pos);
566         bool locked() const;
567         bool ok() const;
568         bool starting() const;
569
570         samplecnt_t update_interval () const;
571         samplecnt_t resolution () const;
572         bool requires_seekahead () const { return false; }
573         void init ();
574
575         std::string position_string() const;
576         std::string delta_string() const;
577
578         float bpm() const { return _bpm; }
579
580   protected:
581         PBD::ScopedConnectionList port_connections;
582
583         /// pulses per quarter note for one MIDI clock sample (default 24)
584         int         ppqn;
585
586         /// the duration of one ppqn in sample time
587         double      one_ppqn_in_samples;
588
589         /// the timestamp of the first MIDI clock message
590         samplepos_t  first_timestamp;
591
592         /// the time stamp and should-be transport position of the last inbound MIDI clock message
593         samplepos_t  last_timestamp;
594         double      should_be_position;
595
596         /// the number of midi clock messages received (zero-based)
597         /// since start
598         long midi_clock_count;
599
600         /// a DLL to track MIDI clock
601
602         double _speed;
603         bool _running;
604         double _bpm;
605
606         void start (MIDI::Parser& parser, samplepos_t timestamp);
607         void contineu (MIDI::Parser& parser, samplepos_t timestamp);
608         void stop (MIDI::Parser& parser, samplepos_t timestamp);
609         void position (MIDI::Parser& parser, MIDI::byte* message, size_t size, samplepos_t timestamp);
610         // we can't use continue because it is a C++ keyword
611         void calculate_one_ppqn_in_samples_at(samplepos_t time);
612         samplepos_t calculate_song_position(uint16_t song_position_in_sixteenth_notes);
613         void calculate_filter_coefficients (double qpm);
614         void update_midi_clock (MIDI::Parser& parser, samplepos_t timestamp);
615 };
616
617 class LIBARDOUR_API Engine_TransportMaster : public TransportMaster
618 {
619   public:
620         Engine_TransportMaster (AudioEngine&);
621         ~Engine_TransportMaster  ();
622
623         void pre_process (pframes_t nframes, samplepos_t now,  boost::optional<samplepos_t>);
624         bool speed_and_position (double& speed, samplepos_t& pos, samplepos_t &, samplepos_t &, samplepos_t);
625
626         bool starting() const { return _starting; }
627         void reset (bool with_position);
628         bool locked() const;
629         bool ok() const;
630         samplecnt_t update_interval () const;
631         samplecnt_t resolution () const { return 1; }
632         bool requires_seekahead () const { return false; }
633         bool sample_clock_synced() const { return true; }
634         void init ();
635         void check_backend();
636         bool allow_request (TransportRequestSource, TransportRequestType) const;
637
638         std::string position_string() const;
639         std::string delta_string() const;
640
641   private:
642         AudioEngine& engine;
643         bool _starting;
644 };
645
646 } /* namespace */
647
648 #endif /* __ardour_transport_master_h__ */