changeset 173:07e57fce1beb

add: initial implementation of win32 pcm output
author Sam <sam@basx.dev>
date Tue, 02 May 2023 00:34:10 +0700
parents 062b03d5d094
children 2a31a1785b4a
files src/semicongine/platform/windows/audio.nim
diffstat 1 files changed, 43 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/platform/windows/audio.nim	Tue May 02 00:33:46 2023 +0700
+++ b/src/semicongine/platform/windows/audio.nim	Tue May 02 00:34:10 2023 +0700
@@ -0,0 +1,43 @@
+import winim
+import winim/extra
+
+import ../../audiotypes
+
+template checkWinMMResult*(call: untyped) =
+  let value = call
+  if value < 0:
+    raise newException(Exception, "Windows multimedia error: " & astToStr(call) &
+      " returned " & $value)
+type
+  NativeSoundDevice* = object
+    handle: HWAVEOUT
+ 
+proc openSoundDevice*(sampleRate: uint32, bufferSize: uint32): NativeSoundDevice =
+  var format = WAVEFORMATEX(
+    wFormatTag: WAVE_FORMAT_PCM,
+    nChannels: 2,
+    nSamplesPerSec: DWORD(sampleRate),
+    nAvgBytesPerSec: DWORD(sampleRate) * 4,
+    nBlockAlign: 4,
+    wBitsPerSample: 16,
+    cbSize: 0,
+  )
+
+  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)),
+    dwBytesRecorded: 0,
+    dwUser: DWORD_PTR(0),
+    dwFlags: 0,
+    dwLoops: 1,
+    lpNext: nil,
+    reserved: DWORD_PTR(0)
+  )
+  checkWinMMResult waveOutPrepareHeader(soundDevice.handle, addr data, UINT(sizeof(WAVEHDR)))
+  checkWinMMResult waveOutWrite(soundDevice.handle, addr data, UINT(sizeof(WAVEHDR)))
+
+proc closeSoundDevice*(soundDevice: NativeSoundDevice) =
+  waveOutClose(soundDevice.handle)