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:
+13
-17
@@ -260,11 +260,14 @@ func (a *icomAudio) PlayTX(pcm []byte, rate, ch, bits int, stop <-chan struct{})
|
|||||||
if rate > 0 && rate != 16000 {
|
if rate > 0 && rate != 16000 {
|
||||||
mono = resampleLinear(mono, 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
|
const frame = 320 // samples per packet: 20 ms at 16 kHz, the rig's own cadence
|
||||||
tick := time.NewTicker(20 * time.Millisecond)
|
tick := time.NewTicker(20 * time.Millisecond)
|
||||||
defer tick.Stop()
|
defer tick.Stop()
|
||||||
var outerSeq uint16 = 1
|
buf := make([]byte, frame*2)
|
||||||
var sendSeq uint16
|
|
||||||
for pos := 0; pos < len(mono); pos += frame {
|
for pos := 0; pos < len(mono); pos += frame {
|
||||||
select {
|
select {
|
||||||
case <-stop:
|
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")
|
return fmt.Errorf("the audio stream closed mid-message")
|
||||||
case <-tick.C:
|
case <-tick.C:
|
||||||
}
|
}
|
||||||
pkt := make([]byte, 0x18+frame*2)
|
for i := 0; i < frame; i++ {
|
||||||
icnLE.PutUint32(pkt[0:], uint32(len(pkt)))
|
var v float32
|
||||||
icnLE.PutUint16(pkt[6:], outerSeq)
|
if pos+i < len(mono) {
|
||||||
icnLE.PutUint32(pkt[8:], a.aID)
|
v = mono[pos+i] * 32767
|
||||||
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
|
|
||||||
if v > 32767 {
|
if v > 32767 {
|
||||||
v = 32767
|
v = 32767
|
||||||
} else if v < -32768 {
|
} else if v < -32768 {
|
||||||
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 {
|
if err := a.SendTXChunk(buf); err != nil {
|
||||||
return fmt.Errorf("sending audio to the rig: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
outerSeq++
|
|
||||||
sendSeq++
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user