21 #include "../../SDL_internal.h" 23 #if SDL_AUDIO_DRIVER_WINMM 27 #include "../../core/windows/SDL_windows.h" 33 #include "../SDL_audio_c.h" 36 #ifndef WAVE_FORMAT_IEEE_FLOAT 37 #define WAVE_FORMAT_IEEE_FLOAT 0x0003 40 #define DETECT_DEV_IMPL(iscap, typ, capstyp) \ 41 static void DetectWave##typ##Devs(void) { \ 42 const UINT iscapture = iscap ? 1 : 0; \ 43 const UINT devcount = wave##typ##GetNumDevs(); \ 46 for (i = 0; i < devcount; i++) { \ 47 if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ 48 char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \ 50 SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \ 57 DETECT_DEV_IMPL(
SDL_FALSE, Out, WAVEOUTCAPS)
58 DETECT_DEV_IMPL(
SDL_TRUE, In, WAVEINCAPS)
61 WINMM_DetectDevices(
void)
68 CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
69 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
78 ReleaseSemaphore(this->hidden->audio_sem, 1,
NULL);
84 FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
85 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
94 ReleaseSemaphore(this->hidden->audio_sem, 1,
NULL);
98 SetMMerror(
char *
function, MMRESULT code)
101 char errbuf[MAXERRORLENGTH];
102 wchar_t werrbuf[MAXERRORLENGTH];
107 waveOutGetErrorText(code, werrbuf, MAXERRORLENGTH - len);
108 WideCharToMultiByte(CP_ACP, 0, werrbuf, -1, errbuf + len,
115 WINMM_WaitDevice(
_THIS)
118 WaitForSingleObject(this->hidden->audio_sem, INFINITE);
122 WINMM_GetDeviceBuf(
_THIS)
124 return (
Uint8 *) (this->hidden->
125 wavebuf[this->hidden->next_buffer].lpData);
129 WINMM_PlayDevice(
_THIS)
132 waveOutWrite(this->hidden->hout,
133 &this->hidden->wavebuf[this->hidden->next_buffer],
134 sizeof(this->hidden->wavebuf[0]));
135 this->hidden->next_buffer = (this->hidden->next_buffer + 1) %
NUM_BUFFERS;
139 WINMM_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
141 const int nextbuf = this->hidden->next_buffer;
147 WaitForSingleObject(this->hidden->audio_sem, INFINITE);
150 SDL_memcpy(buffer, this->hidden->wavebuf[nextbuf].lpData, this->spec.size);
153 result = waveInAddBuffer(this->hidden->hin,
154 &this->hidden->wavebuf[nextbuf],
155 sizeof (this->hidden->wavebuf[nextbuf]));
156 if (result != MMSYSERR_NOERROR) {
161 this->hidden->next_buffer = (nextbuf + 1) %
NUM_BUFFERS;
166 WINMM_FlushCapture(
_THIS)
169 if (WaitForSingleObject(this->hidden->audio_sem, 0) == WAIT_OBJECT_0) {
170 const int nextbuf = this->hidden->next_buffer;
172 waveInAddBuffer(this->hidden->hin,
173 &this->hidden->wavebuf[nextbuf],
174 sizeof (this->hidden->wavebuf[nextbuf]));
175 this->hidden->next_buffer = (nextbuf + 1) %
NUM_BUFFERS;
180 WINMM_CloseDevice(
_THIS)
184 if (this->hidden->hout) {
185 waveOutReset(this->hidden->hout);
189 if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
190 waveOutUnprepareHeader(this->hidden->hout,
191 &this->hidden->wavebuf[i],
192 sizeof (this->hidden->wavebuf[i]));
196 waveOutClose(this->hidden->hout);
199 if (this->hidden->hin) {
200 waveInReset(this->hidden->hin);
204 if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
205 waveInUnprepareHeader(this->hidden->hin,
206 &this->hidden->wavebuf[i],
207 sizeof (this->hidden->wavebuf[i]));
210 waveInClose(this->hidden->hin);
213 if (this->hidden->audio_sem) {
214 CloseHandle(this->hidden->audio_sem);
222 PrepWaveFormat(
_THIS, UINT devId, WAVEFORMATEX *pfmt,
const int iscapture)
227 pfmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
229 pfmt->wFormatTag = WAVE_FORMAT_PCM;
234 pfmt->nSamplesPerSec = this->
spec.
freq;
235 pfmt->nBlockAlign = pfmt->nChannels * (pfmt->wBitsPerSample / 8);
236 pfmt->nAvgBytesPerSec = pfmt->nSamplesPerSec * pfmt->nBlockAlign;
239 return (waveInOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
241 return (waveOutOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
246 WINMM_OpenDevice(
_THIS,
void *handle,
const char *devname,
int iscapture)
249 int valid_datatype = 0;
251 WAVEFORMATEX waveformat;
252 UINT devId = WAVE_MAPPER;
255 if (handle !=
NULL) {
257 const size_t val = ((
size_t) handle) - 1;
264 if (this->hidden ==
NULL) {
271 this->hidden->wavebuf[i].dwUser = 0xFFFF;
276 while ((!valid_datatype) && (test_format)) {
277 switch (test_format) {
283 if (PrepWaveFormat(
this, devId, &waveformat, iscapture)) {
296 if (!valid_datatype) {
305 result = waveInOpen(&this->hidden->hin, devId, &waveformat,
306 (DWORD_PTR) CaptureSound, (DWORD_PTR)
this,
308 if (result != MMSYSERR_NOERROR) {
309 return SetMMerror(
"waveInOpen()", result);
312 result = waveOutOpen(&this->hidden->hout, devId, &waveformat,
313 (DWORD_PTR) FillSound, (DWORD_PTR)
this,
315 if (result != MMSYSERR_NOERROR) {
316 return SetMMerror(
"waveOutOpen()", result);
325 result = waveInGetDevCaps((UINT) this->hidden->hout,
326 &caps, sizeof (caps));
327 if (result != MMSYSERR_NOERROR) {
328 return SetMMerror(
"waveInGetDevCaps()", result);
330 printf(
"Audio device: %s\n", caps.szPname);
333 result = waveOutGetDevCaps((UINT) this->hidden->hout,
334 &caps,
sizeof(caps));
335 if (result != MMSYSERR_NOERROR) {
336 return SetMMerror(
"waveOutGetDevCaps()", result);
338 printf(
"Audio device: %s\n", caps.szPname);
344 this->hidden->audio_sem =
345 CreateSemaphore(
NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS,
NULL);
346 if (this->hidden->audio_sem ==
NULL) {
351 this->hidden->mixbuf =
353 if (this->hidden->mixbuf ==
NULL) {
359 this->hidden->wavebuf[
i].dwBufferLength = this->
spec.
size;
360 this->hidden->wavebuf[
i].dwFlags = WHDR_DONE;
361 this->hidden->wavebuf[
i].lpData =
362 (LPSTR) & this->hidden->mixbuf[i * this->spec.size];
365 result = waveInPrepareHeader(this->hidden->hin,
366 &this->hidden->wavebuf[i],
367 sizeof(this->hidden->wavebuf[i]));
368 if (result != MMSYSERR_NOERROR) {
369 return SetMMerror(
"waveInPrepareHeader()", result);
372 result = waveInAddBuffer(this->hidden->hin,
373 &this->hidden->wavebuf[i],
374 sizeof(this->hidden->wavebuf[i]));
375 if (result != MMSYSERR_NOERROR) {
376 return SetMMerror(
"waveInAddBuffer()", result);
379 result = waveOutPrepareHeader(this->hidden->hout,
380 &this->hidden->wavebuf[i],
381 sizeof(this->hidden->wavebuf[i]));
382 if (result != MMSYSERR_NOERROR) {
383 return SetMMerror(
"waveOutPrepareHeader()", result);
389 result = waveInStart(this->hidden->hin);
390 if (result != MMSYSERR_NOERROR) {
391 return SetMMerror(
"waveInStart()", result);
418 "winmm",
"Windows Waveform Audio", WINMM_Init, 0
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
void(* DetectDevices)(void)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
Uint16 SDL_AudioFormat
Audio format flags.
AudioBootStrap WINMM_bootstrap
SDL_AudioFormat SDL_NextAudioFormat(void)
#define SDL_AUDIO_ISFLOAT(x)
uint8_t Uint8
An unsigned 8-bit integer type.
#define SDL_AUDIO_BITSIZE(x)
#define SDL_static_cast(type, expression)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
#define SDL_assert(condition)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_OutOfMemory()
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
void(* CloseDevice)(_THIS)
void(* FlushCapture)(_THIS)
Uint8 *(* GetDeviceBuf)(_THIS)
#define SDL_arraysize(array)