X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_ltc.cc;h=8d976ea4da1b35814c9fd1a76174b82021571d6a;hb=0a4f4026a9e98ad2466d7f3e7de41dac8f22a136;hp=d14756c0ba063e524fc68d0b6cd610a1d1fbe40a;hpb=52532839110d4bbd2e4dc3e0eb8967d0f278a611;p=ardour.git diff --git a/libs/ardour/session_ltc.cc b/libs/ardour/session_ltc.cc index d14756c0ba..8d976ea4da 100644 --- a/libs/ardour/session_ltc.cc +++ b/libs/ardour/session_ltc.cc @@ -39,6 +39,25 @@ using namespace Timecode; //#define LTC_GEN_FRAMEDBUG //#define LTC_GEN_TXDBUG +#ifndef MAX +#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) +#endif +#ifndef MIN +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) +#endif + +/* LTC signal should have a rise time of 25 us +/- 5 us. + * yet with most sound-cards a square-wave of 1-2 sample + * introduces rather some ringing and small oscillations. + * so we low-pass filter the signal a bit, depending + * on the sample-rate. + * + * TODO: this should become an adaptive value, when + * the playback speed is increases so that 1 bit < 3-4 + * audio samples, we should fall back to 25 us. + */ +#define LTC_RISE_TIME MIN (100, MAX(25, (2000000 / engine().frame_rate()))) + void Session::ltc_tx_initialize() { @@ -50,6 +69,7 @@ Session::ltc_tx_initialize() 0); ltc_encoder_set_bufsize(ltc_encoder, nominal_frame_rate(), 23.0); + ltc_encoder_set_filter(ltc_encoder, LTC_RISE_TIME); /* buffersize for 1 LTC frame: (1 + sample-rate / fps) bytes * usually returned by ltc_encoder_get_buffersize(encoder) @@ -153,19 +173,6 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end /* range from libltc (38..218) || - 128.0 -> (-90..90) */ const float ltcvol = Config->get_ltc_output_volume()/(90.0); // pow(10, db/20.0)/(90.0); -#if 1 - /* TODO read layency only on demand -> ::ltc_tx_reset() - * this is already prepared. - * - * ..but first fix jack2 issue with re-computing latency - * in the correct order. Until then, querying it in the - * process-callback is the only way to get the current value - * - * update: fix for this issue is known -- common/JackEngine.cpp - * but not yet applied to jack2 git. - */ - ltcport->get_connected_latency_range(ltc_out_latency, true); -#endif DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX %1 to %2 / %3 | lat: %4\n", start_frame, end_frame, nframes, ltc_out_latency.max)); /* all systems go. Now here's the plan: @@ -191,6 +198,9 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end ltc_tx_cleanup(); return; } + if (nominal_frame_rate() <= 48000) { + ltc_encoder_set_filter(ltc_encoder, LTC_RISE_TIME); + } ltc_enc_tcformat = cur_timecode; ltc_tx_reset(); } @@ -208,18 +218,11 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end #define SIGNUM(a) ( (a) < 0 ? -1 : 1) bool speed_changed = false; - /* use port latency compensation */ -#if 1 - /* The generated timecode is offset by the port-latency, + /* port latency compensation: + * The _generated timecode_ is offset by the port-latency, * therefore the offset depends on the direction of transport. */ - framepos_t cycle_start_frame = (current_speed < 0) ? (start_frame + ltc_out_latency.max) : (start_frame - ltc_out_latency.max); -#else - /* This comes in handy when testing sync - record output on an A3 track - * see also http://tracker.ardour.org/view.php?id=5073 - */ - framepos_t cycle_start_frame = start_frame; -#endif + framepos_t cycle_start_frame = (current_speed < 0) ? (start_frame - ltc_out_latency.max) : (start_frame + ltc_out_latency.max); /* cycle-start may become negative due to latency compensation */ if (cycle_start_frame < 0) { cycle_start_frame = 0; } @@ -466,6 +469,24 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX5 restart @ %1 + %2 - %3 | byte %4\n", ltc_enc_pos, ltc_enc_cnt, cyc_off, ltc_enc_byte)); } +#if 1 /* experimental sample bit alignment */ + else if (ltc_speed != 0 && (fptcf / ltc_speed / 80) > 3 ) { + /* We may get away without a DLL if speed-changes are uniform enough and + * no oscillation takes place, the linear approx here should reduce the + * jitter sufficiently when generating LTC from another LTC source or + * JACK-transport or ardour internal clock. + * + * Note that the granularity of the LTC encoder speed is 1 byte = + * (frames-per-timecode-frame / 10) audio-samples. + * + * Thus, tiny speed changes won't have any effect and larger ones + * may lead to oscillations. + * To be better than that, resampling (or a rewrite of the encoder) is + * required. + */ + ltc_speed -= ((ltc_enc_pos + ltc_enc_cnt - poff) - cycle_start_frame) / engine().frame_rate(); + } +#endif // (6) encode and output @@ -530,6 +551,12 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end ltc_enc_byte = (ltc_enc_byte + 1)%10; if (ltc_enc_byte == 0 && ltc_speed != 0) { ltc_encoder_inc_timecode(ltc_encoder); +#if 0 /* force fixed parity -- scope debug */ + LTCFrame f; + ltc_encoder_get_frame(ltc_encoder, &f); + f.biphase_mark_phase_correction=0; + ltc_encoder_set_frame(ltc_encoder, &f); +#endif ltc_tx_recalculate_position(); ltc_enc_cnt = 0; } else if (ltc_enc_byte == 0) {