/* public domain */
#include "qemu-common.h"
+#include "sysemu.h"
#include "audio.h"
#define AUDIO_CAP "winwave"
HWVoiceOut hw;
HWAVEOUT hwo;
WAVEHDR *hdrs;
+ HANDLE event;
void *pcm_buf;
int avail;
int pending;
wave->avail += conf.dac_samples;
}
LeaveCriticalSection (&wave->crit_sect);
+ if (wave->hw.poll_mode) {
+ if (!SetEvent (wave->event)) {
+ AUD_log (AUDIO_CAP, "SetEvent failed %lx\n",
+ GetLastError ());
+ }
+ }
}
}
break;
{
WaveVoiceOut *wave = (WaveVoiceOut *) hw;
int decr;
+ int doreset;
EnterCriticalSection (&wave->crit_sect);
{
}
LeaveCriticalSection (&wave->crit_sect);
+ doreset = hw->poll_mode && (wave->pending >= conf.dac_samples);
+ if (doreset && !ResetEvent (wave->event)) {
+ AUD_log (AUDIO_CAP, "ResetEvent failed %lx\n", GetLastError ());
+ }
+
while (wave->pending >= conf.dac_samples) {
MMRESULT mr;
WAVEHDR *h = &wave->hdrs[wave->curhdr];
wave->pending -= conf.dac_samples;
wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
}
+
return decr;
}
qemu_free (wave->hdrs);
wave->hdrs = NULL;
+
+ if (wave->event) {
+ if (!CloseHandle (wave->event)) {
+ AUD_log (AUDIO_CAP, "CloseHandle failed %lx\n", GetLastError ());
+ }
+ wave->event = NULL;
+ }
+}
+
+static void winwave_poll_out (void *opaque)
+{
+ (void) opaque;
+ audio_run ("winwave_poll_out");
}
static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
+ WaveVoiceOut *wave = (WaveVoiceOut *) hw;
+
switch (cmd) {
case VOICE_ENABLE:
+ {
+ va_list ap;
+ int poll_mode;
+
+ va_start (ap, cmd);
+ poll_mode = va_arg (ap, int);
+ va_end (ap);
+
+ if (poll_mode && !wave->event) {
+ wave->event = CreateEvent (NULL, TRUE, TRUE, NULL);
+ if (!wave->event) {
+ AUD_log (AUDIO_CAP,
+ "CreateEvent: %lx, poll mode will be disabled\n",
+ GetLastError ());
+ }
+ }
+
+ if (wave->event) {
+ int ret;
+
+ ret = qemu_add_wait_object (wave->event, winwave_poll_out,
+ wave);
+ hw->poll_mode = (ret == 0);
+ }
+ else {
+ hw->poll_mode = 0;
+ }
+ }
return 0;
case VOICE_DISABLE:
+ if (wave->event) {
+ qemu_del_wait_object (wave->event, winwave_poll_out, wave);
+ }
return 0;
}
return -1;