Sound System Rework: Phase 2

. Performance boost
  (Completely non-blocking between Sound thread and CPU thread, in the meantime keeping them thread safe)

. Both 32KHz & 48KHz sound can be handled properly now
  (But up-sampling is still not implemented, and I don't think any game requires it.)

. Strategy adjustment
  When your PC is *NOT* capable to run the game at 100%:
  >> DSound    Could yield more fluent sound than OpenAL sometimes, but you will lose the sync between video & audio (since audio is played before video to guarantee fluency)
  >> OpenAL    Ensures video & audio are always sync'ed, but sound could be intermittent(to let slow video catch up)

. Changed default frame limit to: Auto
  (Somehow this can dramatically decrease the chance of wiimote desync in game NSMB)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4724 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2009-12-23 15:34:14 +00:00
parent 0d0a7c515f
commit 9eea60ca69
27 changed files with 358 additions and 314 deletions

View file

@ -33,7 +33,6 @@ DSPDebuggerHLE* m_DebuggerFrame = NULL;
#include "Config.h"
#include "Setup.h"
#include "StringUtil.h"
#include "AudioCommon.h"
#include "LogManager.h"
@ -42,8 +41,8 @@ PLUGIN_GLOBALS* globals = NULL;
DSPInitialize g_dspInitialize;
u8* g_pMemory;
extern std::vector<std::string> sMailLog, sMailTime;
bool g_bMuted = false;
bool g_InitMixer = false;
SoundStream *soundStream = NULL;
// Mailbox utility
@ -203,6 +202,7 @@ void DllConfig(HWND _hParent)
void Initialize(void *init)
{
g_InitMixer = false;
g_dspInitialize = *(DSPInitialize*)init;
g_Config.Load();
@ -211,10 +211,6 @@ void Initialize(void *init)
g_dspState.Reset();
CDSPHandler::CreateInstance();
soundStream = AudioCommon::InitSoundStream(new HLEMixer());
if(!soundStream)
PanicAlert("Error starting up sound stream");
}
void DSP_StopSoundStream()
@ -245,6 +241,7 @@ void Shutdown()
void DoState(unsigned char **ptr, int mode)
{
PointerWrap p(ptr, mode);
p.Do(g_InitMixer);
CDSPHandler::GetInstance().GetUCode()->DoState(p);
}
@ -305,6 +302,19 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value)
// Other DSP fuctions
unsigned short DSP_WriteControlRegister(unsigned short _Value)
{
UDSPControl Temp(_Value);
if (!g_InitMixer)
{
if (!Temp.DSPHalt && Temp.DSPInit)
{
unsigned int AISampleRate, DSPSampleRate;
g_dspInitialize.pGetSampleRate(AISampleRate, DSPSampleRate);
soundStream = AudioCommon::InitSoundStream(new HLEMixer(AISampleRate, DSPSampleRate));
if(!soundStream) PanicAlert("Error starting up sound stream");
// Mixer is initialized
g_InitMixer = true;
}
}
return CDSPHandler::GetInstance().WriteControlRegister(_Value);
}
@ -324,44 +334,26 @@ void DSP_Update(int cycles)
inside Mixer_PushSamples(), 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 DSP_SendAIBuffer(unsigned int address, int sample_rate)
void DSP_SendAIBuffer(unsigned int address, unsigned int num_samples, unsigned int sample_rate)
{
// TODO: This is not yet fully threadsafe.
if (!soundStream) {
if (!soundStream)
return;
}
CMixer* pMixer = soundStream->GetMixer();
if (pMixer && address)
{
short* samples = (short*)Memory_Get_Pointer(address);
/*
short samples[16] = {0}; // interleaved stereo
if (address)
{
for (int i = 0; i < 16; i++)
{
samples[i] = Memory_Read_U16(address + i * 2);
}
// FIXME: Write the audio to a file
//if (log_ai)
// g_wave_writer.AddStereoSamples(samples, 8);
}
*/
// sample_rate is usually 32k here,
// sample_rate could be 32khz/48khz here,
// see Core/DSP/DSP.cpp for better information
pMixer->PushSamples(samples, 32 / 4, sample_rate);
pMixer->PushSamples(samples, num_samples, sample_rate);
// FIXME: Write the audio to a file
//if (log_ai)
// g_wave_writer.AddStereoSamples(samples, 8);
}
// SoundStream is updated only when necessary (there is no 70 ms limit
// so each sample now triggers the sound stream)
// TODO: think about this.
static int counter = 0;
counter++;
if ((counter & 31) == 0 && soundStream)
soundStream->Update();
soundStream->Update();
}
void DSP_ClearAudioBuffer()