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