diff --git a/README.md b/README.md index c207401..64bd454 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,11 @@ are written by the app itself. machine that can hear the LTC signal; it decodes the SMPTE frames from a PCM pipe (ffmpeg/sox one-liners in its header) and POSTs running/stopped/no-signal, the timecode, and the frame rate (incl. - 29.97 drop-frame) to the module's `/ltc` ingest route. `--selftest` - checks the decoder; `--demo` feeds synthetic LTC end-to-end with no - audio hardware. + 29.97 drop-frame) to the module's `/ltc` ingest route. LTC on one + input of a multichannel interface: capture all channels and pick one + with `--channels 18 --ch 5` — never downmix LTC into program audio. + `--selftest` checks the decoder; `--demo` feeds synthetic LTC + end-to-end with no audio hardware. 2. A stage-display layout field labeled "LTC", read over ProPresenter's stage websocket — value and freshness only, no frame rate. - **Clock** — a big booth clock; also the smallest possible module and the diff --git a/tools/ltc-reader.js b/tools/ltc-reader.js index b1bf21f..1ac4408 100644 --- a/tools/ltc-reader.js +++ b/tools/ltc-reader.js @@ -6,10 +6,10 @@ * * ProPresenter's APIs expose no timecode (see modules/propresenter-timers), * so this tool reads LTC where it actually lives: the audio signal. Pipe - * mono PCM (signed 16-bit little-endian) into stdin from any capture - * front-end; the decoded state is POSTed to the Timers module's /ltc - * ingest route — ~4×/s while running, 1×/s as a keepalive otherwise, and - * immediately on every state change. + * PCM (signed 16-bit little-endian) into stdin from any capture front-end; + * the decoded state is POSTed to the Timers module's /ltc ingest route — + * ~4×/s while running, 1×/s as a keepalive otherwise, and immediately on + * every state change. * * macOS (ffmpeg; list input devices with * `ffmpeg -f avfoundation -list_devices true -i ""`): @@ -21,11 +21,23 @@ * ffmpeg -loglevel error -f dshow -i audio="" -ac 1 \ * -ar 48000 -f s16le - | node tools/ltc-reader.js * + * LTC on one input of a multichannel interface (a console bus, a Dante/ + * MADI card, input 5 of a Scarlett 18i20…): do NOT downmix with -ac 1 — + * summing LTC with program audio corrupts the bit transitions. Capture the + * channels as they are and tell the reader which one carries LTC (1-based): + * ffmpeg -loglevel error -f avfoundation -i ":0" -ar 48000 -f s16le - \ + * | node tools/ltc-reader.js --channels 18 --ch 5 + * (--channels must match what the capture actually emits; ffmpeg keeps + * the device's native count unless -ac says otherwise, and prints it on + * stderr at startup. sox: match its -c flag.) + * * Flags: * --url ProdDash base URL (default http://127.0.0.1:24500) * --module target module id (default propresenter-timers) * --token matches the module's "LTC reader token" admin setting * --sr stdin sample rate (default 48000) + * --channels interleaved channels in the stdin stream (default 1) + * --ch which channel carries LTC, 1-based (default 1) * --source