21 #include "../../SDL_internal.h" 23 #if SDL_AUDIO_DRIVER_WINMM 27 #include "../../core/windows/SDL_windows.h" 33 #include "../SDL_audio_c.h" 37 #if defined(__MINGW32__) && defined(_MMSYSTEM_H) 39 typedef struct tagWAVEINCAPS2W
43 MMVERSION vDriverVersion;
44 WCHAR szPname[MAXPNAMELEN];
48 GUID ManufacturerGuid;
51 } WAVEINCAPS2W,*PWAVEINCAPS2W,*NPWAVEINCAPS2W,*LPWAVEINCAPS2W;
53 typedef struct tagWAVEOUTCAPS2W
57 MMVERSION vDriverVersion;
58 WCHAR szPname[MAXPNAMELEN];
63 GUID ManufacturerGuid;
66 } WAVEOUTCAPS2W,*PWAVEOUTCAPS2W,*NPWAVEOUTCAPS2W,*LPWAVEOUTCAPS2W;
70 #ifndef WAVE_FORMAT_IEEE_FLOAT 71 #define WAVE_FORMAT_IEEE_FLOAT 0x0003 74 #define DETECT_DEV_IMPL(iscap, typ, capstyp) \ 75 static void DetectWave##typ##Devs(void) { \ 76 const UINT iscapture = iscap ? 1 : 0; \ 77 const UINT devcount = wave##typ##GetNumDevs(); \ 80 for (i = 0; i < devcount; i++) { \ 81 if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ 82 char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \ 84 SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \ 91 DETECT_DEV_IMPL(
SDL_FALSE, Out, WAVEOUTCAPS)
92 DETECT_DEV_IMPL(
SDL_TRUE, In, WAVEINCAPS)
95 WINMM_DetectDevices(
void)
102 CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
103 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
108 if (uMsg != WIM_DATA)
112 ReleaseSemaphore(this->hidden->audio_sem, 1,
NULL);
118 FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
119 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
124 if (uMsg != WOM_DONE)
128 ReleaseSemaphore(this->hidden->audio_sem, 1,
NULL);
132 SetMMerror(
char *
function, MMRESULT code)
135 char errbuf[MAXERRORLENGTH];
136 wchar_t werrbuf[MAXERRORLENGTH];
141 waveOutGetErrorText(code, werrbuf, MAXERRORLENGTH - len);
142 WideCharToMultiByte(CP_ACP, 0, werrbuf, -1, errbuf + len,
149 WINMM_WaitDevice(
_THIS)
152 WaitForSingleObject(this->hidden->audio_sem, INFINITE);
156 WINMM_GetDeviceBuf(
_THIS)
158 return (
Uint8 *) (this->hidden->
159 wavebuf[this->hidden->next_buffer].lpData);
163 WINMM_PlayDevice(
_THIS)
166 waveOutWrite(this->hidden->hout,
167 &this->hidden->wavebuf[this->hidden->next_buffer],
168 sizeof(this->hidden->wavebuf[0]));
169 this->hidden->next_buffer = (this->hidden->next_buffer + 1) %
NUM_BUFFERS;
173 WINMM_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
175 const int nextbuf = this->hidden->next_buffer;
181 WaitForSingleObject(this->hidden->audio_sem, INFINITE);
184 SDL_memcpy(buffer, this->hidden->wavebuf[nextbuf].lpData, this->spec.size);
187 result = waveInAddBuffer(this->hidden->hin,
188 &this->hidden->wavebuf[nextbuf],
189 sizeof (this->hidden->wavebuf[nextbuf]));
190 if (result != MMSYSERR_NOERROR) {
195 this->hidden->next_buffer = (nextbuf + 1) %
NUM_BUFFERS;
200 WINMM_FlushCapture(
_THIS)
203 if (WaitForSingleObject(this->hidden->audio_sem, 0) == WAIT_OBJECT_0) {
204 const int nextbuf = this->hidden->next_buffer;
206 waveInAddBuffer(this->hidden->hin,
207 &this->hidden->wavebuf[nextbuf],
208 sizeof (this->hidden->wavebuf[nextbuf]));
209 this->hidden->next_buffer = (nextbuf + 1) %
NUM_BUFFERS;
214 WINMM_CloseDevice(
_THIS)
218 if (this->hidden->hout) {
219 waveOutReset(this->hidden->hout);
223 if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
224 waveOutUnprepareHeader(this->hidden->hout,
225 &this->hidden->wavebuf[i],
226 sizeof (this->hidden->wavebuf[i]));
230 waveOutClose(this->hidden->hout);
233 if (this->hidden->hin) {
234 waveInReset(this->hidden->hin);
238 if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
239 waveInUnprepareHeader(this->hidden->hin,
240 &this->hidden->wavebuf[i],
241 sizeof (this->hidden->wavebuf[i]));
244 waveInClose(this->hidden->hin);
247 if (this->hidden->audio_sem) {
248 CloseHandle(this->hidden->audio_sem);
256 PrepWaveFormat(
_THIS, UINT devId, WAVEFORMATEX *pfmt,
const int iscapture)
261 pfmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
263 pfmt->wFormatTag = WAVE_FORMAT_PCM;
268 pfmt->nSamplesPerSec = this->
spec.
freq;
269 pfmt->nBlockAlign = pfmt->nChannels * (pfmt->wBitsPerSample / 8);
270 pfmt->nAvgBytesPerSec = pfmt->nSamplesPerSec * pfmt->nBlockAlign;
273 return (waveInOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
275 return (waveOutOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
280 WINMM_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
283 int valid_datatype = 0;
285 WAVEFORMATEX waveformat;
286 UINT devId = WAVE_MAPPER;
289 if (handle !=
NULL) {
291 const size_t val = ((
size_t) handle) - 1;
298 if (this->hidden ==
NULL) {
305 this->hidden->wavebuf[i].dwUser = 0xFFFF;
310 while ((!valid_datatype) && (test_format)) {
311 switch (test_format) {
317 if (PrepWaveFormat(
this, devId, &waveformat, iscapture)) {
330 if (!valid_datatype) {
339 result = waveInOpen(&this->hidden->hin, devId, &waveformat,
340 (DWORD_PTR) CaptureSound, (DWORD_PTR)
this,
342 if (result != MMSYSERR_NOERROR) {
343 return SetMMerror(
"waveInOpen()", result);
346 result = waveOutOpen(&this->hidden->hout, devId, &waveformat,
347 (DWORD_PTR) FillSound, (DWORD_PTR)
this,
349 if (result != MMSYSERR_NOERROR) {
350 return SetMMerror(
"waveOutOpen()", result);
359 result = waveInGetDevCaps((UINT) this->hidden->hout,
360 &caps, sizeof (caps));
361 if (result != MMSYSERR_NOERROR) {
362 return SetMMerror(
"waveInGetDevCaps()", result);
364 printf(
"Audio device: %s\n", caps.szPname);
367 result = waveOutGetDevCaps((UINT) this->hidden->hout,
368 &caps,
sizeof(caps));
369 if (result != MMSYSERR_NOERROR) {
370 return SetMMerror(
"waveOutGetDevCaps()", result);
372 printf(
"Audio device: %s\n", caps.szPname);
378 this->hidden->audio_sem = CreateSemaphore(
NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS,
NULL);
379 if (this->hidden->audio_sem ==
NULL) {
384 this->hidden->mixbuf =
386 if (this->hidden->mixbuf ==
NULL) {
392 this->hidden->wavebuf[
i].dwBufferLength = this->
spec.
size;
393 this->hidden->wavebuf[
i].dwFlags = WHDR_DONE;
394 this->hidden->wavebuf[
i].lpData =
395 (LPSTR) & this->hidden->mixbuf[i * this->spec.size];
398 result = waveInPrepareHeader(this->hidden->hin,
399 &this->hidden->wavebuf[i],
400 sizeof(this->hidden->wavebuf[i]));
401 if (result != MMSYSERR_NOERROR) {
402 return SetMMerror(
"waveInPrepareHeader()", result);
405 result = waveInAddBuffer(this->hidden->hin,
406 &this->hidden->wavebuf[i],
407 sizeof(this->hidden->wavebuf[i]));
408 if (result != MMSYSERR_NOERROR) {
409 return SetMMerror(
"waveInAddBuffer()", result);
412 result = waveOutPrepareHeader(this->hidden->hout,
413 &this->hidden->wavebuf[i],
414 sizeof(this->hidden->wavebuf[i]));
415 if (result != MMSYSERR_NOERROR) {
416 return SetMMerror(
"waveOutPrepareHeader()", result);
422 result = waveInStart(this->hidden->hin);
423 if (result != MMSYSERR_NOERROR) {
424 return SetMMerror(
"waveInStart()", result);
451 "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.
SDL_AudioFormat SDL_NextAudioFormat(void)
#define SDL_AUDIO_ISFLOAT(x)
EGLImageKHR EGLint EGLint * handle
#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)
AudioBootStrap WINMM_bootstrap
#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)