SPU2: Add function to pause output stream

This commit is contained in:
Connor McLaughlin 2021-12-18 22:24:32 +10:00 committed by refractionpcsx2
parent 59e5b1918f
commit 9173b40e2e
6 changed files with 59 additions and 2 deletions

View File

@ -46,11 +46,12 @@ StereoOut32 StereoOut16::UpSample() const
} }
class NullOutModule : public SndOutModule class NullOutModule final : public SndOutModule
{ {
public: public:
bool Init() override { return true; } bool Init() override { return true; }
void Close() override {} void Close() override {}
void SetPaused(bool paused) override {}
int GetEmptySampleCount() override { return 0; } int GetEmptySampleCount() override { return 0; }
const wchar_t* GetIdent() const override const wchar_t* GetIdent() const override
@ -421,6 +422,11 @@ void SndBuffer::ClearContents()
SndBuffer::ssFreeze = 256; //Delays sound output for about 1 second. 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) void SndBuffer::Write(const StereoOut32& Sample)
{ {
// Log final output to wavefile. // Log final output to wavefile.

View File

@ -618,6 +618,7 @@ public:
static void Cleanup(); static void Cleanup();
static void Write(const StereoOut32& Sample); static void Write(const StereoOut32& Sample);
static void ClearContents(); static void ClearContents();
static void SetPaused(bool paused);
// Note: When using with 32 bit output buffers, the user of this function is responsible // 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 // 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 bool Init() = 0;
virtual void Close() = 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. // Returns the number of empty samples in the output buffer.
// (which is effectively the amount of data played since the last update) // (which is effectively the amount of data played since the last update)
virtual int GetEmptySampleCount() = 0; virtual int GetEmptySampleCount() = 0;

View File

@ -296,6 +296,7 @@ public:
return false; return false;
} }
m_paused = false;
return true; return true;
} }
@ -314,6 +315,21 @@ public:
return nframes; 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 int GetEmptySampleCount() override
{ {
u64 pos; u64 pos;

View File

@ -125,10 +125,20 @@ private:
pSourceVoice->SubmitSourceBuffer(&buf); pSourceVoice->SubmitSourceBuffer(&buf);
} }
pSourceVoice->Start(0, 0); Start();
return true; return true;
} }
void Stop()
{
pSourceVoice->Stop();
}
void Start()
{
pSourceVoice->Start(0, 0);
}
protected: protected:
STDMETHOD_(void, OnVoiceProcessingPassStart) STDMETHOD_(void, OnVoiceProcessingPassStart)
(UINT32) override {} (UINT32) override {}
@ -187,6 +197,7 @@ private:
wil::com_ptr_nothrow<IXAudio2> pXAudio2; wil::com_ptr_nothrow<IXAudio2> pXAudio2;
IXAudio2MasteringVoice* pMasteringVoice = nullptr; IXAudio2MasteringVoice* pMasteringVoice = nullptr;
std::unique_ptr<BaseStreamingVoice> m_voiceContext; std::unique_ptr<BaseStreamingVoice> m_voiceContext;
bool m_paused = false;
public: public:
bool Init() override bool Init() override
@ -304,6 +315,7 @@ public:
return false; return false;
} }
m_paused = false;
return true; return true;
} }
@ -329,6 +341,19 @@ public:
return m_voiceContext->GetEmptySampleCount(); 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 const wchar_t* GetIdent() const override
{ {
return L"xaudio2"; return L"xaudio2";

View File

@ -351,6 +351,11 @@ void SPU2shutdown()
#endif #endif
} }
void SPU2SetOutputPaused(bool paused)
{
SndBuffer::SetPaused(paused);
}
#ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
static u32 lastTicks; static u32 lastTicks;
static bool lState[6]; static bool lState[6];

View File

@ -31,6 +31,7 @@ s32 SPU2reset(PS2Modes isRunningPSXMode);
s32 SPU2open(); s32 SPU2open();
void SPU2close(); void SPU2close();
void SPU2shutdown(); void SPU2shutdown();
void SPU2SetOutputPaused(bool paused);
void SPU2write(u32 mem, u16 value); void SPU2write(u32 mem, u16 value);
u16 SPU2read(u32 mem); u16 SPU2read(u32 mem);