From 9173b40e2ebd4a0137afe6357b28e737968fda15 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Dec 2021 22:24:32 +1000 Subject: [PATCH] SPU2: Add function to pause output stream --- pcsx2/SPU2/SndOut.cpp | 8 +++++++- pcsx2/SPU2/SndOut.h | 4 ++++ pcsx2/SPU2/SndOut_Cubeb.cpp | 16 ++++++++++++++++ pcsx2/SPU2/Windows/SndOut_XAudio2.cpp | 27 ++++++++++++++++++++++++++- pcsx2/SPU2/spu2.cpp | 5 +++++ pcsx2/SPU2/spu2.h | 1 + 6 files changed, 59 insertions(+), 2 deletions(-) diff --git a/pcsx2/SPU2/SndOut.cpp b/pcsx2/SPU2/SndOut.cpp index 107fb6493e..85f4b174ce 100644 --- a/pcsx2/SPU2/SndOut.cpp +++ b/pcsx2/SPU2/SndOut.cpp @@ -46,11 +46,12 @@ StereoOut32 StereoOut16::UpSample() const } -class NullOutModule : public SndOutModule +class NullOutModule final : public SndOutModule { public: bool Init() override { return true; } void Close() override {} + void SetPaused(bool paused) override {} int GetEmptySampleCount() override { return 0; } const wchar_t* GetIdent() const override @@ -421,6 +422,11 @@ void SndBuffer::ClearContents() SndBuffer::ssFreeze = 256; //Delays sound output for about 1 second. } +void SndBuffer::SetPaused(bool paused) +{ + mods[OutputModule]->SetPaused(paused); +} + void SndBuffer::Write(const StereoOut32& Sample) { // Log final output to wavefile. diff --git a/pcsx2/SPU2/SndOut.h b/pcsx2/SPU2/SndOut.h index d0bc3ac8b1..a539f94793 100644 --- a/pcsx2/SPU2/SndOut.h +++ b/pcsx2/SPU2/SndOut.h @@ -618,6 +618,7 @@ public: static void Cleanup(); static void Write(const StereoOut32& Sample); static void ClearContents(); + static void SetPaused(bool paused); // Note: When using with 32 bit output buffers, the user of this function is responsible // for shifting the values to where they need to be manually. The fixed point depth of @@ -644,6 +645,9 @@ public: virtual bool Init() = 0; virtual void Close() = 0; + // Temporarily pauses the stream, preventing it from requesting data. + virtual void SetPaused(bool paused) = 0; + // Returns the number of empty samples in the output buffer. // (which is effectively the amount of data played since the last update) virtual int GetEmptySampleCount() = 0; diff --git a/pcsx2/SPU2/SndOut_Cubeb.cpp b/pcsx2/SPU2/SndOut_Cubeb.cpp index 51681b3719..a066b1c50d 100644 --- a/pcsx2/SPU2/SndOut_Cubeb.cpp +++ b/pcsx2/SPU2/SndOut_Cubeb.cpp @@ -296,6 +296,7 @@ public: return false; } + m_paused = false; return true; } @@ -314,6 +315,21 @@ public: return nframes; } + void SetPaused(bool paused) override + { + if (paused == m_paused || !stream) + return; + + const int rv = paused ? cubeb_stream_stop(stream) : cubeb_stream_start(stream); + if (rv != CUBEB_OK) + { + Console.Error("(Cubeb) Could not %s stream: %d", paused ? "pause" : "resume", rv); + return; + } + + m_paused = paused; + } + int GetEmptySampleCount() override { u64 pos; diff --git a/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp b/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp index 885f46e49e..faa09873cf 100644 --- a/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp +++ b/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp @@ -125,10 +125,20 @@ private: pSourceVoice->SubmitSourceBuffer(&buf); } - pSourceVoice->Start(0, 0); + Start(); return true; } + void Stop() + { + pSourceVoice->Stop(); + } + + void Start() + { + pSourceVoice->Start(0, 0); + } + protected: STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) override {} @@ -187,6 +197,7 @@ private: wil::com_ptr_nothrow pXAudio2; IXAudio2MasteringVoice* pMasteringVoice = nullptr; std::unique_ptr m_voiceContext; + bool m_paused = false; public: bool Init() override @@ -304,6 +315,7 @@ public: return false; } + m_paused = false; return true; } @@ -329,6 +341,19 @@ public: return m_voiceContext->GetEmptySampleCount(); } + void SetPaused(bool paused) override + { + if (m_voiceContext == nullptr || m_paused == paused) + return; + + if (paused) + m_voiceContext->Stop(); + else + m_voiceContext->Start(); + + m_paused = paused; + } + const wchar_t* GetIdent() const override { return L"xaudio2"; diff --git a/pcsx2/SPU2/spu2.cpp b/pcsx2/SPU2/spu2.cpp index 1ee7d2638f..68e2f19b37 100644 --- a/pcsx2/SPU2/spu2.cpp +++ b/pcsx2/SPU2/spu2.cpp @@ -351,6 +351,11 @@ void SPU2shutdown() #endif } +void SPU2SetOutputPaused(bool paused) +{ + SndBuffer::SetPaused(paused); +} + #ifdef DEBUG_KEYS static u32 lastTicks; static bool lState[6]; diff --git a/pcsx2/SPU2/spu2.h b/pcsx2/SPU2/spu2.h index c8db3bd17a..f0213ea51e 100644 --- a/pcsx2/SPU2/spu2.h +++ b/pcsx2/SPU2/spu2.h @@ -31,6 +31,7 @@ s32 SPU2reset(PS2Modes isRunningPSXMode); s32 SPU2open(); void SPU2close(); void SPU2shutdown(); +void SPU2SetOutputPaused(bool paused); void SPU2write(u32 mem, u16 value); u16 SPU2read(u32 mem);