package audio import ( "context" "fmt" "time" ) // Check verifies that the sink name is ready without producing sound: null // is always ready; oto initializes the audio context (default format 44.1 // kHz stereo 16 bit) and waits for it to become ready, so "no audio device" // (servers, containers, missing PulseAudio/ALSA library) shows up in // `talk doctor` rather than at the first announcement. func Check(ctx context.Context, name string) error { switch name { case NameNull: return nil case NameOto: c, err := contextFor(pcmFormat{SampleRate: 44100, Channels: 2, BitsPerCoded: 16}) if err != nil { return err } select { case <-c.ready: if err := c.ctx.Err(); err != nil { return fmt.Errorf("oto: initialization failed: %w", err) } return nil case <-ctx.Done(): return fmt.Errorf("oto: audio device not responding (%v)", ctx.Err()) case <-time.After(5 * time.Second): return fmt.Errorf("oto: audio device not responding within 5 s") } default: return fmt.Errorf("unknown audio sink %q (allowed: %q, %q)", name, NameOto, NameNull) } }