From 3afa17f752a06c438d912c85519d3edb34023447 Mon Sep 17 00:00:00 2001
From: magumagu <magumagu9@gmail.com>
Date: Thu, 27 Mar 2014 17:56:05 -0700
Subject: [PATCH] Move audio handling out of DSP emulation.

This is good for a couple of reasons: one, it gets rid of duplicated code,
and two, DSP emulation shouldn't need to interact with audio in the first
place.
---
 Source/Core/AudioCommon/AudioCommon.cpp | 21 ++++++++
 Source/Core/AudioCommon/AudioCommon.h   |  2 +
 Source/Core/Core/Core.cpp               |  3 ++
 Source/Core/Core/DSPEmulator.h          |  7 ---
 Source/Core/Core/HW/CPU.cpp             |  6 ++-
 Source/Core/Core/HW/DSP.cpp             |  8 ++-
 Source/Core/Core/HW/DSPHLE/DSPHLE.cpp   | 65 -------------------------
 Source/Core/Core/HW/DSPHLE/DSPHLE.h     |  8 ---
 Source/Core/Core/HW/DSPLLE/DSPLLE.cpp   | 64 ------------------------
 Source/Core/Core/HW/DSPLLE/DSPLLE.h     |  5 --
 Source/Core/DolphinWX/ConfigMain.cpp    |  2 +
 11 files changed, 38 insertions(+), 153 deletions(-)

diff --git a/Source/Core/AudioCommon/AudioCommon.cpp b/Source/Core/AudioCommon/AudioCommon.cpp
index 07da747c1e..c2fd936974 100644
--- a/Source/Core/AudioCommon/AudioCommon.cpp
+++ b/Source/Core/AudioCommon/AudioCommon.cpp
@@ -159,4 +159,25 @@ namespace AudioCommon
 			soundStream->SetVolume(SConfig::GetInstance().m_Volume);
 		}
 	}
+
+	void ClearAudioBuffer(bool mute)
+	{
+		if (soundStream)
+			soundStream->Clear(mute);
+	}
+
+	void SendAIBuffer(short *samples, unsigned int num_samples)
+	{
+		if (!soundStream)
+			return;
+
+		CMixer* pMixer = soundStream->GetMixer();
+
+		if (pMixer && samples)
+		{
+			pMixer->PushSamples(samples, num_samples);
+		}
+
+		soundStream->Update();
+	}
 }
diff --git a/Source/Core/AudioCommon/AudioCommon.h b/Source/Core/AudioCommon/AudioCommon.h
index 3faf387bcc..4fd4b6a965 100644
--- a/Source/Core/AudioCommon/AudioCommon.h
+++ b/Source/Core/AudioCommon/AudioCommon.h
@@ -19,4 +19,6 @@ namespace AudioCommon
 	std::vector<std::string> GetSoundBackends();
 	void PauseAndLock(bool doLock, bool unpauseOnUnlock=true);
 	void UpdateSoundStream();
+	void ClearAudioBuffer(bool mute);
+	void SendAIBuffer(short* samples, unsigned int num_samples);
 }
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index a4184797a6..a4d4a6fdda 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -410,6 +410,8 @@ void EmuThread()
 
 	}
 
+	AudioCommon::InitSoundStream(g_pWindowHandle);
+
 	// The hardware is initialized.
 	g_bHwInit = true;
 
@@ -507,6 +509,7 @@ void EmuThread()
 	Pad::Shutdown();
 	Wiimote::Shutdown();
 	g_video_backend->Shutdown();
+	AudioCommon::ShutdownSoundStream();
 }
 
 // Set or get the running state
diff --git a/Source/Core/Core/DSPEmulator.h b/Source/Core/Core/DSPEmulator.h
index 71a12635e8..49e086ff6f 100644
--- a/Source/Core/Core/DSPEmulator.h
+++ b/Source/Core/Core/DSPEmulator.h
@@ -4,7 +4,6 @@
 
 #pragma once
 
-#include "AudioCommon/SoundStream.h"
 #include "Common/ChunkFile.h"
 
 class DSPEmulator
@@ -26,15 +25,9 @@ public:
 	virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) = 0;
 	virtual unsigned short DSP_ReadControlRegister() = 0;
 	virtual unsigned short DSP_WriteControlRegister(unsigned short) = 0;
-	virtual void DSP_SendAIBuffer(unsigned int address, unsigned int num_samples) = 0;
 	virtual void DSP_Update(int cycles) = 0;
 	virtual void DSP_StopSoundStream() = 0;
-	virtual void DSP_ClearAudioBuffer(bool mute) = 0;
 	virtual u32 DSP_UpdateRate() = 0;
-
-protected:
-	SoundStream *soundStream;
-	void *m_hWnd;
 };
 
 DSPEmulator *CreateDSPEmulator(bool HLE);
diff --git a/Source/Core/Core/HW/CPU.cpp b/Source/Core/Core/HW/CPU.cpp
index 13717b395c..613974b675 100644
--- a/Source/Core/Core/HW/CPU.cpp
+++ b/Source/Core/Core/HW/CPU.cpp
@@ -2,6 +2,8 @@
 // Licensed under GPLv2
 // Refer to the license.txt file included.
 
+#include "AudioCommon/AudioCommon.h"
+
 #include "Common/Common.h"
 #include "Common/Thread.h"
 
@@ -112,14 +114,14 @@ void CCPU::EnableStepping(const bool _bStepping)
 		PowerPC::Pause();
 		m_StepEvent.Reset();
 		g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PAUSE);
-		DSP::GetDSPEmulator()->DSP_ClearAudioBuffer(true);
+		AudioCommon::ClearAudioBuffer(true);
 	}
 	else
 	{
 		PowerPC::Start();
 		m_StepEvent.Set();
 		g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PLAY);
-		DSP::GetDSPEmulator()->DSP_ClearAudioBuffer(false);
+		AudioCommon::ClearAudioBuffer(false);
 	}
 }
 
diff --git a/Source/Core/Core/HW/DSP.cpp b/Source/Core/Core/HW/DSP.cpp
index 114a23b1e8..2394243396 100644
--- a/Source/Core/Core/HW/DSP.cpp
+++ b/Source/Core/Core/HW/DSP.cpp
@@ -23,6 +23,8 @@
 // the just used buffer through the AXList (or whatever it might be called in
 // Nintendo games).
 
+#include "AudioCommon/AudioCommon.h"
+
 #include "Common/MemoryUtil.h"
 
 #include "Core/ConfigManager.h"
@@ -482,7 +484,9 @@ void UpdateAudioDMA()
 
 		if (g_audioDMA.BlocksLeft == 0)
 		{
-			dsp_emulator->DSP_SendAIBuffer(g_audioDMA.SourceAddress, 8*g_audioDMA.AudioDMAControl.NumBlocks);
+			void *address = Memory::GetPointer(g_audioDMA.SourceAddress);
+			unsigned samples = 8 * g_audioDMA.AudioDMAControl.NumBlocks;
+			AudioCommon::SendAIBuffer((short*)address, samples);
 			GenerateDSPInterrupt(DSP::INT_AID);
 			g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks;
 			g_audioDMA.ReadAddress = g_audioDMA.SourceAddress;
@@ -492,7 +496,7 @@ void UpdateAudioDMA()
 	{
 		// Send silence. Yeah, it's a bit of a waste to sample rate convert
 		// silence.  or hm. Maybe we shouldn't do this :)
-		dsp_emulator->DSP_SendAIBuffer(0, AudioInterface::GetAIDSampleRate());
+		AudioCommon::SendAIBuffer(0, AudioInterface::GetAIDSampleRate());
 	}
 }
 
diff --git a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp
index 5f79722638..90a1fe1edf 100644
--- a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp
+++ b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp
@@ -19,8 +19,6 @@
 
 DSPHLE::DSPHLE()
 {
-	m_InitMixer = false;
-	soundStream = nullptr;
 }
 
 // Mailbox utility
@@ -43,7 +41,6 @@ struct DSPState
 
 bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
 {
-	m_hWnd = hWnd;
 	m_bWii = bWii;
 	m_pUCode = nullptr;
 	m_lastUCode = nullptr;
@@ -54,7 +51,6 @@ bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
 	m_DSPControl.DSPHalt = 1;
 	m_DSPControl.DSPInit = 1;
 
-	m_InitMixer = false;
 	m_dspState.Reset();
 
 	return true;
@@ -66,7 +62,6 @@ void DSPHLE::DSP_StopSoundStream()
 
 void DSPHLE::Shutdown()
 {
-	AudioCommon::ShutdownSoundStream();
 }
 
 void DSPHLE::DSP_Update(int cycles)
@@ -139,23 +134,6 @@ void DSPHLE::DoState(PointerWrap &p)
 		p.SetMode(PointerWrap::MODE_VERIFY);
 		return;
 	}
-	bool prevInitMixer = m_InitMixer;
-	p.Do(m_InitMixer);
-	if (prevInitMixer != m_InitMixer && p.GetMode() == PointerWrap::MODE_READ)
-	{
-		if (m_InitMixer)
-		{
-			InitMixer();
-			AudioCommon::PauseAndLock(true);
-		}
-		else
-		{
-			AudioCommon::PauseAndLock(false);
-			soundStream->Stop();
-			delete soundStream;
-			soundStream = nullptr;
-		}
-	}
 
 	p.DoPOD(m_DSPControl);
 	p.DoPOD(m_dspState);
@@ -260,25 +238,10 @@ void DSPHLE::DSP_WriteMailBoxLow(bool _CPUMailbox, unsigned short _Value)
 	}
 }
 
-void DSPHLE::InitMixer()
-{
-	soundStream = AudioCommon::InitSoundStream(m_hWnd);
-	if (!soundStream) PanicAlert("Error starting up sound stream");
-	// Mixer is initialized
-	m_InitMixer = true;
-}
-
 // Other DSP fuctions
 u16 DSPHLE::DSP_WriteControlRegister(unsigned short _Value)
 {
 	DSP::UDSPControl Temp(_Value);
-	if (!m_InitMixer)
-	{
-		if (!Temp.DSPHalt)
-		{
-			InitMixer();
-		}
-	}
 
 	if (Temp.DSPReset)
 	{
@@ -301,34 +264,6 @@ u16 DSPHLE::DSP_ReadControlRegister()
 	return m_DSPControl.Hex;
 }
 
-
-// The reason that we don't disable this entire
-// function when Other Audio is disabled is that then we can't turn it back on
-// again once the game has started.
-void DSPHLE::DSP_SendAIBuffer(unsigned int address, unsigned int num_samples)
-{
-	if (!soundStream)
-		return;
-
-	CMixer* pMixer = soundStream->GetMixer();
-
-	if (pMixer && address)
-	{
-		short* samples = (short*)HLEMemory_Get_Pointer(address);
-		pMixer->PushSamples(samples, num_samples);
-	}
-
-	soundStream->Update();
-}
-
-void DSPHLE::DSP_ClearAudioBuffer(bool mute)
-{
-	if (soundStream)
-		soundStream->Clear(mute);
-}
-
 void DSPHLE::PauseAndLock(bool doLock, bool unpauseOnUnlock)
 {
-	if (doLock || unpauseOnUnlock)
-		DSP_ClearAudioBuffer(doLock);
 }
diff --git a/Source/Core/Core/HW/DSPHLE/DSPHLE.h b/Source/Core/Core/HW/DSPHLE/DSPHLE.h
index 4642f9d9b2..ad84d08947 100644
--- a/Source/Core/Core/HW/DSPHLE/DSPHLE.h
+++ b/Source/Core/Core/HW/DSPHLE/DSPHLE.h
@@ -4,9 +4,6 @@
 
 #pragma once
 
-#include "AudioCommon/AudioCommon.h"
-#include "AudioCommon/SoundStream.h"
-
 #include "Core/DSPEmulator.h"
 #include "Core/HW/DSP.h"
 #include "Core/HW/DSPHLE/MailHandler.h"
@@ -30,10 +27,8 @@ public:
 	virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) override;
 	virtual unsigned short DSP_ReadControlRegister() override;
 	virtual unsigned short DSP_WriteControlRegister(unsigned short) override;
-	virtual void DSP_SendAIBuffer(unsigned int address, unsigned int num_samples) override;
 	virtual void DSP_Update(int cycles) override;
 	virtual void DSP_StopSoundStream() override;
-	virtual void DSP_ClearAudioBuffer(bool mute) override;
 	virtual u32 DSP_UpdateRate() override;
 
 	CMailHandler& AccessMailHandler() { return m_MailHandler; }
@@ -45,13 +40,10 @@ public:
 
 private:
 	void SendMailToDSP(u32 _uMail);
-	void InitMixer();
 
 	// Declarations and definitions
 	bool m_bWii;
 
-	bool m_InitMixer;
-
 	// Fake mailbox utility
 	struct DSPState
 	{
diff --git a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp
index bff5bb1d43..697e69586d 100644
--- a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp
+++ b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp
@@ -2,9 +2,6 @@
 // Licensed under GPLv2
 // Refer to the license.txt file included.
 
-#include "AudioCommon/AudioCommon.h"
-#include "AudioCommon/Mixer.h"
-
 #include "Common/Atomic.h"
 #include "Common/ChunkFile.h"
 #include "Common/Common.h"
@@ -33,8 +30,6 @@
 
 DSPLLE::DSPLLE()
 {
-	soundStream = nullptr;
-	m_InitMixer = false;
 	m_bIsRunning = false;
 	m_cycle_count = 0;
 }
@@ -80,24 +75,6 @@ void DSPLLE::DoState(PointerWrap &p)
 	p.Do(cyclesLeft);
 	p.Do(init_hax);
 	p.Do(m_cycle_count);
-
-	bool prevInitMixer = m_InitMixer;
-	p.Do(m_InitMixer);
-	if (prevInitMixer != m_InitMixer && p.GetMode() == PointerWrap::MODE_READ)
-	{
-		if (m_InitMixer)
-		{
-			InitMixer();
-			AudioCommon::PauseAndLock(true);
-		}
-		else
-		{
-			AudioCommon::PauseAndLock(false);
-			soundStream->Stop();
-			delete soundStream;
-			soundStream = nullptr;
-		}
-	}
 }
 
 // Regular thread
@@ -131,10 +108,8 @@ void DSPLLE::dsp_thread(DSPLLE *dsp_lle)
 
 bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
 {
-	m_hWnd = hWnd;
 	m_bWii = bWii;
 	m_bDSPThread = bDSPThread;
-	m_InitMixer = false;
 
 	std::string irom_file = File::GetUserPath(D_GCUSER_IDX) + DSP_IROM;
 	std::string coef_file = File::GetUserPath(D_GCUSER_IDX) + DSP_COEF;
@@ -177,24 +152,11 @@ void DSPLLE::DSP_StopSoundStream()
 
 void DSPLLE::Shutdown()
 {
-	AudioCommon::ShutdownSoundStream();
 	DSPCore_Shutdown();
 }
 
-void DSPLLE::InitMixer()
-{
-	soundStream = AudioCommon::InitSoundStream(m_hWnd);
-	if (!soundStream) PanicAlert("Error starting up sound stream");
-	// Mixer is initialized
-	m_InitMixer = true;
-}
-
 u16 DSPLLE::DSP_WriteControlRegister(u16 _uFlag)
 {
-	if (!m_InitMixer)
-	{
-		InitMixer();
-	}
 	DSPInterpreter::WriteCR(_uFlag);
 
 	// Check if the CPU has set an external interrupt (CR_EXTERNAL_INT)
@@ -318,34 +280,8 @@ u32 DSPLLE::DSP_UpdateRate()
 	return 12600; // TO BE TWEAKED
 }
 
-void DSPLLE::DSP_SendAIBuffer(unsigned int address, unsigned int num_samples)
-{
-	if (!soundStream)
-		return;
-
-	CMixer *pMixer = soundStream->GetMixer();
-
-	if (pMixer && address)
-	{
-		address &= (address & 0x10000000) ? 0x13ffffff : 0x01ffffff;
-		const short *samples = (const short *)&g_dsp.cpu_ram[address];
-		pMixer->PushSamples(samples, num_samples);
-	}
-
-	soundStream->Update();
-}
-
-void DSPLLE::DSP_ClearAudioBuffer(bool mute)
-{
-	if (soundStream)
-		soundStream->Clear(mute);
-}
-
 void DSPLLE::PauseAndLock(bool doLock, bool unpauseOnUnlock)
 {
-	if (doLock || unpauseOnUnlock)
-		DSP_ClearAudioBuffer(doLock);
-
 	if (doLock)
 		m_csDSPThreadActive.lock();
 	else
diff --git a/Source/Core/Core/HW/DSPLLE/DSPLLE.h b/Source/Core/Core/HW/DSPLLE/DSPLLE.h
index f7acbbf3f9..10381ae8c5 100644
--- a/Source/Core/Core/HW/DSPLLE/DSPLLE.h
+++ b/Source/Core/Core/HW/DSPLLE/DSPLLE.h
@@ -4,7 +4,6 @@
 
 #pragma once
 
-#include "AudioCommon/SoundStream.h"
 #include "Common/Thread.h"
 
 #include "Core/DSPEmulator.h"
@@ -28,19 +27,15 @@ public:
 	virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) override;
 	virtual unsigned short DSP_ReadControlRegister() override;
 	virtual unsigned short DSP_WriteControlRegister(unsigned short) override;
-	virtual void DSP_SendAIBuffer(unsigned int address, unsigned int num_samples) override;
 	virtual void DSP_Update(int cycles) override;
 	virtual void DSP_StopSoundStream() override;
-	virtual void DSP_ClearAudioBuffer(bool mute) override;
 	virtual u32 DSP_UpdateRate() override;
 
 private:
 	static void dsp_thread(DSPLLE* lpParameter);
-	void InitMixer();
 
 	std::thread m_hDSPThread;
 	std::mutex m_csDSPThreadActive;
-	bool m_InitMixer;
 	bool m_bWii;
 	bool m_bDSPThread;
 	bool m_bIsRunning;
diff --git a/Source/Core/DolphinWX/ConfigMain.cpp b/Source/Core/DolphinWX/ConfigMain.cpp
index 3f1812420f..61297f6e37 100644
--- a/Source/Core/DolphinWX/ConfigMain.cpp
+++ b/Source/Core/DolphinWX/ConfigMain.cpp
@@ -23,6 +23,8 @@
 #include <wx/spinctrl.h>
 #include <wx/stattext.h>
 
+#include "AudioCommon/AudioCommon.h"
+
 #include "Common/Common.h"
 #include "Common/CommonPaths.h"
 #include "Common/FileSearch.h"