From fa52e7c1b74aaf07a9e446cf53bd0625decb9436 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 29 Sep 2018 22:19:41 -0700 Subject: [PATCH] Fix audio device error with PA renderer (and constify some methods) --- .../audio/renderers/portaudiorenderer.cpp | 40 +++++++++++++++---- .../audio/renderers/portaudiorenderer.h | 4 +- app/streaming/audio/renderers/renderer.h | 4 +- app/streaming/audio/renderers/sdl.h | 4 +- app/streaming/audio/renderers/sdlaud.cpp | 4 +- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/app/streaming/audio/renderers/portaudiorenderer.cpp b/app/streaming/audio/renderers/portaudiorenderer.cpp index abc057ce..076ef4b5 100644 --- a/app/streaming/audio/renderers/portaudiorenderer.cpp +++ b/app/streaming/audio/renderers/portaudiorenderer.cpp @@ -109,7 +109,7 @@ void PortAudioRenderer::submitAudio(short* audioBuffer, int audioSize) } } -bool PortAudioRenderer::testAudio(int audioConfiguration) +bool PortAudioRenderer::testAudio(int audioConfiguration) const { PaStreamParameters params = {}; @@ -120,6 +120,13 @@ bool PortAudioRenderer::testAudio(int audioConfiguration) return false; } + const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo(outputDeviceIndex); + if (deviceInfo == nullptr) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Pa_GetDeviceInfo() failed"); + return false; + } + switch (audioConfiguration) { case AUDIO_CONFIGURATION_STEREO: @@ -135,20 +142,37 @@ bool PortAudioRenderer::testAudio(int audioConfiguration) params.sampleFormat = paInt16; params.device = outputDeviceIndex; + params.suggestedLatency = deviceInfo->defaultLowOutputLatency; - PaError error = Pa_IsFormatSupported(nullptr, ¶ms, 48000); - if (error == paFormatIsSupported) { - return true; - } - else { + // We used to just use Pa_IsFormatSupported() but there are cases + // where Pa_IsFormatSupported() will fail but when we actually + // call Pa_OpenStream(), it fails with device unavailable. + PaStream* stream; + PaError error = Pa_OpenStream(&stream, nullptr, ¶ms, + 48000, + SAMPLES_PER_FRAME, + paNoFlag, + nullptr, nullptr); + if (error != paNoError) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Pa_IsFormatSupported() failed: %s", + "Pa_OpenStream() failed: %s", Pa_GetErrorText(error)); return false; } + + error = Pa_StartStream(m_Stream); + if (error != paNoError) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Pa_StartStream() failed: %s", + Pa_GetErrorText(error)); + } + + Pa_CloseStream(stream); + + return error == paNoError; } -int PortAudioRenderer::detectAudioConfiguration() +int PortAudioRenderer::detectAudioConfiguration() const { const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice()); if (deviceInfo == nullptr) { diff --git a/app/streaming/audio/renderers/portaudiorenderer.h b/app/streaming/audio/renderers/portaudiorenderer.h index 8c203329..d1a08b2e 100644 --- a/app/streaming/audio/renderers/portaudiorenderer.h +++ b/app/streaming/audio/renderers/portaudiorenderer.h @@ -20,9 +20,9 @@ public: virtual void submitAudio(short* audioBuffer, int audioSize); - virtual bool testAudio(int audioConfiguration); + virtual bool testAudio(int audioConfiguration) const; - virtual int detectAudioConfiguration(); + virtual int detectAudioConfiguration() const; static int paStreamCallback(const void *input, void *output, diff --git a/app/streaming/audio/renderers/renderer.h b/app/streaming/audio/renderers/renderer.h index 95bc7f40..e67687e2 100644 --- a/app/streaming/audio/renderers/renderer.h +++ b/app/streaming/audio/renderers/renderer.h @@ -14,7 +14,7 @@ public: virtual void submitAudio(short* audioBuffer, int audioSize) = 0; - virtual bool testAudio(int audioConfiguration) = 0; + virtual bool testAudio(int audioConfiguration) const = 0; - virtual int detectAudioConfiguration() = 0; + virtual int detectAudioConfiguration() const = 0; }; diff --git a/app/streaming/audio/renderers/sdl.h b/app/streaming/audio/renderers/sdl.h index b210a4c2..1d22e9ff 100644 --- a/app/streaming/audio/renderers/sdl.h +++ b/app/streaming/audio/renderers/sdl.h @@ -19,9 +19,9 @@ public: virtual void submitAudio(short* audioBuffer, int audioSize); - virtual bool testAudio(int audioConfiguration); + virtual bool testAudio(int audioConfiguration) const; - virtual int detectAudioConfiguration(); + virtual int detectAudioConfiguration() const; private: SDL_AudioDeviceID m_AudioDevice; diff --git a/app/streaming/audio/renderers/sdlaud.cpp b/app/streaming/audio/renderers/sdlaud.cpp index e7f505f0..dc888c80 100644 --- a/app/streaming/audio/renderers/sdlaud.cpp +++ b/app/streaming/audio/renderers/sdlaud.cpp @@ -13,7 +13,7 @@ // This isn't accurate on macOS and Linux (PulseAudio), // since they both report supporting a large number of // channels, regardless of the actual output device. -int SdlAudioRenderer::detectAudioConfiguration() +int SdlAudioRenderer::detectAudioConfiguration() const { SDL_AudioSpec want, have; SDL_AudioDeviceID dev; @@ -51,7 +51,7 @@ int SdlAudioRenderer::detectAudioConfiguration() } } -bool SdlAudioRenderer::testAudio(int audioConfiguration) +bool SdlAudioRenderer::testAudio(int audioConfiguration) const { SDL_AudioSpec want, have; SDL_AudioDeviceID dev;