Add context to remaining OpenAL device errors
This commit is contained in:
1 parent
0712e3150c
commit
21e0627509
2 files changed
+34
-21
No files matched your search
@@ -70,14 +70,16 @@ type Stream struct {
|
|||||||
client *gumble.Client
|
client *gumble.Client
|
||||||
link gumble.Detacher
|
link gumble.Detacher
|
||||||
|
|
||||||
deviceSource *openal.CaptureDevice
|
deviceSource *openal.CaptureDevice
|
||||||
sourceFormat openal.Format
|
inputDeviceName string
|
||||||
sourceChannels int
|
outputDeviceName string
|
||||||
sourceFrameSize int
|
sourceFormat openal.Format
|
||||||
micVolume atomic.Uint32 // float32 stored as bits
|
sourceChannels int
|
||||||
sourceMu sync.Mutex
|
sourceFrameSize int
|
||||||
sourceStop chan bool
|
micVolume atomic.Uint32 // float32 stored as bits
|
||||||
sourceDone chan struct{}
|
sourceMu sync.Mutex
|
||||||
|
sourceStop chan bool
|
||||||
|
sourceDone chan struct{}
|
||||||
|
|
||||||
deviceSink *openal.Device
|
deviceSink *openal.Device
|
||||||
contextSink *openal.Context
|
contextSink *openal.Context
|
||||||
@@ -154,11 +156,13 @@ func New(client *gumble.Client, inputDevice *string, outputDevice *string, test
|
|||||||
}
|
}
|
||||||
|
|
||||||
s := &Stream{
|
s := &Stream{
|
||||||
client: client,
|
client: client,
|
||||||
sourceFormat: inputFormat,
|
inputDeviceName: devName,
|
||||||
sourceChannels: sourceChannels,
|
outputDeviceName: outName,
|
||||||
sourceFrameSize: frmsz,
|
sourceFormat: inputFormat,
|
||||||
micAGC: audio.NewAGC(), // Always enable AGC for outgoing mic
|
sourceChannels: sourceChannels,
|
||||||
|
sourceFrameSize: frmsz,
|
||||||
|
micAGC: audio.NewAGC(), // Always enable AGC for outgoing mic
|
||||||
}
|
}
|
||||||
s.micVolume.Store(math.Float32bits(1.0))
|
s.micVolume.Store(math.Float32bits(1.0))
|
||||||
if sourceChannels == 2 {
|
if sourceChannels == 2 {
|
||||||
@@ -167,21 +171,21 @@ func New(client *gumble.Client, inputDevice *string, outputDevice *string, test
|
|||||||
|
|
||||||
s.deviceSource = idev
|
s.deviceSource = idev
|
||||||
if s.deviceSource == nil {
|
if s.deviceSource == nil {
|
||||||
return nil, ErrInputDevice
|
return nil, fmt.Errorf("%w: capture device %q is unavailable", ErrInputDevice, deviceName(devName))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.deviceSink = odev
|
s.deviceSink = odev
|
||||||
if s.deviceSink == nil {
|
if s.deviceSink == nil {
|
||||||
return nil, ErrOutputDevice
|
return nil, fmt.Errorf("%w: playback device %q is unavailable", ErrOutputDevice, deviceName(outName))
|
||||||
}
|
}
|
||||||
s.contextSink = s.deviceSink.CreateContext()
|
s.contextSink = s.deviceSink.CreateContext()
|
||||||
if s.contextSink == nil {
|
if s.contextSink == nil {
|
||||||
err := s.deviceSink.Err()
|
err := s.deviceSink.Err()
|
||||||
s.Destroy()
|
s.Destroy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w: %v", ErrOutputDevice, err)
|
return nil, fmt.Errorf("%w: creating context for playback device %q: %v", ErrOutputDevice, deviceName(outName), err)
|
||||||
}
|
}
|
||||||
return nil, ErrOutputDevice
|
return nil, fmt.Errorf("%w: could not create context for playback device %q", ErrOutputDevice, deviceName(outName))
|
||||||
}
|
}
|
||||||
// OpenAL contexts are current to an OS thread. Move ownership to one
|
// OpenAL contexts are current to an OS thread. Move ownership to one
|
||||||
// dedicated render thread before any source or buffer is created.
|
// dedicated render thread before any source or buffer is created.
|
||||||
@@ -360,11 +364,11 @@ func (s *Stream) StartSource(inputDevice *string) error {
|
|||||||
return ErrState
|
return ErrState
|
||||||
}
|
}
|
||||||
if s.deviceSource == nil {
|
if s.deviceSource == nil {
|
||||||
return ErrMic
|
return fmt.Errorf("%w: capture device %q is unavailable", ErrMic, deviceName(s.inputDeviceName))
|
||||||
}
|
}
|
||||||
s.deviceSource.CaptureStart()
|
s.deviceSource.CaptureStart()
|
||||||
if err := s.deviceSource.Err(); err != nil {
|
if err := s.deviceSource.Err(); err != nil {
|
||||||
return fmt.Errorf("%w: %v", ErrMic, err)
|
return fmt.Errorf("%w: starting capture device %q: %v", ErrMic, deviceName(s.inputDeviceName), err)
|
||||||
}
|
}
|
||||||
stop := make(chan bool)
|
stop := make(chan bool)
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
@@ -386,11 +390,11 @@ func (s *Stream) StopSource() error {
|
|||||||
// The routine owns capture access; wait for it before closing/reusing it.
|
// The routine owns capture access; wait for it before closing/reusing it.
|
||||||
<-done
|
<-done
|
||||||
if s.deviceSource == nil {
|
if s.deviceSource == nil {
|
||||||
return ErrMic
|
return fmt.Errorf("%w: capture device %q is unavailable", ErrMic, deviceName(s.inputDeviceName))
|
||||||
}
|
}
|
||||||
s.deviceSource.CaptureStop()
|
s.deviceSource.CaptureStop()
|
||||||
if err := s.deviceSource.Err(); err != nil {
|
if err := s.deviceSource.Err(); err != nil {
|
||||||
return fmt.Errorf("%w: %v", ErrMic, err)
|
return fmt.Errorf("%w: stopping capture device %q: %v", ErrMic, deviceName(s.inputDeviceName), err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,15 @@ func TestDeviceOpenErrorsIncludeConfiguredDevice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regression: later capture start failures also omitted the configured device.
|
||||||
|
func TestStartSourceUnavailableDeviceIncludesName(t *testing.T) {
|
||||||
|
s := &Stream{inputDeviceName: "virtual_mic.monitor"}
|
||||||
|
err := s.StartSource(nil)
|
||||||
|
if !errors.Is(err, ErrMic) || !strings.Contains(err.Error(), "virtual_mic.monitor") {
|
||||||
|
t.Fatalf("start error %q", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStopSourceWaitsForWorker(t *testing.T) {
|
func TestStopSourceWaitsForWorker(t *testing.T) {
|
||||||
stop, done := make(chan bool), make(chan struct{})
|
stop, done := make(chan bool), make(chan struct{})
|
||||||
s := &Stream{sourceStop: stop, sourceDone: done}
|
s := &Stream{sourceStop: stop, sourceDone: done}
|
||||||
|
|||||||
Reference in new issue
Block a user