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)
57 , ltc_detect_fps_cnt (0)
58 , ltc_detect_fps_max (0)
59 , sync_lock_broken (false)
61 if ((_port = AudioEngine::instance()->register_input_port (DataType::AUDIO, string_compose ("%1 in", _name))) == 0) {
62 throw failed_constructor();
65 DEBUG_TRACE (DEBUG::Slave, string_compose ("LTC registered %1\n", _port->name()));
67 memset(&prev_sample, 0, sizeof(LTCFrameExt));
71 AudioEngine::instance()->Xrun.connect_same_thread (port_connections, boost::bind (<C_TransportMaster::resync_xrun, this));
72 AudioEngine::instance()->GraphReordered.connect_same_thread (port_connections, boost::bind (<C_TransportMaster::resync_latency, this));
76 LTC_TransportMaster::init ()
82 LTC_TransportMaster::set_session (Session *s)
84 config_connection.disconnect ();
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();
96 if (Config->get_use_session_timecode_format() && _session) {
97 samples_per_timecode_frame = _session->samples_per_timecode_frame();
101 ltc_decoder_free (decoder);
104 decoder = ltc_decoder_create((int) samples_per_ltc_frame, 128 /*queue size*/);
106 parse_timecode_offset();
109 _session->config.ParameterChanged.connect_same_thread (config_connection, boost::bind (<C_TransportMaster::parameter_changed, this, _1));
113 LTC_TransportMaster::~LTC_TransportMaster()
115 port_connections.drop_connections();
116 config_connection.disconnect();
118 if (did_reset_tc_format) {
119 _session->config.set_timecode_format (saved_tc_format);
122 ltc_decoder_free(decoder);
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;
136 LTC_TransportMaster::parameter_changed (std::string const & p)
138 if (p == "slave-timecode-offset"
139 || p == "timecode-format"
141 parse_timecode_offset();
146 LTC_TransportMaster::update_interval() const
149 return AudioEngine::instance()->sample_rate() / timecode.rate;
152 return AudioEngine::instance()->sample_rate(); /* useless but what other answer is there? */
156 LTC_TransportMaster::resolution () const
158 return (samplecnt_t) (ENGINE->sample_rate() / 1000);
162 LTC_TransportMaster::locked () const
164 return (delayedlocked < 5);
168 LTC_TransportMaster::ok() const
174 LTC_TransportMaster::resync_xrun()
176 DEBUG_TRACE (DEBUG::LTC, "LTC resync_xrun()\n");
177 sync_lock_broken = false;
181 LTC_TransportMaster::resync_latency()
183 DEBUG_TRACE (DEBUG::LTC, "LTC resync_latency()\n");
184 sync_lock_broken = false;
187 _port->get_connected_latency_range (ltc_slave_latency, false);
192 LTC_TransportMaster::reset (bool with_ts)
194 DEBUG_TRACE (DEBUG::LTC, "LTC reset()\n");
196 current.update (current.position, 0, current.speed);
199 transport_direction = 0;
200 sync_lock_broken = false;
205 LTC_TransportMaster::parse_ltc (const ARDOUR::pframes_t nframes, const Sample* const in, const ARDOUR::samplecnt_t posinfo)
208 unsigned char sound[8192];
210 if (nframes > 8192) {
211 /* TODO warn once or wrap, loop conversion below
212 * does jack/A3 support > 8192 spp anyway?
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);
222 ltc_decoder_write (decoder, sound, nframes, posinfo);
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) {
244 LTC_TransportMaster::detect_discontinuity(LTCFrameExt *sample, int fps, bool fuzzy) {
245 bool discontinuity_detected = false;
248 ( sample->reverse && prev_sample.ltc.frame_units == 0)
249 ||(!sample->reverse && sample->ltc.frame_units == 0)
251 memcpy(&prev_sample, sample, sizeof(LTCFrameExt));
255 if (sample->reverse) {
256 ltc_frame_decrement(&prev_sample.ltc, fps, LTC_TV_525_60, 0);
258 ltc_frame_increment(&prev_sample.ltc, fps, LTC_TV_525_60, 0);
260 if (!equal_ltc_sample_time(&prev_sample.ltc, &sample->ltc)) {
261 discontinuity_detected = true;
264 memcpy(&prev_sample, sample, sizeof(LTCFrameExt));
265 return discontinuity_detected;
269 LTC_TransportMaster::detect_ltc_fps(int frameno, bool df)
271 bool fps_changed = false;
272 double detected_fps = 0;
273 if (frameno > ltc_detect_fps_max)
275 ltc_detect_fps_max = frameno;
277 ltc_detect_fps_cnt++;
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;
283 /* LTC df -> indicates fractional framerate */
285 detected_fps = detected_fps * 999.0 / 1000.0;
287 detected_fps = detected_fps * 1000.0 / 1001.0;
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"));
294 detected_fps = 0; /* no cange */
297 ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
301 if (detected_fps != 0 && (detected_fps != timecode.rate || df != timecode.drop)) {
302 timecode.rate = detected_fps;
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));
310 /* poll and check session TC */
311 TimecodeFormat tc_format = apparent_timecode_format();
312 TimecodeFormat cur_timecode = _session->config.get_timecode_format();
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;
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))
327 _session->config.set_timecode_format (tc_format);
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;
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))
341 printed_timecode_warning = true;
344 ltc_timecode = tc_format;
345 a3e_timecode = cur_timecode;
347 if (Config->get_use_session_timecode_format() && _session) {
348 samples_per_timecode_frame = _session->samples_per_timecode_frame();
350 samples_per_timecode_frame = ENGINE->sample_rate() / Timecode::timecode_to_frames_per_second (ltc_timecode);
357 LTC_TransportMaster::process_ltc(samplepos_t const now)
360 LTC_TV_STANDARD tv_standard = LTC_TV_625_50;
362 while (ltc_decoder_read (decoder, &sample)) {
366 ltc_frame_to_time (&stime, &sample.ltc, 0);
367 timecode.negative = false;
368 timecode.subframes = 0;
370 /* set timecode.rate and timecode.drop: */
372 const bool ltc_is_stationary = equal_ltc_sample_time (&prev_sample.ltc, &sample.ltc);
374 if (detect_discontinuity (&sample, ceil(timecode.rate), !fps_detected)) {
377 ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
380 fps_detected = false;
383 if (!ltc_is_stationary && detect_ltc_fps (stime.frame, (sample.ltc.dfbit)? true : false)) {
389 if (DEBUG_ENABLED (DEBUG::LTC)) {
390 /* use fprintf for simpler correct formatting of times
392 fprintf (stderr, "LTC@%ld %02d:%02d:%02d%c%02d | %8lld %8lld%s\n",
397 (sample.ltc.dfbit) ? '.' : ':',
401 sample.reverse ? " R" : " "
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
411 int fps_i = ceil(timecode.rate);
416 tv_standard = LTC_TV_525_60;
418 tv_standard = LTC_TV_1125_60;
422 tv_standard = LTC_TV_625_50;
425 tv_standard = LTC_TV_FILM_24; /* == LTC_TV_1125_60 == no offset, 24,30fps BGF */
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);
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;
443 timecode.hours = stime.hours;
444 timecode.minutes = stime.mins;
445 timecode.seconds = stime.secs;
446 timecode.frames = stime.frame;
448 samplepos_t ltc_sample; // audio-sample corresponding to position of LTC frame
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);
453 Timecode::timecode_to_sample (timecode, ltc_sample, true, false, (double)ENGINE->sample_rate(), 100, timecode_negative_offset, timecode_offset);
456 ltc_sample += ltc_slave_latency.max;
458 /* This LTC frame spans sample time between sample.off_start .. sample.off_end
460 * NOTE: these sample times are NOT the ones that LTC is representing. They are
461 * derived our own audioengine's monotonic audio clock.
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.
469 samplepos_t cur_timestamp = sample.off_end + 1;
470 double ltc_speed = current.speed;
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));
474 if (cur_timestamp <= current.timestamp || current.timestamp == 0) {
475 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed: UNCHANGED: %1\n", current.speed));
477 ltc_speed = double (ltc_sample - current.position) / double (cur_timestamp - current.timestamp);
479 /* provide a .1% deadzone to lock the speed */
480 if (fabs (ltc_speed - 1.0) <= 0.001) {
484 if (fabs (ltc_speed) > 10.0) {
488 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC speed: %1\n", ltc_speed));
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);
493 } /* end foreach decoded LTC sample */
497 LTC_TransportMaster::pre_process (ARDOUR::pframes_t nframes, samplepos_t now, boost::optional<samplepos_t> session_pos)
499 Sample* in = (Sample*) AudioEngine::instance()->port_engine().get_buffer (_port->port_handle(), nframes);
500 sampleoffset_t skip = now - (monotonic_cnt + nframes);
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));
506 if (current.timestamp == 0) {
507 if (delayedlocked < 10) {
511 } else if (current.speed != 0) {
515 DEBUG_TRACE (DEBUG::LTC, string_compose ("pre-process with audio clock time: %1\n", now));
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.
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));
534 /* Now feed the incoming LTC signal into the decoder */
536 parse_ltc (nframes, in, now);
538 /* and pull out actual LTC frame data */
542 if (current.timestamp == 0) {
543 DEBUG_TRACE (DEBUG::LTC, "last timestamp == 0\n");
545 } else if (current.speed != 0) {
546 DEBUG_TRACE (DEBUG::LTC, string_compose ("speed non-zero (%1)\n", current.speed));
547 if (delayedlocked > 1) {
549 } else if (_current_delta == 0) {
554 if (abs (now - current.timestamp) > FLYWHEEL_TIMEOUT) {
555 DEBUG_TRACE (DEBUG::LTC, "flywheel timeout\n");
557 /* don't change position from last known */
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));
568 const samplepos_t current_pos = current.position + ((now - current.timestamp) * current.speed);
569 _current_delta = current_pos - *session_pos;
575 Timecode::TimecodeFormat
576 LTC_TransportMaster::apparent_timecode_format () const
578 if (timecode.rate == 24 && !timecode.drop)
580 else if (timecode.rate == 25 && !timecode.drop)
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)
591 /* XXX - unknown timecode format */
592 return _session->config.get_timecode_format();
596 LTC_TransportMaster::position_string() const
598 if (!_collect || current.timestamp == 0) {
599 return " --:--:--:--";
601 return Timecode::timecode_format_time(timecode);
605 LTC_TransportMaster::delta_string() const
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"));
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));