diff --git a/internal/cat/tci_audio.go b/internal/cat/tci_audio.go index 882ee39..844ebf4 100644 --- a/internal/cat/tci_audio.go +++ b/internal/cat/tci_audio.go @@ -81,8 +81,8 @@ type tciAudio struct { samples int64 peak float64 peakAt time.Time - probe int - lastErr string + probeByType map[int]int + lastErr string // widthLogged keeps the one-line note about the sample width to once a // session — it is a fact about the radio, not an event. widthLogged bool @@ -110,7 +110,6 @@ func (t *TCI) StartTCIAudio(rx, rate int) error { t.audio.rx = rx t.audio.rate = rate t.audio.frames, t.audio.samples, t.audio.peak = 0, 0, 0 - t.audio.probe = 0 t.audio.lastErr = "" t.audio.mu.Unlock() @@ -182,10 +181,20 @@ func (t *TCI) handleBinary(data []byte) { length := int(le.Uint32(data[20:])) stype := int(le.Uint32(data[24:])) + // Counted PER STREAM TYPE, not overall. + // + // A single counter was spent on the first forty receive-audio frames, which + // arrive twenty-four times a second — so a transmit-chrono or transmit-audio + // frame, the two this needs to see before the voice keyer can be written, + // would never have been logged at all. They only appear once the operator + // keys the radio, long after any global budget is gone. t.audio.mu.Lock() - probe := t.audio.probe + if t.audio.probeByType == nil { + t.audio.probeByType = map[int]int{} + } + probe := t.audio.probeByType[stype] if probe < tciAudioProbeMax { - t.audio.probe++ + t.audio.probeByType[stype]++ } t.audio.mu.Unlock() if probe < tciAudioProbeMax { @@ -194,7 +203,11 @@ func (t *TCI) handleBinary(data []byte) { } if stype != tciStreamRXAudio { - return // IQ, TX audio echo, chrono: not this file's business yet + // IQ, transmit audio, chrono. Nothing consumes them yet — but the chrono + // frames are what a voice keyer over TCI would have to answer, and their + // size and cadence cannot be guessed from the documentation. They are + // logged (per type, see above) and dropped. + return } if codec != 0 { t.audioErr(fmt.Sprintf("stream is codec=%d, and nothing here decodes a compressed stream", codec))