From 8b05e7abf019c391de912b8f5edf3918da34c78b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 14 Jan 2015 00:45:12 +0100 Subject: [PATCH] Adjust the audio speed on non-60hz Android devices to compensate. Greatly improves audio stability on Nexus S. Fixes #6677 . --- Core/HW/StereoResampler.cpp | 17 +++++++++++++++++ Core/HW/StereoResampler.h | 5 +---- UI/DevScreens.cpp | 7 +++++++ Windows/main.cpp | 2 ++ ios/main.mm | 2 ++ native | 2 +- 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index fdfcb4329..7edf2a037 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -20,6 +20,7 @@ #include #include "base/logging.h" +#include "base/NativeApp.h" #include "Common/ChunkFile.h" #include "Common/MathUtil.h" #include "Common/Atomics.h" @@ -30,6 +31,22 @@ #include #endif + +StereoResampler::StereoResampler() + : m_dma_mixer(this, 44100) +{ + // Some Android devices are v-synced to non-60Hz framerates. We simply timestretch audio to fit. + // TODO: should only do this if auto frameskip is off? + + float refresh = System_GetPropertyInt(SYSPROP_DISPLAY_REFRESH_RATE) / 1000.0f; + + // If framerate is "close"... + if (refresh != 60.0f && refresh > 50.0f && refresh < 70.0f) { + m_dma_mixer.SetInputSampleRate((int)(44100 * (refresh / 60.0f))); + } +} + + inline void ClampBufferToS16(s16 *out, const s32 *in, size_t size) { #ifdef _M_SSE // Size will always be 16-byte aligned as the hwBlockSize is. diff --git a/Core/HW/StereoResampler.h b/Core/HW/StereoResampler.h index 38cf449f9..504eed158 100644 --- a/Core/HW/StereoResampler.h +++ b/Core/HW/StereoResampler.h @@ -39,10 +39,7 @@ class StereoResampler { public: - StereoResampler() - : m_dma_mixer(this, 44100) - { - } + StereoResampler(); virtual ~StereoResampler() {} diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 61b3eb2cd..f3132bf0c 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -330,8 +330,15 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new InfoItem("Frames per buffer", StringFromFormat("%d", System_GetPropertyInt(SYSPROP_AUDIO_FRAMES_PER_BUFFER)))); deviceSpecs->Add(new InfoItem("Optimal sample rate", StringFromFormat("%d Hz", System_GetPropertyInt(SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE)))); deviceSpecs->Add(new InfoItem("Optimal frames per buffer", StringFromFormat("%d", System_GetPropertyInt(SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER)))); + + deviceSpecs->Add(new ItemHeader("Display Information")); + deviceSpecs->Add(new InfoItem("Native Resolution", StringFromFormat("%dx%d", + System_GetPropertyInt(SYSPROP_DISPLAY_XRES), + System_GetPropertyInt(SYSPROP_DISPLAY_YRES)))); + deviceSpecs->Add(new InfoItem("Refresh rate", StringFromFormat("%0.3f Hz", (float)System_GetPropertyInt(SYSPROP_DISPLAY_REFRESH_RATE) / 1000.0f))); #endif + deviceSpecs->Add(new ItemHeader("Version Information")); std::string apiVersion = thin3d->GetInfoString(T3DInfo::APIVERSION); apiVersion.resize(30); diff --git a/Windows/main.cpp b/Windows/main.cpp index de38e42e3..dcf1c222b 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -263,6 +263,8 @@ int System_GetPropertyInt(SystemProperty prop) { switch (prop) { case SYSPROP_AUDIO_SAMPLE_RATE: return winAudioBackend ? winAudioBackend->GetSampleRate() : -1; + case SYSPROP_DISPLAY_REFRESH_RATE: + return 60000; default: return -1; } diff --git a/ios/main.mm b/ios/main.mm index abc4887c5..def51c996 100644 --- a/ios/main.mm +++ b/ios/main.mm @@ -26,6 +26,8 @@ int System_GetPropertyInt(SystemProperty prop) { switch (prop) { case SYSPROP_AUDIO_SAMPLE_RATE: return 44100; + case SYSPROP_DISPLAY_REFRESH_RATE: + return 60000; default: return -1; } diff --git a/native b/native index 477e0e89f..d2f95b919 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 477e0e89f9269b573edbfbc84c22199c4d449203 +Subproject commit d2f95b91909418d07cb6cdd3f6b8f7cf5ad4dc09