diff --git a/internal/audio/devices.go b/internal/audio/devices.go index 611ffee..f7d9cef 100644 --- a/internal/audio/devices.go +++ b/internal/audio/devices.go @@ -101,3 +101,30 @@ func endpointName(dev *wca.IMMDevice, fallback string) string { } return fallback } + +// DeviceName resolves an endpoint id to its friendly name. +// +// Diagnostics quote the id that was CONFIGURED, which is a GUID — an operator +// told "no audio at all from {0.0.1.00000000}.{6a27abfd…}" learns nothing they +// can act on, while "no audio at all from DAX RX 1 (FlexRadio DAX)" points +// straight at the DAX panel. +// +// Falls back to the id when the endpoint cannot be found, which is itself worth +// seeing: a device that has disappeared explains an empty recording too. +func DeviceName(id string) string { + if id == "" { + return "(none)" + } + for _, list := range []func() ([]Device, error){ListInputDevices, ListOutputDevices} { + devs, err := list() + if err != nil { + continue + } + for _, d := range devs { + if d.ID == id { + return d.Name + } + } + } + return id +} diff --git a/internal/audio/recorder.go b/internal/audio/recorder.go index 3c52d85..402af36 100644 --- a/internal/audio/recorder.go +++ b/internal/audio/recorder.go @@ -155,7 +155,7 @@ func (r *Recorder) Start(fromDev, micDev string, prerollSec int) error { r.lastA = time.Now() r.srcMu.Unlock() }); err != nil { - LogSink("recorder: capture from %q failed: %v", fromDev, err) + LogSink("recorder: capture from %q failed: %v", DeviceName(fromDev), err) } }() if twoSrc { @@ -170,7 +170,7 @@ func (r *Recorder) Start(fromDev, micDev string, prerollSec int) error { r.lastB = time.Now() r.srcMu.Unlock() }); err != nil { - LogSink("recorder: capture from %q failed: %v", micDev, err) + LogSink("recorder: capture from %q failed: %v", DeviceName(micDev), err) } }() } @@ -193,11 +193,11 @@ func (r *Recorder) Start(fromDev, micDev string, prerollSec int) error { aQuiet, bQuiet := r.lastA.IsZero(), r.lastB.IsZero() r.srcMu.Unlock() if aQuiet { - LogSink("recorder: no audio at all from %q after 3 s — the device opened but nothing is streaming", fromDev) - AlertSink("No audio from %s — nothing is being recorded", fromDev) + LogSink("recorder: no audio at all from %q after 3 s — the device opened but nothing is streaming", DeviceName(fromDev)) + AlertSink("No audio from %s — nothing is being recorded", DeviceName(fromDev)) } if twoSrc && bQuiet { - LogSink("recorder: no audio at all from %q after 3 s — the device opened but nothing is streaming", micDev) + LogSink("recorder: no audio at all from %q after 3 s — the device opened but nothing is streaming", DeviceName(micDev)) } }() diff --git a/internal/audio/wav.go b/internal/audio/wav.go index ee318cf..0a8953d 100644 --- a/internal/audio/wav.go +++ b/internal/audio/wav.go @@ -33,13 +33,13 @@ func writeWAV(path string, pcm []byte) error { put(uint32(36 + dataLen)) f.WriteString("WAVE") f.WriteString("fmt ") - put(uint32(16)) // PCM fmt chunk size - put(uint16(1)) // WAVE_FORMAT_PCM - put(uint16(channels)) // - put(uint32(sampleRate)) // - put(uint32(bytesPerSec)) // byte rate - put(uint16(blockAlign)) // - put(uint16(bitsPerSample)) // + put(uint32(16)) // PCM fmt chunk size + put(uint16(1)) // WAVE_FORMAT_PCM + put(uint16(channels)) // + put(uint32(sampleRate)) // + put(uint32(bytesPerSec)) // byte rate + put(uint16(blockAlign)) // + put(uint16(bitsPerSample)) // f.WriteString("data") put(uint32(dataLen)) _, err = f.Write(pcm)