Skip to content

Commit 6679dc0

Browse files
committed
Add wave* and some time* functions
1 parent 42bfe2d commit 6679dc0

File tree

3 files changed

+349
-1
lines changed

3 files changed

+349
-1
lines changed

lib/winmm-sys/src/lib.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,51 @@ extern "system" {
1111
pub fn sndPlaySoundW(pszSound: LPCWSTR, fuSound: UINT) -> BOOL;
1212
pub fn timeBeginPeriod(uPeriod: UINT) -> MMRESULT;
1313
pub fn timeEndPeriod(uPeriod: UINT) -> MMRESULT;
14+
pub fn timeGetDevCaps(ptc: LPTIMECAPS, cbtc: UINT) -> MMRESULT;
15+
pub fn timeGetTime() -> DWORD;
16+
pub fn waveInAddBuffer(hwi: HWAVEIN, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT;
17+
pub fn waveInClose(hwi: HWAVEIN) -> MMRESULT;
18+
// pub fn waveInGetDevCapsA();
19+
pub fn waveInGetDevCapsW(uDeviceID: UINT_PTR, pwic: LPWAVEINCAPSW, cbwic: UINT) -> MMRESULT;
20+
// pub fn waveInGetErrorTextA();
21+
pub fn waveInGetErrorTextW(mmrError: MMRESULT, pszText: LPWSTR, cchText: UINT) -> MMRESULT;
22+
// pub fn waveInGetID();
23+
pub fn waveInGetNumDevs() -> UINT;
24+
pub fn waveInGetPosition(hwi: HWAVEIN, pmmt: LPMMTIME, cbmmt: UINT) -> MMRESULT;
25+
pub fn waveInMessage(hwi: HWAVEIN, uMsg: UINT, dw1: DWORD_PTR, dw2: DWORD_PTR) -> MMRESULT;
26+
pub fn waveInOpen(
27+
phwi: LPHWAVEIN, uDeviceID: UINT, pwfx: LPCWAVEFORMATEX, dwCallback: DWORD_PTR,
28+
dwInstance: DWORD_PTR, fdwOpen: DWORD
29+
) -> MMRESULT;
30+
pub fn waveInPrepareHeader(hwi: HWAVEIN, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT;
31+
pub fn waveInReset(hwi: HWAVEIN) -> MMRESULT;
32+
pub fn waveInStart(hwi: HWAVEIN) -> MMRESULT;
33+
pub fn waveInStop(hwi: HWAVEIN) -> MMRESULT;
34+
pub fn waveInUnprepareHeader(hwi: HWAVEIN, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT;
35+
pub fn waveOutBreakLoop(hwo: HWAVEOUT) -> MMRESULT;
36+
pub fn waveOutClose(hwo: HWAVEOUT) -> MMRESULT;
37+
// pub fn waveOutGetDevCapsA();
38+
pub fn waveOutGetDevCapsW(uDeviceID: UINT_PTR, pwoc: LPWAVEOUTCAPSW, cbwoc: UINT) -> MMRESULT;
39+
// pub fn waveOutGetErrorTextA();
40+
pub fn waveOutGetErrorTextW(mmrError: MMRESULT, pszText: LPWSTR, cchText: UINT) -> MMRESULT;
41+
// pub fn waveOutGetID();
42+
pub fn waveOutGetNumDevs() -> UINT;
43+
pub fn waveOutGetPitch(hwo: HWAVEOUT, pdwPitch: LPDWORD) -> MMRESULT;
44+
pub fn waveOutGetPlaybackRate(hwo: HWAVEOUT, pdwRate: LPDWORD) -> MMRESULT;
45+
pub fn waveOutGetPosition(hwo: HWAVEOUT, pmmt: LPMMTIME, cbmmt: UINT) -> MMRESULT;
46+
pub fn waveOutGetVolume(hwo: HWAVEOUT, pdwVolume: LPDWORD) -> MMRESULT;
47+
pub fn waveOutMessage(hwo: HWAVEOUT, uMsg: UINT, dw1: DWORD_PTR, dw2: DWORD_PTR) -> MMRESULT;
48+
pub fn waveOutOpen(
49+
phwo: LPHWAVEOUT, uDeviceID: UINT, pwfx: LPCWAVEFORMATEX, dwCallback: DWORD_PTR,
50+
dwInstance: DWORD_PTR, fdwOpen: DWORD
51+
) -> MMRESULT;
52+
pub fn waveOutPause(hwo: HWAVEOUT) -> MMRESULT;
53+
pub fn waveOutPrepareHeader(hwo: HWAVEOUT, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT;
54+
pub fn waveOutReset(hwo: HWAVEOUT) -> MMRESULT;
55+
pub fn waveOutRestart(hwo: HWAVEOUT) -> MMRESULT;
56+
pub fn waveOutSetPitch(hwo: HWAVEOUT, dwPitch: DWORD) -> MMRESULT;
57+
pub fn waveOutSetPlaybackRate(hwo: HWAVEOUT, dwRate: DWORD) -> MMRESULT;
58+
pub fn waveOutSetVolume(hwo: HWAVEOUT, dwVolume: DWORD) -> MMRESULT;
59+
pub fn waveOutUnprepareHeader(hwo: HWAVEOUT, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT;
60+
pub fn waveOutWrite(hwo: HWAVEOUT, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT;
1461
}

src/mmsystem.rs

Lines changed: 250 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,257 @@
11
// Copyright © 2015, Peter Atashian
22
// Licensed under the MIT License <LICENSE.md>
3+
//! MM procedure declarations, constant definitions and macros
4+
//109 (Win 7 SDK)
5+
pub type MMVERSION = ::UINT;
36
pub type MMRESULT = ::UINT;
7+
#[repr(C)] #[derive(Clone, Copy, Debug)]
8+
pub struct MMTIME {
9+
wType: ::UINT,
10+
u: MMTIME_u,
11+
}
12+
pub type PMMTIME = *mut MMTIME;
13+
pub type NPMMTIME = *mut MMTIME;
14+
pub type LPMMTIME = *mut MMTIME;
15+
#[repr(C)] #[derive(Clone, Copy, Debug)]
16+
pub struct MMTIME_u {
17+
data: [u8; 8],
18+
}
19+
impl MMTIME_u {
20+
#[inline]
21+
pub unsafe fn ms(&self) -> &::DWORD {
22+
::std::mem::transmute(&self.data)
23+
}
24+
#[inline]
25+
pub unsafe fn sample(&self) -> &::DWORD {
26+
::std::mem::transmute(&self.data)
27+
}
28+
#[inline]
29+
pub unsafe fn cb(&self) -> &::DWORD {
30+
::std::mem::transmute(&self.data)
31+
}
32+
#[inline]
33+
pub unsafe fn ticks(&self) -> &::DWORD {
34+
::std::mem::transmute(&self.data)
35+
}
36+
#[inline]
37+
pub unsafe fn smpte(&self) -> &MMTIME_smpte {
38+
::std::mem::transmute(&self.data)
39+
}
40+
#[inline]
41+
pub unsafe fn midi(&self) -> &MMTIME_midi {
42+
::std::mem::transmute(&self.data)
43+
}
444

45+
#[inline]
46+
pub unsafe fn ms_mut(&mut self) -> &mut ::DWORD {
47+
::std::mem::transmute(&mut self.data)
48+
}
49+
#[inline]
50+
pub unsafe fn sample_mut(&mut self) -> &mut ::DWORD {
51+
::std::mem::transmute(&mut self.data)
52+
}
53+
#[inline]
54+
pub unsafe fn cb_mut(&mut self) -> &mut ::DWORD {
55+
::std::mem::transmute(&mut self.data)
56+
}
57+
#[inline]
58+
pub unsafe fn ticks_mut(&mut self) -> &mut ::DWORD {
59+
::std::mem::transmute(&mut self.data)
60+
}
61+
#[inline]
62+
pub unsafe fn smpte_mut(&mut self) -> &mut MMTIME_smpte {
63+
::std::mem::transmute(&mut self.data)
64+
}
65+
#[inline]
66+
pub unsafe fn midi_mut(&mut self) -> &mut MMTIME_midi {
67+
::std::mem::transmute(&mut self.data)
68+
}
69+
}
70+
#[repr(C)] #[derive(Clone, Copy, Debug)]
71+
pub struct MMTIME_smpte {
72+
pub hour: ::BYTE,
73+
pub min: ::BYTE,
74+
pub sec: ::BYTE,
75+
pub frame: ::BYTE,
76+
pub fps: ::BYTE,
77+
pub dummy: ::BYTE,
78+
pub pad: [::BYTE; 2],
79+
}
80+
#[repr(C)] #[derive(Clone, Copy, Debug)]
81+
pub struct MMTIME_midi {
82+
pub songptrpos: ::DWORD,
83+
}
84+
pub const TIME_MS: ::UINT = 0x0001;
85+
pub const TIME_SAMPLES: ::UINT = 0x0002;
86+
pub const TIME_BYTES: ::UINT = 0x0004;
87+
pub const TIME_SMPTE: ::UINT = 0x0008;
88+
pub const TIME_MIDI: ::UINT = 0x0010;
89+
pub const TIME_TICKS: ::UINT = 0x0020;
90+
pub const MM_JOY1MOVE: ::UINT = 0x3A0;
91+
pub const MM_JOY2MOVE: ::UINT = 0x3A1;
92+
pub const MM_JOY1ZMOVE: ::UINT = 0x3A2;
93+
pub const MM_JOY2ZMOVE: ::UINT = 0x3A3;
94+
pub const MM_JOY1BUTTONDOWN: ::UINT = 0x3B5;
95+
pub const MM_JOY2BUTTONDOWN: ::UINT = 0x3B6;
96+
pub const MM_JOY1BUTTONUP: ::UINT = 0x3B7;
97+
pub const MM_JOY2BUTTONUP: ::UINT = 0x3B8;
98+
pub const MM_MCINOTIFY: ::UINT = 0x3B9;
99+
pub const MM_WOM_OPEN: ::UINT = 0x3BB;
100+
pub const MM_WOM_CLOSE: ::UINT = 0x3BC;
101+
pub const MM_WOM_DONE: ::UINT = 0x3BD;
102+
pub const MM_WIM_OPEN: ::UINT = 0x3BE;
103+
pub const MM_WIM_CLOSE: ::UINT = 0x3BF;
104+
pub const MM_WIM_DATA: ::UINT = 0x3C0;
105+
pub const MM_MIM_OPEN: ::UINT = 0x3C1;
106+
pub const MM_MIM_CLOSE: ::UINT = 0x3C2;
107+
pub const MM_MIM_DATA: ::UINT = 0x3C3;
108+
pub const MM_MIM_LONGDATA: ::UINT = 0x3C4;
109+
pub const MM_MIM_ERROR: ::UINT = 0x3C5;
110+
pub const MM_MIM_LONGERROR: ::UINT = 0x3C6;
111+
pub const MM_MOM_OPEN: ::UINT = 0x3C7;
112+
pub const MM_MOM_CLOSE: ::UINT = 0x3C8;
113+
pub const MM_MOM_DONE: ::UINT = 0x3C9;
114+
pub const MMSYSERR_BASE: MMRESULT = 0;
115+
pub const WAVERR_BASE: MMRESULT = 32;
116+
pub const MIDIERR_BASE: MMRESULT = 64;
117+
pub const TIMERR_BASE: MMRESULT = 96;
118+
pub const JOYERR_BASE: MMRESULT = 160;
119+
pub const MCIERR_BASE: MMRESULT = 256;
120+
pub const MIXERR_BASE: MMRESULT = 1024;
121+
pub const MMSYSERR_NOERROR: MMRESULT = 0;
122+
pub const MMSYSERR_ERROR: MMRESULT = MMSYSERR_BASE + 1;
123+
pub const MMSYSERR_BADDEVICEID: MMRESULT = MMSYSERR_BASE + 2;
124+
pub const MMSYSERR_NOTENABLED: MMRESULT = MMSYSERR_BASE + 3;
125+
pub const MMSYSERR_ALLOCATED: MMRESULT = MMSYSERR_BASE + 4;
126+
pub const MMSYSERR_INVALHANDLE: MMRESULT = MMSYSERR_BASE + 5;
127+
pub const MMSYSERR_NODRIVER: MMRESULT = MMSYSERR_BASE + 6;
128+
pub const MMSYSERR_NOMEM: MMRESULT = MMSYSERR_BASE + 7;
129+
pub const MMSYSERR_NOTSUPPORTED: MMRESULT = MMSYSERR_BASE + 8;
130+
pub const MMSYSERR_BADERRNUM: MMRESULT = MMSYSERR_BASE + 9;
131+
pub const MMSYSERR_INVALFLAG: MMRESULT = MMSYSERR_BASE + 10;
132+
pub const MMSYSERR_INVALPARAM: MMRESULT = MMSYSERR_BASE + 11;
133+
pub const MMSYSERR_HANDLEBUSY: MMRESULT = MMSYSERR_BASE + 12;
134+
pub const MMSYSERR_INVALIDALIAS: MMRESULT = MMSYSERR_BASE + 13;
135+
pub const MMSYSERR_BADDB: MMRESULT = MMSYSERR_BASE + 14;
136+
pub const MMSYSERR_KEYNOTFOUND: MMRESULT = MMSYSERR_BASE + 15;
137+
pub const MMSYSERR_READERROR: MMRESULT = MMSYSERR_BASE + 16;
138+
pub const MMSYSERR_WRITEERROR: MMRESULT = MMSYSERR_BASE + 17;
139+
pub const MMSYSERR_DELETEERROR: MMRESULT = MMSYSERR_BASE + 18;
140+
pub const MMSYSERR_VALNOTFOUND: MMRESULT = MMSYSERR_BASE + 19;
141+
pub const MMSYSERR_NODRIVERCB: MMRESULT = MMSYSERR_BASE + 20;
142+
pub const MMSYSERR_MOREDATA: MMRESULT = MMSYSERR_BASE + 21;
143+
pub const MMSYSERR_LASTERROR: MMRESULT = MMSYSERR_BASE + 21;
144+
pub const CALLBACK_TYPEMASK: ::DWORD = 0x00070000;
145+
pub const CALLBACK_NULL: ::DWORD = 0x00000000;
146+
pub const CALLBACK_WINDOW: ::DWORD = 0x00010000;
147+
pub const CALLBACK_TASK: ::DWORD = 0x00020000;
148+
pub const CALLBACK_FUNCTION: ::DWORD = 0x00030000;
149+
pub const CALLBACK_THREAD: ::DWORD = CALLBACK_TASK;
150+
pub const CALLBACK_EVENT: ::DWORD = 0x00050000;
151+
//497 (Win 7 SDK)
152+
pub const WAVERR_BADFORMAT: MMRESULT = WAVERR_BASE + 0;
153+
pub const WAVERR_STILLPLAYING: MMRESULT = WAVERR_BASE + 1;
154+
pub const WAVERR_UNPREPARED: MMRESULT = WAVERR_BASE + 2;
155+
pub const WAVERR_SYNC: MMRESULT = WAVERR_BASE + 3;
156+
pub const WAVERR_LASTERROR: MMRESULT = WAVERR_BASE + 3;
157+
DECLARE_HANDLE!(HWAVEIN, HWAVEIN__);
158+
DECLARE_HANDLE!(HWAVEOUT, HWAVEOUT__);
159+
pub type LPHWAVEIN = *mut HWAVEIN;
160+
pub type LPHWAVEOUT = *mut HWAVEOUT;
161+
pub const WOM_OPEN: ::UINT = MM_WOM_OPEN;
162+
pub const WOM_CLOSE: ::UINT = MM_WOM_CLOSE;
163+
pub const WOM_DONE: ::UINT = MM_WOM_DONE;
164+
pub const WIM_OPEN: ::UINT = MM_WIM_OPEN;
165+
pub const WIM_CLOSE: ::UINT = MM_WIM_CLOSE;
166+
pub const WIM_DATA: ::UINT = MM_WIM_DATA;
167+
pub const WAVE_MAPPER: ::UINT = 0xFFFFFFFF;
168+
pub const WAVE_FORMAT_QUERY: ::DWORD = 0x0001;
169+
pub const WAVE_ALLOWSYNC: ::DWORD = 0x0002;
170+
pub const WAVE_MAPPED: ::DWORD = 0x0004;
171+
pub const WAVE_FORMAT_DIRECT: ::DWORD = 0x0008;
172+
pub const WAVE_FORMAT_DIRECT_QUERY: ::DWORD = WAVE_FORMAT_QUERY | WAVE_FORMAT_DIRECT;
173+
pub const WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE: ::DWORD = 0x0010;
174+
#[repr(C)] #[derive(Clone, Copy, Debug)]
175+
pub struct WAVEHDR {
176+
pub lpData: ::LPSTR,
177+
pub dwBufferLength: ::DWORD,
178+
pub dwBytesRecorded: ::DWORD,
179+
pub dwUser: ::DWORD_PTR,
180+
pub dwFlags: ::DWORD,
181+
pub dwLoops: ::DWORD,
182+
pub lpNext: *mut WAVEHDR,
183+
pub reserved: ::DWORD_PTR,
184+
}
185+
pub type PWAVEHDR = *mut WAVEHDR;
186+
pub type NPWAVEHDR = *mut WAVEHDR;
187+
pub type LPWAVEHDR = *mut WAVEHDR;
188+
#[repr(C)] #[derive(Clone, Copy, Debug)]
189+
pub struct WAVEOUTCAPSW {
190+
pub wMid: ::WORD,
191+
pub wPid: ::WORD,
192+
pub vDriverVersion: MMVERSION,
193+
pub szPname: [::WCHAR; 32],
194+
pub dwFormats: ::DWORD,
195+
pub wChannels: ::WORD,
196+
pub wReserved1: ::WORD,
197+
pub dwSupport: ::DWORD,
198+
}
199+
pub type PWAVEOUTCAPSW = *mut WAVEOUTCAPSW;
200+
pub type NPWAVEOUTCAPSW = *mut WAVEOUTCAPSW;
201+
pub type LPWAVEOUTCAPSW = *mut WAVEOUTCAPSW;
202+
#[repr(C)] #[derive(Clone, Copy, Debug)]
203+
pub struct WAVEINCAPSW {
204+
pub wMid: ::WORD,
205+
pub wPid: ::WORD,
206+
pub vDriverVersion: MMVERSION,
207+
pub szPname: [::WCHAR; 32],
208+
pub dwFormats: ::DWORD,
209+
pub wChannels: ::WORD,
210+
pub wReserved1: ::WORD,
211+
}
212+
pub type PWAVEINCAPSW = *mut WAVEINCAPSW;
213+
pub type NPWAVEINCAPSW = *mut WAVEINCAPSW;
214+
pub type LPWAVEINCAPSW = *mut WAVEINCAPSW;
215+
pub const WAVE_INVALIDFORMAT: ::DWORD = 0x00000000;
216+
pub const WAVE_FORMAT_1M08: ::DWORD = 0x00000001;
217+
pub const WAVE_FORMAT_1S08: ::DWORD = 0x00000002;
218+
pub const WAVE_FORMAT_1M16: ::DWORD = 0x00000004;
219+
pub const WAVE_FORMAT_1S16: ::DWORD = 0x00000008;
220+
pub const WAVE_FORMAT_2M08: ::DWORD = 0x00000010;
221+
pub const WAVE_FORMAT_2S08: ::DWORD = 0x00000020;
222+
pub const WAVE_FORMAT_2M16: ::DWORD = 0x00000040;
223+
pub const WAVE_FORMAT_2S16: ::DWORD = 0x00000080;
224+
pub const WAVE_FORMAT_4M08: ::DWORD = 0x00000100;
225+
pub const WAVE_FORMAT_4S08: ::DWORD = 0x00000200;
226+
pub const WAVE_FORMAT_4M16: ::DWORD = 0x00000400;
227+
pub const WAVE_FORMAT_4S16: ::DWORD = 0x00000800;
228+
pub const WAVE_FORMAT_44M08: ::DWORD = 0x00000100;
229+
pub const WAVE_FORMAT_44S08: ::DWORD = 0x00000200;
230+
pub const WAVE_FORMAT_44M16: ::DWORD = 0x00000400;
231+
pub const WAVE_FORMAT_44S16: ::DWORD = 0x00000800;
232+
pub const WAVE_FORMAT_48M08: ::DWORD = 0x00001000;
233+
pub const WAVE_FORMAT_48S08: ::DWORD = 0x00002000;
234+
pub const WAVE_FORMAT_48M16: ::DWORD = 0x00004000;
235+
pub const WAVE_FORMAT_48S16: ::DWORD = 0x00008000;
236+
pub const WAVE_FORMAT_96M08: ::DWORD = 0x00010000;
237+
pub const WAVE_FORMAT_96S08: ::DWORD = 0x00020000;
238+
pub const WAVE_FORMAT_96M16: ::DWORD = 0x00040000;
239+
pub const WAVE_FORMAT_96S16: ::DWORD = 0x00080000;
240+
//782 (Win 7 SDK)
241+
pub type PWAVEFORMATEX = *mut ::WAVEFORMATEX;
242+
pub type NPWAVEFORMATEX = *mut ::WAVEFORMATEX;
243+
pub type LPWAVEFORMATEX = *mut ::WAVEFORMATEX;
244+
pub type LPCWAVEFORMATEX = *const ::WAVEFORMATEX;
245+
//2170 (Win 7 SDK)
5246
pub const TIMERR_NOERROR: ::MMRESULT = 0;
6-
pub const TIMERR_BASE: ::MMRESULT = 96;
7247
pub const TIMERR_NOCANDO: ::MMRESULT = TIMERR_BASE + 1;
8248
pub const TIMERR_STRUCT: ::MMRESULT = TIMERR_BASE + 33;
249+
//2198 (Win 7 SDK)
250+
#[repr(C)] #[derive(Clone, Copy, Debug)]
251+
pub struct TIMECAPS {
252+
pub wPeriodMin: ::UINT,
253+
pub wPeriodMax: ::UINT,
254+
}
255+
pub type PTIMECAPS = *mut TIMECAPS;
256+
pub type NPTIMECAPS = *mut TIMECAPS;
257+
pub type LPTIMECAPS = *mut TIMECAPS;

tests/winmm.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright © 2015, Jordan Miner
2+
// Licensed under the MIT License <LICENSE.md>
3+
#![feature(test)]
4+
#![cfg(windows)]
5+
extern crate winmm;
6+
extern crate test;
7+
use winmm::*;
8+
use test::black_box as bb;
9+
#[test]
10+
fn functions() {
11+
bb(PlaySoundA);
12+
bb(PlaySoundW);
13+
bb(sndPlaySoundA);
14+
bb(sndPlaySoundW);
15+
bb(timeBeginPeriod);
16+
bb(timeEndPeriod);
17+
bb(timeGetDevCaps);
18+
bb(timeGetTime);
19+
bb(waveInAddBuffer);
20+
bb(waveInClose);
21+
bb(waveInGetDevCapsW);
22+
bb(waveInGetErrorTextW);
23+
bb(waveInGetNumDevs);
24+
bb(waveInGetPosition);
25+
bb(waveInMessage);
26+
bb(waveInOpen);
27+
bb(waveInPrepareHeader);
28+
bb(waveInReset);
29+
bb(waveInStart);
30+
bb(waveInStop);
31+
bb(waveInUnprepareHeader);
32+
bb(waveOutBreakLoop);
33+
bb(waveOutClose);
34+
bb(waveOutGetDevCapsW);
35+
bb(waveOutGetErrorTextW);
36+
bb(waveOutGetNumDevs);
37+
bb(waveOutGetPitch);
38+
bb(waveOutGetPlaybackRate);
39+
bb(waveOutGetPosition);
40+
bb(waveOutGetVolume);
41+
bb(waveOutMessage);
42+
bb(waveOutOpen);
43+
bb(waveOutPause);
44+
bb(waveOutPrepareHeader);
45+
bb(waveOutReset);
46+
bb(waveOutRestart);
47+
bb(waveOutSetPitch);
48+
bb(waveOutSetPlaybackRate);
49+
bb(waveOutSetVolume);
50+
bb(waveOutUnprepareHeader);
51+
bb(waveOutWrite);
52+
}

0 commit comments

Comments
 (0)