# HG changeset patch # User Sam # Date 1682962450 -25200 # Node ID 07e57fce1bebbfa3773eecdcad17debe167e6fb5 # Parent 062b03d5d094914953321734d1f7278a356c1f13 add: initial implementation of win32 pcm output diff -r 062b03d5d094 -r 07e57fce1beb 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)