win32: move sound sync to sound drivers

This commit is contained in:
OV2 2019-02-12 17:56:01 +01:00
parent 761c41ba85
commit 4aa65d1df6
7 changed files with 54 additions and 14 deletions

View File

@ -110,6 +110,11 @@ void CWaveOut::StopPlayback()
waveOutPause(hWaveOut); waveOutPause(hWaveOut);
} }
int CWaveOut::GetAvailableBytes()
{
return ((blockCount - bufferCount) * singleBufferBytes) - partialOffset;
}
void CWaveOut::ProcessSound() void CWaveOut::ProcessSound()
{ {
int freeBytes = ((blockCount - bufferCount) * singleBufferBytes) - partialOffset; int freeBytes = ((blockCount - bufferCount) * singleBufferBytes) - partialOffset;
@ -137,6 +142,22 @@ void CWaveOut::ProcessSound()
if (!initDone) if (!initDone)
return; return;
if(Settings.SoundSync && !Settings.TurboMode && !Settings.Mute)
{
// no sound sync when speed is not set to 100%
while((freeBytes >> 1) < availableSamples)
{
ResetEvent(GUI.SoundSyncEvent);
if(!GUI.AllowSoundSync || WaitForSingleObject(GUI.SoundSyncEvent, 1000) != WAIT_OBJECT_0)
{
S9xClearSamples();
return;
}
freeBytes = GetAvailableBytes();
}
}
if (partialOffset != 0) { if (partialOffset != 0) {
UINT32 samplesleftinblock = (singleBufferBytes - partialOffset) >> 1; UINT32 samplesleftinblock = (singleBufferBytes - partialOffset) >> 1;
BYTE *offsetBuffer = (BYTE *)waveHeaders[writeOffset].lpData + partialOffset; BYTE *offsetBuffer = (BYTE *)waveHeaders[writeOffset].lpData + partialOffset;

View File

@ -18,6 +18,7 @@ class CWaveOut : public IS9xSoundOutput
void BeginPlayback(void); void BeginPlayback(void);
void StopPlayback(void); void StopPlayback(void);
void ProcessSound(void); void ProcessSound(void);
int GetAvailableBytes();
HWAVEOUT hWaveOut; HWAVEOUT hWaveOut;
bool initDone; bool initDone;

View File

@ -268,6 +268,11 @@ void CXAudio2::StopPlayback()
pSourceVoice->Stop(0); pSourceVoice->Stop(0);
} }
int CXAudio2::GetAvailableBytes()
{
return ((blockCount - bufferCount) * singleBufferBytes) - partialOffset;
}
/* CXAudio2::ProcessSound /* CXAudio2::ProcessSound
The mixing function called by the sound core when new samples are available. The mixing function called by the sound core when new samples are available.
SoundBuffer is divided into blockCount blocks. If there are enough available samples and a free block, SoundBuffer is divided into blockCount blocks. If there are enough available samples and a free block,
@ -276,7 +281,7 @@ the OnBufferComplete callback.
*/ */
void CXAudio2::ProcessSound() void CXAudio2::ProcessSound()
{ {
int freeBytes = ((blockCount - bufferCount) * singleBufferBytes) - partialOffset; int freeBytes = GetAvailableBytes();
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
@ -289,7 +294,7 @@ void CXAudio2::ProcessSound()
availableSamples = S9xGetSampleCount(); availableSamples = S9xGetSampleCount();
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl && !Settings.SoundSync)
{ {
// Using rate control, we should always keep the emulator's sound buffers empty to // Using rate control, we should always keep the emulator's sound buffers empty to
// maintain an accurate measurement. // maintain an accurate measurement.
@ -303,6 +308,21 @@ void CXAudio2::ProcessSound()
if(!initDone) if(!initDone)
return; return;
if(Settings.SoundSync && !Settings.TurboMode && !Settings.Mute)
{
// no sound sync when speed is not set to 100%
while((freeBytes >> 1) < availableSamples)
{
ResetEvent(GUI.SoundSyncEvent);
if(!GUI.AllowSoundSync || WaitForSingleObject(GUI.SoundSyncEvent, 1000) != WAIT_OBJECT_0)
{
S9xClearSamples();
return;
}
freeBytes = GetAvailableBytes();
}
}
if (partialOffset != 0) { if (partialOffset != 0) {
BYTE *offsetBuffer = soundBuffer + writeOffset + partialOffset; BYTE *offsetBuffer = soundBuffer + writeOffset + partialOffset;
UINT32 samplesleftinblock = (singleBufferBytes - partialOffset) >> 1; UINT32 samplesleftinblock = (singleBufferBytes - partialOffset) >> 1;

View File

@ -40,6 +40,7 @@ private:
void ProcessSound(void); void ProcessSound(void);
bool InitXAudio2(void); bool InitXAudio2(void);
void DeInitXAudio2(void); void DeInitXAudio2(void);
int GetAvailableBytes();
std::vector<std::wstring> GetDeviceList(); std::vector<std::wstring> GetDeviceList();
int FindDeviceIndex(TCHAR *audio_device); int FindDeviceIndex(TCHAR *audio_device);

View File

@ -117,6 +117,7 @@ void WinSetDefaultValues ()
Settings.TakeScreenshot=false; Settings.TakeScreenshot=false;
GUI.Language=0; GUI.Language=0;
GUI.AllowSoundSync = true;
} }

View File

@ -87,7 +87,6 @@ extern SNPServer NPServer;
__int64 PCBase, PCFrameTime, PCFrameTimeNTSC, PCFrameTimePAL, PCStart, PCEnd; __int64 PCBase, PCFrameTime, PCFrameTimeNTSC, PCFrameTimePAL, PCStart, PCEnd;
DWORD PCStartTicks, PCEndTicks; DWORD PCStartTicks, PCEndTicks;
bool PCFrameTimeIsDefault = true;
INT_PTR CALLBACK DlgSoundConf(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DlgSoundConf(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK DlgInfoProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DlgInfoProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
@ -3455,13 +3454,6 @@ int WINAPI WinMain(
if(run_loop) if(run_loop)
{ {
// no sound sync when speed is not set to 100%
while (!S9xSyncSound()) {
ResetEvent(GUI.SoundSyncEvent);
if (!PCFrameTimeIsDefault || WaitForSingleObject(GUI.SoundSyncEvent, 1000) != WAIT_OBJECT_0)
S9xClearSamples();
}
ProcessInput(); ProcessInput();
if(GUI.rewindBufferSize if(GUI.rewindBufferSize
@ -3901,12 +3893,15 @@ static void ResetFrameTimer ()
{ {
QueryPerformanceCounter((LARGE_INTEGER*)&PCStart); QueryPerformanceCounter((LARGE_INTEGER*)&PCStart);
PCStartTicks = timeGetTime()*1000; PCStartTicks = timeGetTime()*1000;
if (Settings.FrameTime == Settings.FrameTimeNTSC) PCFrameTime = PCFrameTimeNTSC; if (Settings.FrameTime == Settings.FrameTimeNTSC)
else if (Settings.FrameTime == Settings.FrameTimePAL) PCFrameTime = PCFrameTimePAL; PCFrameTime = PCFrameTimeNTSC;
else PCFrameTime = (__int64)((double)(PCBase * Settings.FrameTime) * .000001); else if (Settings.FrameTime == Settings.FrameTimePAL)
PCFrameTime = PCFrameTimePAL;
else
PCFrameTime = (__int64)((double)(PCBase * Settings.FrameTime) * .000001);
// determines if we can do sound sync // determines if we can do sound sync
PCFrameTimeIsDefault = Settings.PAL ? Settings.FrameTime == Settings.FrameTimePAL : Settings.FrameTime == Settings.FrameTimeNTSC; GUI.AllowSoundSync = Settings.PAL ? Settings.FrameTime == Settings.FrameTimePAL : Settings.FrameTime == Settings.FrameTimeNTSC;
if (GUI.hFrameTimer) if (GUI.hFrameTimer)
timeKillEvent (GUI.hFrameTimer); timeKillEvent (GUI.hFrameTimer);

View File

@ -217,6 +217,7 @@ struct sGUI {
CRITICAL_SECTION SoundCritSect; CRITICAL_SECTION SoundCritSect;
HANDLE SoundSyncEvent; HANDLE SoundSyncEvent;
TCHAR AudioDevice[MAX_AUDIO_NAME_LENGTH]; TCHAR AudioDevice[MAX_AUDIO_NAME_LENGTH];
bool AllowSoundSync;
TCHAR RomDir [_MAX_PATH]; TCHAR RomDir [_MAX_PATH];
TCHAR ScreensDir [_MAX_PATH]; TCHAR ScreensDir [_MAX_PATH];