# HG changeset patch # User Sam # Date 1682962450 -25200 # Node ID f3b723eb89d596126521a68d83aa91aa2e10bfb3 # Parent 1f2cc5837dff80fd6b55ee1842313fa5f6e447a8 add: initial implementation of win32 pcm output diff -r 1f2cc5837dff -r f3b723eb89d5 src/semicongine/platform/windows/audio.nim --- 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)