fix(icom): one sequence space for everything sent on the audio stream

The voice keyer and the live microphone each numbered their packets from 1.
A message played after a talk session re-used sequence numbers the rig had
already seen and was discarded wholesale: the PTT keyed for the full length
of the message and none of it was modulated. PlayTX now feeds the same framer
and counters as the microphone.
This commit is contained in:
2026-08-30 02:25:37 +02:00
parent dbc97ad61b
commit 7de7cb96c3
+13 -17
View File
@@ -260,11 +260,14 @@ func (a *icomAudio) PlayTX(pcm []byte, rate, ch, bits int, stop <-chan struct{})
if rate > 0 && rate != 16000 {
mono = resampleLinear(mono, rate, 16000)
}
// Through the SAME framer and counters as the live microphone. Each of the
// two used to number its own packets from 1, and a voice-keyer message sent
// after a talk session re-used sequence numbers the rig had already seen —
// it keyed for the full length of the message and modulated none of it.
const frame = 320 // samples per packet: 20 ms at 16 kHz, the rig's own cadence
tick := time.NewTicker(20 * time.Millisecond)
defer tick.Stop()
var outerSeq uint16 = 1
var sendSeq uint16
buf := make([]byte, frame*2)
for pos := 0; pos < len(mono); pos += frame {
select {
case <-stop:
@@ -273,28 +276,21 @@ func (a *icomAudio) PlayTX(pcm []byte, rate, ch, bits int, stop <-chan struct{})
return fmt.Errorf("the audio stream closed mid-message")
case <-tick.C:
}
pkt := make([]byte, 0x18+frame*2)
icnLE.PutUint32(pkt[0:], uint32(len(pkt)))
icnLE.PutUint16(pkt[6:], outerSeq)
icnLE.PutUint32(pkt[8:], a.aID)
icnLE.PutUint32(pkt[12:], a.aRemote)
pkt[0x10], pkt[0x11] = 0x81, 0x01
icnBE.PutUint16(pkt[0x12:], sendSeq)
icnBE.PutUint32(pkt[0x14:], frame*2)
for i := 0; i < frame && pos+i < len(mono); i++ {
v := mono[pos+i] * 32767
for i := 0; i < frame; i++ {
var v float32
if pos+i < len(mono) {
v = mono[pos+i] * 32767
}
if v > 32767 {
v = 32767
} else if v < -32768 {
v = -32768
}
icnLE.PutUint16(pkt[0x18+i*2:], uint16(int16(v)))
icnLE.PutUint16(buf[i*2:], uint16(int16(v)))
}
if _, err := a.conn.Write(pkt); err != nil {
return fmt.Errorf("sending audio to the rig: %w", err)
if err := a.SendTXChunk(buf); err != nil {
return err
}
outerSeq++
sendSeq++
}
return nil
}