2 Copyright (C) 2012 Paul Davis
3 Witten by 2012 Robin Gareus <robin@gareus.org>
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.
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.
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.
22 #include <sys/types.h>
25 #include "pbd/error.h"
26 #include "pbd/failed_constructor.h"
27 #include "pbd/pthread_utils.h"
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"
39 using namespace ARDOUR;
42 using namespace Timecode;
44 #define ENGINE AudioEngine::instance()
45 #define FLYWHEEL_TIMEOUT ( 1 * ENGINE->sample_rate() )
47 /* XXX USE Config->get_ltc_input */
49 LTC_TransportMaster::LTC_TransportMaster (std::string const & name)
50 : TimecodeTransportMaster (name, LTC)
51 , did_reset_tc_format (false)
53 , samples_per_ltc_frame (0)
54 , fps_detected (false)
59 , ltc_detect_fps_cnt (0)
60 , ltc_detect_fps_max (0)
61 , sync_lock_broken (false)
63 if ((_port = AudioEngine::instance()->register_input_port (DataType::AUDIO, string_compose ("%1 in", _name))) == 0) {
64 throw failed_constructor();
67 DEBUG_TRACE (DEBUG::Slave, string_compose ("LTC registered %1\n", _port->name()));
69 memset(&prev_sample, 0, sizeof(LTCFrameExt));
73 AudioEngine::instance()->Xrun.connect_same_thread (port_connections, boost::bind (<C_TransportMaster::resync_xrun, this));
74 AudioEngine::instance()->GraphReordered.connect_same_thread (port_connections, boost::bind (<C_TransportMaster::resync_latency, this));
78 LTC_TransportMaster::init ()
84 LTC_TransportMaster::set_session (Session *s)
86 config_connection.disconnect ();
91 samples_per_ltc_frame = _session->samples_per_timecode_frame();
92 timecode.rate = _session->timecode_frames_per_second();
93 timecode.drop = _session->timecode_drop_frames();
94 printed_timecode_warning = false;
95 ltc_timecode = _session->config.get_timecode_format();
96 a3e_timecode = _session->config.get_timecode_format();
98 if (Config->get_use_session_timecode_format() && _session) {
99 samples_per_timecode_frame = _session->samples_per_timecode_frame();
103 ltc_decoder_free (decoder);
106 decoder = ltc_decoder_create((int) samples_per_ltc_frame, 128 /*queue size*/);
108 parse_timecode_offset();
111 _session->config.ParameterChanged.connect_same_thread (config_connection, boost::bind (<C_TransportMaster::parameter_changed, this, _1));
115 LTC_TransportMaster::~LTC_TransportMaster()
117 port_connections.drop_connections();
118 config_connection.disconnect();
120 if (did_reset_tc_format) {
121 _session->config.set_timecode_format (saved_tc_format);
124 ltc_decoder_free(decoder);
128 LTC_TransportMaster::parse_timecode_offset() {
129 Timecode::Time offset_tc;
130 Timecode::parse_timecode_format(_session->config.get_slave_timecode_offset(), offset_tc);
131 offset_tc.rate = _session->timecode_frames_per_second();
132 offset_tc.drop = _session->timecode_drop_frames();
133 _session->timecode_to_sample(offset_tc, timecode_offset, false, false);
134 timecode_negative_offset = offset_tc.negative;
138 LTC_TransportMaster::parameter_changed (std::string const & p)
140 if (p == "slave-timecode-offset"
141 || p == "timecode-format"
143 parse_timecode_offset();
148 LTC_TransportMaster::resolution () const
150 return (samplecnt_t) (ENGINE->sample_rate() / 1000);
154 LTC_TransportMaster::locked () const
156 return (delayedlocked < 5);
160 LTC_TransportMaster::ok() const
166 LTC_TransportMaster::resync_xrun()
168 DEBUG_TRACE (DEBUG::LTC, "LTC resync_xrun()\n");
169 sync_lock_broken = false;
173 LTC_TransportMaster::resync_latency()
175 DEBUG_TRACE (DEBUG::LTC, "LTC resync_latency()\n");
176 sync_lock_broken = false;
179 _port->get_connected_latency_range (ltc_slave_latency, false);
184 LTC_TransportMaster::reset (bool with_ts)
186 DEBUG_TRACE (DEBUG::LTC, "LTC reset()\n");
191 transport_direction = 0;
193 sync_lock_broken = false;
198 LTC_TransportMaster::parse_ltc (const ARDOUR::pframes_t nframes, const Sample* const in, const ARDOUR::samplecnt_t posinfo)
201 unsigned char sound[8192];
203 if (nframes > 8192) {
204 /* TODO warn once or wrap, loop conversion below
205 * does jack/A3 support > 8192 spp anyway?
210 for (i = 0; i < nframes; i++) {
211 const int snd=(int) rint ((127.0*in[i])+128.0);
212 sound[i] = (unsigned char) (snd&0xff);
215 ltc_decoder_write (decoder, sound, nframes, posinfo);
221 LTC_TransportMaster::equal_ltc_sample_time(LTCFrame *a, LTCFrame *b) {
222 if (a->frame_units != b->frame_units ||
223 a->frame_tens != b->frame_tens ||
224 a->dfbit != b->dfbit ||
225 a->secs_units != b->secs_units ||
226 a->secs_tens != b->secs_tens ||
227 a->mins_units != b->mins_units ||
228 a->mins_tens != b->mins_tens ||
229 a->hours_units != b->hours_units ||
230 a->hours_tens != b->hours_tens) {
237 LTC_TransportMaster::detect_discontinuity(LTCFrameExt *sample, int fps, bool fuzzy) {
238 bool discontinuity_detected = false;
241 ( sample->reverse && prev_sample.ltc.frame_units == 0)
242 ||(!sample->reverse && sample->ltc.frame_units == 0)
244 memcpy(&prev_sample, sample, sizeof(LTCFrameExt));
248 if (sample->reverse) {
249 ltc_frame_decrement(&prev_sample.ltc, fps, LTC_TV_525_60, 0);
251 ltc_frame_increment(&prev_sample.ltc, fps, LTC_TV_525_60, 0);
253 if (!equal_ltc_sample_time(&prev_sample.ltc, &sample->ltc)) {
254 discontinuity_detected = true;
257 memcpy(&prev_sample, sample, sizeof(LTCFrameExt));
258 return discontinuity_detected;
262 LTC_TransportMaster::detect_ltc_fps(int frameno, bool df)
264 bool fps_changed = false;
265 double detected_fps = 0;
266 if (frameno > ltc_detect_fps_max)
268 ltc_detect_fps_max = frameno;
270 ltc_detect_fps_cnt++;
272 if (ltc_detect_fps_cnt > 40) {
273 if (ltc_detect_fps_cnt > ltc_detect_fps_max) {
274 detected_fps = ltc_detect_fps_max + 1;
276 /* LTC df -> indicates fractional framerate */
278 detected_fps = detected_fps * 999.0 / 1000.0;
280 detected_fps = detected_fps * 1000.0 / 1001.0;
284 if (timecode.rate != detected_fps || timecode.drop != df) {
285 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC detected FPS: %1%2\n", detected_fps, df?"df":"ndf"));
287 detected_fps = 0; /* no cange */
290 ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
294 if (detected_fps != 0 && (detected_fps != timecode.rate || df != timecode.drop)) {
295 timecode.rate = detected_fps;
297 samples_per_ltc_frame = double(_session->sample_rate()) / timecode.rate;
298 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC reset to FPS: %1%2 ; audio-samples per LTC: %3\n",
299 detected_fps, df?"df":"ndf", samples_per_ltc_frame));
303 /* poll and check session TC */
304 TimecodeFormat tc_format = apparent_timecode_format();
305 TimecodeFormat cur_timecode = _session->config.get_timecode_format();
307 if (Config->get_timecode_sync_frame_rate()) {
308 /* enforce time-code */
309 if (!did_reset_tc_format) {
310 saved_tc_format = cur_timecode;
311 did_reset_tc_format = true;
313 if (cur_timecode != tc_format) {
314 if (ceil(Timecode::timecode_to_frames_per_second(cur_timecode)) != ceil(Timecode::timecode_to_frames_per_second(tc_format))) {
315 warning << string_compose(_("Session framerate adjusted from %1 to LTC's %2."),
316 Timecode::timecode_format_name(cur_timecode),
317 Timecode::timecode_format_name(tc_format))
320 _session->config.set_timecode_format (tc_format);
323 /* only warn about TC mismatch */
324 if (ltc_timecode != tc_format) printed_timecode_warning = false;
325 if (a3e_timecode != cur_timecode) printed_timecode_warning = false;
327 if (cur_timecode != tc_format && ! printed_timecode_warning) {
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 and LTC framerate mismatch: LTC:%1 Session:%2."),
330 Timecode::timecode_format_name(tc_format),
331 Timecode::timecode_format_name(cur_timecode))
334 printed_timecode_warning = true;
337 ltc_timecode = tc_format;
338 a3e_timecode = cur_timecode;
340 if (Config->get_use_session_timecode_format() && _session) {
341 samples_per_timecode_frame = _session->samples_per_timecode_frame();
343 samples_per_timecode_frame = ENGINE->sample_rate() / Timecode::timecode_to_frames_per_second (ltc_timecode);
350 LTC_TransportMaster::process_ltc(samplepos_t const now)
353 LTC_TV_STANDARD tv_standard = LTC_TV_625_50;
355 while (ltc_decoder_read (decoder, &sample)) {
359 ltc_frame_to_time (&stime, &sample.ltc, 0);
360 timecode.negative = false;
361 timecode.subframes = 0;
363 /* set timecode.rate and timecode.drop: */
365 const bool ltc_is_stationary = equal_ltc_sample_time (&prev_sample.ltc, &sample.ltc);
367 if (detect_discontinuity (&sample, ceil(timecode.rate), !fps_detected)) {
370 ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
373 fps_detected = false;
376 if (!ltc_is_stationary && detect_ltc_fps (stime.frame, (sample.ltc.dfbit)? true : false)) {
382 if (DEBUG_ENABLED (DEBUG::LTC)) {
383 /* use fprintf for simpler correct formatting of times
385 fprintf (stderr, "LTC@%ld %02d:%02d:%02d%c%02d | %8lld %8lld%s\n",
390 (sample.ltc.dfbit) ? '.' : ':',
394 sample.reverse ? " R" : " "
399 /* when a full LTC sample is decoded, the timecode the LTC sample
400 * is referring has just passed.
401 * So we send the _next_ timecode which
402 * is expected to start at the end of the current sample
404 int fps_i = ceil(timecode.rate);
409 tv_standard = LTC_TV_525_60;
411 tv_standard = LTC_TV_1125_60;
415 tv_standard = LTC_TV_625_50;
418 tv_standard = LTC_TV_FILM_24; /* == LTC_TV_1125_60 == no offset, 24,30fps BGF */
422 if (!sample.reverse) {
423 ltc_frame_increment(&sample.ltc, fps_i, tv_standard, 0);
424 ltc_frame_to_time(&stime, &sample.ltc, 0);
425 transport_direction = 1;
426 sample.off_start -= ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
427 sample.off_end -= ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
429 ltc_frame_decrement(&sample.ltc, fps_i, tv_standard, 0);
430 int off = sample.off_end - sample.off_start;
431 sample.off_start += off - ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
432 sample.off_end += off - ltc_frame_alignment(samples_per_timecode_frame, tv_standard);
433 transport_direction = -1;
436 timecode.hours = stime.hours;
437 timecode.minutes = stime.mins;
438 timecode.seconds = stime.secs;
439 timecode.frames = stime.frame;
441 samplepos_t ltc_sample; // audio-sample corresponding to position of LTC frame
443 if (_session && Config->get_use_session_timecode_format()) {
444 Timecode::timecode_to_sample (timecode, ltc_sample, true, false, (double)ENGINE->sample_rate(), _session->config.get_subframes_per_frame(), timecode_negative_offset, timecode_offset);
446 Timecode::timecode_to_sample (timecode, ltc_sample, true, false, (double)ENGINE->sample_rate(), 100, timecode_negative_offset, timecode_offset);
449 ltc_sample += ltc_slave_latency.max;
451 /* This LTC frame spans sample time between sample.off_start .. sample.off_end
453 * NOTE: these sample times are NOT the ones that LTC is representing. They are
454 * derived our own audioengine's monotonic audio clock.
456 * So we expect the next frame to span sample.off_end+1 and ... <don't care for now>.
457 * That isn't the time we will necessarily receive the LTC frame, but the decoder
458 * should tell us that its span begins there.
462 samplepos_t cur_timestamp = sample.off_end + 1;
464 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC S: %1 LS: %2 N: %3 L: %4\n", ltc_sample, last_ltc_sample, cur_timestamp, last_timestamp));
466 if (cur_timestamp <= last_timestamp || last_timestamp == 0) {
467 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed: UNCHANGED: %1\n", ltc_speed));
469 ltc_speed = double (ltc_sample - last_ltc_sample) / double (cur_timestamp - last_timestamp);
470 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed: %1\n", ltc_speed));
473 if (fabs (ltc_speed) > 10.0) {
477 last_timestamp = cur_timestamp;
478 last_ltc_sample = ltc_sample;
480 } /* end foreach decoded LTC sample */
484 LTC_TransportMaster::speed_and_position (double& speed, samplepos_t& pos, samplepos_t now)
486 if (!_collect || last_timestamp == 0) {
490 /* XXX these are not atomics and maybe modified in a thread other other than the one
491 that is executing this.
496 /* provide a .1% deadzone to lock the speed */
497 if (fabs (speed - 1.0) <= 0.001) {
501 if (speed != 0 && delayedlocked == 0 && fabs(speed) != 1.0) {
502 sync_lock_broken = true;
503 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed not locked %1 based on %2\n", speed, ltc_speed));
506 pos = last_ltc_sample;
507 pos += (now - last_timestamp) * speed;
513 LTC_TransportMaster::pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t> session_pos)
515 Sample* in = (Sample*) AudioEngine::instance()->port_engine().get_buffer (_port->port_handle(), nframes);
516 sampleoffset_t skip = now - (monotonic_cnt + nframes);
519 DEBUG_TRACE (DEBUG::LTC, string_compose ("pre-process - TID:%1 | latency: %2 | skip %3 | session ? %4| last %5 | dir %6 | sp %7\n",
520 pthread_name(), ltc_slave_latency.max, skip, (_session ? 'y' : 'n'), last_timestamp, transport_direction, ltc_speed));
522 if (last_timestamp == 0) {
523 if (delayedlocked < 10) {
527 } else if (ltc_speed != 0) {
531 DEBUG_TRACE (DEBUG::LTC, string_compose ("pre-process with audio clock time: %1\n", now));
533 /* if the audioengine failed to take the process lock, it won't
534 call this method, and time will appear to skip. Reset the
535 LTC decoder's state by giving it some silence.
539 DEBUG_TRACE (DEBUG::LTC, string_compose("engine skipped %1 samples. Feeding silence to LTC parser.\n", skip));
540 if (skip >= 8192) skip = 8192;
541 unsigned char sound[8192];
542 memset (sound, 0x80, sizeof(char) * skip);
543 ltc_decoder_write (decoder, sound, nframes, now);
544 } else if (skip != 0) {
545 /* this should never happen. it may if monotonic_cnt, now overflow on 64bit */
546 DEBUG_TRACE (DEBUG::LTC, string_compose("engine skipped %1 samples\n", skip));
550 /* Now feed the incoming LTC signal into the decoder */
552 parse_ltc (nframes, in, now);
554 /* and pull out actual LTC frame data */
558 if (last_timestamp == 0) {
559 DEBUG_TRACE (DEBUG::LTC, "last timestamp == 0\n");
561 } else if (ltc_speed != 0) {
562 DEBUG_TRACE (DEBUG::LTC, string_compose ("speed non-zero (%1)\n", ltc_speed));
563 if (delayedlocked > 1) {
565 } else if (_current_delta == 0) {
570 if (abs (now - last_timestamp) > FLYWHEEL_TIMEOUT) {
571 DEBUG_TRACE (DEBUG::LTC, "flywheel timeout\n");
573 /* don't change position from last known */
579 const samplepos_t current_pos = last_ltc_sample + ((now - last_timestamp) * ltc_speed);
580 _current_delta = current_pos - *session_pos;
586 Timecode::TimecodeFormat
587 LTC_TransportMaster::apparent_timecode_format () const
589 if (timecode.rate == 24 && !timecode.drop)
591 else if (timecode.rate == 25 && !timecode.drop)
593 else if (rint(timecode.rate * 100) == 2997 && !timecode.drop)
594 return (fr2997() ? timecode_2997000 : timecode_2997);
595 else if (rint(timecode.rate * 100) == 2997 && timecode.drop)
596 return (fr2997() ? timecode_2997000drop : timecode_2997drop);
597 else if (timecode.rate == 30 && timecode.drop)
598 return timecode_2997drop; // timecode_30drop; // LTC counting to 30 samples w/DF *means* 29.97 df
599 else if (timecode.rate == 30 && !timecode.drop)
602 /* XXX - unknown timecode format */
603 return _session->config.get_timecode_format();
607 LTC_TransportMaster::position_string() const
609 if (!_collect || last_timestamp == 0) {
610 return " --:--:--:--";
612 return Timecode::timecode_format_time(timecode);
616 LTC_TransportMaster::delta_string() const
620 if (!_collect || last_timestamp == 0) {
621 snprintf (delta, sizeof(delta), "\u2012\u2012\u2012\u2012");
622 } else if ((monotonic_cnt - last_timestamp) > 2 * samples_per_ltc_frame) {
623 snprintf (delta, sizeof(delta), "%s", _("flywheel"));
625 snprintf (delta, sizeof(delta), "\u0394<span foreground=\"%s\" face=\"monospace\" >%s%s%lld</span>sm",
626 sync_lock_broken ? "red" : "green",
627 LEADINGZERO(::llabs(_current_delta)), PLUSMINUS(-_current_delta), ::llabs(_current_delta));