Respect OpenAL capture availability

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-09 12:57:26 -04:00
committed by Brandon McGinty
parent db31ba33de
commit 4914182812
+21 -6
View File
@@ -103,12 +103,15 @@ func New(client *gumble.Client, inputDevice *string, outputDevice *string, test
inputFormat := openal.FormatStereo16
sourceChannels := 2
idev := openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, inputFormat, uint32(frmsz))
// Keep several frames in the capture ring so normal scheduler jitter does
// not overflow a PipeWire/Pulse capture stream.
captureBufferSize := uint32(frmsz * 4)
idev := openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, inputFormat, captureBufferSize)
if idev == nil {
log.Info("OpenAL capture: stereo failed, trying mono")
inputFormat = openal.FormatMono16
sourceChannels = 1
idev = openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, inputFormat, uint32(frmsz))
idev = openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, inputFormat, captureBufferSize)
}
if idev == nil {
log.Error("OpenAL capture: failed to open device %q", devName)
@@ -618,19 +621,26 @@ func (s *Stream) sourceRoutine(inputDevice *string) {
devName = *inputDevice
}
reopened := false
if frameSize != s.sourceFrameSize {
s.deviceSource.CaptureCloseDevice()
reopened = true
s.sourceFrameSize = frameSize
s.deviceSource = openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, s.sourceFormat, uint32(s.sourceFrameSize))
captureBufferSize := uint32(s.sourceFrameSize * 4)
s.deviceSource = openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, s.sourceFormat, captureBufferSize)
if s.deviceSource == nil && s.sourceFormat == openal.FormatStereo16 {
s.sourceFormat = openal.FormatMono16
s.sourceChannels = 1
s.deviceSource = openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, s.sourceFormat, uint32(s.sourceFrameSize))
s.deviceSource = openal.CaptureOpenDevice(devName, gumble.AudioSampleRate, s.sourceFormat, captureBufferSize)
}
}
if s.deviceSource == nil {
return
}
// Reopening after an interval change creates a stopped capture device.
if reopened {
s.deviceSource.CaptureStart()
}
ticker := time.NewTicker(interval)
defer ticker.Stop()
@@ -649,9 +659,14 @@ func (s *Stream) sourceRoutine(inputDevice *string) {
sampleCount := frameSize * s.sourceChannels
int16Buffer := make([]int16, sampleCount)
// Capture microphone if available
// alcCaptureSamples requires the requested frames to already be
// available. PipeWire and PulseAudio do not guarantee that a Go
// ticker fires precisely on a capture-frame boundary.
hasMicInput := false
buff := s.deviceSource.CaptureSamples(uint32(frameSize))
var buff []byte
if s.deviceSource.CapturedSamples() >= uint32(frameSize) {
buff = s.deviceSource.CaptureSamples(uint32(frameSize))
}
if len(buff) == sampleCount*2 {
hasMicInput = true
if micFailed {