win32: XAudio2: Allow partially filling sample blocks.

Use minimal Snes9x-side buffer with XAudio2.
This commit is contained in:
Brandon Wright 2019-02-06 17:29:46 -06:00
parent 2701e7219c
commit d8579ff9cb
3 changed files with 40 additions and 13 deletions

View File

@ -146,7 +146,7 @@ bool CXAudio2::InitVoices(void)
wfx.cbSize = 0; wfx.cbSize = 0;
if( FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx, if( FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx,
XAUDIO2_VOICE_NOSRC , XAUDIO2_DEFAULT_FREQ_RATIO, this, NULL, NULL ) ) ) { XAUDIO2_VOICE_USEFILTER, XAUDIO2_DEFAULT_FREQ_RATIO, this, NULL, NULL ) ) ) {
DXTRACE_ERR_MSGBOX(TEXT("Unable to create source voice."),hr); DXTRACE_ERR_MSGBOX(TEXT("Unable to create source voice."),hr);
return false; return false;
} }
@ -239,6 +239,7 @@ bool CXAudio2::SetupSound()
{ {
soundBuffer = new uint8[sum_bufferSize]; soundBuffer = new uint8[sum_bufferSize];
writeOffset = 0; writeOffset = 0;
partialOffset = 0;
} }
else { else {
DeInitVoices(); DeInitVoices();
@ -275,7 +276,7 @@ the OnBufferComplete callback.
*/ */
void CXAudio2::ProcessSound() void CXAudio2::ProcessSound()
{ {
int freeBytes = (blockCount - bufferCount) * singleBufferBytes; int freeBytes = ((blockCount - bufferCount) * singleBufferBytes) - partialOffset;
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
@ -302,15 +303,38 @@ void CXAudio2::ProcessSound()
if(!initDone) if(!initDone)
return; return;
BYTE * curBuffer; if (partialOffset != 0) {
BYTE *offsetBuffer = soundBuffer + writeOffset + partialOffset;
UINT32 samplesleftinblock = (singleBufferBytes - partialOffset) >> (Settings.SixteenBitSound ? 1 : 0);
if (availableSamples < ((singleBufferBytes - partialOffset) >> (Settings.SixteenBitSound ? 1 : 0)))
{
S9xMixSamples(offsetBuffer, availableSamples);
partialOffset += availableSamples << (Settings.SixteenBitSound ? 1 : 0);
availableSamples = 0;
}
else
{
S9xMixSamples(offsetBuffer, samplesleftinblock);
partialOffset = 0;
availableSamples -= samplesleftinblock;
PushBuffer(singleBufferBytes, soundBuffer + writeOffset, NULL);
writeOffset += singleBufferBytes;
writeOffset %= sum_bufferSize;
}
}
while(availableSamples > singleBufferSamples && bufferCount < blockCount) { while (availableSamples > singleBufferSamples && bufferCount < blockCount) {
curBuffer = soundBuffer + writeOffset; BYTE *curBuffer = soundBuffer + writeOffset;
S9xMixSamples(curBuffer,singleBufferSamples); S9xMixSamples(curBuffer, singleBufferSamples);
PushBuffer(singleBufferBytes,curBuffer,NULL); PushBuffer(singleBufferBytes, curBuffer, NULL);
writeOffset+=singleBufferBytes; writeOffset += singleBufferBytes;
writeOffset%=sum_bufferSize; writeOffset %= sum_bufferSize;
availableSamples -= singleBufferSamples; availableSamples -= singleBufferSamples;
}
if (availableSamples > 0 && bufferCount < blockCount) {
S9xMixSamples(soundBuffer + writeOffset, availableSamples);
partialOffset = availableSamples << (Settings.SixteenBitSound ? 1 : 0);
} }
} }

View File

@ -26,9 +26,9 @@ private:
UINT32 singleBufferSamples; // samples in one block UINT32 singleBufferSamples; // samples in one block
UINT32 singleBufferBytes; // bytes in one block UINT32 singleBufferBytes; // bytes in one block
UINT32 blockCount; // soundBuffer is divided into blockCount blocks UINT32 blockCount; // soundBuffer is divided into blockCount blocks
// currently set to 4 // currently set to 8
UINT32 writeOffset; // offset into the buffer for the next block UINT32 writeOffset; // offset into the buffer for the next block
UINT32 partialOffset; // offset into non-complete block
uint8 *soundBuffer; // the buffer itself uint8 *soundBuffer; // the buffer itself
bool InitVoices(void); bool InitVoices(void);

View File

@ -51,7 +51,10 @@ bool ReInitSound()
if(S9xSoundOutput) if(S9xSoundOutput)
S9xSoundOutput->DeInitSoundOutput(); S9xSoundOutput->DeInitSoundOutput();
return S9xInitSound(GUI.SoundBufferSize,0); if (S9xSoundOutput == &S9xDirectSound)
return S9xInitSound(GUI.SoundBufferSize, 0);
else
return S9xInitSound(0, 0);
} }
void CloseSoundDevice() { void CloseSoundDevice() {