-
Notifications
You must be signed in to change notification settings - Fork 2
/
writer_windows.go
77 lines (67 loc) · 1.73 KB
/
writer_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// 30 august 2014
package pcmio
import (
"syscall"
"unsafe"
)
// #cgo CFLAGS: --std=c99
// #cgo LDFLAGS: -lkernel32 -lwinmm
// #include "winapi_windows.h"
import "C"
type writer struct {
wo C.HWAVEOUT
event C.HANDLE
}
func openDefaultWriter(format Format, rate uint) (*writer, error) {
var fmt C.WAVEFORMATEX
w := new(writer)
lasterr := C.xCreateEvent(&w.event)
if lasterr != 0 {
return nil, syscall.Errno(lasterr)
}
fmt.wFormatTag = C.WAVE_FORMAT_PCM
fmt.nChannels = 1
fmt.nSamplesPerSec = C.DWORD(rate)
switch format {
case U8:
fmt.wBitsPerSample = 8
}
fmt.nBlockAlign = (fmt.nChannels * fmt.wBitsPerSample) / 8
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * C.DWORD(fmt.nBlockAlign)
fmt.cbSize = 0
err := C.waveOutOpen(&w.wo, C.WAVE_MAPPER, &fmt,
C.DWORD_PTR(uintptr(unsafe.Pointer(w.event))), 0,
C.CALLBACK_EVENT | C.WAVE_FORMAT_DIRECT)
if err != C.MMSYSERR_NOERROR {
return nil, waveOutError(err)
}
return w, nil
}
func (w *writer) Write(p []byte) (n int, err error) {
var hdr C.WAVEHDR
hdr.lpData = C.LPSTR(unsafe.Pointer(&p[0]))
hdr.dwBufferLength = C.DWORD(len(p))
hdr.dwFlags = 0
hdr.dwLoops = 0
lasterr := C.xResetEvent(w.event)
if lasterr != 0 {
return 0, syscall.Errno(lasterr)
}
xerr := C.waveOutPrepareHeader(w.wo, &hdr, C.UINT(unsafe.Sizeof(hdr)))
if xerr != C.MMSYSERR_NOERROR {
return 0, waveOutError(xerr)
}
xerr = C.waveOutWrite(w.wo, &hdr, C.UINT(unsafe.Sizeof(hdr)))
if xerr != C.MMSYSERR_NOERROR {
return 0, waveOutError(xerr)
}
lasterr = C.xWaitForSingleObject(w.event)
if lasterr != 0 {
return 0, syscall.Errno(lasterr)
}
xerr = C.waveOutUnprepareHeader(w.wo, &hdr, C.UINT(unsafe.Sizeof(hdr)))
if xerr != C.MMSYSERR_NOERROR {
return 0, waveOutError(xerr)
}
return len(p), nil
}