mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Sound System Rework: Phase 2 (cont'ed)
. Fixed super fast refresh rate issue . Recovered <TAB> shortcut key for ThrottleSkipping . Removed redundant "soundstream->Update()" in DSPLLE (Thanks to LordMark) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4728 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -111,7 +111,7 @@ void DSound::SoundLoop()
|
||||
int numBytesToRender = FIX128(ModBufferSize(currentPos - lastPos));
|
||||
if (numBytesToRender >= 256)
|
||||
{
|
||||
if (numBytesToRender > sizeof(realtimeBuffer) * sizeof(short))
|
||||
if (numBytesToRender > sizeof(realtimeBuffer))
|
||||
PanicAlert("soundThread: too big render call");
|
||||
m_mixer->Mix(realtimeBuffer, numBytesToRender / 4);
|
||||
WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
|
||||
#include "Atomic.h"
|
||||
|
||||
#include "Mixer.h"
|
||||
#include "AudioCommon.h"
|
||||
|
||||
@ -41,37 +40,13 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
|
||||
numLeft = (numLeft > numSamples) ? numSamples : numLeft;
|
||||
|
||||
// Do re-sampling if needed
|
||||
if (m_sampleRate == m_dspSampleRate)
|
||||
if (m_sampleRate == 32000)
|
||||
{
|
||||
for (unsigned int i = 0; i < numLeft * 2; i++)
|
||||
samples[i] = Common::swap16(m_buffer[(m_indexR + i) & INDEX_MASK]);
|
||||
m_indexR += numLeft * 2;
|
||||
}
|
||||
else if (m_sampleRate < m_dspSampleRate) // If down-sampling needed
|
||||
{
|
||||
_dbg_assert_msg_(DSPHLE, !(numSamples % 2), "Number of Samples: %i must be even!", numSamples);
|
||||
|
||||
short *pDest = samples;
|
||||
int last_l, last_r, cur_l, cur_r;
|
||||
|
||||
for (unsigned int i = 0; i < numLeft * 3 / 2; i++)
|
||||
{
|
||||
cur_l = Common::swap16(m_buffer[(m_indexR + i * 2) & INDEX_MASK]);
|
||||
cur_r = Common::swap16(m_buffer[(m_indexR + i * 2 + 1) & INDEX_MASK]);
|
||||
|
||||
if (i % 3)
|
||||
{
|
||||
*pDest++ = (last_l + cur_r) / 2;
|
||||
*pDest++ = (last_r + cur_r) / 2;
|
||||
}
|
||||
|
||||
last_l = cur_l;
|
||||
last_r = cur_r;
|
||||
}
|
||||
|
||||
m_indexR += numLeft * 2 * 3 / 2;
|
||||
}
|
||||
else if (m_sampleRate > m_dspSampleRate)
|
||||
else
|
||||
{
|
||||
// AyuanX: Up-sampling is not implemented yet
|
||||
PanicAlert("Mixer: Up-sampling is not implemented yet!");
|
||||
@ -143,16 +118,8 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
|
||||
if (numSamples > numLeft)
|
||||
memset(&samples[numLeft * 2], 0, (numSamples - numLeft) * 4);
|
||||
|
||||
// Add the HLE sound
|
||||
if (m_sampleRate < m_dspSampleRate)
|
||||
{
|
||||
PanicAlert("Mixer: DSPHLE down-sampling is not implemented yet!\n"
|
||||
"Usually no game should require this, please report!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Premix(samples, numSamples, m_sampleRate);
|
||||
}
|
||||
// Add the DSPHLE sound, re-sampling is done inside
|
||||
Premix(samples, numSamples);
|
||||
|
||||
// Add the DTK Music
|
||||
if (m_EnableDTKMusic)
|
||||
@ -161,19 +128,17 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
|
||||
g_dspInitialize.pGetAudioStreaming(samples, numSamples, m_sampleRate);
|
||||
}
|
||||
|
||||
Common::AtomicAdd(m_numSamples, -(int)numLeft);
|
||||
Common::AtomicAdd(m_numSamples, -(s32)numLeft);
|
||||
|
||||
return numSamples;
|
||||
}
|
||||
|
||||
|
||||
void CMixer::PushSamples(short *samples, unsigned int num_samples, unsigned int sample_rate)
|
||||
void CMixer::PushSamples(short *samples, unsigned int num_samples)
|
||||
{
|
||||
// The auto throttle function. This loop will put a ceiling on the CPU MHz.
|
||||
if (m_throttle)
|
||||
{
|
||||
// AyuanX: Remember to reserve "num_samples * 1.5" free sample space at least!
|
||||
// Becuse we may do re-sampling later
|
||||
while (Common::AtomicLoad(m_numSamples) >= MAX_SAMPLES - RESERVED_SAMPLES)
|
||||
{
|
||||
if (g_dspInitialize.pEmulatorState)
|
||||
@ -181,8 +146,12 @@ void CMixer::PushSamples(short *samples, unsigned int num_samples, unsigned int
|
||||
if (*g_dspInitialize.pEmulatorState != 0)
|
||||
break;
|
||||
}
|
||||
soundStream->Update();
|
||||
// Shortcut key for Throttle Skipping
|
||||
#ifdef _WIN32
|
||||
if (GetAsyncKeyState(VK_TAB)) break;;
|
||||
#endif
|
||||
SLEEP(1);
|
||||
soundStream->Update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +160,7 @@ void CMixer::PushSamples(short *samples, unsigned int num_samples, unsigned int
|
||||
return;
|
||||
|
||||
// AyuanX: Actual re-sampling work has been moved to sound thread
|
||||
// to alleviates the workload on main thread
|
||||
// to alleviate the workload on main thread
|
||||
// and we simply store raw data here to make fast mem copy
|
||||
int over_bytes = num_samples * 4 - (MAX_SAMPLES * 2 - (m_indexW & INDEX_MASK)) * sizeof(short);
|
||||
if (over_bytes > 0)
|
||||
@ -206,12 +175,7 @@ void CMixer::PushSamples(short *samples, unsigned int num_samples, unsigned int
|
||||
|
||||
m_indexW += num_samples * 2;
|
||||
|
||||
if (m_sampleRate < m_dspSampleRate)
|
||||
{
|
||||
// This is kind of tricky :P
|
||||
num_samples = num_samples * 2 / 3;
|
||||
}
|
||||
else if (m_sampleRate > m_dspSampleRate)
|
||||
if (m_sampleRate != 32000)
|
||||
{
|
||||
PanicAlert("Mixer: Up-sampling is not implemented yet!");
|
||||
}
|
||||
|
@ -19,16 +19,16 @@
|
||||
#define _MIXER_H_
|
||||
|
||||
// 16 bit Stereo
|
||||
#define MAX_SAMPLES (1024 * 4)
|
||||
#define MAX_SAMPLES (1024 * 8)
|
||||
#define INDEX_MASK (MAX_SAMPLES * 2 - 1)
|
||||
#define RESERVED_SAMPLES (MAX_SAMPLES / 8)
|
||||
#define RESERVED_SAMPLES (256)
|
||||
|
||||
class CMixer {
|
||||
|
||||
public:
|
||||
CMixer(unsigned int AISampleRate = 48000, unsigned int DSPSampleRate = 48000)
|
||||
CMixer(unsigned int AISampleRate = 48000, unsigned int DACSampleRate = 48000)
|
||||
: m_aiSampleRate(AISampleRate)
|
||||
, m_dspSampleRate(DSPSampleRate)
|
||||
, m_dacSampleRate(DACSampleRate)
|
||||
, m_bits(16)
|
||||
, m_channels(2)
|
||||
, m_HLEready(false)
|
||||
@ -36,19 +36,21 @@ public:
|
||||
, m_indexW(0)
|
||||
, m_indexR(0)
|
||||
{
|
||||
// AyuanX: When sample rate differs, we have to do re-sampling
|
||||
// AyuanX: The internal (Core & DSP) sample rate is fixed at 32KHz
|
||||
// So when AI/DAC sample rate differs than 32KHz, we have to do re-sampling
|
||||
// I perfer speed so let's do down-sampling instead of up-sampling
|
||||
// If you like better sound than speed, feel free to implement the up-sampling code
|
||||
m_sampleRate = (m_aiSampleRate < m_dspSampleRate) ? m_aiSampleRate : m_dspSampleRate;
|
||||
m_sampleRate = 32000;
|
||||
NOTICE_LOG(AUDIO_INTERFACE, "Mixer is initialized (AISampleRate:%i, DACSampleRate:%i)", AISampleRate, DACSampleRate);
|
||||
}
|
||||
|
||||
// Called from audio threads
|
||||
virtual unsigned int Mix(short* samples, unsigned int numSamples);
|
||||
virtual void Premix(short *samples, unsigned int numSamples, unsigned int sampleRate) {}
|
||||
virtual void Premix(short *samples, unsigned int numSamples) {}
|
||||
unsigned int GetNumSamples();
|
||||
|
||||
// Called from main thread
|
||||
virtual void PushSamples(short* samples, unsigned int num_samples, unsigned int sample_rate);
|
||||
virtual void PushSamples(short* samples, unsigned int num_samples);
|
||||
unsigned int GetSampleRate() {return m_sampleRate;}
|
||||
|
||||
void SetThrottle(bool use) { m_throttle = use;}
|
||||
@ -62,7 +64,7 @@ public:
|
||||
protected:
|
||||
unsigned int m_sampleRate;
|
||||
unsigned int m_aiSampleRate;
|
||||
unsigned int m_dspSampleRate;
|
||||
unsigned int m_dacSampleRate;
|
||||
int m_bits;
|
||||
int m_channels;
|
||||
|
||||
|
@ -25,7 +25,7 @@ class NullMixer : public CMixer {
|
||||
|
||||
public:
|
||||
virtual unsigned int Mix(short *samples, unsigned int numSamples) { return 0; }
|
||||
virtual void PushSamples(short* samples, unsigned int num_samples, unsigned int sample_rate) {}
|
||||
virtual void PushSamples(short* samples, unsigned int num_samples) {}
|
||||
};
|
||||
|
||||
class NullSound : public SoundStream
|
||||
|
@ -35,9 +35,9 @@
|
||||
#endif // WIN32
|
||||
// 16 bit Stereo
|
||||
#define SFX_MAX_SOURCE 1
|
||||
#define OAL_NUM_BUFFERS 8
|
||||
#define OAL_NUM_BUFFERS 16
|
||||
#define OAL_MAX_SAMPLES 512 // AyuanX: Don't make it too large, as larger buffer means longer delay
|
||||
#define OAL_THRESHOLD 128
|
||||
#define OAL_THRESHOLD 128 // Some games are quite sensitive to delay
|
||||
#endif
|
||||
|
||||
class OpenALStream: public SoundStream
|
||||
|
@ -27,7 +27,7 @@ typedef void (__cdecl* TDSP_WriteMailBox)(bool _CPUMailbox, unsigned short);
|
||||
typedef unsigned short (__cdecl* TDSP_ReadMailBox)(bool _CPUMailbox);
|
||||
typedef unsigned short (__cdecl* TDSP_ReadControlRegister)();
|
||||
typedef unsigned short (__cdecl* TDSP_WriteControlRegister)(unsigned short);
|
||||
typedef void (__cdecl *TDSP_SendAIBuffer)(unsigned int address, unsigned int num_samples, unsigned int sample_rate);
|
||||
typedef void (__cdecl *TDSP_SendAIBuffer)(unsigned int address, unsigned int num_samples);
|
||||
typedef void (__cdecl *TDSP_Update)(int cycles);
|
||||
typedef void (__cdecl *TDSP_StopSoundStream)();
|
||||
typedef void (__cdecl *TDSP_ClearAudioBuffer)();
|
||||
|
@ -700,7 +700,7 @@ void Callback_VideoCopiedToXFB(bool video_update)
|
||||
|
||||
while (Timer.GetTimeDifference() < wait_frametime * frames)
|
||||
{
|
||||
if (no_framelimit==0)
|
||||
if (no_framelimit == 0)
|
||||
Common::SleepCurrentThread(1);
|
||||
}
|
||||
}
|
||||
|
@ -54,13 +54,13 @@ union AICR
|
||||
struct
|
||||
{
|
||||
unsigned PSTAT : 1; // sample counter/playback enable
|
||||
unsigned AFR : 1; // AI Frequency (0=32khz 1=48khz)
|
||||
unsigned AIFR : 1; // AI Frequency (0=32khz 1=48khz)
|
||||
unsigned AIINTMSK : 1; // 0=interrupt masked 1=interrupt enabled
|
||||
unsigned AIINT : 1; // audio interrupt status
|
||||
unsigned AIINTVLD : 1; // This bit controls whether AIINT is affected by the AIIT register
|
||||
// matching AISLRCNT. Once set, AIINT will hold
|
||||
unsigned SCRESET : 1; // write to reset counter
|
||||
unsigned DSPFR : 1; // DSP Frequency (0=48khz 1=32khz)
|
||||
unsigned DACFR : 1; // DAC Frequency (0=48khz 1=32khz)
|
||||
unsigned :25;
|
||||
};
|
||||
u32 hex;
|
||||
@ -90,16 +90,16 @@ struct SAudioRegister
|
||||
// STATE_TO_SAVE
|
||||
static SAudioRegister g_AudioRegister;
|
||||
static u64 g_LastCPUTime = 0;
|
||||
static unsigned int g_SampleRate = 32000;
|
||||
static unsigned int g_DSPSampleRate = 32000;
|
||||
static unsigned int g_AISampleRate = 32000;
|
||||
static unsigned int g_DACSampleRate = 32000;
|
||||
static u64 g_CPUCyclesPerSample = 0xFFFFFFFFFFFULL;
|
||||
|
||||
void DoState(PointerWrap &p)
|
||||
{
|
||||
p.Do(g_AudioRegister);
|
||||
p.Do(g_LastCPUTime);
|
||||
p.Do(g_SampleRate);
|
||||
p.Do(g_DSPSampleRate);
|
||||
p.Do(g_AISampleRate);
|
||||
p.Do(g_DACSampleRate);
|
||||
p.Do(g_CPUCyclesPerSample);
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ void ReadStreamBlock(short* _pPCM);
|
||||
void Init()
|
||||
{
|
||||
g_AudioRegister.m_SampleCounter = 0;
|
||||
g_AudioRegister.m_Control.AFR = 1;
|
||||
g_AudioRegister.m_Control.AIFR = 1;
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
@ -169,22 +169,22 @@ void Write32(const u32 _Value, const u32 _Address)
|
||||
g_AudioRegister.m_Control.AIINTVLD = tmpAICtrl.AIINTVLD;
|
||||
|
||||
// Set frequency
|
||||
if (tmpAICtrl.AFR != g_AudioRegister.m_Control.AFR)
|
||||
if (tmpAICtrl.AIFR != g_AudioRegister.m_Control.AIFR)
|
||||
{
|
||||
INFO_LOG(AUDIO_INTERFACE, "Change Freq to %s", tmpAICtrl.AFR ? "48khz":"32khz");
|
||||
g_AudioRegister.m_Control.AFR = tmpAICtrl.AFR;
|
||||
INFO_LOG(AUDIO_INTERFACE, "Change Freq to %s", tmpAICtrl.AIFR ? "48khz":"32khz");
|
||||
g_AudioRegister.m_Control.AIFR = tmpAICtrl.AIFR;
|
||||
}
|
||||
// Set DSP frequency
|
||||
if (tmpAICtrl.DSPFR != g_AudioRegister.m_Control.DSPFR)
|
||||
if (tmpAICtrl.DACFR != g_AudioRegister.m_Control.DACFR)
|
||||
{
|
||||
INFO_LOG(AUDIO_INTERFACE, "AI_CONTROL_REGISTER: Change DSPFR Freq to %s", tmpAICtrl.DSPFR ? "48khz":"32khz");
|
||||
g_AudioRegister.m_Control.DSPFR = tmpAICtrl.DSPFR;
|
||||
INFO_LOG(AUDIO_INTERFACE, "AI_CONTROL_REGISTER: Change DSPFR Freq to %s", tmpAICtrl.DACFR ? "48khz":"32khz");
|
||||
g_AudioRegister.m_Control.DACFR = tmpAICtrl.DACFR;
|
||||
}
|
||||
|
||||
g_SampleRate = tmpAICtrl.AFR ? 48000 : 32000;
|
||||
g_DSPSampleRate = tmpAICtrl.DSPFR ? 32000 : 48000;
|
||||
g_AISampleRate = tmpAICtrl.AIFR ? 48000 : 32000;
|
||||
g_DACSampleRate = tmpAICtrl.DACFR ? 32000 : 48000;
|
||||
|
||||
g_CPUCyclesPerSample = SystemTimers::GetTicksPerSecond() / g_SampleRate;
|
||||
g_CPUCyclesPerSample = SystemTimers::GetTicksPerSecond() / g_AISampleRate;
|
||||
|
||||
// Streaming counter
|
||||
if (tmpAICtrl.PSTAT != g_AudioRegister.m_Control.PSTAT)
|
||||
@ -264,10 +264,10 @@ void GenerateAudioInterrupt()
|
||||
UpdateInterrupts();
|
||||
}
|
||||
|
||||
void Callback_GetSampleRate(unsigned int &_AISampleRate, unsigned int &_DSPSampleRate)
|
||||
void Callback_GetSampleRate(unsigned int &_AISampleRate, unsigned int &_DACSampleRate)
|
||||
{
|
||||
_AISampleRate = g_SampleRate;
|
||||
_DSPSampleRate = g_DSPSampleRate;
|
||||
_AISampleRate = g_AISampleRate;
|
||||
_DACSampleRate = g_DACSampleRate;
|
||||
}
|
||||
|
||||
// Callback for the disc streaming
|
||||
@ -282,12 +282,12 @@ unsigned int Callback_GetStreaming(short* _pDestBuffer, unsigned int _numSamples
|
||||
const int rvolume = g_AudioRegister.m_Volume.rightVolume;
|
||||
|
||||
|
||||
if (g_SampleRate == 48000 && _sampleRate == 32000)
|
||||
if (g_AISampleRate == 48000 && _sampleRate == 32000)
|
||||
{
|
||||
_dbg_assert_msg_(AUDIO_INTERFACE, !(_numSamples % 2), "Number of Samples: %i must be even!", _numSamples);
|
||||
_numSamples = _numSamples * 3 / 2;
|
||||
}
|
||||
else if (g_SampleRate == 32000 && _sampleRate == 48000)
|
||||
else if (g_AISampleRate == 32000 && _sampleRate == 48000)
|
||||
{
|
||||
// AyuanX: Up-sampling is not implemented yet
|
||||
PanicAlert("AUDIO_INTERFACE: Up-sampling is not implemented yet!");
|
||||
@ -299,7 +299,7 @@ unsigned int Callback_GetStreaming(short* _pDestBuffer, unsigned int _numSamples
|
||||
if (pos == 0)
|
||||
ReadStreamBlock(pcm);
|
||||
|
||||
if (g_SampleRate == 48000 && _sampleRate == 32000)
|
||||
if (g_AISampleRate == 48000 && _sampleRate == 32000)
|
||||
{
|
||||
if (i % 3)
|
||||
{
|
||||
@ -393,16 +393,6 @@ void IncreaseSampleCount(const u32 _iAmount)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int GetAISampleRate()
|
||||
{
|
||||
return g_SampleRate;
|
||||
}
|
||||
|
||||
unsigned int GetDSPSampleRate()
|
||||
{
|
||||
return g_DSPSampleRate;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// update timer
|
||||
|
@ -34,16 +34,12 @@ void DoState(PointerWrap &p);
|
||||
void Update();
|
||||
|
||||
// Called by DSP plugin
|
||||
void Callback_GetSampleRate(unsigned int &_AISampleRate, unsigned int &_DSPSampleRate);
|
||||
void Callback_GetSampleRate(unsigned int &_AISampleRate, unsigned int &_DACSampleRate);
|
||||
unsigned int Callback_GetStreaming(short* _pDestBuffer, unsigned int _numSamples, unsigned int _sampleRate = 48000);
|
||||
|
||||
void Read32(u32& _uReturnValue, const u32 _iAddress);
|
||||
void Write32(const u32 _iValue, const u32 _iAddress);
|
||||
|
||||
// Get the audio rates (48000 or 32000 only)
|
||||
unsigned int GetAISampleRate();
|
||||
unsigned int GetDSPSampleRate();
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
@ -484,17 +484,17 @@ void UpdateAudioDMA()
|
||||
|
||||
// AyuanX: let's do it in a bundle to speed up
|
||||
if (g_audioDMA.BlocksLeft == g_audioDMA.AudioDMAControl.NumBlocks)
|
||||
dsp_plugin->DSP_SendAIBuffer(g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks * 8, AudioInterface::GetDSPSampleRate());
|
||||
dsp_plugin->DSP_SendAIBuffer(g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks * 8);
|
||||
|
||||
// g_audioDMA.ReadAddress += 32;
|
||||
g_audioDMA.BlocksLeft--;
|
||||
|
||||
if (g_audioDMA.BlocksLeft == 0)
|
||||
{
|
||||
GenerateDSPInterrupt(DSP::INT_AID);
|
||||
// g_audioDMA.ReadAddress = g_audioDMA.SourceAddress;
|
||||
g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks;
|
||||
// DEBUG_LOG(DSPLLE, "ADMA read addresses: %08x", g_audioDMA.ReadAddress);
|
||||
GenerateDSPInterrupt(DSP::INT_AID);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -112,7 +112,7 @@ int et_Dec;
|
||||
int et_VI;
|
||||
int et_SI;
|
||||
int et_AI;
|
||||
int et_AudioFifo;
|
||||
int et_AudioDMA;
|
||||
int et_DSP;
|
||||
int et_IPC_HLE;
|
||||
int et_FakeGPWD; // DC watchdog hack
|
||||
@ -127,6 +127,9 @@ int
|
||||
// These shouldn't be period controlled either, most likely.
|
||||
DSP_PERIOD,
|
||||
|
||||
// This is a fixed value, don't change it
|
||||
AUDIO_DMA_PERIOD,
|
||||
|
||||
// This is completely arbitrary. If we find that we need lower latency, we can just
|
||||
// increase this number.
|
||||
IPC_HLE_PERIOD,
|
||||
@ -165,12 +168,10 @@ void DSPCallback(u64 userdata, int cyclesLate)
|
||||
CoreTiming::ScheduleEvent(DSP_PERIOD - cyclesLate, et_DSP);
|
||||
}
|
||||
|
||||
void AudioFifoCallback(u64 userdata, int cyclesLate)
|
||||
void AudioDMACallback(u64 userdata, int cyclesLate)
|
||||
{
|
||||
int period = CPU_CORE_CLOCK / (AudioInterface::GetDSPSampleRate() * 4 / 32);
|
||||
DSP::UpdateAudioDMA(); // Push audio to speakers.
|
||||
|
||||
CoreTiming::ScheduleEvent(period - cyclesLate, et_AudioFifo);
|
||||
CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD - cyclesLate, et_AudioDMA);
|
||||
}
|
||||
|
||||
void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate)
|
||||
@ -275,6 +276,9 @@ void Init()
|
||||
// This is the biggest question mark.
|
||||
AI_PERIOD = GetTicksPerSecond() / 80;
|
||||
|
||||
// System internal sample rate is fixed at 32KHz
|
||||
AUDIO_DMA_PERIOD = CPU_CORE_CLOCK / (32000 * 4 / 32);
|
||||
|
||||
Common::Timer::IncreaseResolution();
|
||||
// store and convert localtime at boot to timebase ticks
|
||||
startTimeBaseTicks = (u64)(CPU_CORE_CLOCK / TIMER_RATIO) * (u64)CEXIIPL::GetGCTime();
|
||||
@ -284,7 +288,7 @@ void Init()
|
||||
et_VI = CoreTiming::RegisterEvent("VICallback", VICallback);
|
||||
et_SI = CoreTiming::RegisterEvent("SICallback", SICallback);
|
||||
et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback);
|
||||
et_AudioFifo = CoreTiming::RegisterEvent("AudioFifoCallback", AudioFifoCallback);
|
||||
et_AudioDMA = CoreTiming::RegisterEvent("AudioDMACallback", AudioDMACallback);
|
||||
et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
|
||||
// Always register this. Increases chances of DC/SC save state compatibility.
|
||||
et_FakeGPWD = CoreTiming::RegisterEvent("FakeGPWatchdogCallback", FakeGPWatchdogCallback);
|
||||
@ -294,7 +298,7 @@ void Init()
|
||||
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine(), et_VI);
|
||||
CoreTiming::ScheduleEvent(DSP_PERIOD, et_DSP);
|
||||
CoreTiming::ScheduleEvent(GetTicksPerSecond() / 60, et_SI);
|
||||
CoreTiming::ScheduleEvent(CPU_CORE_CLOCK / (32000 * 4 / 32), et_AudioFifo);
|
||||
CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA);
|
||||
|
||||
// For DC watchdog hack
|
||||
if (Core::GetStartupParameter().bCPUThread)
|
||||
|
@ -141,6 +141,7 @@
|
||||
// cr (Not g_dsp.r[CR]) bits
|
||||
// See HW/DSP.cpp.
|
||||
#define CR_HALT 0x0004
|
||||
#define CR_INIT 0x0400
|
||||
#define CR_EXTERNAL_INT 0x0002
|
||||
|
||||
|
||||
|
@ -286,7 +286,7 @@ void CConfigMain::CreateGUIControls()
|
||||
wxT("\nIt can be convenient in a Wii game that already has a cursor."));
|
||||
WiimoteStatusLEDs->SetToolTip(wxT("Show which wiimotes are connected in the statusbar."));
|
||||
WiimoteStatusSpeakers->SetToolTip(wxT("Show wiimote speaker status in the statusbar."));
|
||||
DSPThread->SetToolTip(wxT("This should be on when using HLE and off when using LLE."));
|
||||
DSPThread->SetToolTip(wxT("Run DSPLLE on a dedicate thread, this has no affect on DSPHLE."));
|
||||
CPUThread->SetToolTip(wxT("This splits the Video and CPU threads, so they can be run on separate cores.")
|
||||
wxT("\nCauses major speed improvements on PCs with more than one core,")
|
||||
wxT("\nbut can also cause occasional crashes/glitches."));
|
||||
|
Reference in New Issue
Block a user