feat(icom): live microphone over the network — the last remote brick
The talk button learns the network road the voice keyer already took: when To-radio is the radio itself, the microphone is captured and re-framed into the rig's 320-sample packets, the capture callback serving as the clock — the mic delivers in real time, so no ring and no pacer. Counters and the frame remainder live on the audio stream, so a talk session spans calls. PTT keys before and releases after, through the same code as the USB path. With this, a network Icom is a complete remote station over three UDP ports: RX audio to the headset, live voice and recorded messages back, CW through the rig's keyer, CAT for everything else.
This commit is contained in:
@@ -10729,9 +10729,44 @@ func (a *App) AudioStartTX() error {
|
||||
if strings.TrimSpace(cfg.ToRadio) == "" {
|
||||
return fmt.Errorf(`no "To radio" device set — pick the rig's USB Audio CODEC output in Settings → Audio`)
|
||||
}
|
||||
// Live mic over the radio's own link: the To-radio "device" is the radio.
|
||||
// Fetched before keying so a missing stream refuses cleanly with the PTT
|
||||
// never touched.
|
||||
var netSend func([]byte) error
|
||||
if cfg.ToRadio == audio.NetworkDeviceID {
|
||||
if strings.TrimSpace(cfg.RecordingDevice) == "" {
|
||||
return fmt.Errorf("pick your microphone as the Recording mic in Settings → Audio")
|
||||
}
|
||||
type sender interface {
|
||||
TXAudioSender() (func([]byte) error, error)
|
||||
}
|
||||
err := a.cat.IcomDo(func(ic cat.IcomController) error {
|
||||
p, ok := ic.(sender)
|
||||
if !ok {
|
||||
return fmt.Errorf("this radio cannot take live microphone audio over its link yet")
|
||||
}
|
||||
fn, err := p.TXAudioSender()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
netSend = fn
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := a.pttKey(cfg); err != nil { // key first — no point streaming to a rig that isn't transmitting
|
||||
return err
|
||||
}
|
||||
if netSend != nil {
|
||||
if err := a.audioMgr.StartTXAudioNetwork(cfg.RecordingDevice, netSend); err != nil {
|
||||
a.pttUnkey()
|
||||
return err
|
||||
}
|
||||
applog.Printf("audio: TX start (mic=%q → the radio over the network, ptt=%q)", cfg.RecordingDevice, cfg.PTTMethod)
|
||||
return nil
|
||||
}
|
||||
if err := a.audioMgr.StartTXAudio(cfg.RecordingDevice, cfg.ToRadio); err != nil {
|
||||
a.pttUnkey()
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user