37 lines
1.1 KiB
Go
37 lines
1.1 KiB
Go
package audio
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Check prüft, ob der Sink name einsatzbereit ist, ohne Ton zu erzeugen:
|
||
|
|
// null ist immer bereit; oto initialisiert den Audio-Kontext (Standard-
|
||
|
|
// Format 44,1 kHz Stereo 16 Bit) und wartet auf dessen Bereitschaft — so
|
||
|
|
// fällt „kein Audiogerät" (Server, Container, fehlende PulseAudio/ALSA-
|
||
|
|
// Bibliothek) in `talk doctor` auf, nicht erst bei der ersten Ansage.
|
||
|
|
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: Initialisierung fehlgeschlagen: %w", err)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
case <-ctx.Done():
|
||
|
|
return fmt.Errorf("oto: Audio-Gerät antwortet nicht (%v)", ctx.Err())
|
||
|
|
case <-time.After(5 * time.Second):
|
||
|
|
return fmt.Errorf("oto: Audio-Gerät antwortet nicht binnen 5 s")
|
||
|
|
}
|
||
|
|
default:
|
||
|
|
return fmt.Errorf("unbekannter audio sink %q (erlaubt: %q, %q)", name, NameOto, NameNull)
|
||
|
|
}
|
||
|
|
}
|