From e95662cebf8a78701336dd53b051907193eb099a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 24 Mar 2023 14:47:58 +0100 Subject: [PATCH] Separate out the core interface around the resampler, in order to move it out from __sceAudio. --- Core/HLE/__sceAudio.cpp | 64 +++++++++++++++++++++---------------- Core/HLE/__sceAudio.h | 8 ++--- Core/HW/StereoResampler.cpp | 4 --- Core/HW/StereoResampler.h | 3 +- UI/BackgroundAudio.cpp | 4 +-- 5 files changed, 45 insertions(+), 38 deletions(-) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 93966df598..0b2b66e0ce 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -49,6 +49,33 @@ StereoResampler resampler; +// numFrames is number of stereo frames. +// This is called from *outside* the emulator thread. +int __AudioMix(short *outstereo, int numFrames, int sampleRate) { + return resampler.Mix(outstereo, numFrames, false, sampleRate); +} + +void __AudioGetDebugStats(char *buf, size_t bufSize) { + resampler.GetAudioDebugStats(buf, bufSize); +} + +void __AudioClear() { + resampler.Clear(); +} + +void __AudioPushSamples(const s32 *audio, int numSamples) { + if (audio) { + resampler.PushSamples(audio, numSamples); + } else { + resampler.Clear(); + } +} + +void __AudioResetStatCounters() { + resampler.ResetStatCounters(); +} + + // Should be used to lock anything related to the outAudioQueue. // atomic locks are used on the lock. TODO: make this lock-free std::atomic_flag atomicLock_; @@ -109,7 +136,7 @@ static void __AudioCPUMHzChange() { void __AudioInit() { - resampler.ResetStatCounters(); + __AudioResetStatCounters(); mixFrequency = 44100; srcFrequency = 0; @@ -132,7 +159,7 @@ void __AudioInit() { clampedMixBuffer = new s16[hwBlockSize * 2]; memset(mixBuffer, 0, hwBlockSize * 2 * sizeof(s32)); - resampler.Clear(); + __AudioClear(); CoreTiming::RegisterMHzChangeCallback(&__AudioCPUMHzChange); } @@ -155,15 +182,18 @@ void __AudioDoState(PointerWrap &p) { mixFrequency = 44100; } - // TODO: This never happens because maxVer=1. if (s >= 2) { - resampler.DoState(p); + // TODO: Next time we bump, get rid of this. It's kinda useless. + StereoResampler::DoState(p); + if (p.mode == p.MODE_READ) { + __AudioClear(); + } } else { // Only to preserve the previous file format. Might cause a slight audio glitch on upgrades? FixedSizeQueue outAudioQueue; outAudioQueue.DoState(p); - resampler.Clear(); + __AudioClear(); } int chanCount = ARRAY_SIZE(chans); @@ -333,9 +363,7 @@ void __AudioSetSRCFrequency(int freq) { srcFrequency = freq; } -// Mix samples from the various audio channels into a single sample queue. -// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should -// just sleep the main emulator thread a little. +// Mix samples from the various audio channels into a single sample queue, managed by the backend implementation. void __AudioUpdate(bool resetRecording) { // Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied // to the CPU. Much better to throttle the frame rate on frame display and just throw away audio @@ -427,7 +455,7 @@ void __AudioUpdate(bool resetRecording) { } if (g_Config.bEnableSound) { - resampler.PushSamples(mixBuffer, hwBlockSize); + __AudioPushSamples(mixBuffer, hwBlockSize); #ifndef MOBILE_DEVICE if (g_Config.bSaveLoadResetsAVdumping && resetRecording) { __StopLogAudio(); @@ -465,24 +493,6 @@ void __AudioUpdate(bool resetRecording) { } } -// numFrames is number of stereo frames. -// This is called from *outside* the emulator thread. -int __AudioMix(short *outstereo, int numFrames, int sampleRate) { - return resampler.Mix(outstereo, numFrames, false, sampleRate); -} - -void __AudioGetDebugStats(char *buf, size_t bufSize) { - resampler.GetAudioDebugStats(buf, bufSize); -} - -void __PushExternalAudio(const s32 *audio, int numSamples) { - if (audio) { - resampler.PushSamples(audio, numSamples); - } else { - resampler.Clear(); - } -} - #ifndef MOBILE_DEVICE void __StartLogAudio(const Path& filename) { if (!m_logAudio) { diff --git a/Core/HLE/__sceAudio.h b/Core/HLE/__sceAudio.h index c4050587f1..380f2efdea 100644 --- a/Core/HLE/__sceAudio.h +++ b/Core/HLE/__sceAudio.h @@ -41,17 +41,17 @@ void __AudioShutdown(); void __AudioSetOutputFrequency(int freq); void __AudioSetSRCFrequency(int freq); -typedef void(*AudioUserCallback); -void __AudioSetUserCallback(AudioUserCallback callback); - // May return SCE_ERROR_AUDIO_CHANNEL_BUSY if buffer too large u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking); void __AudioWakeThreads(AudioChannel &chan, int result, int step); void __AudioWakeThreads(AudioChannel &chan, int result); +// Resampler API, to be extracted int __AudioMix(short *outstereo, int numSamples, int sampleRate); void __AudioGetDebugStats(char *buf, size_t bufSize); -void __PushExternalAudio(const s32 *audio, int numSamples); // Should not be used in-game, only at the menu! +void __AudioClear(); +void __AudioPushSamples(const s32 *audio, int numSamples); // Should not be used in-game, only at the menu! +void __AudioResetStatCounters(); int __AudioGetHostAttemptBlockSize(); diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index 9534a8e52f..f33f2bc1aa 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -346,8 +346,4 @@ void StereoResampler::ResetStatCounters() { void StereoResampler::DoState(PointerWrap &p) { auto s = p.Section("resampler", 1); - if (!s) - return; - if (p.mode == p.MODE_READ) - Clear(); } diff --git a/Core/HW/StereoResampler.h b/Core/HW/StereoResampler.h index 4b10d032c0..13cdb1a2b1 100644 --- a/Core/HW/StereoResampler.h +++ b/Core/HW/StereoResampler.h @@ -41,7 +41,8 @@ public: void Clear(); - void DoState(PointerWrap &p); + // TODO: Get rid of this. + static void DoState(PointerWrap &p); void GetAudioDebugStats(char *buf, size_t bufSize); void ResetStatCounters(); diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 705d4976c4..49284a2af4 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -344,7 +344,7 @@ bool BackgroundAudio::Play() { // Immediately stop the sound if it is turned off while playing. if (!g_Config.bEnableSound) { Clear(true); - __PushExternalAudio(0, 0); + __AudioClear(); return true; } @@ -393,7 +393,7 @@ bool BackgroundAudio::Play() { } } - __PushExternalAudio(buffer, sz); + __AudioPushSamples(buffer, sz); if (at3Reader_ && fadingOut_ && volume_ <= 0.0f) { Clear(true);