winwave: poll mode
Signed-off-by: malc <av1474@comtv.ru>
This commit is contained in:
parent
d56316388d
commit
e0bda367e5
|
@ -1,6 +1,7 @@
|
||||||
/* public domain */
|
/* public domain */
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
#include "sysemu.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
|
||||||
#define AUDIO_CAP "winwave"
|
#define AUDIO_CAP "winwave"
|
||||||
|
@ -23,6 +24,7 @@ typedef struct {
|
||||||
HWVoiceOut hw;
|
HWVoiceOut hw;
|
||||||
HWAVEOUT hwo;
|
HWAVEOUT hwo;
|
||||||
WAVEHDR *hdrs;
|
WAVEHDR *hdrs;
|
||||||
|
HANDLE event;
|
||||||
void *pcm_buf;
|
void *pcm_buf;
|
||||||
int avail;
|
int avail;
|
||||||
int pending;
|
int pending;
|
||||||
|
@ -120,6 +122,12 @@ static void CALLBACK winwave_callback (
|
||||||
wave->avail += conf.dac_samples;
|
wave->avail += conf.dac_samples;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection (&wave->crit_sect);
|
LeaveCriticalSection (&wave->crit_sect);
|
||||||
|
if (wave->hw.poll_mode) {
|
||||||
|
if (!SetEvent (wave->event)) {
|
||||||
|
AUD_log (AUDIO_CAP, "SetEvent failed %lx\n",
|
||||||
|
GetLastError ());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -211,6 +219,7 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
|
||||||
{
|
{
|
||||||
WaveVoiceOut *wave = (WaveVoiceOut *) hw;
|
WaveVoiceOut *wave = (WaveVoiceOut *) hw;
|
||||||
int decr;
|
int decr;
|
||||||
|
int doreset;
|
||||||
|
|
||||||
EnterCriticalSection (&wave->crit_sect);
|
EnterCriticalSection (&wave->crit_sect);
|
||||||
{
|
{
|
||||||
|
@ -221,6 +230,11 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
|
||||||
}
|
}
|
||||||
LeaveCriticalSection (&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) {
|
while (wave->pending >= conf.dac_samples) {
|
||||||
MMRESULT mr;
|
MMRESULT mr;
|
||||||
WAVEHDR *h = &wave->hdrs[wave->curhdr];
|
WAVEHDR *h = &wave->hdrs[wave->curhdr];
|
||||||
|
@ -235,6 +249,7 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
|
||||||
wave->pending -= conf.dac_samples;
|
wave->pending -= conf.dac_samples;
|
||||||
wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
|
wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
return decr;
|
return decr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,15 +264,61 @@ static void winwave_fini_out (HWVoiceOut *hw)
|
||||||
|
|
||||||
qemu_free (wave->hdrs);
|
qemu_free (wave->hdrs);
|
||||||
wave->hdrs = NULL;
|
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, ...)
|
static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
||||||
{
|
{
|
||||||
|
WaveVoiceOut *wave = (WaveVoiceOut *) hw;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case VOICE_ENABLE:
|
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;
|
return 0;
|
||||||
|
|
||||||
case VOICE_DISABLE:
|
case VOICE_DISABLE:
|
||||||
|
if (wave->event) {
|
||||||
|
qemu_del_wait_object (wave->event, winwave_poll_out, wave);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in a new issue