Merge pull request #214 from magumagu/zelda-ucode-cleanup
Zelda ucode cleanup
This commit is contained in:
commit
784c636db8
|
@ -99,9 +99,6 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples, bool consider_
|
||||||
// Flush cached variable
|
// Flush cached variable
|
||||||
Common::AtomicStore(m_indexR, indexR);
|
Common::AtomicStore(m_indexR, indexR);
|
||||||
|
|
||||||
// Add the DSPHLE sound, re-sampling is done inside
|
|
||||||
Premix(samples, numSamples);
|
|
||||||
|
|
||||||
// Add the DTK Music
|
// Add the DTK Music
|
||||||
// Re-sampling is done inside
|
// Re-sampling is done inside
|
||||||
AudioInterface::Callback_GetStreaming(samples, numSamples, m_sampleRate);
|
AudioInterface::Callback_GetStreaming(samples, numSamples, m_sampleRate);
|
||||||
|
|
|
@ -26,7 +26,6 @@ public:
|
||||||
, m_dacSampleRate(DACSampleRate)
|
, m_dacSampleRate(DACSampleRate)
|
||||||
, m_bits(16)
|
, m_bits(16)
|
||||||
, m_channels(2)
|
, m_channels(2)
|
||||||
, m_HLEready(false)
|
|
||||||
, m_logAudio(0)
|
, m_logAudio(0)
|
||||||
, m_indexW(0)
|
, m_indexW(0)
|
||||||
, m_indexR(0)
|
, m_indexR(0)
|
||||||
|
@ -45,7 +44,6 @@ public:
|
||||||
|
|
||||||
// Called from audio threads
|
// Called from audio threads
|
||||||
virtual unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit = true);
|
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
|
// Called from main thread
|
||||||
virtual void PushSamples(const short* samples, unsigned int num_samples);
|
virtual void PushSamples(const short* samples, unsigned int num_samples);
|
||||||
|
@ -53,11 +51,6 @@ public:
|
||||||
|
|
||||||
void SetThrottle(bool use) { m_throttle = use;}
|
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)
|
virtual void StartLogAudio(const std::string& filename)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +95,6 @@ protected:
|
||||||
|
|
||||||
WaveFileWriter g_wave_writer;
|
WaveFileWriter g_wave_writer;
|
||||||
|
|
||||||
bool m_HLEready;
|
|
||||||
bool m_logAudio;
|
bool m_logAudio;
|
||||||
|
|
||||||
bool m_throttle;
|
bool m_throttle;
|
||||||
|
|
|
@ -78,7 +78,6 @@ set(SRCS ActionReplay.cpp
|
||||||
HW/DSPHLE/UCodes/UCode_Zelda_ADPCM.cpp
|
HW/DSPHLE/UCodes/UCode_Zelda_ADPCM.cpp
|
||||||
HW/DSPHLE/UCodes/UCode_Zelda_Voice.cpp
|
HW/DSPHLE/UCodes/UCode_Zelda_Voice.cpp
|
||||||
HW/DSPHLE/UCodes/UCode_Zelda_Synth.cpp
|
HW/DSPHLE/UCodes/UCode_Zelda_Synth.cpp
|
||||||
HW/DSPHLE/HLEMixer.cpp
|
|
||||||
HW/DSPHLE/MailHandler.cpp
|
HW/DSPHLE/MailHandler.cpp
|
||||||
HW/DSPHLE/DSPHLE.cpp
|
HW/DSPHLE/DSPHLE.cpp
|
||||||
HW/DSPLLE/DSPDebugInterface.cpp
|
HW/DSPLLE/DSPDebugInterface.cpp
|
||||||
|
|
|
@ -106,7 +106,6 @@
|
||||||
<ClCompile Include="HW\CPU.cpp" />
|
<ClCompile Include="HW\CPU.cpp" />
|
||||||
<ClCompile Include="HW\DSP.cpp" />
|
<ClCompile Include="HW\DSP.cpp" />
|
||||||
<ClCompile Include="HW\DSPHLE\DSPHLE.cpp" />
|
<ClCompile Include="HW\DSPHLE\DSPHLE.cpp" />
|
||||||
<ClCompile Include="HW\DSPHLE\HLEMixer.cpp" />
|
|
||||||
<ClCompile Include="HW\DSPHLE\MailHandler.cpp" />
|
<ClCompile Include="HW\DSPHLE\MailHandler.cpp" />
|
||||||
<ClCompile Include="HW\DSPHLE\UCodes\UCodes.cpp" />
|
<ClCompile Include="HW\DSPHLE\UCodes\UCodes.cpp" />
|
||||||
<ClCompile Include="HW\DSPHLE\UCodes\UCode_AX.cpp" />
|
<ClCompile Include="HW\DSPHLE\UCodes\UCode_AX.cpp" />
|
||||||
|
@ -305,7 +304,6 @@
|
||||||
<ClInclude Include="HW\CPU.h" />
|
<ClInclude Include="HW\CPU.h" />
|
||||||
<ClInclude Include="HW\DSP.h" />
|
<ClInclude Include="HW\DSP.h" />
|
||||||
<ClInclude Include="HW\DSPHLE\DSPHLE.h" />
|
<ClInclude Include="HW\DSPHLE\DSPHLE.h" />
|
||||||
<ClInclude Include="HW\DSPHLE\HLEMixer.h" />
|
|
||||||
<ClInclude Include="HW\DSPHLE\MailHandler.h" />
|
<ClInclude Include="HW\DSPHLE\MailHandler.h" />
|
||||||
<ClInclude Include="HW\DSPHLE\UCodes\UCodes.h" />
|
<ClInclude Include="HW\DSPHLE\UCodes\UCodes.h" />
|
||||||
<ClInclude Include="HW\DSPHLE\UCodes\UCode_AX.h" />
|
<ClInclude Include="HW\DSPHLE\UCodes\UCode_AX.h" />
|
||||||
|
|
|
@ -347,9 +347,6 @@
|
||||||
<ClCompile Include="HW\DSPHLE\DSPHLE.cpp">
|
<ClCompile Include="HW\DSPHLE\DSPHLE.cpp">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="HW\DSPHLE\HLEMixer.cpp">
|
|
||||||
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="HW\DSPHLE\MailHandler.cpp">
|
<ClCompile Include="HW\DSPHLE\MailHandler.cpp">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -873,9 +870,6 @@
|
||||||
<ClInclude Include="HW\DSPHLE\DSPHLE.h">
|
<ClInclude Include="HW\DSPHLE\DSPHLE.h">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="HW\DSPHLE\HLEMixer.h">
|
|
||||||
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="HW\DSPHLE\MailHandler.h">
|
<ClInclude Include="HW\DSPHLE\MailHandler.h">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\DSP Interface + HLE\HLE</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
#include "Core/HW/VideoInterface.h"
|
#include "Core/HW/VideoInterface.h"
|
||||||
#include "Core/HW/DSPHLE/DSPHLE.h"
|
#include "Core/HW/DSPHLE/DSPHLE.h"
|
||||||
#include "Core/HW/DSPHLE/HLEMixer.h"
|
|
||||||
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
||||||
|
|
||||||
DSPHLE::DSPHLE()
|
DSPHLE::DSPHLE()
|
||||||
|
@ -266,7 +265,7 @@ void DSPHLE::InitMixer()
|
||||||
unsigned int AISampleRate, DACSampleRate;
|
unsigned int AISampleRate, DACSampleRate;
|
||||||
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
||||||
delete soundStream;
|
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");
|
if (!soundStream) PanicAlert("Error starting up sound stream");
|
||||||
// Mixer is initialized
|
// Mixer is initialized
|
||||||
m_InitMixer = true;
|
m_InitMixer = true;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
|
|
@ -16,30 +16,16 @@ CUCode_AX::CUCode_AX(DSPHLE* dsp_hle, u32 crc)
|
||||||
: IUCode(dsp_hle, crc)
|
: IUCode(dsp_hle, crc)
|
||||||
, m_work_available(false)
|
, m_work_available(false)
|
||||||
, m_cmdlist_size(0)
|
, m_cmdlist_size(0)
|
||||||
, m_run_on_thread(false)
|
|
||||||
{
|
{
|
||||||
WARN_LOG(DSPHLE, "Instantiating CUCode_AX: crc=%08x", crc);
|
WARN_LOG(DSPHLE, "Instantiating CUCode_AX: crc=%08x", crc);
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
|
|
||||||
LoadResamplingCoefficients();
|
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()
|
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();
|
m_rMailHandler.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,32 +66,6 @@ void CUCode_AX::LoadResamplingCoefficients()
|
||||||
m_coeffs_available = true;
|
m_coeffs_available = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUCode_AX::SpawnAXThread(CUCode_AX* self)
|
|
||||||
{
|
|
||||||
self->AXThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUCode_AX::AXThread()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> 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()
|
void CUCode_AX::SignalWorkEnd()
|
||||||
{
|
{
|
||||||
// Signal end of processing
|
// Signal end of processing
|
||||||
|
@ -113,20 +73,6 @@ void CUCode_AX::SignalWorkEnd()
|
||||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUCode_AX::NotifyAXThread()
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> 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()
|
void CUCode_AX::HandleCommandList()
|
||||||
{
|
{
|
||||||
// Temp variables for addresses computation
|
// Temp variables for addresses computation
|
||||||
|
@ -660,15 +606,10 @@ void CUCode_AX::HandleMail(u32 mail)
|
||||||
|
|
||||||
bool set_next_is_cmdlist = false;
|
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)
|
if (next_is_cmdlist)
|
||||||
{
|
{
|
||||||
CopyCmdList(mail, cmdlist_size);
|
CopyCmdList(mail, cmdlist_size);
|
||||||
StartWorking();
|
m_work_available = true;
|
||||||
}
|
}
|
||||||
else if (m_UploadSetupInProgress)
|
else if (m_UploadSetupInProgress)
|
||||||
{
|
{
|
||||||
|
@ -682,7 +623,6 @@ void CUCode_AX::HandleMail(u32 mail)
|
||||||
}
|
}
|
||||||
else if (mail == MAIL_NEW_UCODE)
|
else if (mail == MAIL_NEW_UCODE)
|
||||||
{
|
{
|
||||||
soundStream->GetMixer()->SetHLEReady(false);
|
|
||||||
m_UploadSetupInProgress = true;
|
m_UploadSetupInProgress = true;
|
||||||
}
|
}
|
||||||
else if (mail == MAIL_RESET)
|
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);
|
ERROR_LOG(DSPHLE, "Unknown mail sent to AX::HandleMail: %08x", mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_processing.unlock();
|
|
||||||
next_is_cmdlist = set_next_is_cmdlist;
|
next_is_cmdlist = set_next_is_cmdlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,12 +661,6 @@ void CUCode_AX::CopyCmdList(u32 addr, u16 size)
|
||||||
m_cmdlist_size = 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)
|
void CUCode_AX::Update(int cycles)
|
||||||
{
|
{
|
||||||
// Used for UCode switching.
|
// Used for UCode switching.
|
||||||
|
@ -767,8 +700,6 @@ void CUCode_AX::DoAXState(PointerWrap& p)
|
||||||
|
|
||||||
void CUCode_AX::DoState(PointerWrap& p)
|
void CUCode_AX::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_processing);
|
|
||||||
|
|
||||||
DoStateShared(p);
|
DoStateShared(p);
|
||||||
DoAXState(p);
|
DoAXState(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,15 +56,10 @@ public:
|
||||||
virtual ~CUCode_AX();
|
virtual ~CUCode_AX();
|
||||||
|
|
||||||
virtual void HandleMail(u32 mail) override;
|
virtual void HandleMail(u32 mail) override;
|
||||||
virtual void MixAdd(short* out_buffer, int nsamples) override;
|
|
||||||
virtual void Update(int cycles) override;
|
virtual void Update(int cycles) override;
|
||||||
virtual void DoState(PointerWrap& p) override;
|
virtual void DoState(PointerWrap& p) override;
|
||||||
u32 GetUpdateMs() 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:
|
protected:
|
||||||
enum MailType
|
enum MailType
|
||||||
{
|
{
|
||||||
|
@ -92,19 +87,8 @@ protected:
|
||||||
// This flag is set if there is anything to process.
|
// This flag is set if there is anything to process.
|
||||||
bool m_work_available;
|
bool m_work_available;
|
||||||
|
|
||||||
// Volatile because it's set by HandleMail and accessed in
|
u16 m_cmdlist[512];
|
||||||
// HandleCommandList, which are running in two different threads.
|
u32 m_cmdlist_size;
|
||||||
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;
|
|
||||||
|
|
||||||
// Table of coefficients for polyphase sample rate conversion.
|
// Table of coefficients for polyphase sample rate conversion.
|
||||||
// The coefficients aren't always available (they are part of the DSP DROM)
|
// 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.
|
// 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);
|
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();
|
virtual void HandleCommandList();
|
||||||
void SignalWorkEnd();
|
void SignalWorkEnd();
|
||||||
|
|
||||||
|
|
|
@ -667,8 +667,6 @@ u32 CUCode_AXWii::GetUpdateMs()
|
||||||
|
|
||||||
void CUCode_AXWii::DoState(PointerWrap &p)
|
void CUCode_AXWii::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_processing);
|
|
||||||
|
|
||||||
DoStateShared(p);
|
DoStateShared(p);
|
||||||
DoAXState(p);
|
DoAXState(p);
|
||||||
|
|
||||||
|
|
|
@ -130,11 +130,13 @@ void CUCode_Zelda::HandleMail_LightVersion(u32 _uMail)
|
||||||
if (m_bSyncCmdPending)
|
if (m_bSyncCmdPending)
|
||||||
{
|
{
|
||||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
|
|
||||||
|
MixAudio();
|
||||||
|
|
||||||
m_CurBuffer++;
|
m_CurBuffer++;
|
||||||
|
|
||||||
if (m_CurBuffer == m_NumBuffers)
|
if (m_CurBuffer == m_NumBuffers)
|
||||||
{
|
{
|
||||||
soundStream->GetMixer()->SetHLEReady(true);
|
|
||||||
m_bSyncCmdPending = false;
|
m_bSyncCmdPending = false;
|
||||||
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
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_NumSyncMail = 0;
|
||||||
m_bSyncInProgress = false;
|
m_bSyncInProgress = false;
|
||||||
|
|
||||||
|
MixAudio();
|
||||||
|
|
||||||
m_CurBuffer++;
|
m_CurBuffer++;
|
||||||
|
|
||||||
m_rMailHandler.PushMail(DSP_SYNC);
|
m_rMailHandler.PushMail(DSP_SYNC);
|
||||||
|
@ -200,7 +204,6 @@ void CUCode_Zelda::HandleMail_SMSVersion(u32 _uMail)
|
||||||
m_rMailHandler.PushMail(DSP_FRAME_END);
|
m_rMailHandler.PushMail(DSP_FRAME_END);
|
||||||
// DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
// DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
|
|
||||||
soundStream->GetMixer()->SetHLEReady(true);
|
|
||||||
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
||||||
// soundStream->Update(); //do it in this thread to avoid sync problems
|
// 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_SyncFlags[n] = _uMail & 0xFFFF;
|
||||||
m_bSyncInProgress = false;
|
m_bSyncInProgress = false;
|
||||||
|
|
||||||
// Normally, we should mix to the buffers used by the game.
|
m_CurVoice = m_MaxVoice;
|
||||||
// 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;
|
|
||||||
|
|
||||||
if (m_CurVoice >= m_NumVoices)
|
if (m_CurVoice >= m_NumVoices)
|
||||||
{
|
{
|
||||||
|
MixAudio();
|
||||||
|
|
||||||
m_CurBuffer++;
|
m_CurBuffer++;
|
||||||
|
|
||||||
m_rMailHandler.PushMail(DSP_SYNC);
|
m_rMailHandler.PushMail(DSP_SYNC);
|
||||||
|
@ -330,7 +315,6 @@ void CUCode_Zelda::HandleMail_NormalVersion(u32 _uMail)
|
||||||
m_rMailHandler.PushMail(DSP_FRAME_END);
|
m_rMailHandler.PushMail(DSP_FRAME_END);
|
||||||
//g_dspInitialize.pGenerateDSPInterrupt();
|
//g_dspInitialize.pGenerateDSPInterrupt();
|
||||||
|
|
||||||
soundStream->GetMixer()->SetHLEReady(true);
|
|
||||||
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
||||||
// soundStream->Update(); //do it in this thread to avoid sync problems
|
// 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)
|
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?
|
// TODO find a better way to protect from HLEMixer?
|
||||||
soundStream->GetMixer()->SetHLEReady(false);
|
|
||||||
m_UploadSetupInProgress = true;
|
m_UploadSetupInProgress = true;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -484,8 +467,8 @@ void CUCode_Zelda::ExecuteList()
|
||||||
// Addresses for right & left buffers in main memory
|
// Addresses for right & left buffers in main memory
|
||||||
// Each buffer is 160 bytes long. The number of (both left & right) buffers
|
// Each buffer is 160 bytes long. The number of (both left & right) buffers
|
||||||
// is set by the first mail of the list.
|
// is set by the first mail of the list.
|
||||||
m_RightBuffersAddr = Read32() & 0x7FFFFFFF;
|
|
||||||
m_LeftBuffersAddr = Read32() & 0x7FFFFFFF;
|
m_LeftBuffersAddr = Read32() & 0x7FFFFFFF;
|
||||||
|
m_RightBuffersAddr = Read32() & 0x7FFFFFFF;
|
||||||
|
|
||||||
DEBUG_LOG(DSPHLE, "DsyncFrame");
|
DEBUG_LOG(DSPHLE, "DsyncFrame");
|
||||||
// These alternate between three sets of mixing buffers. They are all three fairly near,
|
// 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)
|
void CUCode_Zelda::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
// It's bad if we try to save during Mix()
|
|
||||||
std::lock_guard<std::mutex> lk(m_csMix);
|
|
||||||
|
|
||||||
p.Do(m_AFCCoefTable);
|
p.Do(m_AFCCoefTable);
|
||||||
p.Do(m_MiscTable);
|
p.Do(m_MiscTable);
|
||||||
|
|
||||||
|
|
|
@ -125,9 +125,7 @@ public:
|
||||||
void HandleMail_LightVersion(u32 _uMail);
|
void HandleMail_LightVersion(u32 _uMail);
|
||||||
void HandleMail_SMSVersion(u32 _uMail);
|
void HandleMail_SMSVersion(u32 _uMail);
|
||||||
void HandleMail_NormalVersion(u32 _uMail);
|
void HandleMail_NormalVersion(u32 _uMail);
|
||||||
|
|
||||||
void Update(int cycles) override;
|
void Update(int cycles) override;
|
||||||
void MixAdd(short* buffer, int size) override;
|
|
||||||
|
|
||||||
void CopyPBsFromRAM();
|
void CopyPBsFromRAM();
|
||||||
void CopyPBsToRAM();
|
void CopyPBsToRAM();
|
||||||
|
@ -291,4 +289,6 @@ private:
|
||||||
|
|
||||||
// Renders a voice and mixes it into LeftBuffer, RightBuffer
|
// Renders a voice and mixes it into LeftBuffer, RightBuffer
|
||||||
void RenderAddVoice(ZeldaVoicePB& PB, s32* _LeftBuffer, s32* _RightBuffer, int _Size);
|
void RenderAddVoice(ZeldaVoicePB& PB, s32* _LeftBuffer, s32* _RightBuffer, int _Size);
|
||||||
|
|
||||||
|
void MixAudio();
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,9 +49,7 @@ void CUCode_Zelda::WritebackVoicePB(u32 _Addr, ZeldaVoicePB& PB)
|
||||||
|
|
||||||
int CUCode_Zelda::ConvertRatio(int pb_ratio)
|
int CUCode_Zelda::ConvertRatio(int pb_ratio)
|
||||||
{
|
{
|
||||||
float _ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
|
return pb_ratio * 16;
|
||||||
u32 _ratio = (pb_ratio << 16);
|
|
||||||
return (u64)((_ratio * _ratioFactor) * 16) >> 16;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CUCode_Zelda::SizeForResampling(ZeldaVoicePB &PB, int size, int ratio) {
|
int CUCode_Zelda::SizeForResampling(ZeldaVoicePB &PB, int size, int ratio) {
|
||||||
|
@ -739,17 +737,13 @@ ContinueWithBlock:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// size is in stereo samples.
|
void CUCode_Zelda::MixAudio()
|
||||||
void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_csMix);
|
const int BufferSamples = 5 * 16;
|
||||||
// Safety check
|
|
||||||
if (_Size > 256 * 1024 - 8)
|
|
||||||
_Size = 256 * 1024 - 8;
|
|
||||||
|
|
||||||
// Final mix buffers
|
// Final mix buffers
|
||||||
memset(m_LeftBuffer, 0, _Size * sizeof(s32));
|
memset(m_LeftBuffer, 0, BufferSamples * sizeof(s32));
|
||||||
memset(m_RightBuffer, 0, _Size * sizeof(s32));
|
memset(m_RightBuffer, 0, BufferSamples * sizeof(s32));
|
||||||
|
|
||||||
// For each PB...
|
// For each PB...
|
||||||
for (u32 i = 0; i < m_NumVoices; i++)
|
for (u32 i = 0; i < m_NumVoices; i++)
|
||||||
|
@ -769,22 +763,24 @@ void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
|
||||||
if (pb.KeyOff != 0)
|
if (pb.KeyOff != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RenderAddVoice(pb, m_LeftBuffer, m_RightBuffer, _Size);
|
RenderAddVoice(pb, m_LeftBuffer, m_RightBuffer, BufferSamples);
|
||||||
WritebackVoicePB(m_VoicePBsAddr + (i * 0x180), pb);
|
WritebackVoicePB(m_VoicePBsAddr + (i * 0x180), pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post processing, final conversion.
|
// 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 left = m_LeftBuffer[i];
|
||||||
s32 right = (s32)_Buffer[1] + m_RightBuffer[i];
|
s32 right = m_RightBuffer[i];
|
||||||
|
|
||||||
MathUtil::Clamp(&left, -32768, 32767);
|
MathUtil::Clamp(&left, -32768, 32767);
|
||||||
_Buffer[0] = (short)left;
|
left_buffer[i] = Common::swap16((short)left);
|
||||||
|
|
||||||
MathUtil::Clamp(&right, -32768, 32767);
|
MathUtil::Clamp(&right, -32768, 32767);
|
||||||
_Buffer[1] = (short)right;
|
right_buffer[i] = Common::swap16((short)right);
|
||||||
|
|
||||||
_Buffer += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,6 @@ public:
|
||||||
|
|
||||||
// Cycles are out of the 81/121mhz the DSP runs at.
|
// Cycles are out of the 81/121mhz the DSP runs at.
|
||||||
virtual void Update(int cycles) = 0;
|
virtual void Update(int cycles) = 0;
|
||||||
virtual void MixAdd(short* buffer, int size) {}
|
|
||||||
virtual u32 GetUpdateMs() = 0;
|
virtual u32 GetUpdateMs() = 0;
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p) { DoStateShared(p); }
|
virtual void DoState(PointerWrap &p) { DoStateShared(p); }
|
||||||
|
@ -95,7 +94,6 @@ protected:
|
||||||
void DoStateShared(PointerWrap &p);
|
void DoStateShared(PointerWrap &p);
|
||||||
|
|
||||||
CMailHandler& m_rMailHandler;
|
CMailHandler& m_rMailHandler;
|
||||||
std::mutex m_csMix;
|
|
||||||
|
|
||||||
enum EDSP_Codes
|
enum EDSP_Codes
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue