win32: WaveOut: Add underrun recovery and buffer size min.

This commit is contained in:
Brandon Wright 2019-02-12 12:32:47 -06:00
parent be52994d01
commit 0772e3828c
2 changed files with 24 additions and 0 deletions

View File

@ -44,6 +44,8 @@ bool CWaveOut::SetupSound()
UINT32 blockTime = GUI.SoundBufferSize / blockCount; UINT32 blockTime = GUI.SoundBufferSize / blockCount;
singleBufferSamples = (Settings.SoundPlaybackRate * blockTime) / 1000; singleBufferSamples = (Settings.SoundPlaybackRate * blockTime) / 1000;
if (singleBufferSamples < 256)
singleBufferSamples = 256;
singleBufferSamples *= 2; singleBufferSamples *= 2;
singleBufferBytes = singleBufferSamples * 2; singleBufferBytes = singleBufferSamples * 2;
sumBufferSize = singleBufferBytes * blockCount; sumBufferSize = singleBufferBytes * blockCount;
@ -88,6 +90,8 @@ void CWaveOut::DeInitSoundOutput()
if (!initDone) if (!initDone)
return; return;
StopPlayback();
waveOutReset(hWaveOut); waveOutReset(hWaveOut);
if (!waveHeaders.empty()) if (!waveHeaders.empty())
@ -115,10 +119,29 @@ int CWaveOut::GetAvailableBytes()
return ((blockCount - bufferCount) * singleBufferBytes) - partialOffset; return ((blockCount - bufferCount) * singleBufferBytes) - partialOffset;
} }
// Fill the set of blocks preceding writeOffset with silence and write them
// to the output to get the buffer back to 50%
void CWaveOut::RecoverFromUnderrun()
{
writeOffset = (writeOffset - (blockCount / 2) + blockCount) % blockCount;
for (int i = 0; i < blockCount / 2; i++)
{
memset(waveHeaders[writeOffset].lpData, 0, singleBufferBytes);
waveOutWrite(hWaveOut, &waveHeaders[writeOffset], sizeof(WAVEHDR));
InterlockedIncrement(&bufferCount);
writeOffset++;
writeOffset %= blockCount;
}
}
void CWaveOut::ProcessSound() void CWaveOut::ProcessSound()
{ {
int freeBytes = ((blockCount - bufferCount) * singleBufferBytes) - partialOffset; int freeBytes = ((blockCount - bufferCount) * singleBufferBytes) - partialOffset;
if (bufferCount == 0)
RecoverFromUnderrun();
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
S9xUpdateDynamicRate(freeBytes, sumBufferSize); S9xUpdateDynamicRate(freeBytes, sumBufferSize);

View File

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