Merge pull request #220 from magumagu/audio-handling-cleanup-v2

Audio handling cleanup v2
This commit is contained in:
Pierre Bourdon 2014-03-30 13:24:52 +02:00
commit 76fafb1c7b
12 changed files with 81 additions and 232 deletions

View File

@ -26,8 +26,13 @@ SoundStream *soundStream = nullptr;
namespace AudioCommon namespace AudioCommon
{ {
SoundStream *InitSoundStream(CMixer *mixer, void *hWnd) SoundStream *InitSoundStream(void *hWnd)
{ {
unsigned int AISampleRate, DACSampleRate;
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
delete soundStream;
CMixer *mixer = new CMixer(AISampleRate, DACSampleRate, 48000);
// TODO: possible memleak with mixer // TODO: possible memleak with mixer
std::string backend = SConfig::GetInstance().sBackend; std::string backend = SConfig::GetInstance().sBackend;
@ -128,15 +133,6 @@ namespace AudioCommon
return backends; return backends;
} }
bool UseJIT()
{
if (!Movie::IsDSPHLE() && Movie::IsPlayingInput() && Movie::IsConfigSaved())
{
return true;
}
return SConfig::GetInstance().m_DSPEnableJIT;
}
void PauseAndLock(bool doLock, bool unpauseOnUnlock) void PauseAndLock(bool doLock, bool unpauseOnUnlock)
{ {
if (soundStream) if (soundStream)
@ -163,4 +159,25 @@ namespace AudioCommon
soundStream->SetVolume(SConfig::GetInstance().m_Volume); 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();
}
} }

View File

@ -12,37 +12,13 @@ class CMixer;
extern SoundStream *soundStream; extern SoundStream *soundStream;
// UDSPControl
union UDSPControl
{
u16 Hex;
struct
{
u16 DSPReset : 1; // Write 1 to reset and waits for 0
u16 DSPAssertInt : 1;
u16 DSPHalt : 1;
u16 AI : 1;
u16 AI_mask : 1;
u16 ARAM : 1;
u16 ARAM_mask : 1;
u16 DSP : 1;
u16 DSP_mask : 1;
u16 ARAM_DMAState : 1; // DSPGetDMAStatus() uses this flag
u16 DSPInitCode : 1;
u16 DSPInit : 1; // DSPInit() writes to this flag
u16 pad : 4;
};
UDSPControl(u16 _Hex = 0) : Hex(_Hex) {}
};
namespace AudioCommon namespace AudioCommon
{ {
SoundStream *InitSoundStream(CMixer *mixer, void *hWnd); SoundStream *InitSoundStream(void *hWnd);
void ShutdownSoundStream(); void ShutdownSoundStream();
std::vector<std::string> GetSoundBackends(); std::vector<std::string> GetSoundBackends();
bool UseJIT();
void PauseAndLock(bool doLock, bool unpauseOnUnlock=true); void PauseAndLock(bool doLock, bool unpauseOnUnlock=true);
void UpdateSoundStream(); void UpdateSoundStream();
void ClearAudioBuffer(bool mute);
void SendAIBuffer(short* samples, unsigned int num_samples);
} }

View File

@ -410,6 +410,8 @@ void EmuThread()
} }
AudioCommon::InitSoundStream(g_pWindowHandle);
// The hardware is initialized. // The hardware is initialized.
g_bHwInit = true; g_bHwInit = true;
@ -507,6 +509,7 @@ void EmuThread()
Pad::Shutdown(); Pad::Shutdown();
Wiimote::Shutdown(); Wiimote::Shutdown();
g_video_backend->Shutdown(); g_video_backend->Shutdown();
AudioCommon::ShutdownSoundStream();
} }
// Set or get the running state // Set or get the running state

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include "AudioCommon/SoundStream.h"
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
class DSPEmulator class DSPEmulator
@ -26,15 +25,9 @@ public:
virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) = 0; virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) = 0;
virtual unsigned short DSP_ReadControlRegister() = 0; virtual unsigned short DSP_ReadControlRegister() = 0;
virtual unsigned short DSP_WriteControlRegister(unsigned short) = 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_Update(int cycles) = 0;
virtual void DSP_StopSoundStream() = 0; virtual void DSP_StopSoundStream() = 0;
virtual void DSP_ClearAudioBuffer(bool mute) = 0;
virtual u32 DSP_UpdateRate() = 0; virtual u32 DSP_UpdateRate() = 0;
protected:
SoundStream *soundStream;
void *m_hWnd;
}; };
DSPEmulator *CreateDSPEmulator(bool HLE); DSPEmulator *CreateDSPEmulator(bool HLE);

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2 // Licensed under GPLv2
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "AudioCommon/AudioCommon.h"
#include "Common/Common.h" #include "Common/Common.h"
#include "Common/Thread.h" #include "Common/Thread.h"
@ -112,14 +114,14 @@ void CCPU::EnableStepping(const bool _bStepping)
PowerPC::Pause(); PowerPC::Pause();
m_StepEvent.Reset(); m_StepEvent.Reset();
g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PAUSE); g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PAUSE);
DSP::GetDSPEmulator()->DSP_ClearAudioBuffer(true); AudioCommon::ClearAudioBuffer(true);
} }
else else
{ {
PowerPC::Start(); PowerPC::Start();
m_StepEvent.Set(); m_StepEvent.Set();
g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PLAY); g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PLAY);
DSP::GetDSPEmulator()->DSP_ClearAudioBuffer(false); AudioCommon::ClearAudioBuffer(false);
} }
} }

View File

@ -23,6 +23,8 @@
// the just used buffer through the AXList (or whatever it might be called in // the just used buffer through the AXList (or whatever it might be called in
// Nintendo games). // Nintendo games).
#include "AudioCommon/AudioCommon.h"
#include "Common/MemoryUtil.h" #include "Common/MemoryUtil.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
@ -76,34 +78,6 @@ union UARAMCount
}; };
}; };
// UDSPControl
#define DSP_CONTROL_MASK 0x0C07
union UDSPControl
{
u16 Hex;
struct
{
// DSP Control
u16 DSPReset : 1; // Write 1 to reset and waits for 0
u16 DSPAssertInt : 1;
u16 DSPHalt : 1;
// Interrupt for DMA to the AI/speakers
u16 AID : 1;
u16 AID_mask : 1;
// ARAM DMA interrupt
u16 ARAM : 1;
u16 ARAM_mask : 1;
// DSP DMA interrupt
u16 DSP : 1;
u16 DSP_mask : 1;
// Other ???
u16 DMAState : 1; // DSPGetDMAStatus() uses this flag. __ARWaitForDMA() uses it too...maybe it's just general DMA flag
u16 unk3 : 1;
u16 DSPInit : 1; // DSPInit() writes to this flag
u16 pad : 4;
};
};
// DSPState // DSPState
struct DSPState struct DSPState
{ {
@ -394,7 +368,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
if (tmpControl.DSP) g_dspState.DSPControl.DSP = 0; if (tmpControl.DSP) g_dspState.DSPControl.DSP = 0;
// unknown // unknown
g_dspState.DSPControl.unk3 = tmpControl.unk3; g_dspState.DSPControl.DSPInitCode = tmpControl.DSPInitCode;
g_dspState.DSPControl.pad = tmpControl.pad; g_dspState.DSPControl.pad = tmpControl.pad;
if (g_dspState.DSPControl.pad != 0) if (g_dspState.DSPControl.pad != 0)
{ {
@ -510,7 +484,9 @@ void UpdateAudioDMA()
if (g_audioDMA.BlocksLeft == 0) 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); GenerateDSPInterrupt(DSP::INT_AID);
g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks;
g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; g_audioDMA.ReadAddress = g_audioDMA.SourceAddress;
@ -520,7 +496,7 @@ void UpdateAudioDMA()
{ {
// Send silence. Yeah, it's a bit of a waste to sample rate convert // Send silence. Yeah, it's a bit of a waste to sample rate convert
// silence. or hm. Maybe we shouldn't do this :) // silence. or hm. Maybe we shouldn't do this :)
dsp_emulator->DSP_SendAIBuffer(0, AudioInterface::GetAIDSampleRate()); AudioCommon::SendAIBuffer(0, AudioInterface::GetAIDSampleRate());
} }
} }

View File

@ -27,6 +27,35 @@ enum
ARAM_MASK = 0x00FFFFFF, ARAM_MASK = 0x00FFFFFF,
}; };
// UDSPControl
#define DSP_CONTROL_MASK 0x0C07
union UDSPControl
{
u16 Hex;
struct
{
// DSP Control
u16 DSPReset : 1; // Write 1 to reset and waits for 0
u16 DSPAssertInt : 1;
u16 DSPHalt : 1;
// Interrupt for DMA to the AI/speakers
u16 AID : 1;
u16 AID_mask : 1;
// ARAM DMA interrupt
u16 ARAM : 1;
u16 ARAM_mask : 1;
// DSP DMA interrupt
u16 DSP : 1;
u16 DSP_mask : 1;
// Other ???
u16 DMAState : 1; // DSPGetDMAStatus() uses this flag. __ARWaitForDMA() uses it too...maybe it's just general DMA flag
u16 DSPInitCode : 1; // Indicator that the DSP was initialized?
u16 DSPInit : 1; // DSPInit() writes to this flag
u16 pad : 4;
};
UDSPControl(u16 _Hex = 0) : Hex(_Hex) {}
};
void Init(bool hle); void Init(bool hle);
void Shutdown(); void Shutdown();

View File

@ -19,8 +19,6 @@
DSPHLE::DSPHLE() DSPHLE::DSPHLE()
{ {
m_InitMixer = false;
soundStream = nullptr;
} }
// Mailbox utility // Mailbox utility
@ -43,7 +41,6 @@ struct DSPState
bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
{ {
m_hWnd = hWnd;
m_bWii = bWii; m_bWii = bWii;
m_pUCode = nullptr; m_pUCode = nullptr;
m_lastUCode = nullptr; m_lastUCode = nullptr;
@ -54,7 +51,6 @@ bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
m_DSPControl.DSPHalt = 1; m_DSPControl.DSPHalt = 1;
m_DSPControl.DSPInit = 1; m_DSPControl.DSPInit = 1;
m_InitMixer = false;
m_dspState.Reset(); m_dspState.Reset();
return true; return true;
@ -66,7 +62,6 @@ void DSPHLE::DSP_StopSoundStream()
void DSPHLE::Shutdown() void DSPHLE::Shutdown()
{ {
AudioCommon::ShutdownSoundStream();
} }
void DSPHLE::DSP_Update(int cycles) void DSPHLE::DSP_Update(int cycles)
@ -139,23 +134,6 @@ void DSPHLE::DoState(PointerWrap &p)
p.SetMode(PointerWrap::MODE_VERIFY); p.SetMode(PointerWrap::MODE_VERIFY);
return; 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_DSPControl);
p.DoPOD(m_dspState); p.DoPOD(m_dspState);
@ -260,28 +238,10 @@ void DSPHLE::DSP_WriteMailBoxLow(bool _CPUMailbox, unsigned short _Value)
} }
} }
void DSPHLE::InitMixer()
{
unsigned int AISampleRate, DACSampleRate;
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
delete soundStream;
soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate, 48000), m_hWnd);
if (!soundStream) PanicAlert("Error starting up sound stream");
// Mixer is initialized
m_InitMixer = true;
}
// Other DSP fuctions // Other DSP fuctions
u16 DSPHLE::DSP_WriteControlRegister(unsigned short _Value) u16 DSPHLE::DSP_WriteControlRegister(unsigned short _Value)
{ {
UDSPControl Temp(_Value); DSP::UDSPControl Temp(_Value);
if (!m_InitMixer)
{
if (!Temp.DSPHalt)
{
InitMixer();
}
}
if (Temp.DSPReset) if (Temp.DSPReset)
{ {
@ -304,34 +264,6 @@ u16 DSPHLE::DSP_ReadControlRegister()
return m_DSPControl.Hex; 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) void DSPHLE::PauseAndLock(bool doLock, bool unpauseOnUnlock)
{ {
if (doLock || unpauseOnUnlock)
DSP_ClearAudioBuffer(doLock);
} }

View File

@ -4,10 +4,8 @@
#pragma once #pragma once
#include "AudioCommon/AudioCommon.h"
#include "AudioCommon/SoundStream.h"
#include "Core/DSPEmulator.h" #include "Core/DSPEmulator.h"
#include "Core/HW/DSP.h"
#include "Core/HW/DSPHLE/MailHandler.h" #include "Core/HW/DSPHLE/MailHandler.h"
class UCodeInterface; class UCodeInterface;
@ -29,10 +27,8 @@ public:
virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) override; virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) override;
virtual unsigned short DSP_ReadControlRegister() override; virtual unsigned short DSP_ReadControlRegister() override;
virtual unsigned short DSP_WriteControlRegister(unsigned short) 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_Update(int cycles) override;
virtual void DSP_StopSoundStream() override; virtual void DSP_StopSoundStream() override;
virtual void DSP_ClearAudioBuffer(bool mute) override;
virtual u32 DSP_UpdateRate() override; virtual u32 DSP_UpdateRate() override;
CMailHandler& AccessMailHandler() { return m_MailHandler; } CMailHandler& AccessMailHandler() { return m_MailHandler; }
@ -44,13 +40,10 @@ public:
private: private:
void SendMailToDSP(u32 _uMail); void SendMailToDSP(u32 _uMail);
void InitMixer();
// Declarations and definitions // Declarations and definitions
bool m_bWii; bool m_bWii;
bool m_InitMixer;
// Fake mailbox utility // Fake mailbox utility
struct DSPState struct DSPState
{ {
@ -73,7 +66,7 @@ private:
UCodeInterface* m_pUCode; UCodeInterface* m_pUCode;
UCodeInterface* m_lastUCode; UCodeInterface* m_lastUCode;
UDSPControl m_DSPControl; DSP::UDSPControl m_DSPControl;
CMailHandler m_MailHandler; CMailHandler m_MailHandler;
bool m_bHalt; bool m_bHalt;

View File

@ -2,9 +2,6 @@
// Licensed under GPLv2 // Licensed under GPLv2
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "AudioCommon/AudioCommon.h"
#include "AudioCommon/Mixer.h"
#include "Common/Atomic.h" #include "Common/Atomic.h"
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/Common.h" #include "Common/Common.h"
@ -33,8 +30,6 @@
DSPLLE::DSPLLE() DSPLLE::DSPLLE()
{ {
soundStream = nullptr;
m_InitMixer = false;
m_bIsRunning = false; m_bIsRunning = false;
m_cycle_count = 0; m_cycle_count = 0;
} }
@ -80,24 +75,6 @@ void DSPLLE::DoState(PointerWrap &p)
p.Do(cyclesLeft); p.Do(cyclesLeft);
p.Do(init_hax); p.Do(init_hax);
p.Do(m_cycle_count); 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 // Regular thread
@ -131,10 +108,8 @@ void DSPLLE::dsp_thread(DSPLLE *dsp_lle)
bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
{ {
m_hWnd = hWnd;
m_bWii = bWii; m_bWii = bWii;
m_bDSPThread = bDSPThread; m_bDSPThread = bDSPThread;
m_InitMixer = false;
std::string irom_file = File::GetUserPath(D_GCUSER_IDX) + DSP_IROM; std::string irom_file = File::GetUserPath(D_GCUSER_IDX) + DSP_IROM;
std::string coef_file = File::GetUserPath(D_GCUSER_IDX) + DSP_COEF; std::string coef_file = File::GetUserPath(D_GCUSER_IDX) + DSP_COEF;
@ -143,7 +118,9 @@ bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
irom_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_IROM; irom_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_IROM;
if (!File::Exists(coef_file)) if (!File::Exists(coef_file))
coef_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_COEF; coef_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_COEF;
if (!DSPCore_Init(irom_file, coef_file, AudioCommon::UseJIT()))
bool use_jit = SConfig::GetInstance().m_DSPEnableJIT;
if (!DSPCore_Init(irom_file, coef_file, use_jit))
return false; return false;
g_dsp.cpu_ram = Memory::GetPointer(0); g_dsp.cpu_ram = Memory::GetPointer(0);
@ -175,31 +152,11 @@ void DSPLLE::DSP_StopSoundStream()
void DSPLLE::Shutdown() void DSPLLE::Shutdown()
{ {
AudioCommon::ShutdownSoundStream();
DSPCore_Shutdown(); DSPCore_Shutdown();
} }
void DSPLLE::InitMixer()
{
unsigned int AISampleRate, DACSampleRate;
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
delete soundStream;
soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate, 48000), m_hWnd);
if (!soundStream) PanicAlert("Error starting up sound stream");
// Mixer is initialized
m_InitMixer = true;
}
u16 DSPLLE::DSP_WriteControlRegister(u16 _uFlag) u16 DSPLLE::DSP_WriteControlRegister(u16 _uFlag)
{ {
UDSPControl Temp(_uFlag);
if (!m_InitMixer)
{
if (!Temp.DSPHalt)
{
InitMixer();
}
}
DSPInterpreter::WriteCR(_uFlag); DSPInterpreter::WriteCR(_uFlag);
// Check if the CPU has set an external interrupt (CR_EXTERNAL_INT) // Check if the CPU has set an external interrupt (CR_EXTERNAL_INT)
@ -323,34 +280,8 @@ u32 DSPLLE::DSP_UpdateRate()
return 12600; // TO BE TWEAKED 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) void DSPLLE::PauseAndLock(bool doLock, bool unpauseOnUnlock)
{ {
if (doLock || unpauseOnUnlock)
DSP_ClearAudioBuffer(doLock);
if (doLock) if (doLock)
m_csDSPThreadActive.lock(); m_csDSPThreadActive.lock();
else else

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include "AudioCommon/SoundStream.h"
#include "Common/Thread.h" #include "Common/Thread.h"
#include "Core/DSPEmulator.h" #include "Core/DSPEmulator.h"
@ -28,19 +27,15 @@ public:
virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) override; virtual unsigned short DSP_ReadMailBoxLow(bool _CPUMailbox) override;
virtual unsigned short DSP_ReadControlRegister() override; virtual unsigned short DSP_ReadControlRegister() override;
virtual unsigned short DSP_WriteControlRegister(unsigned short) 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_Update(int cycles) override;
virtual void DSP_StopSoundStream() override; virtual void DSP_StopSoundStream() override;
virtual void DSP_ClearAudioBuffer(bool mute) override;
virtual u32 DSP_UpdateRate() override; virtual u32 DSP_UpdateRate() override;
private: private:
static void dsp_thread(DSPLLE* lpParameter); static void dsp_thread(DSPLLE* lpParameter);
void InitMixer();
std::thread m_hDSPThread; std::thread m_hDSPThread;
std::mutex m_csDSPThreadActive; std::mutex m_csDSPThreadActive;
bool m_InitMixer;
bool m_bWii; bool m_bWii;
bool m_bDSPThread; bool m_bDSPThread;
bool m_bIsRunning; bool m_bIsRunning;

View File

@ -23,6 +23,8 @@
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include <wx/stattext.h> #include <wx/stattext.h>
#include "AudioCommon/AudioCommon.h"
#include "Common/Common.h" #include "Common/Common.h"
#include "Common/CommonPaths.h" #include "Common/CommonPaths.h"
#include "Common/FileSearch.h" #include "Common/FileSearch.h"