re: a 6-channel capture scrambles and duplicates channels unless the maps match
The ADV audio capture I shared with the port is withdrawn as evidence. They
could not match it against anything -- the movie bed, any of the three voice
streams, BGM_103, S00A -- with best-vs-runner-up margins of 0.001 to 0.016
everywhere, and they controlled that three ways before saying so. They also
noticed capture channels 3 and 6 were byte-identical.
That duplicate pair reproduces without the emulator, and it is my capture chain.
Six channels each carrying a different tone, played to the null sink and
recorded from its monitor with the same parec invocation:
sink map NOT matching the client (the original setup)
expected 400 800 200 1600 3200 6400
captured 400 3200 200 800 800 200 ch2 == ch5 byte-identical
sink map made identical to Canary s stream map, and passed to parec too
captured 400 800 200 1600 3200 6400 no duplicates -- CONTROL PASSED
PulseAudio remaps when the maps differ, and a 6-channel remap silently drops
channels and duplicates others. No error, no warning; the WAV has the right
length, channel count and plausible per-channel levels.
Withdrawn with it: "all six channels carry signal", and the observation that
non-zero surround and LFE weakly supported the 5.1 reading of a voice cue s
three streams. The port said a duplicated channel is not an independent one and
they were right before this control existed.
Unaffected: the three-XMA-context concurrency result, which is read from the
emulator s own log rather than the audio path, on two independent boots.
The control needed no emulator, no disc and thirty seconds. It was not run, an
artefact was published, and the person who found the defect was the one who
could not see the instrument.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
92
docs/re/audio-capture-channel-map-trap.md
Normal file
92
docs/re/audio-capture-channel-map-trap.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# 🔴 A 6-channel PulseAudio capture SCRAMBLES AND DUPLICATES channels unless the maps match
|
||||
|
||||
**Classification: measured**, on the capture chain itself rather than on the
|
||||
game. Recorded because a capture taken with this defect was handed to the port
|
||||
as evidence, cost them a full controlled analysis, and the negative they
|
||||
correctly reported was **my instrument, not the guest**.
|
||||
|
||||
## What happened
|
||||
|
||||
`adv-game-output-6ch.wav` was captured from Canary through a PulseAudio null
|
||||
sink and shared as "what the game emits during `ADV`". The port could not match
|
||||
it against **anything** — the `ADV` bed, any of the three XMA voice streams,
|
||||
`BGM_103`, `S00A` — with best-vs-runner-up margins of 0.001–0.016 everywhere,
|
||||
i.e. plateaux rather than peaks. They controlled that three ways (their
|
||||
instrument finds `bed` vs `bed` at r=1.000 margin +0.115; their `.ogv` reference
|
||||
matches the disc's `.wmv` at r=1.000 margin +0.114; and drift was excluded by
|
||||
windowed lags scattering across the movie). They also observed that **capture
|
||||
channels 3 and 6 were byte-identical, same MD5**.
|
||||
|
||||
That duplicate pair is the tell, and it is reproducible without the emulator.
|
||||
|
||||
## The control I should have run first
|
||||
|
||||
Six channels, each a **different** tone, so any reorder, drop or duplication
|
||||
shows up as a wrong frequency. Played to the sink with `paplay`, recorded from
|
||||
its monitor with the same `parec` invocation the `ADV` capture used.
|
||||
|
||||
**Sink map `FL,FR,RL,RR,FC,LFE`, i.e. NOT the stream's map — the original setup:**
|
||||
|
||||
| channel | expected | captured | |
|
||||
|---|---|---|---|
|
||||
| 0 | 400 Hz | 400 Hz | ok |
|
||||
| 1 | 800 Hz | **3200 Hz** | wrong |
|
||||
| 2 | 200 Hz | 200 Hz | ok |
|
||||
| 3 | 1600 Hz | **800 Hz** | wrong |
|
||||
| 4 | 3200 Hz | **800 Hz** | wrong |
|
||||
| 5 | 6400 Hz | **200 Hz** | wrong |
|
||||
|
||||
`ch2 == ch5`, **byte-identical** — the same artefact the port found. The 6400 Hz
|
||||
and 1600 Hz channels are **gone entirely**, replaced by duplicates.
|
||||
|
||||
**Sink map made identical to Canary's own stream map**
|
||||
(`front-left,front-right,front-center,lfe,rear-left,rear-right`), and the same
|
||||
map given to `parec` explicitly:
|
||||
|
||||
| channel | expected | captured |
|
||||
|---|---|---|
|
||||
| 0–5 | 400 / 800 / 200 / 1600 / 3200 / 6400 | **400 / 800 / 200 / 1600 / 3200 / 6400** |
|
||||
|
||||
No duplicates. **CONTROL PASSED.**
|
||||
|
||||
## The rule
|
||||
|
||||
⚠️ **A null sink whose `channel_map` differs from the client's makes PulseAudio
|
||||
remap, and a 6-channel remap silently loses channels and duplicates others.**
|
||||
There is no error, no warning, and the WAV has the right length, the right
|
||||
channel count and plausible per-channel levels. Set the sink's map to the
|
||||
client's, and pass the same map to `parec`:
|
||||
|
||||
```bash
|
||||
MAP=front-left,front-right,front-center,lfe,rear-left,rear-right
|
||||
pactl load-module module-null-sink sink_name=cap channels=6 channel_map=$MAP
|
||||
parec -d cap.monitor --channels=6 --rate=48000 --format=s16le --channel-map=$MAP …
|
||||
```
|
||||
|
||||
## 🔴 What this withdraws
|
||||
|
||||
* **`adv-game-output-6ch.wav` is withdrawn as evidence.** Its channels are
|
||||
scrambled and one pair is a duplicate. Nothing should be concluded from it,
|
||||
in either direction — it is not evidence that the game emits something
|
||||
unexpected, and the port's inability to match it is fully explained.
|
||||
* **"All six channels carry signal"** — withdrawn. One of the six was a copy of
|
||||
another.
|
||||
* **"The surround and LFE channels are not zero, which a stereo guest padded
|
||||
into a 6-channel frame would give"** — withdrawn. It was offered as weak
|
||||
support for the 5.1 reading of a voice cue's three streams
|
||||
([`voice-three-streams-are-concurrent.md`](structures/voice-three-streams-are-concurrent.md)),
|
||||
and it is worth nothing. The port said a duplicated channel is not an
|
||||
independent one, and they were right before this control existed.
|
||||
|
||||
✅ **Unaffected:** the three-XMA-context concurrency result. That is read from
|
||||
the emulator's own log, not from the audio path, and it reproduced on two
|
||||
independent boots.
|
||||
|
||||
## The lesson, in the form it should have been applied
|
||||
|
||||
The corpus's own rule is *run your instrument through a control first*. Here the
|
||||
control needed no emulator, no disc and 30 seconds: **play a known signal through
|
||||
the capture chain and check that it comes back.** It was not run, an artefact was
|
||||
published, and the person who found the defect was the one who could not see the
|
||||
instrument. ⚠️ **A capture is an instrument, not just an output** — the same
|
||||
scrutiny a parser or an estimator gets.
|
||||
Reference in New Issue
Block a user