FLAC-Chop
September 6, 2026 · View on GitHub
A small, cross-platform tool for sample-exact cutting of RF-capture files
(Ideally produced by the MISRC-GUI pipeline)
A Rust core reads the file metadata directly (no soxi/ffprobe shell-out) and
SoX performs the actual cut. The GUI is Qt6.
It correctly handles the things that trip up generic audio editors on these
files: the RF "20 kHz header = 20 MSPS real" convention, the 36-bit
total_samples wrap that long captures hit, and unfinalized/piped captures
whose FLAC header total is unknown.
Supported input formats
| Input | Recognized by | Rate source |
|---|---|---|
FLAC (.flac, .ldf, any file starting with the fLaC magic) | header + magic | header (RF /1000 rule applies) |
PCM WAV (.wav) | header | header: audio rate as-is; >1 MHz = real RF rate; else /1000 |
headerless raw PCM .u8 .u16 .s8 .s16 (also .r8/.r16/.raw/.bin) | extension | filename only: an <n>msps hint (e.g. ..._8-bit_20msps.u8) is REQUIRED |
- Unknown extensions with a
fLaCorRIFFmagic header are detected by sniffing the first bytes of the file, so renamed captures just work. - Raw PCM files have no header at all: the rate comes only from the filename
(
..._20msps.u8→ 20 MSPS) and total samples from the file size. Without an<n>mspshint the probe refuses to guess. - Raw files are treated as mono (cxadc/DdD RF convention) unless a channel count is set explicitly.
- Headerless raw RF is pinned to the same /1000 SoX stream rate as the equivalent FLAC, so sinc cutoffs and resample modes behave identically.
Downloads
Downloads for Windows / MacOS / Linux X86 & ARM64 are under Releases
Packaged release artifacts are self-contained: they bundle SoX and required runtime libraries. You should not need to install SoX separately when using release downloads.
If you build FLAC-Chop from source, SoX still needs to be available on PATH
(or via FLAC_CHOP_SOX=/path/to/sox).
Features
- Real-time HH:MM:SS duration for RF captures, not the 1000×-wrong header value.
- Handles
total_sampleswrapping past 2³⁶ (recovers the true sample count). - Reads the MISRC/DdD Vorbis tags (
RF_TOTAL_SAMPLES,RF_SAMPLE_RATE,DURATION_SECONDS) as the authoritative in-file record. - Falls back to a sibling
.log/.wavfor unfinalized captures, then to an exact FLAC frame-header scan. - Surfaces non-fatal probe warnings (tag-unit corrections, Vorbis self-consistency mismatches, scan misalignment) in the GUI and on CLI stderr.
- Async probing — loading a 100 GB file doesn't freeze the window.
- IN / OUT markers via a single time box + Set IN / Set OUT buttons (ld-analyse style), with a dual-handle slider.
- Optional output processing modes for RF captures: keep source rate, or downsample to 10 (HiFi FM) / 16 / 20 / 24 / 28.6 MSPS, with wiki-aligned basic SoX sinc filter presets.
- Bit-depth control (keep source, 8-bit, or 6-bit crush emulation stored in an 8-bit FLAC container; no dither — pure requantization for maximum compression efficiency and SNR).
- Headless
probe_cliandchop_clifor scripting / validation. - Self-healing FLAC headers: when a capture's STREAMINFO
total_sampleswas never finalized (some MISRC HiFi writers store the real count / 1000), the true count is recovered from theRF_TOTAL_SAMPLESVorbis tag and the header is repaired in place before cutting — without it SoX refuses every cut past the mis-declared end. - Cut outputs are validated (a SoX run that exits 0 but writes a header-only file is a hard failure) and the cut's RF Vorbis tags are rewritten to the new altered metadata in place — the same method the MISRC-GUI recorder uses (grow the comment into adjacent padding / trim the vendor string), so no temp file and no full-file rewrite is ever needed. Files that cannot fit get a full verified splice that leaves 4096 bytes of padding behind (the old lofty-based writer was dropped: its FLAC writer corrupts files).
Using the GUI
- Browse to a capture file — FLAC (
.flac/.ldf), PCM WAV, or headerless raw PCM (.u8/.u16/.s8/.s16); any file with a matching magic header is accepted too. Drag-and-drop takes any local file and lets the probe decide (a clear error appears if the format is unsupported). - The probe runs on a background thread; the "Total (real)" label shows the
real-time duration and a provenance tag (
vorbis RF_TOTAL_SAMPLES,companion file,scanned from frames, or ). If the probe emitted non-fatal warnings (e.g. a tag-unit correction), a ⚠ with the details is appended to the label and shown in the status line. - Move the slider or type a time into the time box, then click Set IN / Set OUT to drop the IN (green) and OUT (red) markers. On load the handles sit at the start/end of the tape.
- Click Process. FLAC-Chop writes
<input>-cut.flacnext to the source viasox <in> <out> trim <start>s <len>s(thessuffix = sample counts, so the cut is sample-exact at the real MSPS rate).
Headless use
# probe a file (print sniffed format, real rate, total samples, real duration, provenance)
cargo run --release --manifest-path core/Cargo.toml --example probe_cli -- file.flac
# cut: chop_cli <in> <out.flac> <start_sec> <len_sec>
cargo run --release --manifest-path core/Cargo.toml --example chop_cli -- file.flac out.flac 60 10
# cut + convert: chop_convert_cli <in> <out> <start_sec> <len_sec> <out_rate_khz|0=keep> <out_bits|0=source> [filter 0/1]
# e.g. cut to 10 MSPS (HiFi FM) 6-bit with the sinc profile:
cargo run --release --manifest-path core/Cargo.toml --example chop_convert_cli -- file.flac out.flac 60 10 10000 6 1
The CLIs run the exact same probe → plan → SoX path as the GUI and accept the
same input formats. Headerless raw inputs must carry the rate in their name
(e.g. ..._8-bit_20msps.u8).
Status & Limitations
- No progress percentage during a cut (SoX doesn't emit sample progress to a captured pipe easily); the GUI shows a busy indicator instead.
- 6-bit RF output is emulated by pure bit-shift requantization to 6-bit precision stored in an 8-bit FLAC container, with no dither (SoX/FLAC cannot encode true 6-bit FLAC directly; dithering was removed as it adds incompressible noise and hurts compression efficiency and SNR).
Author
© Harry Munday 2026 harry@opcomedia.com (therealharrypm - Discord)