fix for sound sometimes looping endlessly if you pause and bring up a menu or dialog,

possible fix for an occasional crash when changing synchronizer mode,
fix for sound.clear not actually working,
fix for screen gap settings messing up certain alternate LCD layout calculations (I thought I already checked this in)
This commit is contained in:
nitsuja 2009-11-05 07:45:31 +00:00
parent 7d450e5a13
commit 5902173ae0
6 changed files with 77 additions and 36 deletions

View File

@ -225,10 +225,17 @@ void SPU_SetSynchMode(int mode, int method)
synchmethod = (ESynchMethod)method;
delete synchronizer;
//grr does this need to be locked? spu might need a lock method
// or maybe not, maybe the platform-specific code that calls this function can deal with it.
synchronizer = metaspu_construct(synchmethod);
}
}
void SPU_ClearOutputBuffer()
{
if(SNDCore && SNDCore->ClearBuffer)
SNDCore->ClearBuffer();
}
void SPU_SetVolume(int volume)
{
::volume = volume;
@ -896,17 +903,13 @@ void SPU_Emulate_user(bool mix)
if (audiosize > SPU_user->bufsize)
audiosize = SPU_user->bufsize;
int samplesOutput;
if(synchmode == ESynchMode_Synchronous)
{
int done = synchronizer->output_samples(SPU_user->outbuf, audiosize);
SNDCore->UpdateAudio(SPU_user->outbuf,done);
}
samplesOutput = synchronizer->output_samples(SPU_user->outbuf, audiosize);
else
{
SPU_MixAudio(mix,SPU_user,audiosize);
SNDCore->UpdateAudio(SPU_user->outbuf, audiosize);
}
samplesOutput = (SPU_MixAudio(mix,SPU_user,audiosize), audiosize);
SNDCore->UpdateAudio(SPU_user->outbuf, samplesOutput);
}
}

View File

@ -62,6 +62,7 @@ struct SoundInterface_struct
void (*MuteAudio)();
void (*UnMuteAudio)();
void (*SetVolume)(int volume);
void (*ClearBuffer)();
};
extern SoundInterface_struct SNDDummy;
@ -132,6 +133,7 @@ int SPU_Init(int coreid, int buffersize);
void SPU_Pause(int pause);
void SPU_SetVolume(int volume);
void SPU_SetSynchMode(int mode, int method);
void SPU_ClearOutputBuffer(void);
void SPU_Reset(void);
void SPU_DeInit(void);
void SPU_KeyOn(int channel);

View File

@ -18,11 +18,8 @@
#endif
// a few functions that maybe aren't part of the Lua engine
// functions that maybe aren't part of the Lua engine
// but didn't make sense to add to BaseDriver (at least not yet)
static void Clear_Sound_Buffer() {
if(SPU_user) SPU_user->ShutUp();
}
static bool IsHardwareAddressValid(u32 address) {
// maybe TODO? let's say everything is valid.
return true;
@ -1402,7 +1399,7 @@ void LuaRescueHook(lua_State* L, lua_Debug *dbg)
bool stopworrying = true;
if(!info.panic)
{
Clear_Sound_Buffer();
SPU_ClearOutputBuffer();
#if defined(ASK_USER_ON_FREEZE) && defined(_WIN32)
DialogsOpen++;
int answer = MessageBox(HWnd, "A Lua script has been running for quite a while. Maybe it is in an infinite loop.\n\nWould you like to stop the script?\n\n(Yes to stop it now,\n No to keep running and not ask again,\n Cancel to keep running but ask again later)", "Lua Alert", MB_YESNOCANCEL | MB_DEFBUTTON3 | MB_ICONASTERISK);
@ -3464,7 +3461,7 @@ DEFINE_LUA_FUNCTION(movie_close, "")
DEFINE_LUA_FUNCTION(sound_clear, "")
{
Clear_Sound_Buffer();
SPU_ClearOutputBuffer();
return 0;
}

View File

@ -5422,7 +5422,10 @@ static LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam
if(IsDlgCheckboxChecked(hDlg,IDC_SYNCHMETHOD_P)) snd_synchmethod = 2;
WritePrivateProfileInt("Sound", "SynchMethod", snd_synchmethod, IniName);
SPU_SetSynchMode(snd_synchmode, snd_synchmethod);
{
Lock lock;
SPU_SetSynchMode(snd_synchmode, snd_synchmethod);
}
//write interpolation type
CommonSettings.spuInterpolationMode = (SPUInterpolationMode)SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_GETCURSEL, 0, 0);

View File

@ -44,6 +44,7 @@ u32 SNDDXGetAudioSpace();
void SNDDXMuteAudio();
void SNDDXUnMuteAudio();
void SNDDXSetVolume(int volume);
void SNDDXClearAudioBuffer();
SoundInterface_struct SNDDIRECTX = {
SNDCORE_DIRECTX,
@ -54,7 +55,8 @@ SoundInterface_struct SNDDIRECTX = {
SNDDXGetAudioSpace,
SNDDXMuteAudio,
SNDDXUnMuteAudio,
SNDDXSetVolume
SNDDXSetVolume,
SNDDXClearAudioBuffer,
};
LPDIRECTSOUND8 lpDS8;
@ -67,6 +69,8 @@ static u32 soundoffset=0;
static u32 soundbufsize;
static LONG soundvolume;
static int issoundmuted;
static bool insilence;
static int samplecounter_fakecontribution = 0;
//////////////////////////////////////////////////////////////////////////////
static volatile bool doterminate;
@ -234,18 +238,44 @@ void SNDDXDeInit()
void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
{
LPVOID buffer1;
LPVOID buffer2;
DWORD buffer1_size, buffer2_size;
int samplecounter;
{
Lock lock;
samplecounter = win_sound_samplecounter -= num_samples;
if(num_samples)
{
samplecounter = win_sound_samplecounter -= num_samples - samplecounter_fakecontribution;
samplecounter_fakecontribution = 0;
}
else
{
samplecounter = win_sound_samplecounter -= 245;
samplecounter_fakecontribution += 245;
}
}
bool silence = (samplecounter<-44100*15/60); //behind by more than a quarter second -> silence
if(insilence)
{
if(silence)
return;
else
insilence = false;
}
else
{
if(silence)
{
insilence = true;
SNDDXClearAudioBuffer();
return;
}
}
LPVOID buffer1;
LPVOID buffer2;
DWORD buffer1_size, buffer2_size;
HRESULT hr = lpDSB2->Lock(soundoffset, num_samples * sizeof(s16) * 2,
&buffer1, &buffer1_size, &buffer2, &buffer2_size, 0);
if(FAILED(hr))
@ -255,17 +285,9 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
return;
}
if(silence) {
memset(buffer1, 0, buffer1_size);
if(buffer2)
memset(buffer2, 0, buffer2_size);
}
else
{
memcpy(buffer1, buffer, buffer1_size);
if(buffer2)
memcpy(buffer2, ((u8 *)buffer)+buffer1_size, buffer2_size);
}
memcpy(buffer1, buffer, buffer1_size);
if(buffer2)
memcpy(buffer2, ((u8 *)buffer)+buffer1_size, buffer2_size);
soundoffset += buffer1_size + buffer2_size;
soundoffset %= soundbufsize;
@ -274,6 +296,20 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
}
void SNDDXClearAudioBuffer()
{
LPVOID buffer1;
DWORD buffer1_size;
HRESULT hr = lpDSB2->Lock(0, 0, &buffer1, &buffer1_size, NULL, NULL, DSBLOCK_ENTIREBUFFER);
if(FAILED(hr))
return;
memset(buffer1, 0, buffer1_size);
lpDSB2->Unlock(buffer1, buffer1_size, NULL, 0);
}
//////////////////////////////////////////////////////////////////////////////
static inline u32 circularDist(u32 from, u32 to, u32 size)

View File

@ -158,11 +158,11 @@ public:
case 0:
return width;
case 90:
return height + screengap;
return height + ((layout == 0) ? screengap : 0);
case 180:
return width;
case 270:
return height + screengap;
return height + ((layout == 0) ? screengap : 0);
default:
return 0;
}
@ -171,11 +171,11 @@ public:
int rotatedheightgap() {
switch(rotation) {
case 0:
return height + screengap;
return height + ((layout == 0) ? screengap : 0);
case 90:
return width;
case 180:
return height + screengap;
return height + ((layout == 0) ? screengap : 0);
case 270:
return width;
default: