| @@ -224,6 +224,8 @@ struct Win32SoundOutput { | |||
| uint32 runningSampleIndex; | |||
| int bytesPerSample; | |||
| int secondaryBufferSize; | |||
| real32 tSine; | |||
| int latencySampleCount; | |||
| }; | |||
| internal void win32FillSoundBuffer(Win32SoundOutput *soundOutput, DWORD byteToLock, DWORD bytesToWrite) { | |||
| @@ -236,19 +238,19 @@ internal void win32FillSoundBuffer(Win32SoundOutput *soundOutput, DWORD byteToLo | |||
| DWORD region1SampleCount = region1Size/soundOutput->bytesPerSample; | |||
| int16 *sampleOut = (int16*)region1; | |||
| for (DWORD sampleIndex = 0; sampleIndex < region1SampleCount; sampleIndex++) { | |||
| real32 t = 2.0f * PI32 * (real32)soundOutput->runningSampleIndex / (real32)soundOutput->wavePeriod; | |||
| int16 sampleValue = (int16)(sin(t) * (real32)soundOutput->toneVolume); | |||
| int16 sampleValue = (int16)(sin(soundOutput->tSine) * (real32)soundOutput->toneVolume); | |||
| *sampleOut++ = sampleValue; | |||
| *sampleOut++ = sampleValue; | |||
| soundOutput->tSine += 2.0f * PI32 / (real32)soundOutput->wavePeriod; | |||
| soundOutput->runningSampleIndex++; | |||
| } | |||
| DWORD region2SampleCount = region2Size/soundOutput->bytesPerSample; | |||
| sampleOut = (int16*)region2; | |||
| for (DWORD sampleIndex = 0; sampleIndex < region2SampleCount; sampleIndex++) { | |||
| real32 t = 2.0f * PI32 * (real32)soundOutput->runningSampleIndex / (real32)soundOutput->wavePeriod; | |||
| int16 sampleValue = (int16)(sin(t) * soundOutput->toneVolume); | |||
| int16 sampleValue = (int16)(sin(soundOutput->tSine) * (real32)soundOutput->toneVolume); | |||
| *sampleOut++ = sampleValue; | |||
| *sampleOut++ = sampleValue; | |||
| soundOutput->tSine += 2.0f * PI32 / (real32)soundOutput->wavePeriod; | |||
| soundOutput->runningSampleIndex++; | |||
| } | |||
| globalSecondaryBuffer->Unlock(region1, region1Size, region2, region2Size); | |||
| @@ -305,11 +307,12 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin | |||
| soundOutput.runningSampleIndex = 0; | |||
| soundOutput.bytesPerSample = sizeof(int16)*2; | |||
| soundOutput.secondaryBufferSize = soundOutput.samplesPerSecond*soundOutput.bytesPerSample; | |||
| soundOutput.latencySampleCount = soundOutput.samplesPerSecond / 15.0f; | |||
| win32LoadXInput(); | |||
| win32InitSound(window, soundOutput.samplesPerSecond, soundOutput.secondaryBufferSize); | |||
| win32FillSoundBuffer(&soundOutput, 0, soundOutput.secondaryBufferSize); | |||
| win32FillSoundBuffer(&soundOutput, 0, soundOutput.latencySampleCount*soundOutput.bytesPerSample); | |||
| globalSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); | |||
| LARGE_INTEGER lastCounter; | |||
| @@ -361,6 +364,9 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin | |||
| yOffset += stickY/5000.0 * factor; | |||
| xOffset -= stickX/5000.0 * factor; | |||
| soundOutput.toneHz = 220 + (stickYNorm + 1.0)/2.0 * 220.0; | |||
| soundOutput.wavePeriod = soundOutput.samplesPerSecond / soundOutput.toneHz; | |||
| GameOffscreenBuffer buffer = {}; | |||
| buffer.memory = globalBackBuffer.memory; | |||
| buffer.width = globalBackBuffer.width; | |||
| @@ -376,13 +382,14 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin | |||
| DWORD writeCursor; | |||
| if (SUCCEEDED(globalSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor))) { | |||
| DWORD byteToLock = (soundOutput.runningSampleIndex*soundOutput.bytesPerSample) % soundOutput.secondaryBufferSize; | |||
| DWORD targetCursor = (playCursor + soundOutput.latencySampleCount*soundOutput.bytesPerSample) % soundOutput.secondaryBufferSize; | |||
| DWORD bytesToWrite; | |||
| if (byteToLock == playCursor) { | |||
| if (byteToLock == targetCursor) { | |||
| bytesToWrite = 0; | |||
| } else if (byteToLock > playCursor) { | |||
| bytesToWrite = soundOutput.secondaryBufferSize - byteToLock + playCursor; | |||
| } else if (byteToLock > targetCursor) { | |||
| bytesToWrite = soundOutput.secondaryBufferSize - byteToLock + targetCursor; | |||
| } else { | |||
| bytesToWrite = playCursor - byteToLock; | |||
| bytesToWrite = targetCursor - byteToLock; | |||
| } | |||
| win32FillSoundBuffer(&soundOutput, byteToLock, bytesToWrite); | |||
| } | |||