diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp
index 2b785ffaf4..fa43baeb99 100644
--- a/Source/Core/AudioCommon/Mixer.cpp
+++ b/Source/Core/AudioCommon/Mixer.cpp
@@ -99,9 +99,6 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples, bool consider_
// Flush cached variable
Common::AtomicStore(m_indexR, indexR);
- // Add the DSPHLE sound, re-sampling is done inside
- Premix(samples, numSamples);
-
// Add the DTK Music
// Re-sampling is done inside
AudioInterface::Callback_GetStreaming(samples, numSamples, m_sampleRate);
diff --git a/Source/Core/AudioCommon/Mixer.h b/Source/Core/AudioCommon/Mixer.h
index a892618cca..f7fcdbf14b 100644
--- a/Source/Core/AudioCommon/Mixer.h
+++ b/Source/Core/AudioCommon/Mixer.h
@@ -26,7 +26,6 @@ public:
, m_dacSampleRate(DACSampleRate)
, m_bits(16)
, m_channels(2)
- , m_HLEready(false)
, m_logAudio(0)
, m_indexW(0)
, m_indexR(0)
@@ -45,7 +44,6 @@ public:
// Called from audio threads
virtual unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit = true);
- virtual void Premix(short * /*samples*/, unsigned int /*numSamples*/) {}
// Called from main thread
virtual void PushSamples(const short* samples, unsigned int num_samples);
@@ -53,11 +51,6 @@ public:
void SetThrottle(bool use) { m_throttle = use;}
- // TODO: do we need this
- bool IsHLEReady() const { return m_HLEready;}
- void SetHLEReady(bool ready) { m_HLEready = ready;}
- // ---------------------
-
virtual void StartLogAudio(const std::string& filename)
{
@@ -102,7 +95,6 @@ protected:
WaveFileWriter g_wave_writer;
- bool m_HLEready;
bool m_logAudio;
bool m_throttle;
diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index cae1a15d10..58e67b3cd7 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -78,7 +78,6 @@ set(SRCS ActionReplay.cpp
HW/DSPHLE/UCodes/UCode_Zelda_ADPCM.cpp
HW/DSPHLE/UCodes/UCode_Zelda_Voice.cpp
HW/DSPHLE/UCodes/UCode_Zelda_Synth.cpp
- HW/DSPHLE/HLEMixer.cpp
HW/DSPHLE/MailHandler.cpp
HW/DSPHLE/DSPHLE.cpp
HW/DSPLLE/DSPDebugInterface.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index f91087c3d2..e2b02f8a82 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -106,7 +106,6 @@
-
@@ -305,7 +304,6 @@
-
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 34264a07cf..af927b7b9f 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -347,9 +347,6 @@
HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE
-
- HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE
-
HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE
@@ -873,9 +870,6 @@
HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE
-
- HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE
-
HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE
diff --git a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp
index 0bdffb70a2..eb7ca52ab8 100644
--- a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp
+++ b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp
@@ -15,7 +15,6 @@
#include "Core/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h"
#include "Core/HW/DSPHLE/DSPHLE.h"
-#include "Core/HW/DSPHLE/HLEMixer.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
DSPHLE::DSPHLE()
@@ -266,7 +265,7 @@ void DSPHLE::InitMixer()
unsigned int AISampleRate, DACSampleRate;
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
delete soundStream;
- soundStream = AudioCommon::InitSoundStream(new HLEMixer(this, AISampleRate, DACSampleRate, 48000), m_hWnd);
+ soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate, 48000), m_hWnd);
if (!soundStream) PanicAlert("Error starting up sound stream");
// Mixer is initialized
m_InitMixer = true;
diff --git a/Source/Core/Core/HW/DSPHLE/HLEMixer.cpp b/Source/Core/Core/HW/DSPHLE/HLEMixer.cpp
deleted file mode 100644
index d1d51c4c85..0000000000
--- a/Source/Core/Core/HW/DSPHLE/HLEMixer.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#include "Core/HW/DSPHLE/DSPHLE.h"
-#include "Core/HW/DSPHLE/HLEMixer.h"
-#include "Core/HW/DSPHLE/UCodes/UCodes.h"
-
-void HLEMixer::Premix(short *samples, unsigned int numSamples)
-{
- // if this was called directly from the HLE
- if (IsHLEReady())
- {
- IUCode *pUCode = m_DSPHLE->GetUCode();
- if (pUCode && samples)
- pUCode->MixAdd(samples, numSamples);
- }
-}
-
diff --git a/Source/Core/Core/HW/DSPHLE/HLEMixer.h b/Source/Core/Core/HW/DSPHLE/HLEMixer.h
deleted file mode 100644
index 135bfe97b8..0000000000
--- a/Source/Core/Core/HW/DSPHLE/HLEMixer.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "AudioCommon/AudioCommon.h"
-#include "AudioCommon/Mixer.h"
-
-class DSPHLE;
-
-class HLEMixer : public CMixer
-{
-public:
- HLEMixer(DSPHLE *dsp_hle, unsigned int AISampleRate = 48000, unsigned int DACSampleRate = 48000, unsigned int BackendSampleRate = 32000)
- : CMixer(AISampleRate, DACSampleRate, BackendSampleRate), m_DSPHLE(dsp_hle) {};
-
- virtual void Premix(short *samples, unsigned int numSamples) override;
-private:
- DSPHLE *m_DSPHLE;
-};
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.cpp
index f7eea84f22..379da8bab4 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.cpp
@@ -16,30 +16,16 @@ CUCode_AX::CUCode_AX(DSPHLE* dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
, m_work_available(false)
, m_cmdlist_size(0)
- , m_run_on_thread(false)
{
WARN_LOG(DSPHLE, "Instantiating CUCode_AX: crc=%08x", crc);
m_rMailHandler.PushMail(DSP_INIT);
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
LoadResamplingCoefficients();
-
- // DSP HLE on thread is always disabled because it causes audio
- // issues/glitching (different timing characteristics). m_run_on_thread is
- // always false.
- if (m_run_on_thread)
- m_axthread = std::thread(SpawnAXThread, this);
}
CUCode_AX::~CUCode_AX()
{
- if (m_run_on_thread)
- {
- m_cmdlist_size = (u16)-1; // Special value to signal end
- NotifyAXThread();
- m_axthread.join();
- }
-
m_rMailHandler.Clear();
}
@@ -80,32 +66,6 @@ void CUCode_AX::LoadResamplingCoefficients()
m_coeffs_available = true;
}
-void CUCode_AX::SpawnAXThread(CUCode_AX* self)
-{
- self->AXThread();
-}
-
-void CUCode_AX::AXThread()
-{
- while (true)
- {
- {
- std::unique_lock lk(m_cmdlist_mutex);
- while (m_cmdlist_size == 0)
- m_cmdlist_cv.wait(lk);
- }
-
- if (m_cmdlist_size == (u16)-1) // End of thread signal
- break;
-
- m_processing.lock();
- HandleCommandList();
- m_cmdlist_size = 0;
- SignalWorkEnd();
- m_processing.unlock();
- }
-}
-
void CUCode_AX::SignalWorkEnd()
{
// Signal end of processing
@@ -113,20 +73,6 @@ void CUCode_AX::SignalWorkEnd()
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
}
-void CUCode_AX::NotifyAXThread()
-{
- std::unique_lock lk(m_cmdlist_mutex);
- m_cmdlist_cv.notify_one();
-}
-
-void CUCode_AX::StartWorking()
-{
- if (m_run_on_thread)
- NotifyAXThread();
- else
- m_work_available = true;
-}
-
void CUCode_AX::HandleCommandList()
{
// Temp variables for addresses computation
@@ -660,15 +606,10 @@ void CUCode_AX::HandleMail(u32 mail)
bool set_next_is_cmdlist = false;
- // Wait for DSP processing to be done before answering any mail. This is
- // safe to do because it matches what the DSP does on real hardware: there
- // is no interrupt when a mail from CPU is received.
- m_processing.lock();
-
if (next_is_cmdlist)
{
CopyCmdList(mail, cmdlist_size);
- StartWorking();
+ m_work_available = true;
}
else if (m_UploadSetupInProgress)
{
@@ -682,7 +623,6 @@ void CUCode_AX::HandleMail(u32 mail)
}
else if (mail == MAIL_NEW_UCODE)
{
- soundStream->GetMixer()->SetHLEReady(false);
m_UploadSetupInProgress = true;
}
else if (mail == MAIL_RESET)
@@ -705,7 +645,6 @@ void CUCode_AX::HandleMail(u32 mail)
ERROR_LOG(DSPHLE, "Unknown mail sent to AX::HandleMail: %08x", mail);
}
- m_processing.unlock();
next_is_cmdlist = set_next_is_cmdlist;
}
@@ -722,12 +661,6 @@ void CUCode_AX::CopyCmdList(u32 addr, u16 size)
m_cmdlist_size = size;
}
-void CUCode_AX::MixAdd(short* out_buffer, int nsamples)
-{
- // Should never be called: we do not set HLE as ready.
- // We accurately send samples to RAM instead of directly to the mixer.
-}
-
void CUCode_AX::Update(int cycles)
{
// Used for UCode switching.
@@ -767,8 +700,6 @@ void CUCode_AX::DoAXState(PointerWrap& p)
void CUCode_AX::DoState(PointerWrap& p)
{
- std::lock_guard lk(m_processing);
-
DoStateShared(p);
DoAXState(p);
}
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.h b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.h
index ede8ef6aa3..f29c14659b 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.h
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AX.h
@@ -56,15 +56,10 @@ public:
virtual ~CUCode_AX();
virtual void HandleMail(u32 mail) override;
- virtual void MixAdd(short* out_buffer, int nsamples) override;
virtual void Update(int cycles) override;
virtual void DoState(PointerWrap& p) override;
u32 GetUpdateMs() override;
- // Needed because StdThread.h std::thread implem does not support member
- // pointers. TODO(delroth): obsolete.
- static void SpawnAXThread(CUCode_AX* self);
-
protected:
enum MailType
{
@@ -92,19 +87,8 @@ protected:
// This flag is set if there is anything to process.
bool m_work_available;
- // Volatile because it's set by HandleMail and accessed in
- // HandleCommandList, which are running in two different threads.
- volatile u16 m_cmdlist[512];
- volatile u32 m_cmdlist_size;
-
- bool m_run_on_thread;
-
- // Sync objects
- std::mutex m_processing;
- std::condition_variable m_cmdlist_cv;
- std::mutex m_cmdlist_mutex;
-
- std::thread m_axthread;
+ u16 m_cmdlist[512];
+ u32 m_cmdlist_size;
// Table of coefficients for polyphase sample rate conversion.
// The coefficients aren't always available (they are part of the DSP DROM)
@@ -125,16 +109,6 @@ protected:
// Apply updates to a PB. Generic, used in AX GC and AX Wii.
void ApplyUpdatesForMs(int curr_ms, u16* pb, u16* num_updates, u16* updates);
- // Signal that we should start handling a command list. Dispatches to the
- // AX thread if using a thread, else just sets a boolean flag.
- void StartWorking();
-
- // Send a notification to the AX thread to tell it a new cmdlist addr is
- // available for processing.
- void NotifyAXThread();
-
- void AXThread();
-
virtual void HandleCommandList();
void SignalWorkEnd();
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AXWii.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AXWii.cpp
index 8ebef6e80e..9655f99a36 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AXWii.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_AXWii.cpp
@@ -667,8 +667,6 @@ u32 CUCode_AXWii::GetUpdateMs()
void CUCode_AXWii::DoState(PointerWrap &p)
{
- std::lock_guard lk(m_processing);
-
DoStateShared(p);
DoAXState(p);
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.cpp
index 62c67d7927..ffd50d6b63 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.cpp
@@ -130,11 +130,13 @@ void CUCode_Zelda::HandleMail_LightVersion(u32 _uMail)
if (m_bSyncCmdPending)
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
+
+ MixAudio();
+
m_CurBuffer++;
if (m_CurBuffer == m_NumBuffers)
{
- soundStream->GetMixer()->SetHLEReady(true);
m_bSyncCmdPending = false;
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
}
@@ -189,6 +191,8 @@ void CUCode_Zelda::HandleMail_SMSVersion(u32 _uMail)
m_NumSyncMail = 0;
m_bSyncInProgress = false;
+ MixAudio();
+
m_CurBuffer++;
m_rMailHandler.PushMail(DSP_SYNC);
@@ -200,7 +204,6 @@ void CUCode_Zelda::HandleMail_SMSVersion(u32 _uMail)
m_rMailHandler.PushMail(DSP_FRAME_END);
// DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
- soundStream->GetMixer()->SetHLEReady(true);
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
// soundStream->Update(); //do it in this thread to avoid sync problems
@@ -292,30 +295,12 @@ void CUCode_Zelda::HandleMail_NormalVersion(u32 _uMail)
m_SyncFlags[n] = _uMail & 0xFFFF;
m_bSyncInProgress = false;
- // Normally, we should mix to the buffers used by the game.
- // We don't do it currently for a simple reason:
- // if the game runs fast all the time, then it's OK,
- // but if it runs slow, sound can become choppy.
- // This problem won't happen when mixing to the buffer
- // provided by MixAdd(), because the size of this buffer
- // is automatically adjusted if the game runs slow.
-#if 0
- if (m_SyncFlags[n] & 0x8000)
- {
- for (; m_CurVoice < m_MaxVoice; m_CurVoice++)
- {
- if (m_CurVoice >= m_NumVoices)
- break;
-
- MixVoice(m_CurVoice);
- }
- }
- else
-#endif
- m_CurVoice = m_MaxVoice;
+ m_CurVoice = m_MaxVoice;
if (m_CurVoice >= m_NumVoices)
{
+ MixAudio();
+
m_CurBuffer++;
m_rMailHandler.PushMail(DSP_SYNC);
@@ -330,7 +315,6 @@ void CUCode_Zelda::HandleMail_NormalVersion(u32 _uMail)
m_rMailHandler.PushMail(DSP_FRAME_END);
//g_dspInitialize.pGenerateDSPInterrupt();
- soundStream->GetMixer()->SetHLEReady(true);
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
// soundStream->Update(); //do it in this thread to avoid sync problems
@@ -392,7 +376,6 @@ void CUCode_Zelda::HandleMail_NormalVersion(u32 _uMail)
case 0x0001: // accepts params to either dma to iram and/or dram (used for hotbooting a new ucode)
// TODO find a better way to protect from HLEMixer?
- soundStream->GetMixer()->SetHLEReady(false);
m_UploadSetupInProgress = true;
return;
@@ -484,8 +467,8 @@ void CUCode_Zelda::ExecuteList()
// Addresses for right & left buffers in main memory
// Each buffer is 160 bytes long. The number of (both left & right) buffers
// is set by the first mail of the list.
- m_RightBuffersAddr = Read32() & 0x7FFFFFFF;
m_LeftBuffersAddr = Read32() & 0x7FFFFFFF;
+ m_RightBuffersAddr = Read32() & 0x7FFFFFFF;
DEBUG_LOG(DSPHLE, "DsyncFrame");
// These alternate between three sets of mixing buffers. They are all three fairly near,
@@ -559,9 +542,6 @@ u32 CUCode_Zelda::GetUpdateMs()
void CUCode_Zelda::DoState(PointerWrap &p)
{
- // It's bad if we try to save during Mix()
- std::lock_guard lk(m_csMix);
-
p.Do(m_AFCCoefTable);
p.Do(m_MiscTable);
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.h b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.h
index eab6de743f..e3818a20bf 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.h
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda.h
@@ -125,9 +125,7 @@ public:
void HandleMail_LightVersion(u32 _uMail);
void HandleMail_SMSVersion(u32 _uMail);
void HandleMail_NormalVersion(u32 _uMail);
-
void Update(int cycles) override;
- void MixAdd(short* buffer, int size) override;
void CopyPBsFromRAM();
void CopyPBsToRAM();
@@ -291,4 +289,6 @@ private:
// Renders a voice and mixes it into LeftBuffer, RightBuffer
void RenderAddVoice(ZeldaVoicePB& PB, s32* _LeftBuffer, s32* _RightBuffer, int _Size);
+
+ void MixAudio();
};
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda_Voice.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda_Voice.cpp
index 4393a48f0c..723a0aca98 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda_Voice.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCode_Zelda_Voice.cpp
@@ -49,9 +49,7 @@ void CUCode_Zelda::WritebackVoicePB(u32 _Addr, ZeldaVoicePB& PB)
int CUCode_Zelda::ConvertRatio(int pb_ratio)
{
- float _ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
- u32 _ratio = (pb_ratio << 16);
- return (u64)((_ratio * _ratioFactor) * 16) >> 16;
+ return pb_ratio * 16;
}
int CUCode_Zelda::SizeForResampling(ZeldaVoicePB &PB, int size, int ratio) {
@@ -739,17 +737,13 @@ ContinueWithBlock:
}
}
-// size is in stereo samples.
-void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
+void CUCode_Zelda::MixAudio()
{
- std::lock_guard lk(m_csMix);
- // Safety check
- if (_Size > 256 * 1024 - 8)
- _Size = 256 * 1024 - 8;
+ const int BufferSamples = 5 * 16;
// Final mix buffers
- memset(m_LeftBuffer, 0, _Size * sizeof(s32));
- memset(m_RightBuffer, 0, _Size * sizeof(s32));
+ memset(m_LeftBuffer, 0, BufferSamples * sizeof(s32));
+ memset(m_RightBuffer, 0, BufferSamples * sizeof(s32));
// For each PB...
for (u32 i = 0; i < m_NumVoices; i++)
@@ -769,22 +763,24 @@ void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
if (pb.KeyOff != 0)
continue;
- RenderAddVoice(pb, m_LeftBuffer, m_RightBuffer, _Size);
+ RenderAddVoice(pb, m_LeftBuffer, m_RightBuffer, BufferSamples);
WritebackVoicePB(m_VoicePBsAddr + (i * 0x180), pb);
}
// Post processing, final conversion.
- for (int i = 0; i < _Size; i++)
+ s16* left_buffer = (s16*)HLEMemory_Get_Pointer(m_LeftBuffersAddr);
+ s16* right_buffer = (s16*)HLEMemory_Get_Pointer(m_RightBuffersAddr);
+ left_buffer += m_CurBuffer * BufferSamples;
+ right_buffer += m_CurBuffer * BufferSamples;
+ for (int i = 0; i < BufferSamples; i++)
{
- s32 left = (s32)_Buffer[0] + m_LeftBuffer[i];
- s32 right = (s32)_Buffer[1] + m_RightBuffer[i];
+ s32 left = m_LeftBuffer[i];
+ s32 right = m_RightBuffer[i];
MathUtil::Clamp(&left, -32768, 32767);
- _Buffer[0] = (short)left;
+ left_buffer[i] = Common::swap16((short)left);
MathUtil::Clamp(&right, -32768, 32767);
- _Buffer[1] = (short)right;
-
- _Buffer += 2;
+ right_buffer[i] = Common::swap16((short)right);
}
}
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h
index 73bf8795fb..d011d91370 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h
@@ -77,7 +77,6 @@ public:
// Cycles are out of the 81/121mhz the DSP runs at.
virtual void Update(int cycles) = 0;
- virtual void MixAdd(short* buffer, int size) {}
virtual u32 GetUpdateMs() = 0;
virtual void DoState(PointerWrap &p) { DoStateShared(p); }
@@ -95,7 +94,6 @@ protected:
void DoStateShared(PointerWrap &p);
CMailHandler& m_rMailHandler;
- std::mutex m_csMix;
enum EDSP_Codes
{