port: check-capture refuses a format it cannot read, and accepts the one it nearly rejected

The Decoder is moving to an ALSA `type file` tee, which writes float32. Read as
s16 that yields a plausible-looking file whose only tell is per-channel peaks
alternating exactly -- the two halves of each float landing in alternate
channels. My parser assumed s16 throughout and would have mis-read it
confidently.

An unreadable format now ends the run at PARTIAL (exit 2) rather than PASS:
channels were checked, starvation was not, and the tool says which. A checker
that claims a check it skipped is the shape of every failure this file documents.

AND THE FIRST VERSION OF THE GUARD WAS TOO STRICT -- it rejected one of this
tool's own controls, a six-tone file `ffprobe` correctly calls pcm_s16le, because
the file is WAVE_FORMAT_EXTENSIBLE (tag 0xFFFE) rather than plain PCM. A format
guard that refuses a legitimate capture is the same defect as one that mis-reads
an illegitimate one, pointing the other way. The check turns on wBitsPerSample,
which is what decides the layout; a float tee is 32-bit and still caught.

Control sweep, now the tool's real specification and all of it runnable here:

  real music+SFX bed                        PASS
  voice track, mono, 53% real pauses        PASS
  six distinct tones, PCM and extensible    PASS
  bed with 350 ms holes punched in          FAIL
  the starved capture                       FAIL
  the same tones as float32                 PARTIAL

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
Sylpheed port agent
2026-08-29 16:55:19 +00:00
parent af1d69ed4b
commit 78879dce06
2 changed files with 62 additions and 0 deletions

View File

@@ -239,6 +239,36 @@ Rate alone cannot separate rows 2 and 3; silence alone cannot separate rows 1 an
*and* there is at least 1 gap per second. Real audio is either mostly not silent,
or silent in a few long stretches — not both at once.
### A format it cannot read is refused, not guessed at
Everything in the starvation check assumes 16-bit signed. An ALSA `type file` tee
writes **float32** (`SND_PCM_FORMAT_FLOAT_LE`), and read as s16 that produces a
*plausible-looking* file — the Decoder measured one, and its only tell was
per-channel peaks alternating **exactly**, which is the two halves of each float
landing in alternate channels.
So an unreadable format ends the run at **`PARTIAL`** (exit 2), not `PASS`:
channels were checked, starvation was not, and the tool says which. A checker
that claims a check it skipped is the shape of every failure this file documents.
⚠️ **`WAVE_FORMAT_EXTENSIBLE` (tag `0xFFFE`) is accepted at 16 bits**, and the
first version of the guard was not — it rejected one of this tool's own controls,
a file `ffprobe` correctly calls `pcm_s16le`. **A format guard that refuses a
legitimate capture is the same defect as one that mis-reads an illegitimate one**,
pointing the other way. The check turns on `wBitsPerSample`, which is what
actually decides the sample layout; a float tee is 32-bit and is still caught.
### The control sweep, which is the tool's real specification
| file | verdict |
|---|---|
| real music+SFX bed | `PASS` |
| voice track, mono, 53 % real pauses | `PASS` |
| six distinct tones (PCM and extensible) | `PASS` |
| bed with 350 ms holes punched in | **`FAIL`** |
| the starved capture | **`FAIL`** |
| the same tones as float32 | **`PARTIAL`** |
### ⚠️ The regime this tool cannot judge, and says so
**High silence with very few gaps is what a real voice track looks like (53.2 %

View File

@@ -105,7 +105,33 @@ while i + 8 <= len(d):
i += 8 + sz + (sz & 1)
if fmt is None or off is None:
print(" (not a plain WAV -- starvation check skipped)"); raise SystemExit(0)
tag = struct.unpack('<H', fmt[0:2])[0]
ch = struct.unpack('<H', fmt[2:4])[0]; rate = struct.unpack('<I', fmt[4:8])[0]
bits = struct.unpack('<H', fmt[14:16])[0] if len(fmt) >= 16 else 16
# REFUSE A FORMAT THIS CANNOT READ, rather than mis-reading it confidently.
#
# Everything below assumes 16-bit signed. An ALSA `type file` tee writes
# **float32** (`SND_PCM_FORMAT_FLOAT_LE`), and read as s16 it produces a
# plausible-looking file: the Decoder measured one and its only giveaway was
# per-channel peaks alternating EXACTLY -0.00 / -4.82, which is the two halves
# of each float landing in alternate channels. A checker that mis-reads a format
# is worse than one that has no opinion -- it is the shape of every failure this
# tool exists to catch.
#
# tag 1 = PCM, 3 = IEEE float, 0xFFFE = WAVE_FORMAT_EXTENSIBLE.
#
# ⚠️ EXTENSIBLE IS ACCEPTED AT 16 BITS, and the first version of this guard was
# not -- it rejected one of this tool's own controls, a file `ffprobe` correctly
# calls `pcm_s16le`. A format guard that refuses a legitimate capture is the same
# defect as one that mis-reads an illegitimate one, pointing the other way.
# `wBitsPerSample` is what actually decides how the samples are laid out here, so
# it is what the check turns on; a float tee is 32-bit and is still caught.
if tag not in (1, 0xFFFE) or bits != 16:
print(" 🔴 format tag %d, %d-bit -- this tool reads 16-bit PCM only." % (tag, bits))
print(" Read as s16 a float32 tee looks plausible and is not: its tell is")
print(" per-channel peaks alternating exactly, one float split across two")
print(" channels. Convert first: ffmpeg -i in.wav -c:a pcm_s16le out.wav")
raise SystemExit(4)
avail = len(d) - off
if declared == 0 or declared > avail:
# A streaming writer that never patched its header. The file may also be a
@@ -198,6 +224,12 @@ if tot / float(n) >= 0.10:
PYEOF
starved=$?
set -e
if [ "$starved" = 4 ]; then
# The duplicate test ran (bytes are bytes) but starvation did not. Saying
# "PASS" here would be the tool claiming a check it skipped.
echo "PARTIAL: channels checked, starvation NOT checked -- unreadable sample format."
exit 2
fi
if [ "$starved" = 3 ]; then
echo "FAIL: the recording is starved. A monitor sink advances at wall-clock rate"
echo " and substitutes silence when the producer is late, so this file has"