feat(tci): read the radio's declared format, and record a test WAV

The SunSDR announces its own stream at connect —
audio_stream_sample_type:float32 and audio_stream_channels:2 — and both
were being logged as unhandled while the code worked the format out from
frame arithmetic. The declaration is better evidence and arrives before
the first frame; the arithmetic stays as the check on it. The channel
count now drives the mix-down instead of an assumed stereo.

Adds a ten-second test recording, written as a WAV beside the QSO
recordings. Counting frames proves a socket is delivering bytes; it says
nothing about whether those bytes are the receiver's audio, at the right
rate, in the right order. A stream decoded with the width wrong or the
samples misaligned counts exactly as well as a correct one and sounds
like a fan — so the test is a file the operator can play, the same way
the CW decoder was settled on the air rather than on a spectrogram.

The file is written at the rate the RADIO reported, not a constant: a
recording at the wrong rate plays at the wrong speed, which is the one
fault that would be blamed on the decoding.
This commit is contained in:
2026-08-25 08:25:29 +02:00
parent 9b8168370f
commit 01a23ccb77
7 changed files with 247 additions and 6 deletions
+2
View File
@@ -905,6 +905,8 @@ export function RecomputeAllAwardRefs():Promise<number>;
export function RecomputeAwardRefsForCode(arg1:string):Promise<number>;
export function RecordTCIAudio(arg1:number):Promise<string>;
export function RefreshCtyDat():Promise<main.CtyDatInfo>;
export function RefreshKenwood():Promise<void>;
+4
View File
@@ -1750,6 +1750,10 @@ export function RecomputeAwardRefsForCode(arg1) {
return window['go']['main']['App']['RecomputeAwardRefsForCode'](arg1);
}
export function RecordTCIAudio(arg1) {
return window['go']['main']['App']['RecordTCIAudio'](arg1);
}
export function RefreshCtyDat() {
return window['go']['main']['App']['RefreshCtyDat']();
}