lossprint 1.0
Lossprint detects audio that was lossy-encoded and then decoded back to
PCM—an MP3 re-wrapped as FLAC, for example. For flagged files it also
estimates the encoder family and the source bitrate. The model is a
1.4M-parameter CRNN over dual-resolution mid/side log spectrograms at the
native sample rate.
Results
Threshold 0.5. Each file is scored in one pass over a 14.5-second window;
longer files average their windows. Test releases are disjoint from training.
False-positive rate: 0.24% — 6 of 2,469 untouched lossless masters
(44.1–192 kHz, 16/24-bit, mono and stereo).
Detection rate by encoder and measured bitrate, over 5,973 lab-encoded
test files plus 1,046 lossy files from real releases. Cells show percent
detected (files tested).
| encoder | <112 kbps | 112–159 | 160–223 | 224–287 | ≥288 |
|---|
| MP3 | 100.0% (286) | 100.0% (351) | 100.0% (305) | 100.0% (328) | 99.8% (1,205) |
| AAC | 99.6% (501) | 100.0% (252) | 97.8% (89) | 98.9% (284) | 95.6% (318) |
| Vorbis | 100.0% (145) | 100.0% (110) | 99.0% (96) | 99.2% (123) | 99.4% (702) |
| Opus | 100.0% (266) | 100.0% (142) | 99.2% (118) | 100.0% (108) | 100.0% (76) |
| WMA | 100.0% (359) | 100.0% (180) | 100.0% (107) | — | 100.0% (10) |
| MP2 | — | 100.0% (17) | 100.0% (31) | 100.0% (36) | — |
| Musepack | 100.0% (6) | 100.0% (43) | 100.0% (56) | 100.0% (185) | 99.5% (184) |
AAC by encoder and setting
High-bitrate AAC is the hardest case, so its three hardest settings were
re-encoded from every test track (n > 2,500). Other rows use the sampled
test set.
| encoder | setting | detected |
|---|
| Apple AAC-LC (afconvert) | VBR q127 (~336 kbps) | 94.4% (2,804) |
| CBR 320 | 96.3% (2,588) |
| CBR 256 | 98.1% (105) |
| VBR q109 (~266 kbps) | 100.0% (82) |
| CBR 128 | 100.0% (110) |
| VBR q64 (~121 kbps) | 100.0% (94) |
| CBR 96 | 100.0% (44) |
| Apple HE-AAC v1/v2 | 24–80 kbps | 99.7% (327) |
| FFmpeg native AAC | CBR 256 | 97.7% (2,804) |
| CBR 192 | 100.0% (60) |
| CBR 128 | 100.0% (66) |
| CBR 96 | 100.0% (8) |
Bitrate estimate, on detected test files: median error 3.5%; 85% of
estimates within ±10%, 97% within ±20%.
Use
The
lossprint Rust library and CLI
implement the frontend and classifier. For other integrations:
Decode the whole file at its native sample rate, bit depth, and channel
count—no resampling, downmixing, normalizing, or clipping. Split it into
14.5-second windows (about 1,245 frames at 44.1 kHz). For each window:
- Mid/side:
mid = (L + R) / 2, side = (L − R) / 2. Mono uses an
all-zero side channel.
- STFT size by sample rate:
n_fft = 2048, hop = 512 up to 50 kHz;
4096 / 1024 up to 100 kHz; 8192 / 2048 above.
- Long spectrogram: periodic Hann window, no centering, so frame
t starts
at sample t · hop. Keep bins 0–1023 and take
clamp(20 · log10(|X| + 1e-7), −100, 40) / 50.
- Short spectrogram: the same with an
n_fft / 4 window at the same hop and
frame starts. Keep bins 0–255 and as many frames as the long spectrogram,
then repeat each bin 4× along frequency.
- Stack the channels
[mid_long, side_long, mid_short, side_short].
model.onnx takes float32 [windows, 4, 1024, frames]—both axes dynamic,
windows in one batch sharing a frame count—and returns:
transcode_probability [windows]
family_probability [windows, 7], ordered mp3, aac, vorbis, opus, wma, mp2, mpc
bitrate_kbps [windows]
Average probabilities across windows; average bitrate in log2 space. Family
and bitrate are only meaningful for flagged files.
Data
22,250 tracks were sampled (at most 8 per release) from 11,004 releases, plus
speech masters; masters that already show a codec cutoff were screened out. Each
14.5-second excerpt is paired with delay-aligned copies of itself encoded and
decoded by real encoders—MP3, AAC, Vorbis, Opus, WMA, MP2, Musepack—with nothing
else applied. Splits are by release. Training uses 53,456 such pairs, with extra
weight on high-bitrate AAC. Manifest SHA-256:
823d29c08df1511acd6ebf45093c73365f17c7269c848197ba35c61a74be957b.
Limits
- Mono and stereo only.
- Band-limited lossless audio draws more false positives: 0.3% on 598
band-limited test excerpts, 1.0% on a 1,000-file probe low-passed at
14–20 kHz.
- Windows much longer than 14.5 seconds are untested; chunk long files
instead.
- Unseen encoders, remastering, EQ, resampling, and adversarial processing
may behave differently.
Files
model.safetensors SHA-256:
1ba9797ca09ada646e56dc01884259faccf9feb3b8c31006ccb8be9360ae0df8
model.onnx SHA-256:
ca86c67b4035485a9c1a3b3120b4a555cb7af87b4dd28837c46b297f82c48e7d