21 #include "../../SDL_internal.h"
23 #if SDL_AUDIO_DRIVER_WINMM
27 #include "../../core/windows/SDL_windows.h"
32 #include "../SDL_audio_c.h"
36 #if defined(__MINGW32__) && defined(_MMSYSTEM_H)
38 typedef struct tagWAVEINCAPS2W
42 MMVERSION vDriverVersion;
43 WCHAR szPname[MAXPNAMELEN];
47 GUID ManufacturerGuid;
50 } WAVEINCAPS2W,*PWAVEINCAPS2W,*NPWAVEINCAPS2W,*LPWAVEINCAPS2W;
52 typedef struct tagWAVEOUTCAPS2W
56 MMVERSION vDriverVersion;
57 WCHAR szPname[MAXPNAMELEN];
62 GUID ManufacturerGuid;
65 } WAVEOUTCAPS2W,*PWAVEOUTCAPS2W,*NPWAVEOUTCAPS2W,*LPWAVEOUTCAPS2W;
69 #ifndef WAVE_FORMAT_IEEE_FLOAT
70 #define WAVE_FORMAT_IEEE_FLOAT 0x0003
73 #define DETECT_DEV_IMPL(iscap, typ, capstyp) \
74 static void DetectWave##typ##Devs(void) { \
75 const UINT iscapture = iscap ? 1 : 0; \
76 const UINT devcount = wave##typ##GetNumDevs(); \
79 for (i = 0; i < devcount; i++) { \
80 if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
81 char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \
83 SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
90 DETECT_DEV_IMPL(
SDL_FALSE, Out, WAVEOUTCAPS)
91 DETECT_DEV_IMPL(
SDL_TRUE, In, WAVEINCAPS)
94 WINMM_DetectDevices(
void)
101 CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
102 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
107 if (uMsg != WIM_DATA)
111 ReleaseSemaphore(this->hidden->audio_sem, 1,
NULL);
117 FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
118 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
123 if (uMsg != WOM_DONE)
127 ReleaseSemaphore(this->hidden->audio_sem, 1,
NULL);
131 SetMMerror(
char *
function, MMRESULT code)
134 char errbuf[MAXERRORLENGTH];
135 wchar_t werrbuf[MAXERRORLENGTH];
140 waveOutGetErrorText(code, werrbuf, MAXERRORLENGTH -
len);
141 WideCharToMultiByte(CP_ACP, 0, werrbuf, -1, errbuf +
len,
148 WINMM_WaitDevice(
_THIS)
151 WaitForSingleObject(this->hidden->audio_sem, INFINITE);
155 WINMM_GetDeviceBuf(
_THIS)
157 return (
Uint8 *) (this->hidden->
158 wavebuf[this->hidden->next_buffer].lpData);
162 WINMM_PlayDevice(
_THIS)
165 waveOutWrite(this->hidden->hout,
166 &this->hidden->wavebuf[this->hidden->next_buffer],
167 sizeof(this->hidden->wavebuf[0]));
168 this->hidden->next_buffer = (this->hidden->next_buffer + 1) %
NUM_BUFFERS;
172 WINMM_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
174 const int nextbuf = this->hidden->next_buffer;
180 WaitForSingleObject(this->hidden->audio_sem, INFINITE);
186 result = waveInAddBuffer(this->hidden->hin,
187 &this->hidden->wavebuf[nextbuf],
188 sizeof (this->hidden->wavebuf[nextbuf]));
189 if (
result != MMSYSERR_NOERROR) {
194 this->hidden->next_buffer = (nextbuf + 1) %
NUM_BUFFERS;
199 WINMM_FlushCapture(
_THIS)
202 if (WaitForSingleObject(this->hidden->audio_sem, 0) == WAIT_OBJECT_0) {
203 const int nextbuf = this->hidden->next_buffer;
205 waveInAddBuffer(this->hidden->hin,
206 &this->hidden->wavebuf[nextbuf],
207 sizeof (this->hidden->wavebuf[nextbuf]));
208 this->hidden->next_buffer = (nextbuf + 1) %
NUM_BUFFERS;
213 WINMM_CloseDevice(
_THIS)
217 if (this->hidden->hout) {
218 waveOutReset(this->hidden->hout);
222 if (this->hidden->wavebuf[
i].dwUser != 0xFFFF) {
223 waveOutUnprepareHeader(this->hidden->hout,
224 &this->hidden->wavebuf[
i],
225 sizeof (this->hidden->wavebuf[
i]));
229 waveOutClose(this->hidden->hout);
232 if (this->hidden->hin) {
233 waveInReset(this->hidden->hin);
237 if (this->hidden->wavebuf[
i].dwUser != 0xFFFF) {
238 waveInUnprepareHeader(this->hidden->hin,
239 &this->hidden->wavebuf[
i],
240 sizeof (this->hidden->wavebuf[
i]));
243 waveInClose(this->hidden->hin);
246 if (this->hidden->audio_sem) {
247 CloseHandle(this->hidden->audio_sem);
255 PrepWaveFormat(
_THIS, UINT devId, WAVEFORMATEX *pfmt,
const int iscapture)
260 pfmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
262 pfmt->wFormatTag = WAVE_FORMAT_PCM;
267 pfmt->nSamplesPerSec = this->
spec.
freq;
268 pfmt->nBlockAlign = pfmt->nChannels * (pfmt->wBitsPerSample / 8);
269 pfmt->nAvgBytesPerSec = pfmt->nSamplesPerSec * pfmt->nBlockAlign;
272 return (waveInOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
274 return (waveOutOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
279 WINMM_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
282 int valid_datatype = 0;
284 WAVEFORMATEX waveformat;
285 UINT devId = WAVE_MAPPER;
297 if (this->hidden ==
NULL) {
304 this->hidden->wavebuf[
i].dwUser = 0xFFFF;
309 while ((!valid_datatype) && (test_format)) {
310 switch (test_format) {
329 if (!valid_datatype) {
339 (DWORD_PTR) CaptureSound, (DWORD_PTR)
this,
341 if (
result != MMSYSERR_NOERROR) {
342 return SetMMerror(
"waveInOpen()",
result);
346 (DWORD_PTR) FillSound, (DWORD_PTR)
this,
348 if (
result != MMSYSERR_NOERROR) {
349 return SetMMerror(
"waveOutOpen()",
result);
358 result = waveInGetDevCaps((UINT) this->hidden->hout,
359 &caps, sizeof (caps));
360 if (
result != MMSYSERR_NOERROR) {
361 return SetMMerror(
"waveInGetDevCaps()",
result);
363 printf(
"Audio device: %s\n", caps.szPname);
366 result = waveOutGetDevCaps((UINT) this->hidden->hout,
367 &caps,
sizeof(caps));
368 if (
result != MMSYSERR_NOERROR) {
369 return SetMMerror(
"waveOutGetDevCaps()",
result);
371 printf(
"Audio device: %s\n", caps.szPname);
378 if (this->hidden->audio_sem ==
NULL) {
383 this->hidden->mixbuf =
385 if (this->hidden->mixbuf ==
NULL) {
391 this->hidden->wavebuf[
i].dwBufferLength = this->
spec.
size;
392 this->hidden->wavebuf[
i].dwFlags = WHDR_DONE;
393 this->hidden->wavebuf[
i].lpData =
394 (LPSTR) & this->hidden->mixbuf[
i * this->spec.size];
397 result = waveInPrepareHeader(this->hidden->hin,
398 &this->hidden->wavebuf[
i],
399 sizeof(this->hidden->wavebuf[
i]));
400 if (
result != MMSYSERR_NOERROR) {
401 return SetMMerror(
"waveInPrepareHeader()",
result);
404 result = waveInAddBuffer(this->hidden->hin,
405 &this->hidden->wavebuf[
i],
406 sizeof(this->hidden->wavebuf[
i]));
407 if (
result != MMSYSERR_NOERROR) {
408 return SetMMerror(
"waveInAddBuffer()",
result);
411 result = waveOutPrepareHeader(this->hidden->hout,
412 &this->hidden->wavebuf[
i],
413 sizeof(this->hidden->wavebuf[
i]));
414 if (
result != MMSYSERR_NOERROR) {
415 return SetMMerror(
"waveOutPrepareHeader()",
result);
421 result = waveInStart(this->hidden->hin);
422 if (
result != MMSYSERR_NOERROR) {
423 return SetMMerror(
"waveInStart()",
result);
450 "winmm",
"Windows Waveform Audio", WINMM_Init, 0
#define SDL_assert(condition)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
SDL_AudioFormat SDL_NextAudioFormat(void)
Uint16 SDL_AudioFormat
Audio format flags.
#define SDL_AUDIO_ISFLOAT(x)
#define SDL_AUDIO_BITSIZE(x)
#define SDL_OutOfMemory()
#define SDL_arraysize(array)
#define SDL_static_cast(type, expression)
AudioBootStrap WINMM_bootstrap
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)
EGLImageKHR EGLint EGLint * handle
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 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)
void(* CloseDevice)(_THIS)
void(* FlushCapture)(_THIS)
void(* DetectDevices)(void)
Uint8 *(* GetDeviceBuf)(_THIS)
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
WAVEFORMATEX * waveformat