Best case yet for the microphone. Never looks at the CPU.
Qwen3.8 Max writes the clearest microphone argument of the seven audits. The monitor’s own 0xE0=0xC9 sets the bit HRC6000SetMic() uses, undoing the stock Turn off Microphone input, and the stream it reads is the buffer the stock firmware fills from the microphone. It makes settling that question step one, with a stop rule: if the capture tracks the microphone, stop working on the codec path and tap the discriminator instead. It is also the only audit to check the decoder against a reference itself: the IMBE interleave, the C4FM sync and the trellis transition matrix all match DSD byte for byte.
Then it clears the wrong thing. The Phase-1 bit-level decoder is not the problem covers IMBE synthesis, which needs 11–16 times the 72 MHz CPU; the review never looks at CPU at all. It calls the 24 kHz capture far too low for C4FM, though that is five samples per symbol and the firmware resamples to 38.4 kHz with no frames lost, and it trusts a capture tool that exports the wrong halfwords. 21 of 27 claims hold. It finds two of the four decode-critical issues and reports nothing about the instruments, which puts it at D.
Claims that check out
21 / 27
4 overstated or doubtful · 2 wrong
Decode-critical issues found
2 of 4
misses the 8 kHz rule; clears the decoder
CPU the vocoder needs
11–16×
of 72 MHz; it calls the decode chain correct
Frames lost to the resampler
0 of 180
the 24 kHz rate it calls far too low
ConditionsClean room: a fresh copy of the repository (46eebda with its uncommitted changes, its own docs and the HR-C6000 manual) with no earlier reviews, reviewed by one model through an isolated agent harness with no network, skills or memory.
The run, not graded5 h 10 min · 71 agent steps · 111 tool calls · 598K output tokens · Alibaba Cloud Token Plan · interactive
Read the full review audit
Every claim, every rerun and the modelling behind this grade, as published.
Weights reflect the question asked: find what stops P25 decoding and say how to fix it. Accuracy carries the most weight because a wrong review does harm; coverage and root cause together outweigh it because an accurate review of the wrong things does not help.
Where the points went
The 100-point grade split into the rubric’s weighted slots: filled is earned, empty is lost, with the other models on this task for scale.
1Accuracy2Coverage3Root cause4Fix plan56
UNIONALPHA
74/ 100
Grok 4.6
70/ 100
Muse Spark 1.3 Contributor
68/ 100
DeepSeek V4.1 Flash
66/ 100
Qwen3.8 Max
63/ 100
Qwen3.8 Flash
59/ 100
GLM 5.3 Flash
56/ 100
1Accuracy & evidence30 pts
2Coverage of decode problems25 pts
3Root cause & prioritisation15 pts
4Fix plan & acceptance gates15 pts
5Originality & attribution10 pts
6Clarity & calibration5 pts
Accuracy & evidence30% of the grade
7021.0 pts
21 of 27 claims hold, and its own cross-checks against DSD hold up: the IMBE interleave, the sync and the trellis matrix all match. Two are wrong and both steer the work: the decode chain “is not the problem”, and 24 kHz is “far too low for C4FM”.
Coverage of decode problems25% of the grade
399.8 pts
Finds the microphone evidence and the de-emphasis that sits in front of the capture, keeps the one-layer symbol path and the discriminator tap as real options, and is accurate on Phase 2. It reports nothing about the instruments — the capture, the parser, starvation, memory, epochs and the tick budget — and misses the 8 kHz rule and the vocoder wall.
Root cause & prioritisation15% of the grade
7110.7 pts
Names the sample source as the root cause, puts the experiment that settles it first and writes the branch to abandon the codec path if it answers microphone. But it clears the decoder without measuring it and puts the sample rate second, where the filters belong.
Fix plan & acceptance gates15% of the grade
7110.7 pts
Ordered around the decisive question, with a stop rule, the exact de-emphasis change, the one-layer probe, hrc6000Task suspension and a replay fixture from real capture. It rests step one on a capture tool that exports the wrong samples, and never reaches the vocoder.
Originality & attribution10% of the grade
666.6 pts
Its own reference cross-checks and the stop-rule branch are real additions, and it credits the bring-up notes and stock report it leans on. Most of the rest restates those documents, and the microphone case was made first by Grok 4.6.
Clarity & calibration5% of the grade
783.9 pts
Short, ordered and readable, with a summary table and an honest scope line, and it separates what it executed from what it inferred. Two of its confident statements are wrong.
Weighted total 63, grade D. Grade scale: A ≥ 90 · B 80–89 · C+ 75–79 · C 70–74 · C− 65–69 · D 50–64 · F < 50
Headline findings
Six things to know about this review
Holds up
The clearest microphone case of the seven
The monitor writes 0xE0=0xC9, which sets the bit HRC6000SetMic() toggles, immediately after the stock FM setup wrote 0x89, commented “Turn off Microphone input”. The buffer it reads is the one the stock firmware fills from the microphone, labelled “only use the Left Channel of the Mic Audio”. The manual frames I2S as external-codec and vocoder plumbing and ends FM receive at the speaker, and the stock-firmware analysis found no discriminator route either. The review credits both.
Most audits take the test suite’s word for the decoder. This one compared the tables: the IMBE interleave iW/iX/iY/iZ, the C4FM sync and its inverse, and the trellis dibit-transition matrix all match the bundled DSD sources byte for byte. I reran those comparisons and they hold, including the trellis table the project’s own test re-implements rather than checks. Its build and host-suite results match the baseline too.
It answers the decisive question first, and says when to give up
Step one is the RF-versus-microphone capture contrast with a written branch: if the stream tracks the microphone, stop working on the codec I2S path and go to the discriminator tap. No other audit states the abandon condition. It also proposes the chip’s one-layer mode as a symbol source, the documented hrc6000Task suspension, and a real C4FM capture kept as a replay fixture so the decoder is finally tested against something other than its own generator.
“The Phase-1 bit-level decoder is not the problem … the sync/NID/framing/FEC/IMBE path is correct and well tested.” The bit-level parts are correct, and it proved several of them. IMBE synthesis is in that same path, and emulated it needs 11–16 times the radio’s 72 MHz CPU: 134–458 ms for one voiced 20 ms frame. The review never measures CPU, never mentions the 72 MHz clock, and its plan never reaches the vocoder.
Its second problem is that 24 kHz is “far too low for C4FM”, “the bare minimum that clears Nyquist”, with “almost no margin for the ±3600 Hz C4FM spectrum”. C4FM at 4800 symbols per second occupies under 2.88 kHz of baseband at ±1.8 kHz deviation, 24 kHz is five samples per symbol, and the firmware resamples to 38.4 kHz before the matched filter. In the model that resampled path decodes exactly the frames the direct path does. The rate is not the blocker; the de-emphasis it names next is.
Its first step depends on the c capture and tools/p25_capture.py, which it calls “already validated”. The capture exports the first 80 interleaved halfwords of each row instead of the decoder’s left-channel samples, so 158 of 160 positions differ, and the parser passes streams missing their first or last chunk. It is also the only audit to report nothing about the tooling at all: no starvation counter, no memory budget, no capture epochs, no ring-and-tick arithmetic.
The audits track 4 issues that stop this radio decoding P25. This review: misses the 8 kHz rule; clears the decoder. How the review treated each, from the provenance table: