From bdbb03e16fc91fba3544873c0597978f1e425bb9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 4 May 2019 15:46:11 -0700 Subject: [PATCH] Request 20 ms audio frames on Steam Link to reduce CPU overhead --- app/streaming/audio/audio.cpp | 3 +- app/streaming/audio/renderers/sdlaud.cpp | 4 +- app/streaming/audio/renderers/slaud.cpp | 45 +++---------------- app/streaming/audio/renderers/slaud.h | 2 - .../audio/renderers/soundioaudiorenderer.cpp | 2 +- moonlight-common-c/moonlight-common-c | 2 +- 6 files changed, 12 insertions(+), 46 deletions(-) diff --git a/app/streaming/audio/audio.cpp b/app/streaming/audio/audio.cpp index 8af95673..48a9660e 100644 --- a/app/streaming/audio/audio.cpp +++ b/app/streaming/audio/audio.cpp @@ -41,6 +41,7 @@ bool Session::testAudio(int audioConfiguration) // the renderer the channel count and sample rate. OPUS_MULTISTREAM_CONFIGURATION opusConfig = {}; opusConfig.sampleRate = 48000; + opusConfig.samplesPerFrame = 240; switch (audioConfiguration) { @@ -143,7 +144,7 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength) s_ActiveSession->m_AudioSampleCount++; if (s_ActiveSession->m_AudioRenderer != nullptr) { - int desiredSize = sizeof(short) * SAMPLES_PER_FRAME * s_ActiveSession->m_AudioConfig.channelCount; + int desiredSize = sizeof(short) * s_ActiveSession->m_AudioConfig.samplesPerFrame * s_ActiveSession->m_AudioConfig.channelCount; void* buffer = s_ActiveSession->m_AudioRenderer->getAudioBuffer(&desiredSize); if (buffer == nullptr) { return; diff --git a/app/streaming/audio/renderers/sdlaud.cpp b/app/streaming/audio/renderers/sdlaud.cpp index 955bca08..551d0896 100644 --- a/app/streaming/audio/renderers/sdlaud.cpp +++ b/app/streaming/audio/renderers/sdlaud.cpp @@ -31,7 +31,7 @@ bool SdlAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* // frames contain a non-power of 2 number of samples, // so the slop would require buffering another full frame. // Specifying non-Po2 seems to work for our supported platforms. - want.samples = SAMPLES_PER_FRAME; + want.samples = opusConfig->samplesPerFrame; m_AudioDevice = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0); if (m_AudioDevice == 0) { @@ -41,7 +41,7 @@ bool SdlAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* return false; } - m_AudioBuffer = malloc(SAMPLES_PER_FRAME * sizeof(short) * opusConfig->channelCount); + m_AudioBuffer = malloc(opusConfig->samplesPerFrame * sizeof(short) * opusConfig->channelCount); if (m_AudioBuffer == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to allocate audio buffer"); diff --git a/app/streaming/audio/renderers/slaud.cpp b/app/streaming/audio/renderers/slaud.cpp index b21a373f..e24428d6 100644 --- a/app/streaming/audio/renderers/slaud.cpp +++ b/app/streaming/audio/renderers/slaud.cpp @@ -2,16 +2,9 @@ #include -// To reduce CPU load on the Steam Link, we need to accumulate several frames -// before submitting for playback. Higher frames per submission saves more CPU -// but increases audio latency. -#define FRAMES_PER_SUBMISSION 4 - SLAudioRenderer::SLAudioRenderer() : m_AudioContext(nullptr), - m_AudioStream(nullptr), - m_AudioBuffer(nullptr), - m_AudioBufferBytesFilled(0) + m_AudioStream(nullptr) { SLAudio_SetLogFunction(SLAudioRenderer::slLogCallback, nullptr); } @@ -25,7 +18,7 @@ bool SLAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* o return false; } - m_AudioBufferSize = SAMPLES_PER_FRAME * sizeof(short) * opusConfig->channelCount * FRAMES_PER_SUBMISSION; + m_AudioBufferSize = opusConfig->samplesPerFrame * sizeof(short) * opusConfig->channelCount; m_AudioStream = SLAudio_CreateStream(m_AudioContext, opusConfig->sampleRate, opusConfig->channelCount, @@ -45,29 +38,12 @@ bool SLAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* o void* SLAudioRenderer::getAudioBuffer(int* size) { - SDL_assert(*size == m_AudioBufferSize / FRAMES_PER_SUBMISSION); - - if (m_AudioBuffer == nullptr) { - m_AudioBufferBytesFilled = 0; - m_AudioBuffer = (char*)SLAudio_BeginFrame(m_AudioStream); - if (m_AudioBuffer == nullptr) { - return nullptr; - } - } - - return (void*)&m_AudioBuffer[m_AudioBufferBytesFilled]; + SDL_assert(*size == m_AudioBufferSize); + return SLAudio_BeginFrame(m_AudioStream); } SLAudioRenderer::~SLAudioRenderer() { - if (m_AudioBuffer != nullptr) { - // We had a buffer in flight when we quit. Just in case - // SLAudio doesn't handle this properly, we'll zero and submit - // it just to be safe. - memset(m_AudioBuffer, 0, m_AudioBufferSize); - SLAudio_SubmitFrame(m_AudioStream); - } - if (m_AudioStream != nullptr) { SLAudio_FreeStream(m_AudioStream); } @@ -77,18 +53,9 @@ SLAudioRenderer::~SLAudioRenderer() } } -bool SLAudioRenderer::submitAudio(int bytesWritten) +bool SLAudioRenderer::submitAudio(int) { - m_AudioBufferBytesFilled += bytesWritten; - - // Submit the buffer when it's full - SDL_assert(m_AudioBufferBytesFilled <= m_AudioBufferSize); - if (m_AudioBufferBytesFilled == m_AudioBufferSize) { - SLAudio_SubmitFrame(m_AudioStream); - m_AudioBuffer = nullptr; - m_AudioBufferBytesFilled = 0; - } - + SLAudio_SubmitFrame(m_AudioStream); return true; } diff --git a/app/streaming/audio/renderers/slaud.h b/app/streaming/audio/renderers/slaud.h index 989f146d..bfe8c275 100644 --- a/app/streaming/audio/renderers/slaud.h +++ b/app/streaming/audio/renderers/slaud.h @@ -22,7 +22,5 @@ private: CSLAudioContext* m_AudioContext; CSLAudioStream* m_AudioStream; - char* m_AudioBuffer; int m_AudioBufferSize; - int m_AudioBufferBytesFilled; }; diff --git a/app/streaming/audio/renderers/soundioaudiorenderer.cpp b/app/streaming/audio/renderers/soundioaudiorenderer.cpp index e96b2b7b..fe8982bf 100644 --- a/app/streaming/audio/renderers/soundioaudiorenderer.cpp +++ b/app/streaming/audio/renderers/soundioaudiorenderer.cpp @@ -260,7 +260,7 @@ bool SoundIoAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATI m_RingBuffer = soundio_ring_buffer_create(m_SoundIo, m_OutputStream->bytes_per_sample * m_OpusChannelCount * - SAMPLES_PER_FRAME * + opusConfig->samplesPerFrame * packetsToBuffer); if (m_RingBuffer == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, diff --git a/moonlight-common-c/moonlight-common-c b/moonlight-common-c/moonlight-common-c index 1154cb1d..59481c08 160000 --- a/moonlight-common-c/moonlight-common-c +++ b/moonlight-common-c/moonlight-common-c @@ -1 +1 @@ -Subproject commit 1154cb1d3db53215e46b3c7d2476b27d52d0dfbf +Subproject commit 59481c085a7f774c5d30374636f8bc75da7c676c