fix(icom): the audio stream no longer depends on the speakers
The sink — decode + recorder feed — was built only on the success path of starting the monitor, so speakers-off (the remembered preference) or an output device that failed to open silently disabled the WHOLE stream: the session connected audio=false, and a ticked RX-audio checkbox did nothing. The sink now exists whenever the stream is on; only the monitor obeys the speaker choice.
This commit is contained in:
@@ -15637,6 +15637,25 @@ func (a *App) reloadCAT() {
|
||||
// verification (see icomaudio.go) — hence experimental + opt-in.
|
||||
acfg, _ := a.GetAudioSettings()
|
||||
a.audioMgr.StopMonitor() // clear any prior monitor/sink so a re-save restarts cleanly
|
||||
// The SINK — decode + recorder feed — exists whenever the stream is
|
||||
// on. It used to be built only when the speakers were also wanted,
|
||||
// so "speakers off" (or a sink that failed to open) silently turned
|
||||
// the whole stream off: audio=false on the wire, no recordings, no
|
||||
// voice keyer, and a ticked RX-audio checkbox that did nothing.
|
||||
codec := audio.NewPCM16Codec()
|
||||
audioSink = func(payload []byte) {
|
||||
pcm, err := codec.Decode(payload)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
a.audioMgr.PushMonitorAudio(pcm)
|
||||
// And to the QSO recorder, which has no device to capture from
|
||||
// on this backend. It drops the samples unless a recording is
|
||||
// actually running, so this costs a function call when idle.
|
||||
if a.qsoRec != nil {
|
||||
a.qsoRec.PushRX(pcm)
|
||||
}
|
||||
}
|
||||
// Listening is a CHOICE, remembered: an operator sitting next to the
|
||||
// radio hears it in the room and wants the stream only for the
|
||||
// recorder and the voice keyer. Stop listening turns this off, the
|
||||
@@ -15645,36 +15664,8 @@ func (a *App) reloadCAT() {
|
||||
if a.settingOr(keyAudioMonitorOn, "1") != "1" {
|
||||
applog.Printf("icom-net audio: stream on, speakers off (Listening was stopped by the operator)")
|
||||
} else if err := a.audioMgr.StartMonitorSink(acfg.ListeningDevice); err != nil {
|
||||
applog.Printf("icom-net audio: cannot start output sink: %v", err)
|
||||
applog.Printf("icom-net audio: stream on, but the output sink failed: %v", err)
|
||||
} else {
|
||||
codec := audio.NewPCM16Codec()
|
||||
audioSink = func(payload []byte) {
|
||||
pcm, err := codec.Decode(payload)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// The IC-7760 streams TWO-channel LPCM whatever the conninfo
|
||||
// asks for (rxcodec 0x02 was requested, 1280-byte payloads
|
||||
// kept arriving — 320 stereo frames per 20 ms tick, right
|
||||
// channel all zeros). Played as mono that is half-speed
|
||||
// metallic garble. A stereo-sized packet is folded to its
|
||||
// left channel; a 640-byte mono packet (a rig that honours
|
||||
// the request) passes through untouched.
|
||||
if len(pcm) == 1280 {
|
||||
mono := make([]byte, len(pcm)/2)
|
||||
for i := 0; i+3 < len(pcm); i += 4 {
|
||||
mono[i/2], mono[i/2+1] = pcm[i], pcm[i+1]
|
||||
}
|
||||
pcm = mono
|
||||
}
|
||||
a.audioMgr.PushMonitorAudio(pcm)
|
||||
// And to the QSO recorder, which has no device to capture from
|
||||
// on this backend. It drops the samples unless a recording is
|
||||
// actually running, so this costs a function call when idle.
|
||||
if a.qsoRec != nil {
|
||||
a.qsoRec.PushRX(pcm)
|
||||
}
|
||||
}
|
||||
applog.Printf("icom-net audio: RX audio streaming ENABLED (experimental) → %q", acfg.ListeningDevice)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user