mirror of https://github.com/xqemu/xqemu.git
Windows Waveform Audio driver (no ADC support yet)
Signed-off-by: malc <av1474@comtv.ru>
This commit is contained in:
parent
ad323081aa
commit
d56316388d
2
Makefile
2
Makefile
|
@ -141,7 +141,9 @@ audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
|
||||||
audio-obj-$(CONFIG_FMOD) += fmodaudio.o
|
audio-obj-$(CONFIG_FMOD) += fmodaudio.o
|
||||||
audio-obj-$(CONFIG_ESD) += esdaudio.o
|
audio-obj-$(CONFIG_ESD) += esdaudio.o
|
||||||
audio-obj-$(CONFIG_PA) += paaudio.o
|
audio-obj-$(CONFIG_PA) += paaudio.o
|
||||||
|
audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
|
||||||
audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
|
audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
|
||||||
|
audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
|
||||||
audio-obj-y += wavcapture.o
|
audio-obj-y += wavcapture.o
|
||||||
obj-y += $(addprefix audio/, $(audio-obj-y))
|
obj-y += $(addprefix audio/, $(audio-obj-y))
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,7 @@ extern struct audio_driver coreaudio_audio_driver;
|
||||||
extern struct audio_driver dsound_audio_driver;
|
extern struct audio_driver dsound_audio_driver;
|
||||||
extern struct audio_driver esd_audio_driver;
|
extern struct audio_driver esd_audio_driver;
|
||||||
extern struct audio_driver pa_audio_driver;
|
extern struct audio_driver pa_audio_driver;
|
||||||
|
extern struct audio_driver winwave_audio_driver;
|
||||||
extern struct mixeng_volume nominal_volume;
|
extern struct mixeng_volume nominal_volume;
|
||||||
|
|
||||||
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
|
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* public domain */
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
|
#define AUDIO_CAP "win-int"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
|
#include "audio.h"
|
||||||
|
#include "audio_int.h"
|
||||||
|
#include "audio_win_int.h"
|
||||||
|
|
||||||
|
int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
|
||||||
|
struct audsettings *as)
|
||||||
|
{
|
||||||
|
memset (wfx, 0, sizeof (*wfx));
|
||||||
|
|
||||||
|
wfx->wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
wfx->nChannels = as->nchannels;
|
||||||
|
wfx->nSamplesPerSec = as->freq;
|
||||||
|
wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
|
||||||
|
wfx->nBlockAlign = 1 << (as->nchannels == 2);
|
||||||
|
wfx->cbSize = 0;
|
||||||
|
|
||||||
|
switch (as->fmt) {
|
||||||
|
case AUD_FMT_S8:
|
||||||
|
case AUD_FMT_U8:
|
||||||
|
wfx->wBitsPerSample = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUD_FMT_S16:
|
||||||
|
case AUD_FMT_U16:
|
||||||
|
wfx->wBitsPerSample = 16;
|
||||||
|
wfx->nAvgBytesPerSec <<= 1;
|
||||||
|
wfx->nBlockAlign <<= 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUD_FMT_S32:
|
||||||
|
case AUD_FMT_U32:
|
||||||
|
wfx->wBitsPerSample = 32;
|
||||||
|
wfx->nAvgBytesPerSec <<= 2;
|
||||||
|
wfx->nBlockAlign <<= 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dolog ("Internal logic error: Bad audio format %d\n", as->freq);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
|
||||||
|
struct audsettings *as)
|
||||||
|
{
|
||||||
|
if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
|
||||||
|
dolog ("Invalid wave format, tag is not PCM, but %d\n",
|
||||||
|
wfx->wFormatTag);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wfx->nSamplesPerSec) {
|
||||||
|
dolog ("Invalid wave format, frequency is zero\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
as->freq = wfx->nSamplesPerSec;
|
||||||
|
|
||||||
|
switch (wfx->nChannels) {
|
||||||
|
case 1:
|
||||||
|
as->nchannels = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
as->nchannels = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dolog (
|
||||||
|
"Invalid wave format, number of channels is not 1 or 2, but %d\n",
|
||||||
|
wfx->nChannels
|
||||||
|
);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (wfx->wBitsPerSample) {
|
||||||
|
case 8:
|
||||||
|
as->fmt = AUD_FMT_U8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
as->fmt = AUD_FMT_S16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
as->fmt = AUD_FMT_S32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dolog ("Invalid wave format, bits per sample is not "
|
||||||
|
"8, 16 or 32, but %d\n",
|
||||||
|
wfx->wBitsPerSample);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef AUDIO_WIN_INT_H
|
||||||
|
#define AUDIO_WIN_INT_H
|
||||||
|
|
||||||
|
int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
|
||||||
|
struct audsettings *as);
|
||||||
|
|
||||||
|
int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
|
||||||
|
struct audsettings *as);
|
||||||
|
|
||||||
|
#endif /* AUDIO_WIN_INT_H */
|
|
@ -37,6 +37,8 @@
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
|
|
||||||
|
#include "audio_win_int.h"
|
||||||
|
|
||||||
/* #define DEBUG_DSOUND */
|
/* #define DEBUG_DSOUND */
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -304,101 +306,6 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
|
|
||||||
struct audsettings *as)
|
|
||||||
{
|
|
||||||
memset (wfx, 0, sizeof (*wfx));
|
|
||||||
|
|
||||||
wfx->wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
wfx->nChannels = as->nchannels;
|
|
||||||
wfx->nSamplesPerSec = as->freq;
|
|
||||||
wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
|
|
||||||
wfx->nBlockAlign = 1 << (as->nchannels == 2);
|
|
||||||
wfx->cbSize = 0;
|
|
||||||
|
|
||||||
switch (as->fmt) {
|
|
||||||
case AUD_FMT_S8:
|
|
||||||
case AUD_FMT_U8:
|
|
||||||
wfx->wBitsPerSample = 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AUD_FMT_S16:
|
|
||||||
case AUD_FMT_U16:
|
|
||||||
wfx->wBitsPerSample = 16;
|
|
||||||
wfx->nAvgBytesPerSec <<= 1;
|
|
||||||
wfx->nBlockAlign <<= 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AUD_FMT_S32:
|
|
||||||
case AUD_FMT_U32:
|
|
||||||
wfx->wBitsPerSample = 32;
|
|
||||||
wfx->nAvgBytesPerSec <<= 2;
|
|
||||||
wfx->nBlockAlign <<= 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
dolog ("Internal logic error: Bad audio format %d\n", as->freq);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
|
|
||||||
struct audsettings *as)
|
|
||||||
{
|
|
||||||
if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
|
|
||||||
dolog ("Invalid wave format, tag is not PCM, but %d\n",
|
|
||||||
wfx->wFormatTag);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wfx->nSamplesPerSec) {
|
|
||||||
dolog ("Invalid wave format, frequency is zero\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
as->freq = wfx->nSamplesPerSec;
|
|
||||||
|
|
||||||
switch (wfx->nChannels) {
|
|
||||||
case 1:
|
|
||||||
as->nchannels = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
as->nchannels = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
dolog (
|
|
||||||
"Invalid wave format, number of channels is not 1 or 2, but %d\n",
|
|
||||||
wfx->nChannels
|
|
||||||
);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (wfx->wBitsPerSample) {
|
|
||||||
case 8:
|
|
||||||
as->fmt = AUD_FMT_U8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 16:
|
|
||||||
as->fmt = AUD_FMT_S16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 32:
|
|
||||||
as->fmt = AUD_FMT_S32;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
dolog ("Invalid wave format, bits per sample is not "
|
|
||||||
"8, 16 or 32, but %d\n",
|
|
||||||
wfx->wBitsPerSample);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "dsound_template.h"
|
#include "dsound_template.h"
|
||||||
#define DSBTYPE_IN
|
#define DSBTYPE_IN
|
||||||
#include "dsound_template.h"
|
#include "dsound_template.h"
|
||||||
|
|
|
@ -0,0 +1,312 @@
|
||||||
|
/* public domain */
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
|
#define AUDIO_CAP "winwave"
|
||||||
|
#include "audio_int.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
|
#include "audio_win_int.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int dac_headers;
|
||||||
|
int dac_samples;
|
||||||
|
} conf = {
|
||||||
|
.dac_headers = 4,
|
||||||
|
.dac_samples = 1024
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HWVoiceOut hw;
|
||||||
|
HWAVEOUT hwo;
|
||||||
|
WAVEHDR *hdrs;
|
||||||
|
void *pcm_buf;
|
||||||
|
int avail;
|
||||||
|
int pending;
|
||||||
|
int curhdr;
|
||||||
|
CRITICAL_SECTION crit_sect;
|
||||||
|
} WaveVoiceOut;
|
||||||
|
|
||||||
|
static void winwave_log_mmresult (MMRESULT mr)
|
||||||
|
{
|
||||||
|
const char *str = "BUG";
|
||||||
|
|
||||||
|
switch (mr) {
|
||||||
|
case MMSYSERR_NOERROR:
|
||||||
|
str = "Success";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MMSYSERR_INVALHANDLE:
|
||||||
|
str = "Specified device handle is invalid";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MMSYSERR_BADDEVICEID:
|
||||||
|
str = "Specified device id is out of range";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MMSYSERR_NODRIVER:
|
||||||
|
str = "No device driver is present";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MMSYSERR_NOMEM:
|
||||||
|
str = "Unable to allocate or locl memory";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAVERR_SYNC:
|
||||||
|
str = "Device is synchronous but waveOutOpen was called "
|
||||||
|
"without using the WINWAVE_ALLOWSYNC flag";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAVERR_UNPREPARED:
|
||||||
|
str = "The data block pointed to by the pwh parameter "
|
||||||
|
"hasn't been prepared";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
AUD_log (AUDIO_CAP, "Reason: Unknown (MMRESULT %#x)\n", mr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_log (AUDIO_CAP, "Reason: %s\n", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GCC_FMT_ATTR (2, 3) winwave_logerr (
|
||||||
|
MMRESULT mr,
|
||||||
|
const char *fmt,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start (ap, fmt);
|
||||||
|
AUD_vlog (AUDIO_CAP, fmt, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
winwave_log_mmresult (mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void winwave_anal_close_out (WaveVoiceOut *wave)
|
||||||
|
{
|
||||||
|
MMRESULT mr;
|
||||||
|
|
||||||
|
mr = waveOutClose (wave->hwo);
|
||||||
|
if (mr != MMSYSERR_NOERROR) {
|
||||||
|
winwave_logerr (mr, "waveOutClose\n");
|
||||||
|
}
|
||||||
|
wave->hwo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CALLBACK winwave_callback (
|
||||||
|
HWAVEOUT hwo,
|
||||||
|
UINT msg,
|
||||||
|
DWORD_PTR dwInstance,
|
||||||
|
DWORD_PTR dwParam1,
|
||||||
|
DWORD_PTR dwParam2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WaveVoiceOut *wave = (WaveVoiceOut *) dwInstance;
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
case WOM_DONE:
|
||||||
|
{
|
||||||
|
WAVEHDR *h = (WAVEHDR *) dwParam1;
|
||||||
|
if (!h->dwUser) {
|
||||||
|
h->dwUser = 1;
|
||||||
|
EnterCriticalSection (&wave->crit_sect);
|
||||||
|
{
|
||||||
|
wave->avail += conf.dac_samples;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection (&wave->crit_sect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WOM_CLOSE:
|
||||||
|
case WOM_OPEN:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
AUD_log (AUDIO_CAP, "unknown wave callback msg %x\n", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int err;
|
||||||
|
MMRESULT mr;
|
||||||
|
WAVEFORMATEX wfx;
|
||||||
|
WaveVoiceOut *wave;
|
||||||
|
|
||||||
|
wave = (WaveVoiceOut *) hw;
|
||||||
|
|
||||||
|
InitializeCriticalSection (&wave->crit_sect);
|
||||||
|
|
||||||
|
err = waveformat_from_audio_settings (&wfx, as);
|
||||||
|
if (err) {
|
||||||
|
goto err0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mr = waveOutOpen (&wave->hwo, WAVE_MAPPER, &wfx,
|
||||||
|
(DWORD_PTR) winwave_callback,
|
||||||
|
(DWORD_PTR) wave, CALLBACK_FUNCTION);
|
||||||
|
if (mr != MMSYSERR_NOERROR) {
|
||||||
|
winwave_logerr (mr, "waveOutOpen\n");
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wave->hdrs = audio_calloc (AUDIO_FUNC, conf.dac_headers,
|
||||||
|
sizeof (*wave->hdrs));
|
||||||
|
if (!wave->hdrs) {
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_pcm_init_info (&hw->info, as);
|
||||||
|
hw->samples = conf.dac_samples * conf.dac_headers;
|
||||||
|
wave->avail = hw->samples;
|
||||||
|
|
||||||
|
wave->pcm_buf = audio_calloc (AUDIO_FUNC, conf.dac_samples,
|
||||||
|
conf.dac_headers << hw->info.shift);
|
||||||
|
if (!wave->pcm_buf) {
|
||||||
|
goto err3;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < conf.dac_headers; ++i) {
|
||||||
|
WAVEHDR *h = &wave->hdrs[i];
|
||||||
|
|
||||||
|
h->dwUser = 0;
|
||||||
|
h->dwBufferLength = conf.dac_samples << hw->info.shift;
|
||||||
|
h->lpData = advance (wave->pcm_buf, i * h->dwBufferLength);
|
||||||
|
h->dwFlags = 0;
|
||||||
|
|
||||||
|
mr = waveOutPrepareHeader (wave->hwo, h, sizeof (*h));
|
||||||
|
if (mr != MMSYSERR_NOERROR) {
|
||||||
|
winwave_logerr (mr, "waveOutPrepareHeader(%d)\n", wave->curhdr);
|
||||||
|
goto err4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err4:
|
||||||
|
qemu_free (wave->pcm_buf);
|
||||||
|
err3:
|
||||||
|
qemu_free (wave->hdrs);
|
||||||
|
err2:
|
||||||
|
winwave_anal_close_out (wave);
|
||||||
|
err1:
|
||||||
|
err0:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int winwave_write (SWVoiceOut *sw, void *buf, int len)
|
||||||
|
{
|
||||||
|
return audio_pcm_sw_write (sw, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int winwave_run_out (HWVoiceOut *hw, int live)
|
||||||
|
{
|
||||||
|
WaveVoiceOut *wave = (WaveVoiceOut *) hw;
|
||||||
|
int decr;
|
||||||
|
|
||||||
|
EnterCriticalSection (&wave->crit_sect);
|
||||||
|
{
|
||||||
|
decr = audio_MIN (live, wave->avail);
|
||||||
|
decr = audio_pcm_hw_clip_out (hw, wave->pcm_buf, decr, wave->pending);
|
||||||
|
wave->pending += decr;
|
||||||
|
wave->avail -= decr;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection (&wave->crit_sect);
|
||||||
|
|
||||||
|
while (wave->pending >= conf.dac_samples) {
|
||||||
|
MMRESULT mr;
|
||||||
|
WAVEHDR *h = &wave->hdrs[wave->curhdr];
|
||||||
|
|
||||||
|
h->dwUser = 0;
|
||||||
|
mr = waveOutWrite (wave->hwo, h, sizeof (*h));
|
||||||
|
if (mr != MMSYSERR_NOERROR) {
|
||||||
|
winwave_logerr (mr, "waveOutWrite(%d)\n", wave->curhdr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wave->pending -= conf.dac_samples;
|
||||||
|
wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
|
||||||
|
}
|
||||||
|
return decr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void winwave_fini_out (HWVoiceOut *hw)
|
||||||
|
{
|
||||||
|
WaveVoiceOut *wave = (WaveVoiceOut *) hw;
|
||||||
|
|
||||||
|
winwave_anal_close_out (wave);
|
||||||
|
|
||||||
|
qemu_free (wave->pcm_buf);
|
||||||
|
wave->pcm_buf = NULL;
|
||||||
|
|
||||||
|
qemu_free (wave->hdrs);
|
||||||
|
wave->hdrs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
||||||
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case VOICE_ENABLE:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case VOICE_DISABLE:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *winwave_audio_init (void)
|
||||||
|
{
|
||||||
|
return &conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void winwave_audio_fini (void *opaque)
|
||||||
|
{
|
||||||
|
(void) opaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct audio_option winwave_options[] = {
|
||||||
|
{
|
||||||
|
.name = "DAC_HEADERS",
|
||||||
|
.tag = AUD_OPT_INT,
|
||||||
|
.valp = &conf.dac_headers,
|
||||||
|
.descr = "DAC number of headers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "DAC_SAMPLES",
|
||||||
|
.tag = AUD_OPT_INT,
|
||||||
|
.valp = &conf.dac_samples,
|
||||||
|
.descr = "DAC number of samples per header",
|
||||||
|
},
|
||||||
|
{ /* End of list */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct audio_pcm_ops winwave_pcm_ops = {
|
||||||
|
.init_out = winwave_init_out,
|
||||||
|
.fini_out = winwave_fini_out,
|
||||||
|
.run_out = winwave_run_out,
|
||||||
|
.write = winwave_write,
|
||||||
|
.ctl_out = winwave_ctl_out
|
||||||
|
};
|
||||||
|
|
||||||
|
struct audio_driver winwave_audio_driver = {
|
||||||
|
.name = "winwave",
|
||||||
|
.descr = "Windows Waveform Audio http://msdn.microsoft.com",
|
||||||
|
.options = winwave_options,
|
||||||
|
.init = winwave_audio_init,
|
||||||
|
.fini = winwave_audio_fini,
|
||||||
|
.pcm_ops = &winwave_pcm_ops,
|
||||||
|
.can_be_default = 1,
|
||||||
|
.max_voices_out = INT_MAX,
|
||||||
|
.max_voices_in = 0,
|
||||||
|
.voice_size_out = sizeof (WaveVoiceOut),
|
||||||
|
.voice_size_in = 0
|
||||||
|
};
|
|
@ -48,6 +48,7 @@ helper_cflags=""
|
||||||
libs_softmmu=""
|
libs_softmmu=""
|
||||||
libs_tools=""
|
libs_tools=""
|
||||||
audio_pt_int=""
|
audio_pt_int=""
|
||||||
|
audio_win_int=""
|
||||||
|
|
||||||
# parse CC options first
|
# parse CC options first
|
||||||
for opt do
|
for opt do
|
||||||
|
@ -242,11 +243,13 @@ case $targetos in
|
||||||
CYGWIN*)
|
CYGWIN*)
|
||||||
mingw32="yes"
|
mingw32="yes"
|
||||||
QEMU_CFLAGS="-mno-cygwin $QEMU_CFLAGS"
|
QEMU_CFLAGS="-mno-cygwin $QEMU_CFLAGS"
|
||||||
audio_possible_drivers="sdl"
|
audio_possible_drivers="winwave sdl"
|
||||||
|
audio_drv_list="winwave"
|
||||||
;;
|
;;
|
||||||
MINGW32*)
|
MINGW32*)
|
||||||
mingw32="yes"
|
mingw32="yes"
|
||||||
audio_possible_drivers="dsound sdl fmod"
|
audio_possible_drivers="winwave dsound sdl fmod"
|
||||||
|
audio_drv_list="winwave"
|
||||||
;;
|
;;
|
||||||
GNU/kFreeBSD)
|
GNU/kFreeBSD)
|
||||||
audio_drv_list="oss"
|
audio_drv_list="oss"
|
||||||
|
@ -1169,6 +1172,7 @@ for drv in $audio_drv_list; do
|
||||||
|
|
||||||
dsound)
|
dsound)
|
||||||
libs_softmmu="-lole32 -ldxguid $libs_softmmu"
|
libs_softmmu="-lole32 -ldxguid $libs_softmmu"
|
||||||
|
audio_win_int="yes"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
oss)
|
oss)
|
||||||
|
@ -1179,6 +1183,11 @@ for drv in $audio_drv_list; do
|
||||||
# XXX: Probes for CoreAudio, DirectSound, SDL(?)
|
# XXX: Probes for CoreAudio, DirectSound, SDL(?)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
winwave)
|
||||||
|
libs_softmmu="-lwinmm $libs_softmmu"
|
||||||
|
audio_win_int="yes"
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "$audio_possible_drivers" | grep -q "\<$drv\>" || {
|
echo "$audio_possible_drivers" | grep -q "\<$drv\>" || {
|
||||||
echo
|
echo
|
||||||
|
@ -1885,6 +1894,9 @@ done
|
||||||
if test "$audio_pt_int" = "yes" ; then
|
if test "$audio_pt_int" = "yes" ; then
|
||||||
echo "CONFIG_AUDIO_PT_INT=y" >> $config_host_mak
|
echo "CONFIG_AUDIO_PT_INT=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
if test "$audio_win_int" = "yes" ; then
|
||||||
|
echo "CONFIG_AUDIO_WIN_INT=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
if test "$mixemu" = "yes" ; then
|
if test "$mixemu" = "yes" ; then
|
||||||
echo "CONFIG_MIXEMU=y" >> $config_host_mak
|
echo "CONFIG_MIXEMU=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in New Issue