diff --git a/app/streaming/audio.cpp b/app/streaming/audio.cpp index 325eb1b6..dd2958ab 100644 --- a/app/streaming/audio.cpp +++ b/app/streaming/audio.cpp @@ -70,6 +70,60 @@ Exit: return ret; } +bool Session::testAudio(int audioConfiguration) +{ + SDL_AudioSpec want, have; + SDL_AudioDeviceID dev; + bool ret; + + if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Audio test - SDL_InitSubSystem(SDL_INIT_AUDIO) failed: %s", + SDL_GetError()); + return false; + } + + SDL_zero(want); + want.freq = 48000; + want.format = AUDIO_S16; + want.samples = SAMPLES_PER_FRAME; + + switch (audioConfiguration) { + case AUDIO_CONFIGURATION_STEREO: + want.channels = 2; + break; + case AUDIO_CONFIGURATION_51_SURROUND: + want.channels = 6; + break; + default: + SDL_assert(false); + ret = false; + goto Exit; + } + + // Test audio device for functionality + dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0); + if (dev == 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Audio test - Failed to open audio device: %s", + SDL_GetError()); + ret = false; + goto Exit; + } + + SDL_CloseAudioDevice(dev); + + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Audio test - Successful with %d channels", + want.channels); + + ret = true; + +Exit: + SDL_QuitSubSystem(SDL_INIT_AUDIO); + return ret; +} + int Session::sdlAudioInit(int /* audioConfiguration */, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* /* arContext */, int /* arFlags */) @@ -82,7 +136,7 @@ int Session::sdlAudioInit(int /* audioConfiguration */, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_InitSubSystem(SDL_INIT_AUDIO) failed: %s", SDL_GetError()); - return AUDIO_CONFIGURATION_STEREO; + return -1; } SDL_zero(want); diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index dbee8173..6c1cd69d 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -275,7 +275,8 @@ Session::Session(NvComputer* computer, NvApp& app) m_Window(nullptr), m_VideoDecoder(nullptr), m_DecoderLock(0), - m_NeedsIdr(false) + m_NeedsIdr(false), + m_AudioDisabled(false) { qDebug() << "Server GPU:" << m_Computer->gpuModel; @@ -472,6 +473,12 @@ bool Session::validateLaunch() } } + // Test that audio hardware is functional + m_AudioDisabled = !testAudio(m_StreamConfig.audioConfiguration); + if (m_AudioDisabled) { + emitLaunchWarning("Failed to open audio device. Audio will be unavailable during this session."); + } + if (m_Preferences.videoDecoderSelection == StreamingPreferences::VDS_FORCE_HARDWARE && !isHardwareDecodeAvailable(m_Preferences.videoDecoderSelection, m_StreamConfig.supportsHevc ? VIDEO_FORMAT_H265 : VIDEO_FORMAT_H264, @@ -688,7 +695,8 @@ void Session::exec() } int err = LiStartConnection(&hostInfo, &m_StreamConfig, &k_ConnCallbacks, - &m_VideoCallbacks, &k_AudioCallbacks, + &m_VideoCallbacks, + m_AudioDisabled ? nullptr : &k_AudioCallbacks, NULL, 0, NULL, 0); if (err != 0) { // We already displayed an error dialog in the stage failure diff --git a/app/streaming/session.hpp b/app/streaming/session.hpp index 2cc623bf..8f07baf9 100644 --- a/app/streaming/session.hpp +++ b/app/streaming/session.hpp @@ -49,6 +49,8 @@ private: int sdlDetermineAudioConfiguration(); + bool testAudio(int audioConfiguration); + void getWindowDimensions(bool fullScreen, int& x, int& y, int& width, int& height); @@ -107,6 +109,7 @@ private: IVideoDecoder* m_VideoDecoder; SDL_SpinLock m_DecoderLock; bool m_NeedsIdr; + bool m_AudioDisabled; int m_ActiveVideoFormat; int m_ActiveVideoWidth;