1191
|
1 template CheckWinMMResult*(call: untyped) =
|
|
2 let value = call
|
|
3 if value < 0:
|
|
4 raise newException(Exception, "Windows multimedia error: " & astToStr(call) &
|
|
5 " returned " & $value)
|
|
6 type
|
|
7 NativeSoundDevice* = object
|
|
8 handle: HWAVEOUT
|
|
9 buffers: seq[WAVEHDR]
|
|
10
|
|
11 proc OpenSoundDevice*(sampleRate: uint32, buffers: seq[ptr SoundData]): NativeSoundDevice =
|
|
12 var format = WAVEFORMATEX(
|
|
13 wFormatTag: WAVE_FORMAT_PCM,
|
|
14 nChannels: 2,
|
|
15 nSamplesPerSec: DWORD(sampleRate),
|
|
16 nAvgBytesPerSec: DWORD(sampleRate) * 4,
|
|
17 nBlockAlign: 4,
|
|
18 wBitsPerSample: 16,
|
|
19 cbSize: 0,
|
|
20 )
|
|
21 CheckWinMMResult waveOutOpen(addr result.handle, WAVE_MAPPER, addr format, DWORD_PTR(0), DWORD_PTR(0), CALLBACK_NULL)
|
|
22
|
|
23 for i in 0 ..< buffers.len:
|
|
24 result.buffers.add WAVEHDR(
|
|
25 lpData: cast[cstring](addr buffers[i][][0]),
|
|
26 dwBufferLength: DWORD(buffers[i][].len * sizeof(Sample)),
|
|
27 dwLoops: 1,
|
|
28 )
|
|
29 for i in 0 ..< result.buffers.len:
|
|
30 CheckWinMMResult waveOutPrepareHeader(result.handle, addr result.buffers[i], UINT(sizeof(WAVEHDR)))
|
|
31 CheckWinMMResult waveOutWrite(result.handle, addr result.buffers[i], UINT(sizeof(WAVEHDR)))
|
|
32
|
|
33 proc WriteSoundData*(soundDevice: var NativeSoundDevice, buffer: int) =
|
|
34 while (soundDevice.buffers[buffer].dwFlags and WHDR_DONE) == 0:
|
|
35 sleep(1)
|
|
36 CheckWinMMResult waveOutWrite(soundDevice.handle, addr soundDevice.buffers[buffer], UINT(sizeof(WAVEHDR)))
|
|
37
|
|
38 proc CloseSoundDevice*(soundDevice: var NativeSoundDevice) =
|
|
39 for i in 0 ..< soundDevice.buffers.len:
|
|
40 discard waveOutUnprepareHeader(soundDevice.handle, addr soundDevice.buffers[i], UINT(sizeof(WAVEHDR)))
|
|
41 waveOutClose(soundDevice.handle)
|