Mercurial > games > semicongine
diff src/semicongine/platform/windows/audio.nim @ 637:bb6857da8113
fix: bad audio buffer handling, reduce latency (unbearable on windows)
author | Sam <sam@basx.dev> |
---|---|
date | Tue, 02 May 2023 02:13:46 +0700 |
parents | c5ff8f88c4a0 |
children | 42e99cb20da2 |
line wrap: on
line diff
--- a/src/semicongine/platform/windows/audio.nim Tue May 02 01:03:03 2023 +0700 +++ b/src/semicongine/platform/windows/audio.nim Tue May 02 02:13:46 2023 +0700 @@ -11,8 +11,9 @@ type NativeSoundDevice* = object handle: HWAVEOUT + buffer: WAVEHDR -proc openSoundDevice*(sampleRate: uint32, bufferSize: uint32): NativeSoundDevice = +proc openSoundDevice*(sampleRate: uint32, buffer: ptr SoundData): NativeSoundDevice = var format = WAVEFORMATEX( wFormatTag: WAVE_FORMAT_PCM, nChannels: 2, @@ -24,11 +25,9 @@ ) checkWinMMResult waveOutOpen(addr result.handle, WAVE_MAPPER, addr format, DWORD_PTR(0), DWORD_PTR(0), CALLBACK_NULL) - -proc updateSoundBuffer*(soundDevice: NativeSoundDevice, buffer: var SoundData) = - var data = WAVEHDR( - lpData: cast[cstring](addr buffer[0]), - dwBufferLength: DWORD(buffer.len * sizeof(Sample)), + result.buffer = WAVEHDR( + lpData: cast[cstring](addr buffer[][0]), + dwBufferLength: DWORD(buffer[].len * sizeof(Sample)), dwBytesRecorded: 0, dwUser: DWORD_PTR(0), dwFlags: 0, @@ -36,11 +35,13 @@ lpNext: nil, reserved: DWORD_PTR(0) ) - checkWinMMResult waveOutPrepareHeader(soundDevice.handle, addr data, UINT(sizeof(WAVEHDR))) - checkWinMMResult waveOutWrite(soundDevice.handle, addr data, UINT(sizeof(WAVEHDR))) - while (data.dwFlags and WHDR_DONE) != 1: + checkWinMMResult waveOutPrepareHeader(result.handle, addr result.buffer, UINT(sizeof(WAVEHDR))) + +proc writeSoundData*(soundDevice: var NativeSoundDevice) = + checkWinMMResult waveOutWrite(soundDevice.handle, addr soundDevice.buffer, UINT(sizeof(WAVEHDR))) + while (soundDevice.buffer.dwFlags and WHDR_DONE) != 1: discard - checkWinMMResult waveOutUnprepareHeader(soundDevice.handle, addr data, UINT(sizeof(WAVEHDR))) -proc closeSoundDevice*(soundDevice: NativeSoundDevice) = +proc closeSoundDevice*(soundDevice: var NativeSoundDevice) = + checkWinMMResult waveOutUnprepareHeader(soundDevice.handle, addr soundDevice.buffer, UINT(sizeof(WAVEHDR))) waveOutClose(soundDevice.handle)