Record-from-JX — “didn’t decode cleanly” troubleshooting

When a tape-dump capture fails to decode, get DATA before theorizing. Two debugging marathons (2026-06-26/27) burned days on wrong theories the data would have killed in minutes. Both real software causes have since shipped fixes (v0.8.5); what remains useful is the toolkit + how to tell the failure modes apart.

Diagnostic toolkit

The 4-way failure triage

Pull the temp WAV, boost it, count total bit-0 cycles, run a sliding-window decode. capturePeak alone does NOT predict success. If it works on one machine but not another, AirDrop + diff library.json.

  1. ~0 bit-0 cycles anywhere → the capture contains no dump data (capture timing / early auto-stop / the JX didn’t dump that press / a transient). NOT a decoder bug — a capture event. Don’t assume a cable fault.
  2. Many bit-0 cycles, full buffer fails but a sub-window decodes → the loud-idle trim bug → FIXED v0.8.5 (findFskStartByFreq). This was the systemic, intermittent one (random success/fail at identical gain across weeks of captureLog).
  3. Many bit-0 cycles, even the best window only partially decodes → marginal signal (too quiet; the boost amplified the noise floor into spurious cycles). Needs more level / a cleaner cable, not code.
  4. Decodes on machine A but not B (same gear), or a Recalibrate loop → over-hot saved calibration → FIXED v0.8.6 guardrails (cal target 0.78→0.45, gain cap 30→12). Recovery: clear the device’s saved gain — the Calibrate button does this now (the old “Reset to auto-decode” branch was removed in v0.8.5).

The two root causes (both shipped fixes)

Dead ends — do NOT re-chase (each disproven with data)

Sample rate (the on-disk WAV is always whatever the AudioContext was set to), clipping (failing captures measured 0%), browser DSP (audioDiag proved processingActive:false every time), weak/absent bit-0 (a symptom of idle-in-the-trim, not capture quality), auto-boost level, and the cable — tempting after a reseat seemed to “fix” it, but it failed across two independent rigs and the cause was software both times.

Reach for the data — temp WAV + captureLog + library.json — not the cable.