3 #include "qemu-common.h"
7 #define AUDIO_CAP "winwave"
13 #include "audio_win_int.h"
37 CRITICAL_SECTION crit_sect
;
50 CRITICAL_SECTION crit_sect
;
53 static void winwave_log_mmresult (MMRESULT mr
)
55 const char *str
= "BUG";
58 case MMSYSERR_NOERROR
:
62 case MMSYSERR_INVALHANDLE
:
63 str
= "Specified device handle is invalid";
66 case MMSYSERR_BADDEVICEID
:
67 str
= "Specified device id is out of range";
70 case MMSYSERR_NODRIVER
:
71 str
= "No device driver is present";
75 str
= "Unable to allocate or locl memory";
79 str
= "Device is synchronous but waveOutOpen was called "
80 "without using the WINWAVE_ALLOWSYNC flag";
83 case WAVERR_UNPREPARED
:
84 str
= "The data block pointed to by the pwh parameter "
85 "hasn't been prepared";
88 case WAVERR_STILLPLAYING
:
89 str
= "There are still buffers in the queue";
93 dolog ("Reason: Unknown (MMRESULT %#x)\n", mr
);
97 dolog ("Reason: %s\n", str
);
100 static void GCC_FMT_ATTR (2, 3) winwave_logerr (
109 AUD_vlog (AUDIO_CAP
, fmt
, ap
);
112 AUD_log (NULL
, " failed\n");
113 winwave_log_mmresult (mr
);
116 static void winwave_anal_close_out (WaveVoiceOut
*wave
)
120 mr
= waveOutClose (wave
->hwo
);
121 if (mr
!= MMSYSERR_NOERROR
) {
122 winwave_logerr (mr
, "waveOutClose");
127 static void CALLBACK
winwave_callback_out (
130 DWORD_PTR dwInstance
,
135 WaveVoiceOut
*wave
= (WaveVoiceOut
*) dwInstance
;
140 WAVEHDR
*h
= (WAVEHDR
*) dwParam1
;
143 EnterCriticalSection (&wave
->crit_sect
);
145 wave
->avail
+= conf
.dac_samples
;
147 LeaveCriticalSection (&wave
->crit_sect
);
148 if (wave
->hw
.poll_mode
) {
149 if (!SetEvent (wave
->event
)) {
150 dolog ("DAC SetEvent failed %lx\n", GetLastError ());
162 dolog ("unknown wave out callback msg %x\n", msg
);
166 static int winwave_init_out (HWVoiceOut
*hw
, struct audsettings
*as
)
174 wave
= (WaveVoiceOut
*) hw
;
176 InitializeCriticalSection (&wave
->crit_sect
);
178 err
= waveformat_from_audio_settings (&wfx
, as
);
183 mr
= waveOutOpen (&wave
->hwo
, WAVE_MAPPER
, &wfx
,
184 (DWORD_PTR
) winwave_callback_out
,
185 (DWORD_PTR
) wave
, CALLBACK_FUNCTION
);
186 if (mr
!= MMSYSERR_NOERROR
) {
187 winwave_logerr (mr
, "waveOutOpen");
191 wave
->hdrs
= audio_calloc (AUDIO_FUNC
, conf
.dac_headers
,
192 sizeof (*wave
->hdrs
));
197 audio_pcm_init_info (&hw
->info
, as
);
198 hw
->samples
= conf
.dac_samples
* conf
.dac_headers
;
199 wave
->avail
= hw
->samples
;
201 wave
->pcm_buf
= audio_calloc (AUDIO_FUNC
, conf
.dac_samples
,
202 conf
.dac_headers
<< hw
->info
.shift
);
203 if (!wave
->pcm_buf
) {
207 for (i
= 0; i
< conf
.dac_headers
; ++i
) {
208 WAVEHDR
*h
= &wave
->hdrs
[i
];
211 h
->dwBufferLength
= conf
.dac_samples
<< hw
->info
.shift
;
212 h
->lpData
= advance (wave
->pcm_buf
, i
* h
->dwBufferLength
);
215 mr
= waveOutPrepareHeader (wave
->hwo
, h
, sizeof (*h
));
216 if (mr
!= MMSYSERR_NOERROR
) {
217 winwave_logerr (mr
, "waveOutPrepareHeader(%d)", i
);
225 qemu_free (wave
->pcm_buf
);
227 qemu_free (wave
->hdrs
);
229 winwave_anal_close_out (wave
);
235 static int winwave_write (SWVoiceOut
*sw
, void *buf
, int len
)
237 return audio_pcm_sw_write (sw
, buf
, len
);
240 static int winwave_run_out (HWVoiceOut
*hw
, int live
)
242 WaveVoiceOut
*wave
= (WaveVoiceOut
*) hw
;
246 EnterCriticalSection (&wave
->crit_sect
);
248 decr
= audio_MIN (live
, wave
->avail
);
249 decr
= audio_pcm_hw_clip_out (hw
, wave
->pcm_buf
, decr
, wave
->pending
);
250 wave
->pending
+= decr
;
253 LeaveCriticalSection (&wave
->crit_sect
);
255 doreset
= hw
->poll_mode
&& (wave
->pending
>= conf
.dac_samples
);
256 if (doreset
&& !ResetEvent (wave
->event
)) {
257 dolog ("DAC ResetEvent failed %lx\n", GetLastError ());
260 while (wave
->pending
>= conf
.dac_samples
) {
262 WAVEHDR
*h
= &wave
->hdrs
[wave
->curhdr
];
265 mr
= waveOutWrite (wave
->hwo
, h
, sizeof (*h
));
266 if (mr
!= MMSYSERR_NOERROR
) {
267 winwave_logerr (mr
, "waveOutWrite(%d)", wave
->curhdr
);
271 wave
->pending
-= conf
.dac_samples
;
272 wave
->curhdr
= (wave
->curhdr
+ 1) % conf
.dac_headers
;
278 static void winwave_poll (void *opaque
)
281 audio_run ("winwave_poll");
284 static void winwave_fini_out (HWVoiceOut
*hw
)
288 WaveVoiceOut
*wave
= (WaveVoiceOut
*) hw
;
290 mr
= waveOutReset (wave
->hwo
);
291 if (mr
!= MMSYSERR_NOERROR
) {
292 winwave_logerr (mr
, "waveOutReset");
295 for (i
= 0; i
< conf
.dac_headers
; ++i
) {
296 mr
= waveOutUnprepareHeader (wave
->hwo
, &wave
->hdrs
[i
],
297 sizeof (wave
->hdrs
[i
]));
298 if (mr
!= MMSYSERR_NOERROR
) {
299 winwave_logerr (mr
, "waveOutUnprepareHeader(%d)", i
);
303 winwave_anal_close_out (wave
);
306 qemu_del_wait_object (wave
->event
, winwave_poll
, wave
);
307 if (!CloseHandle (wave
->event
)) {
308 dolog ("DAC CloseHandle failed %lx\n", GetLastError ());
313 qemu_free (wave
->pcm_buf
);
314 wave
->pcm_buf
= NULL
;
316 qemu_free (wave
->hdrs
);
320 static int winwave_ctl_out (HWVoiceOut
*hw
, int cmd
, ...)
323 WaveVoiceOut
*wave
= (WaveVoiceOut
*) hw
;
332 poll_mode
= va_arg (ap
, int);
335 if (poll_mode
&& !wave
->event
) {
336 wave
->event
= CreateEvent (NULL
, TRUE
, TRUE
, NULL
);
338 dolog ("DAC CreateEvent: %lx, poll mode will be disabled\n",
346 ret
= qemu_add_wait_object (wave
->event
, winwave_poll
, wave
);
347 hw
->poll_mode
= (ret
== 0);
353 mr
= waveOutRestart (wave
->hwo
);
354 if (mr
!= MMSYSERR_NOERROR
) {
355 winwave_logerr (mr
, "waveOutRestart");
364 mr
= waveOutPause (wave
->hwo
);
365 if (mr
!= MMSYSERR_NOERROR
) {
366 winwave_logerr (mr
, "waveOutPause");
373 qemu_del_wait_object (wave
->event
, winwave_poll
, wave
);
380 static void winwave_anal_close_in (WaveVoiceIn
*wave
)
384 mr
= waveInClose (wave
->hwi
);
385 if (mr
!= MMSYSERR_NOERROR
) {
386 winwave_logerr (mr
, "waveInClose");
391 static void CALLBACK
winwave_callback_in (
394 DWORD_PTR dwInstance
,
399 WaveVoiceIn
*wave
= (WaveVoiceIn
*) dwInstance
;
404 WAVEHDR
*h
= (WAVEHDR
*) dwParam1
;
407 EnterCriticalSection (&wave
->crit_sect
);
409 wave
->avail
+= conf
.adc_samples
;
411 LeaveCriticalSection (&wave
->crit_sect
);
412 if (wave
->hw
.poll_mode
) {
413 if (!SetEvent (wave
->event
)) {
414 dolog ("ADC SetEvent failed %lx\n", GetLastError ());
426 dolog ("unknown wave in callback msg %x\n", msg
);
430 static void winwave_add_buffers (WaveVoiceIn
*wave
, int samples
)
434 doreset
= wave
->hw
.poll_mode
&& (samples
>= conf
.adc_samples
);
435 if (doreset
&& !ResetEvent (wave
->event
)) {
436 dolog ("ADC ResetEvent failed %lx\n", GetLastError ());
439 while (samples
>= conf
.adc_samples
) {
441 WAVEHDR
*h
= &wave
->hdrs
[wave
->curhdr
];
444 mr
= waveInAddBuffer (wave
->hwi
, h
, sizeof (*h
));
445 if (mr
!= MMSYSERR_NOERROR
) {
446 winwave_logerr (mr
, "waveInAddBuffer(%d)", wave
->curhdr
);
448 wave
->curhdr
= (wave
->curhdr
+ 1) % conf
.adc_headers
;
449 samples
-= conf
.adc_samples
;
453 static int winwave_init_in (HWVoiceIn
*hw
, struct audsettings
*as
)
461 wave
= (WaveVoiceIn
*) hw
;
463 InitializeCriticalSection (&wave
->crit_sect
);
465 err
= waveformat_from_audio_settings (&wfx
, as
);
470 mr
= waveInOpen (&wave
->hwi
, WAVE_MAPPER
, &wfx
,
471 (DWORD_PTR
) winwave_callback_in
,
472 (DWORD_PTR
) wave
, CALLBACK_FUNCTION
);
473 if (mr
!= MMSYSERR_NOERROR
) {
474 winwave_logerr (mr
, "waveInOpen");
478 wave
->hdrs
= audio_calloc (AUDIO_FUNC
, conf
.dac_headers
,
479 sizeof (*wave
->hdrs
));
484 audio_pcm_init_info (&hw
->info
, as
);
485 hw
->samples
= conf
.adc_samples
* conf
.adc_headers
;
488 wave
->pcm_buf
= audio_calloc (AUDIO_FUNC
, conf
.adc_samples
,
489 conf
.adc_headers
<< hw
->info
.shift
);
490 if (!wave
->pcm_buf
) {
494 for (i
= 0; i
< conf
.adc_headers
; ++i
) {
495 WAVEHDR
*h
= &wave
->hdrs
[i
];
498 h
->dwBufferLength
= conf
.adc_samples
<< hw
->info
.shift
;
499 h
->lpData
= advance (wave
->pcm_buf
, i
* h
->dwBufferLength
);
502 mr
= waveInPrepareHeader (wave
->hwi
, h
, sizeof (*h
));
503 if (mr
!= MMSYSERR_NOERROR
) {
504 winwave_logerr (mr
, "waveInPrepareHeader(%d)", i
);
510 winwave_add_buffers (wave
, hw
->samples
);
514 qemu_free (wave
->pcm_buf
);
516 qemu_free (wave
->hdrs
);
518 winwave_anal_close_in (wave
);
524 static void winwave_fini_in (HWVoiceIn
*hw
)
528 WaveVoiceIn
*wave
= (WaveVoiceIn
*) hw
;
530 mr
= waveInReset (wave
->hwi
);
531 if (mr
!= MMSYSERR_NOERROR
) {
532 winwave_logerr (mr
, "waveInReset");
535 for (i
= 0; i
< conf
.adc_headers
; ++i
) {
536 mr
= waveInUnprepareHeader (wave
->hwi
, &wave
->hdrs
[i
],
537 sizeof (wave
->hdrs
[i
]));
538 if (mr
!= MMSYSERR_NOERROR
) {
539 winwave_logerr (mr
, "waveInUnprepareHeader(%d)", i
);
543 winwave_anal_close_in (wave
);
546 qemu_del_wait_object (wave
->event
, winwave_poll
, wave
);
547 if (!CloseHandle (wave
->event
)) {
548 dolog ("ADC CloseHandle failed %lx\n", GetLastError ());
553 qemu_free (wave
->pcm_buf
);
554 wave
->pcm_buf
= NULL
;
556 qemu_free (wave
->hdrs
);
560 static int winwave_run_in (HWVoiceIn
*hw
)
562 WaveVoiceIn
*wave
= (WaveVoiceIn
*) hw
;
563 int live
= audio_pcm_hw_get_live_in (hw
);
564 int dead
= hw
->samples
- live
;
571 EnterCriticalSection (&wave
->crit_sect
);
573 decr
= audio_MIN (dead
, wave
->avail
);
576 LeaveCriticalSection (&wave
->crit_sect
);
580 int left
= hw
->samples
- hw
->wpos
;
581 int conv
= audio_MIN (left
, decr
);
582 hw
->conv (hw
->conv_buf
+ hw
->wpos
,
583 advance (wave
->pcm_buf
, wave
->rpos
<< hw
->info
.shift
),
586 wave
->rpos
= (wave
->rpos
+ conv
) % hw
->samples
;
587 hw
->wpos
= (hw
->wpos
+ conv
) % hw
->samples
;
591 winwave_add_buffers (wave
, ret
);
595 static int winwave_read (SWVoiceIn
*sw
, void *buf
, int size
)
597 return audio_pcm_sw_read (sw
, buf
, size
);
600 static int winwave_ctl_in (HWVoiceIn
*hw
, int cmd
, ...)
603 WaveVoiceIn
*wave
= (WaveVoiceIn
*) hw
;
612 poll_mode
= va_arg (ap
, int);
615 if (poll_mode
&& !wave
->event
) {
616 wave
->event
= CreateEvent (NULL
, TRUE
, TRUE
, NULL
);
618 dolog ("ADC CreateEvent: %lx, poll mode will be disabled\n",
626 ret
= qemu_add_wait_object (wave
->event
, winwave_poll
, wave
);
627 hw
->poll_mode
= (ret
== 0);
633 mr
= waveInStart (wave
->hwi
);
634 if (mr
!= MMSYSERR_NOERROR
) {
635 winwave_logerr (mr
, "waveInStart");
644 mr
= waveInStop (wave
->hwi
);
645 if (mr
!= MMSYSERR_NOERROR
) {
646 winwave_logerr (mr
, "waveInStop");
653 qemu_del_wait_object (wave
->event
, winwave_poll
, wave
);
660 static void *winwave_audio_init (void)
665 static void winwave_audio_fini (void *opaque
)
670 static struct audio_option winwave_options
[] = {
672 .name
= "DAC_HEADERS",
674 .valp
= &conf
.dac_headers
,
675 .descr
= "DAC number of headers",
678 .name
= "DAC_SAMPLES",
680 .valp
= &conf
.dac_samples
,
681 .descr
= "DAC number of samples per header",
684 .name
= "ADC_HEADERS",
686 .valp
= &conf
.adc_headers
,
687 .descr
= "ADC number of headers",
690 .name
= "ADC_SAMPLES",
692 .valp
= &conf
.adc_samples
,
693 .descr
= "ADC number of samples per header",
695 { /* End of list */ }
698 static struct audio_pcm_ops winwave_pcm_ops
= {
699 .init_out
= winwave_init_out
,
700 .fini_out
= winwave_fini_out
,
701 .run_out
= winwave_run_out
,
702 .write
= winwave_write
,
703 .ctl_out
= winwave_ctl_out
,
704 .init_in
= winwave_init_in
,
705 .fini_in
= winwave_fini_in
,
706 .run_in
= winwave_run_in
,
707 .read
= winwave_read
,
708 .ctl_in
= winwave_ctl_in
711 struct audio_driver winwave_audio_driver
= {
713 .descr
= "Windows Waveform Audio http://msdn.microsoft.com",
714 .options
= winwave_options
,
715 .init
= winwave_audio_init
,
716 .fini
= winwave_audio_fini
,
717 .pcm_ops
= &winwave_pcm_ops
,
719 .max_voices_out
= INT_MAX
,
720 .max_voices_in
= INT_MAX
,
721 .voice_size_out
= sizeof (WaveVoiceOut
),
722 .voice_size_in
= sizeof (WaveVoiceIn
)