Minor updates from code review
[ardour.git] / libs / ardour / ltc_slave.cc
1 /*
2     Copyright (C) 2012 Paul Davis
3     Witten by 2012 Robin Gareus <robin@gareus.org>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20 #include <iostream>
21 #include <errno.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include "pbd/error.h"
26 #include "pbd/failed_constructor.h"
27 #include "pbd/pthread_utils.h"
28
29 #include "ardour/debug.h"
30 #include "ardour/profile.h"
31 #include "ardour/transport_master.h"
32 #include "ardour/session.h"
33 #include "ardour/audioengine.h"
34 #include "ardour/audio_port.h"
35
36 #include "pbd/i18n.h"
37
38 using namespace std;
39 using namespace ARDOUR;
40 using namespace MIDI;
41 using namespace PBD;
42 using namespace Timecode;
43
44 #define ENGINE AudioEngine::instance()
45 #define FLYWHEEL_TIMEOUT ( 1 * ENGINE->sample_rate() )
46
47 /* XXX USE Config->get_ltc_input */
48
49 LTC_TransportMaster::LTC_TransportMaster (std::string const & name)
50         : TimecodeTransportMaster (name, LTC)
51         , did_reset_tc_format (false)
52         , saved_tc_format (timecode_24) // whatever ....
53         , decoder (0)
54         , samples_per_ltc_frame (0)
55         , fps_detected (false)
56         , monotonic_cnt (0)
57         , delayedlocked (10)
58         , ltc_detect_fps_cnt (0)
59         , printed_timecode_warning (false)
60         , ltc_detect_fps_max (0)
61         , sync_lock_broken (false)
62         , ltc_timecode (Timecode::timecode_24)
63         , a3e_timecode (Timecode::timecode_24)
64         , samples_per_timecode_frame (0)
65 {
66         if ((_port = AudioEngine::instance()->register_input_port (DataType::AUDIO, string_compose ("%1 in", _name))) == 0) {
67                 throw failed_constructor();
68         }
69
70         DEBUG_TRACE (DEBUG::Slave, string_compose ("LTC registered %1\n", _port->name()));
71
72         memset (&prev_sample, 0, sizeof(LTCFrameExt));
73
74         resync_latency();
75
76         AudioEngine::instance()->Xrun.connect_same_thread (port_connections, boost::bind (&LTC_TransportMaster::resync_xrun, this));
77         AudioEngine::instance()->GraphReordered.connect_same_thread (port_connections, boost::bind (&LTC_TransportMaster::resync_latency, this));
78 }
79
80 void
81 LTC_TransportMaster::init ()
82 {
83         reset (true);
84 }
85
86 void
87 LTC_TransportMaster::set_session (Session *s)
88 {
89         config_connection.disconnect ();
90         _session = s;
91
92         if (_session) {
93
94                 samples_per_ltc_frame = _session->samples_per_timecode_frame();
95                 timecode.rate = _session->timecode_frames_per_second();
96                 timecode.drop  = _session->timecode_drop_frames();
97                 printed_timecode_warning = false;
98                 ltc_timecode = _session->config.get_timecode_format();
99                 a3e_timecode = _session->config.get_timecode_format();
100
101                 if (Config->get_use_session_timecode_format() && _session) {
102                         samples_per_timecode_frame = _session->samples_per_timecode_frame();
103                 }
104
105                 if (decoder) {
106                         ltc_decoder_free (decoder);
107                 }
108
109                 decoder = ltc_decoder_create((int) samples_per_ltc_frame, 128 /*queue size*/);
110
111                 parse_timecode_offset();
112                 reset (true);
113
114                 _session->config.ParameterChanged.connect_same_thread (config_connection, boost::bind (&LTC_TransportMaster::parameter_changed, this, _1));
115         }
116 }
117
118 LTC_TransportMaster::~LTC_TransportMaster()
119 {
120         port_connections.drop_connections();
121         config_connection.disconnect();
122
123         if (did_reset_tc_format) {
124                 _session->config.set_timecode_format (saved_tc_format);
125         }
126
127         ltc_decoder_free(decoder);
128 }
129
130 void
131 LTC_TransportMaster::parse_timecode_offset() {
132         Timecode::Time offset_tc;
133         Timecode::parse_timecode_format(_session->config.get_slave_timecode_offset(), offset_tc);
134         offset_tc.rate = _session->timecode_frames_per_second();
135         offset_tc.drop = _session->timecode_drop_frames();
136         _session->timecode_to_sample(offset_tc, timecode_offset, false, false);
137         timecode_negative_offset = offset_tc.negative;
138 }
139
140 void
141 LTC_TransportMaster::parameter_changed (std::string const & p)
142 {
143         if (p == "slave-timecode-offset"
144                         || p == "timecode-format"
145                         ) {
146                 parse_timecode_offset();
147         }
148 }
149
150 ARDOUR::samplecnt_t
151 LTC_TransportMaster::update_interval() const
152 {
153         if (timecode.rate) {
154                 return AudioEngine::instance()->sample_rate() / timecode.rate;
155         }
156
157         return AudioEngine::instance()->sample_rate(); /* useless but what other answer is there? */
158 }
159
160 ARDOUR::samplecnt_t
161 LTC_TransportMaster::resolution () const
162 {
163         return (samplecnt_t) (ENGINE->sample_rate() / 1000);
164 }
165
166 bool
167 LTC_TransportMaster::locked () const
168 {
169         return (delayedlocked < 5);
170 }
171
172 bool
173 LTC_TransportMaster::ok() const
174 {
175         return true;
176 }
177
178 void
179 LTC_TransportMaster::resync_xrun()
180 {
181         DEBUG_TRACE (DEBUG::LTC, "LTC resync_xrun()\n");
182         sync_lock_broken = false;
183 }
184
185 void
186 LTC_TransportMaster::resync_latency()
187 {
188         DEBUG_TRACE (DEBUG::LTC, "LTC resync_latency()\n");
189         sync_lock_broken = false;
190
191         if (_port) {
192                 _port->get_connected_latency_range (ltc_slave_latency, false);
193         }
194 }
195
196 void
197 LTC_TransportMaster::reset (bool with_position)
198 {
199         DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC reset() with pos ? %1\n", with_position));
200         if (with_position) {
201                 current.update (current.position, 0, current.speed);
202                 _current_delta = 0;
203         } else {
204                 current.reset ();
205         }
206         transport_direction = 0;
207         sync_lock_broken = false;
208         monotonic_cnt = 0;
209 }
210
211 void
212 LTC_TransportMaster::parse_ltc (const ARDOUR::pframes_t nframes, const Sample* const in, const ARDOUR::samplecnt_t posinfo)
213 {
214         pframes_t i;
215         unsigned char sound[8192];
216
217         if (nframes > 8192) {
218                 /* TODO warn once or wrap, loop conversion below
219                  * does jack/A3 support > 8192 spp anyway?
220                  */
221                 return;
222         }
223
224         for (i = 0; i < nframes; i++) {
225                 const int snd=(int) rint ((127.0*in[i])+128.0);
226                 sound[i] = (unsigned char) (snd&0xff);
227         }
228
229         ltc_decoder_write (decoder, sound, nframes, posinfo);
230
231         return;
232 }
233
234 bool
235 LTC_TransportMaster::equal_ltc_sample_time(LTCFrame *a, LTCFrame *b) {
236         if (a->frame_units != b->frame_units ||
237             a->frame_tens  != b->frame_tens ||
238             a->dfbit       != b->dfbit ||
239             a->secs_units  != b->secs_units ||
240             a->secs_tens   != b->secs_tens ||
241             a->mins_units  != b->mins_units ||
242             a->mins_tens   != b->mins_tens ||
243             a->hours_units != b->hours_units ||
244             a->hours_tens  != b->hours_tens) {
245                 return false;
246         }
247         return true;
248 }
249
250 bool
251 LTC_TransportMaster::detect_discontinuity(LTCFrameExt *sample, int fps, bool fuzzy) {
252         bool discontinuity_detected = false;
253
254         if (fuzzy && (
255                   ( sample->reverse && prev_sample.ltc.frame_units == 0)
256                 ||(!sample->reverse && sample->ltc.frame_units == 0)
257                 )) {
258                 memcpy(&prev_sample, sample, sizeof(LTCFrameExt));
259                 return false;
260         }
261
262         if (sample->reverse) {
263                 ltc_frame_decrement(&prev_sample.ltc, fps, LTC_TV_525_60, 0);
264         } else {
265                 ltc_frame_increment(&prev_sample.ltc, fps, LTC_TV_525_60, 0);
266         }
267         if (!equal_ltc_sample_time(&prev_sample.ltc, &sample->ltc)) {
268                 discontinuity_detected = true;
269         }
270
271     memcpy(&prev_sample, sample, sizeof(LTCFrameExt));
272     return discontinuity_detected;
273 }
274
275 bool
276 LTC_TransportMaster::detect_ltc_fps(int frameno, bool df)
277 {
278         bool fps_changed = false;
279         double detected_fps = 0;
280         if (frameno > ltc_detect_fps_max)
281         {
282                 ltc_detect_fps_max = frameno;
283         }
284         ltc_detect_fps_cnt++;
285
286         if (ltc_detect_fps_cnt > 40) {
287                 if (ltc_detect_fps_cnt > ltc_detect_fps_max) {
288                         detected_fps = ltc_detect_fps_max + 1;
289                         if (df) {
290                                 /* LTC df -> indicates fractional framerate */
291                                 if (fr2997()) {
292                                         detected_fps = detected_fps * 999.0 / 1000.0;
293                                 } else {
294                                         detected_fps = detected_fps * 1000.0 / 1001.0;
295                                 }
296                         }
297
298                         if (timecode.rate != detected_fps || timecode.drop != df) {
299                                 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC detected FPS: %1%2\n", detected_fps, df?"df":"ndf"));
300                         } else {
301                                 detected_fps = 0; /* no cange */
302                         }
303                 }
304                 ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
305         }
306
307         /* when changed */
308         if (detected_fps != 0 && (detected_fps != timecode.rate || df != timecode.drop)) {
309                 timecode.rate = detected_fps;
310                 timecode.drop = df;
311                 samples_per_ltc_frame = double(_session->sample_rate()) / timecode.rate;
312                 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC reset to FPS: %1%2 ; audio-samples per LTC: %3\n",
313                                 detected_fps, df?"df":"ndf", samples_per_ltc_frame));
314                 fps_changed=true;
315         }
316
317         /* poll and check session TC */
318         TimecodeFormat tc_format = apparent_timecode_format();
319         TimecodeFormat cur_timecode = _session->config.get_timecode_format();
320
321         if (Config->get_timecode_sync_frame_rate()) {
322                 /* enforce time-code */
323                 if (!did_reset_tc_format) {
324                         saved_tc_format = cur_timecode;
325                         did_reset_tc_format = true;
326                 }
327                 if (cur_timecode != tc_format) {
328                         if (ceil(Timecode::timecode_to_frames_per_second(cur_timecode)) != ceil(Timecode::timecode_to_frames_per_second(tc_format))) {
329                                 warning << string_compose(_("Session framerate adjusted from %1 to LTC's %2."),
330                                                 Timecode::timecode_format_name(cur_timecode),
331                                                 Timecode::timecode_format_name(tc_format))
332                                         << endmsg;
333                         }
334                         _session->config.set_timecode_format (tc_format);
335                 }
336         } else {
337                 /* only warn about TC mismatch */
338                 if (ltc_timecode != tc_format) printed_timecode_warning = false;
339                 if (a3e_timecode != cur_timecode) printed_timecode_warning = false;
340
341                 if (cur_timecode != tc_format && ! printed_timecode_warning) {
342                         if (ceil(Timecode::timecode_to_frames_per_second(cur_timecode)) != ceil(Timecode::timecode_to_frames_per_second(tc_format))) {
343                                 warning << string_compose(_("Session and LTC framerate mismatch: LTC:%1 Session:%2."),
344                                                 Timecode::timecode_format_name(tc_format),
345                                                 Timecode::timecode_format_name(cur_timecode))
346                                         << endmsg;
347                         }
348                         printed_timecode_warning = true;
349                 }
350         }
351         ltc_timecode = tc_format;
352         a3e_timecode = cur_timecode;
353
354         if (Config->get_use_session_timecode_format() && _session) {
355                 samples_per_timecode_frame = _session->samples_per_timecode_frame();
356         } else {
357                 samples_per_timecode_frame = ENGINE->sample_rate() / Timecode::timecode_to_frames_per_second (ltc_timecode);
358         }
359
360         return fps_changed;
361 }
362
363 void
364 LTC_TransportMaster::process_ltc(samplepos_t const now)
365 {
366         LTCFrameExt sample;
367         LTC_TV_STANDARD tv_standard = LTC_TV_625_50;
368
369         while (ltc_decoder_read (decoder, &sample)) {
370
371                 SMPTETimecode stime;
372
373                 ltc_frame_to_time (&stime, &sample.ltc, 0);
374                 timecode.negative  = false;
375                 timecode.subframes  = 0;
376
377                 /* set timecode.rate and timecode.drop: */
378
379                 const bool ltc_is_stationary = equal_ltc_sample_time (&prev_sample.ltc, &sample.ltc);
380
381                 if (detect_discontinuity (&sample, ceil(timecode.rate), !fps_detected)) {
382
383                         if (fps_detected) {
384                                 ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
385                         }
386
387                         fps_detected = false;
388                 }
389
390                 if (!ltc_is_stationary && detect_ltc_fps (stime.frame, (sample.ltc.dfbit)? true : false)) {
391                         reset(true);
392                         fps_detected=true;
393                 }
394
395 #ifndef NDEBUG
396                 if (DEBUG_ENABLED (DEBUG::LTC)) {
397                         /* use fprintf for simpler correct formatting of times
398                          */
399                         fprintf (stderr, "LTC@%ld %02d:%02d:%02d%c%02d | %8lld %8lld%s\n",
400                                  now,
401                                  stime.hours,
402                                  stime.mins,
403                                  stime.secs,
404                                  (sample.ltc.dfbit) ? '.' : ':',
405                                  stime.frame,
406                                  sample.off_start,
407                                  sample.off_end,
408                                  sample.reverse ? " R" : "  "
409                                 );
410                 }
411 #endif
412
413                 /* when a full LTC sample is decoded, the timecode the LTC sample
414                  * is referring has just passed.
415                  * So we send the _next_ timecode which
416                  * is expected to start at the end of the current sample
417                  */
418                 int fps_i = ceil(timecode.rate);
419
420                 switch(fps_i) {
421                         case 30:
422                                 if (timecode.drop) {
423                                         tv_standard = LTC_TV_525_60;
424                                 } else {
425                                         tv_standard = LTC_TV_1125_60;
426                                 }
427                                 break;
428                         case 25:
429                                 tv_standard = LTC_TV_625_50;
430                                 break;
431                         default:
432                                 tv_standard = LTC_TV_FILM_24; /* == LTC_TV_1125_60 == no offset, 24,30fps BGF */
433                                 break;
434                 }
435
436                 if (!sample.reverse) {
437                         ltc_frame_increment(&sample.ltc, fps_i, tv_standard, 0);
438                         ltc_frame_to_time(&stime, &sample.ltc, 0);
439                         transport_direction = 1;
440                         sample.off_start -= ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
441                         sample.off_end -= ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
442                 } else {
443                         ltc_frame_decrement(&sample.ltc, fps_i, tv_standard, 0);
444                         int off = sample.off_end - sample.off_start;
445                         sample.off_start += off - ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
446                         sample.off_end += off - ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
447                         transport_direction = -1;
448                 }
449
450                 timecode.hours   = stime.hours;
451                 timecode.minutes = stime.mins;
452                 timecode.seconds = stime.secs;
453                 timecode.frames  = stime.frame;
454
455                 samplepos_t ltc_sample; // audio-sample corresponding to position of LTC frame
456
457                 if (_session && Config->get_use_session_timecode_format()) {
458                         Timecode::timecode_to_sample (timecode, ltc_sample, true, false, (double)ENGINE->sample_rate(), _session->config.get_subframes_per_frame(), timecode_negative_offset, timecode_offset);
459                 } else {
460                         Timecode::timecode_to_sample (timecode, ltc_sample, true, false, (double)ENGINE->sample_rate(), 100, timecode_negative_offset, timecode_offset);
461                 }
462
463                 ltc_sample += ltc_slave_latency.max;
464
465                 /* This LTC frame spans sample time between sample.off_start  .. sample.off_end
466                  *
467                  * NOTE: these sample times are NOT the ones that LTC is representing. They are
468                  * derived our own audioengine's monotonic audio clock.
469                  *
470                  * So we expect the next frame to span sample.off_end+1 and ... <don't care for now>.
471                  * That isn't the time we will necessarily receive the LTC frame, but the decoder
472                  * should tell us that its span begins there.
473                  *
474                  */
475
476                 samplepos_t cur_timestamp = sample.off_end + 1;
477                 double ltc_speed = current.speed;
478
479                 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC S: %1 LS: %2  N: %3 L: %4 span %5..%6\n", ltc_sample, current.position, cur_timestamp, current.timestamp, sample.off_start, sample.off_end));
480
481                 if (cur_timestamp <= current.timestamp || current.timestamp == 0) {
482                         DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed: UNCHANGED: %1\n", current.speed));
483                 } else {
484                         ltc_speed = double (ltc_sample - current.position) / double (cur_timestamp - current.timestamp);
485
486                         /* provide a .1% deadzone to lock the speed */
487                         if (fabs (ltc_speed - 1.0) <= 0.001) {
488                                 ltc_speed = 1.0;
489                         }
490
491                         if (fabs (ltc_speed) > 10.0) {
492                                 ltc_speed = 0;
493                         }
494
495                         DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed: %1\n", ltc_speed));
496                 }
497                 DEBUG_TRACE (DEBUG::LTC, string_compose ("update current to %1 %2 %3\n", ltc_sample, cur_timestamp, ltc_speed));
498                 current.update (ltc_sample, cur_timestamp, ltc_speed);
499
500         } /* end foreach decoded LTC sample */
501 }
502
503 void
504 LTC_TransportMaster::pre_process (ARDOUR::pframes_t nframes, samplepos_t now, boost::optional<samplepos_t> session_pos)
505 {
506         Sample* in = (Sample*) AudioEngine::instance()->port_engine().get_buffer (_port->port_handle(), nframes);
507         sampleoffset_t skip = now - (monotonic_cnt + nframes);
508         monotonic_cnt = now;
509
510         DEBUG_TRACE (DEBUG::LTC, string_compose ("pre-process - TID:%1 | latency: %2 | skip %3 | session ? %4| last %5 | dir %6 | sp %7\n",
511                                                  pthread_name(), ltc_slave_latency.max, skip, (_session ? 'y' : 'n'), current.timestamp, transport_direction, current.speed));
512
513         if (current.timestamp == 0) {
514                 if (delayedlocked < 10) {
515                         ++delayedlocked;
516                 }
517
518         } else if (current.speed != 0) {
519
520         }
521
522         DEBUG_TRACE (DEBUG::LTC, string_compose ("pre-process with audio clock time: %1\n", now));
523
524         /* if the audioengine failed to take the process lock, it won't
525            call this method, and time will appear to skip. Reset the
526            LTC decoder's state by giving it some silence.
527         */
528
529         if (skip > 0) {
530                 DEBUG_TRACE (DEBUG::LTC, string_compose("engine skipped %1 samples. Feeding silence to LTC parser.\n", skip));
531                 if (skip >= 8192) skip = 8192;
532                 unsigned char sound[8192];
533                 memset (sound, 0x80, sizeof(char) * skip);
534                 ltc_decoder_write (decoder, sound, skip, now);
535         } else if (skip != 0) {
536                 /* this should never happen. it may if monotonic_cnt, now overflow on 64bit */
537                 DEBUG_TRACE (DEBUG::LTC, string_compose("engine skipped %1 samples\n", skip));
538                 reset(true);
539         }
540
541         /* Now feed the incoming LTC signal into the decoder */
542
543         parse_ltc (nframes, in, now);
544
545         /* and pull out actual LTC frame data */
546
547         process_ltc (now);
548
549         if (current.timestamp == 0) {
550                 DEBUG_TRACE (DEBUG::LTC, "last timestamp == 0\n");
551                 return;
552         } else if (current.speed != 0) {
553                 DEBUG_TRACE (DEBUG::LTC, string_compose ("speed non-zero (%1)\n", current.speed));
554                 if (delayedlocked > 1) {
555                         delayedlocked--;
556                 } else if (_current_delta == 0) {
557                         delayedlocked = 0;
558                 }
559         }
560
561         if (abs (now - current.timestamp) > FLYWHEEL_TIMEOUT) {
562                 DEBUG_TRACE (DEBUG::LTC, "flywheel timeout\n");
563                 reset(true);
564                 /* don't change position from last known */
565
566                 return;
567         }
568
569         if (!sync_lock_broken && current.speed != 0 && delayedlocked == 0 && fabs(current.speed) != 1.0) {
570                 sync_lock_broken = true;
571                 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed not locked based on %1\n", current.speed));
572         }
573
574         if (session_pos) {
575                 const samplepos_t current_pos = current.position + ((now - current.timestamp) * current.speed);
576                 _current_delta = current_pos - *session_pos;
577         } else {
578                 _current_delta = 0;
579         }
580 }
581
582 Timecode::TimecodeFormat
583 LTC_TransportMaster::apparent_timecode_format () const
584 {
585         if      (timecode.rate == 24 && !timecode.drop)
586                 return timecode_24;
587         else if (timecode.rate == 25 && !timecode.drop)
588                 return timecode_25;
589         else if (rint(timecode.rate * 100) == 2997 && !timecode.drop)
590                 return (fr2997() ? timecode_2997000 : timecode_2997);
591         else if (rint(timecode.rate * 100) == 2997 &&  timecode.drop)
592                 return (fr2997() ? timecode_2997000drop : timecode_2997drop);
593         else if (timecode.rate == 30 &&  timecode.drop)
594                 return timecode_2997drop; // timecode_30drop; // LTC counting to 30 samples w/DF *means* 29.97 df
595         else if (timecode.rate == 30 && !timecode.drop)
596                 return timecode_30;
597
598         /* XXX - unknown timecode format */
599         return _session->config.get_timecode_format();
600 }
601
602 std::string
603 LTC_TransportMaster::position_string() const
604 {
605         if (!_collect || current.timestamp == 0) {
606                 return " --:--:--:--";
607         }
608         return Timecode::timecode_format_time(timecode);
609 }
610
611 std::string
612 LTC_TransportMaster::delta_string() const
613 {
614         char delta[80];
615
616         if (!_collect || current.timestamp == 0) {
617                 snprintf (delta, sizeof(delta), "\u2012\u2012\u2012\u2012");
618         } else if ((monotonic_cnt - current.timestamp) > 2 * samples_per_ltc_frame) {
619                 snprintf (delta, sizeof(delta), "%s", _("flywheel"));
620         } else {
621                 snprintf (delta, sizeof(delta), "<span foreground=\"%s\" face=\"monospace\" >%s%s%lld</span>sm",
622                                 sync_lock_broken ? "red" : "white",
623                                 LEADINGZERO(::llabs(_current_delta)), PLUSMINUS(-_current_delta), ::llabs(_current_delta));
624         }
625
626         return delta;
627 }