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)