mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
pthreads-based audio and miscellaneous audio clean-up (malc).
ESD support (malc, Frederick Reeve). git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3917 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
@@ -73,6 +73,7 @@ AUDIO_OBJS += ossaudio.o
|
||||
endif
|
||||
ifdef CONFIG_COREAUDIO
|
||||
AUDIO_OBJS += coreaudio.o
|
||||
AUDIO_PT = yes
|
||||
endif
|
||||
ifdef CONFIG_ALSA
|
||||
AUDIO_OBJS += alsaaudio.o
|
||||
@@ -84,6 +85,17 @@ ifdef CONFIG_FMOD
|
||||
AUDIO_OBJS += fmodaudio.o
|
||||
audio/audio.o audio/fmodaudio.o: CPPFLAGS := -I$(CONFIG_FMOD_INC) $(CPPFLAGS)
|
||||
endif
|
||||
ifdef CONFIG_ESD
|
||||
AUDIO_PT = yes
|
||||
AUDIO_PT_INT = yes
|
||||
AUDIO_OBJS += esdaudio.o
|
||||
endif
|
||||
ifdef AUDIO_PT
|
||||
LDFLAGS += -pthread
|
||||
endif
|
||||
ifdef AUDIO_PT_INT
|
||||
AUDIO_OBJS += audio_pt_int.o
|
||||
endif
|
||||
AUDIO_OBJS+= wavcapture.o
|
||||
OBJS+=$(addprefix audio/, $(AUDIO_OBJS))
|
||||
|
||||
|
||||
+9
-2
@@ -404,6 +404,9 @@ endif
|
||||
ifdef CONFIG_ALSA
|
||||
LIBS += -lasound
|
||||
endif
|
||||
ifdef CONFIG_ESD
|
||||
LIBS += -lesd
|
||||
endif
|
||||
ifdef CONFIG_DSOUND
|
||||
LIBS += -lole32 -ldxguid
|
||||
endif
|
||||
@@ -412,6 +415,9 @@ LIBS += $(CONFIG_FMOD_LIB)
|
||||
endif
|
||||
|
||||
SOUND_HW = sb16.o es1370.o
|
||||
ifdef CONFIG_AC97
|
||||
SOUND_HW += ac97.o
|
||||
endif
|
||||
ifdef CONFIG_ADLIB
|
||||
SOUND_HW += fmopl.o adlib.o
|
||||
endif
|
||||
@@ -641,8 +647,9 @@ endif
|
||||
|
||||
ifeq (1, 0)
|
||||
audio.o sdlaudio.o dsoundaudio.o ossaudio.o wavaudio.o noaudio.o \
|
||||
fmodaudio.o alsaaudio.o mixeng.o sb16.o es1370.o gus.o adlib.o: \
|
||||
CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare
|
||||
fmodaudio.o alsaaudio.o mixeng.o sb16.o es1370.o ac97.o gus.o adlib.o \
|
||||
esdaudio.o audio_pt_int.o: \
|
||||
CFLAGS := $(CFLAGS) -O0 -g -Wall -Werror -W -Wsign-compare -Wno-unused
|
||||
endif
|
||||
|
||||
# Include automatically generated dependency files
|
||||
|
||||
+47
-41
@@ -86,9 +86,9 @@ static struct {
|
||||
};
|
||||
|
||||
struct alsa_params_req {
|
||||
unsigned int freq;
|
||||
audfmt_e fmt;
|
||||
unsigned int nchannels;
|
||||
int freq;
|
||||
snd_pcm_format_t fmt;
|
||||
int nchannels;
|
||||
unsigned int buffer_size;
|
||||
unsigned int period_size;
|
||||
};
|
||||
@@ -96,6 +96,7 @@ struct alsa_params_req {
|
||||
struct alsa_params_obt {
|
||||
int freq;
|
||||
audfmt_e fmt;
|
||||
int endianness;
|
||||
int nchannels;
|
||||
snd_pcm_uframes_t samples;
|
||||
};
|
||||
@@ -143,7 +144,7 @@ static int alsa_write (SWVoiceOut *sw, void *buf, int len)
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
}
|
||||
|
||||
static int aud_to_alsafmt (audfmt_e fmt)
|
||||
static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case AUD_FMT_S8:
|
||||
@@ -173,7 +174,8 @@ static int aud_to_alsafmt (audfmt_e fmt)
|
||||
}
|
||||
}
|
||||
|
||||
static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness)
|
||||
static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
|
||||
int *endianness)
|
||||
{
|
||||
switch (alsafmt) {
|
||||
case SND_PCM_FORMAT_S8:
|
||||
@@ -234,7 +236,6 @@ static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined DEBUG_MISMATCHES || defined DEBUG
|
||||
static void alsa_dump_info (struct alsa_params_req *req,
|
||||
struct alsa_params_obt *obt)
|
||||
{
|
||||
@@ -248,7 +249,6 @@ static void alsa_dump_info (struct alsa_params_req *req,
|
||||
req->buffer_size, req->period_size);
|
||||
dolog ("obtained: samples %ld\n", obt->samples);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
|
||||
{
|
||||
@@ -291,6 +291,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
|
||||
unsigned int period_size, buffer_size;
|
||||
snd_pcm_uframes_t obt_buffer_size;
|
||||
const char *typ = in ? "ADC" : "DAC";
|
||||
snd_pcm_format_t obtfmt;
|
||||
|
||||
freq = req->freq;
|
||||
period_size = req->period_size;
|
||||
@@ -327,9 +328,8 @@ static int alsa_open (int in, struct alsa_params_req *req,
|
||||
}
|
||||
|
||||
err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
|
||||
if (err < 0) {
|
||||
if (err < 0 && conf.verbose) {
|
||||
alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
|
||||
@@ -494,6 +494,17 @@ static int alsa_open (int in, struct alsa_params_req *req,
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
|
||||
if (err < 0) {
|
||||
alsa_logerr2 (err, typ, "Failed to get format\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
|
||||
dolog ("Invalid format was returned %d\n", obtfmt);
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = snd_pcm_prepare (handle);
|
||||
if (err < 0) {
|
||||
alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
|
||||
@@ -504,28 +515,41 @@ static int alsa_open (int in, struct alsa_params_req *req,
|
||||
snd_pcm_uframes_t threshold;
|
||||
int bytes_per_sec;
|
||||
|
||||
bytes_per_sec = freq
|
||||
<< (nchannels == 2)
|
||||
<< (req->fmt == AUD_FMT_S16 || req->fmt == AUD_FMT_U16);
|
||||
bytes_per_sec = freq << (nchannels == 2);
|
||||
|
||||
switch (obt->fmt) {
|
||||
case AUD_FMT_S8:
|
||||
case AUD_FMT_U8:
|
||||
break;
|
||||
|
||||
case AUD_FMT_S16:
|
||||
case AUD_FMT_U16:
|
||||
bytes_per_sec <<= 1;
|
||||
break;
|
||||
|
||||
case AUD_FMT_S32:
|
||||
case AUD_FMT_U32:
|
||||
bytes_per_sec <<= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
threshold = (conf.threshold * bytes_per_sec) / 1000;
|
||||
alsa_set_threshold (handle, threshold);
|
||||
}
|
||||
|
||||
obt->fmt = req->fmt;
|
||||
obt->nchannels = nchannels;
|
||||
obt->freq = freq;
|
||||
obt->samples = obt_buffer_size;
|
||||
|
||||
*handlep = handle;
|
||||
|
||||
#if defined DEBUG_MISMATCHES || defined DEBUG
|
||||
if (obt->fmt != req->fmt ||
|
||||
obt->nchannels != req->nchannels ||
|
||||
obt->freq != req->freq) {
|
||||
dolog ("Audio paramters mismatch for %s\n", typ);
|
||||
if (conf.verbose &&
|
||||
(obt->fmt != req->fmt ||
|
||||
obt->nchannels != req->nchannels ||
|
||||
obt->freq != req->freq)) {
|
||||
dolog ("Audio paramters for %s\n", typ);
|
||||
alsa_dump_info (req, obt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
alsa_dump_info (req, obt);
|
||||
@@ -665,9 +689,6 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
|
||||
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
|
||||
struct alsa_params_req req;
|
||||
struct alsa_params_obt obt;
|
||||
audfmt_e effective_fmt;
|
||||
int endianness;
|
||||
int err;
|
||||
snd_pcm_t *handle;
|
||||
audsettings_t obt_as;
|
||||
|
||||
@@ -681,16 +702,10 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness);
|
||||
if (err) {
|
||||
alsa_anal_close (&handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
obt_as.freq = obt.freq;
|
||||
obt_as.nchannels = obt.nchannels;
|
||||
obt_as.fmt = effective_fmt;
|
||||
obt_as.endianness = endianness;
|
||||
obt_as.fmt = obt.fmt;
|
||||
obt_as.endianness = obt.endianness;
|
||||
|
||||
audio_pcm_init_info (&hw->info, &obt_as);
|
||||
hw->samples = obt.samples;
|
||||
@@ -751,9 +766,6 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
|
||||
ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
|
||||
struct alsa_params_req req;
|
||||
struct alsa_params_obt obt;
|
||||
int endianness;
|
||||
int err;
|
||||
audfmt_e effective_fmt;
|
||||
snd_pcm_t *handle;
|
||||
audsettings_t obt_as;
|
||||
|
||||
@@ -767,16 +779,10 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness);
|
||||
if (err) {
|
||||
alsa_anal_close (&handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
obt_as.freq = obt.freq;
|
||||
obt_as.nchannels = obt.nchannels;
|
||||
obt_as.fmt = effective_fmt;
|
||||
obt_as.endianness = endianness;
|
||||
obt_as.fmt = obt.fmt;
|
||||
obt_as.endianness = obt.endianness;
|
||||
|
||||
audio_pcm_init_info (&hw->info, &obt_as);
|
||||
hw->samples = obt.samples;
|
||||
|
||||
+4
-1
@@ -55,6 +55,9 @@ static struct audio_driver *drvtab[] = {
|
||||
#endif
|
||||
#ifdef CONFIG_SDL
|
||||
&sdl_audio_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_ESD
|
||||
&esd_audio_driver,
|
||||
#endif
|
||||
&no_audio_driver,
|
||||
&wav_audio_driver
|
||||
@@ -414,7 +417,7 @@ static void audio_print_options (const char *prefix,
|
||||
{
|
||||
audfmt_e *fmtp = opt->valp;
|
||||
printf (
|
||||
"format, %s = %s, (one of: U8 S8 U16 S16)\n",
|
||||
"format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
|
||||
state,
|
||||
audio_audfmt_to_string (*fmtp)
|
||||
);
|
||||
|
||||
@@ -202,6 +202,7 @@ extern struct audio_driver fmod_audio_driver;
|
||||
extern struct audio_driver alsa_audio_driver;
|
||||
extern struct audio_driver coreaudio_audio_driver;
|
||||
extern struct audio_driver dsound_audio_driver;
|
||||
extern struct audio_driver esd_audio_driver;
|
||||
extern volume_t nominal_volume;
|
||||
|
||||
void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as);
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "qemu-common.h"
|
||||
#include "audio.h"
|
||||
|
||||
#define AUDIO_CAP "audio-pt"
|
||||
|
||||
#include "audio_int.h"
|
||||
#include "audio_pt_int.h"
|
||||
|
||||
static void logerr (struct audio_pt *pt, int err, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
AUD_vlog (pt->drv, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
AUD_log (NULL, "\n");
|
||||
AUD_log (pt->drv, "Reason: %s\n", strerror (err));
|
||||
}
|
||||
|
||||
int audio_pt_init (struct audio_pt *p, void *(*func) (void *),
|
||||
void *opaque, const char *drv, const char *cap)
|
||||
{
|
||||
int err, err2;
|
||||
const char *efunc;
|
||||
|
||||
p->drv = drv;
|
||||
|
||||
err = pthread_mutex_init (&p->mutex, NULL);
|
||||
if (err) {
|
||||
efunc = "pthread_mutex_init";
|
||||
goto err0;
|
||||
}
|
||||
|
||||
err = pthread_cond_init (&p->cond, NULL);
|
||||
if (err) {
|
||||
efunc = "pthread_cond_init";
|
||||
goto err1;
|
||||
}
|
||||
|
||||
err = pthread_create (&p->thread, NULL, func, opaque);
|
||||
if (err) {
|
||||
efunc = "pthread_create";
|
||||
goto err2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
err2 = pthread_cond_destroy (&p->cond);
|
||||
if (err2) {
|
||||
logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
|
||||
}
|
||||
|
||||
err1:
|
||||
err2 = pthread_mutex_destroy (&p->mutex);
|
||||
if (err2) {
|
||||
logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
|
||||
}
|
||||
|
||||
err0:
|
||||
logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int audio_pt_fini (struct audio_pt *p, const char *cap)
|
||||
{
|
||||
int err, ret = 0;
|
||||
|
||||
err = pthread_cond_destroy (&p->cond);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
err = pthread_mutex_destroy (&p->mutex);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int audio_pt_lock (struct audio_pt *p, const char *cap)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_lock (&p->mutex);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audio_pt_unlock (struct audio_pt *p, const char *cap)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_unlock (&p->mutex);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audio_pt_wait (struct audio_pt *p, const char *cap)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = pthread_cond_wait (&p->cond, &p->mutex);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_unlock (&p->mutex);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
|
||||
return -1;
|
||||
}
|
||||
err = pthread_cond_signal (&p->cond);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audio_pt_join (struct audio_pt *p, void **arg, const char *cap)
|
||||
{
|
||||
int err;
|
||||
void *ret;
|
||||
|
||||
err = pthread_join (p->thread, &ret);
|
||||
if (err) {
|
||||
logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC);
|
||||
return -1;
|
||||
}
|
||||
*arg = ret;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef QEMU_AUDIO_PT_INT_H
|
||||
#define QEMU_AUDIO_PT_INT_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
struct audio_pt {
|
||||
const char *drv;
|
||||
pthread_t thread;
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
int audio_pt_init (struct audio_pt *, void *(*) (void *), void *,
|
||||
const char *, const char *);
|
||||
int audio_pt_fini (struct audio_pt *, const char *);
|
||||
int audio_pt_lock (struct audio_pt *, const char *);
|
||||
int audio_pt_unlock (struct audio_pt *, const char *);
|
||||
int audio_pt_wait (struct audio_pt *, const char *);
|
||||
int audio_pt_unlock_and_signal (struct audio_pt *, const char *);
|
||||
int audio_pt_join (struct audio_pt *, void **, const char *);
|
||||
|
||||
#endif /* audio_pt_int.h */
|
||||
@@ -23,16 +23,20 @@
|
||||
*/
|
||||
#ifdef DSBTYPE_IN
|
||||
#define NAME "capture buffer"
|
||||
#define NAME2 "DirectSoundCapture"
|
||||
#define TYPE in
|
||||
#define IFACE IDirectSoundCaptureBuffer
|
||||
#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
|
||||
#define FIELD dsound_capture_buffer
|
||||
#define FIELD2 dsound_capture
|
||||
#else
|
||||
#define NAME "playback buffer"
|
||||
#define NAME2 "DirectSound"
|
||||
#define TYPE out
|
||||
#define IFACE IDirectSoundBuffer
|
||||
#define BUFPTR LPDIRECTSOUNDBUFFER
|
||||
#define FIELD dsound_buffer
|
||||
#define FIELD2 dsound
|
||||
#endif
|
||||
|
||||
static int glue (dsound_unlock_, TYPE) (
|
||||
@@ -192,6 +196,11 @@ static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
|
||||
DSBCAPS bc;
|
||||
#endif
|
||||
|
||||
if (!s->FIELD2) {
|
||||
dsound_logerr ("Attempt to initialize voice without " NAME2 " object");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = waveformat_from_audio_settings (&wfx, as);
|
||||
if (err) {
|
||||
return -1;
|
||||
|
||||
+12
-8
@@ -320,23 +320,22 @@ static int waveformat_from_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
|
||||
|
||||
switch (as->fmt) {
|
||||
case AUD_FMT_S8:
|
||||
wfx->wBitsPerSample = 8;
|
||||
break;
|
||||
|
||||
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_U16:
|
||||
wfx->wBitsPerSample = 16;
|
||||
wfx->nAvgBytesPerSec <<= 1;
|
||||
wfx->nBlockAlign <<= 1;
|
||||
case AUD_FMT_S32:
|
||||
case AUD_FMT_U32:
|
||||
wfx->wBitsPerSample = 32;
|
||||
wfx->nAvgBytesPerSec <<= 2;
|
||||
wfx->nBlockAlign <<= 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -387,8 +386,13 @@ static int waveformat_to_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
|
||||
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 or 16, but %d\n",
|
||||
dolog ("Invalid wave format, bits per sample is not "
|
||||
"8, 16 or 32, but %d\n",
|
||||
wfx->wBitsPerSample);
|
||||
return -1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -150,7 +150,7 @@ static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness)
|
||||
{
|
||||
switch (ossfmt) {
|
||||
case AFMT_S8:
|
||||
*endianness =0;
|
||||
*endianness = 0;
|
||||
*fmt = AUD_FMT_S8;
|
||||
break;
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ static struct {
|
||||
44100,
|
||||
2,
|
||||
AUD_FMT_S16,
|
||||
AUDIO_HOST_ENDIANNESS
|
||||
0
|
||||
},
|
||||
"qemu.wav"
|
||||
};
|
||||
|
||||
@@ -89,6 +89,7 @@ oss="no"
|
||||
dsound="no"
|
||||
coreaudio="no"
|
||||
alsa="no"
|
||||
esd="no"
|
||||
fmod="no"
|
||||
fmod_lib=""
|
||||
fmod_inc=""
|
||||
@@ -261,6 +262,8 @@ for opt do
|
||||
;;
|
||||
--enable-alsa) alsa="yes"
|
||||
;;
|
||||
--enable-esd) esd="yes"
|
||||
;;
|
||||
--enable-dsound) dsound="yes"
|
||||
;;
|
||||
--enable-fmod) fmod="yes"
|
||||
@@ -405,6 +408,7 @@ echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
|
||||
echo " --enable-adlib enable Adlib emulation"
|
||||
echo " --enable-coreaudio enable Coreaudio audio driver"
|
||||
echo " --enable-alsa enable ALSA audio driver"
|
||||
echo " --enable-esd enable EsoundD audio driver"
|
||||
echo " --enable-fmod enable FMOD audio driver"
|
||||
echo " --enable-dsound enable DirectSound audio driver"
|
||||
echo " --disable-vnc-tls disable TLS encryption for VNC server"
|
||||
@@ -717,6 +721,7 @@ echo "mingw32 support $mingw32"
|
||||
echo "Adlib support $adlib"
|
||||
echo "CoreAudio support $coreaudio"
|
||||
echo "ALSA support $alsa"
|
||||
echo "EsounD support $esd"
|
||||
echo "DSound support $dsound"
|
||||
if test "$fmod" = "yes"; then
|
||||
if test -z $fmod_lib || test -z $fmod_inc; then
|
||||
@@ -902,6 +907,10 @@ if test "$alsa" = "yes" ; then
|
||||
echo "CONFIG_ALSA=yes" >> $config_mak
|
||||
echo "#define CONFIG_ALSA 1" >> $config_h
|
||||
fi
|
||||
if test "$esd" = "yes" ; then
|
||||
echo "CONFIG_ESD=yes" >> $config_mak
|
||||
echo "#define CONFIG_ESD 1" >> $config_h
|
||||
fi
|
||||
if test "$dsound" = "yes" ; then
|
||||
echo "CONFIG_DSOUND=yes" >> $config_mak
|
||||
echo "#define CONFIG_DSOUND 1" >> $config_h
|
||||
|
||||
@@ -439,6 +439,13 @@ static void dma_reset(void *opaque)
|
||||
write_cont (d, (0x0d << d->dshift), 0);
|
||||
}
|
||||
|
||||
static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
|
||||
{
|
||||
dolog ("unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n",
|
||||
nchan, dma_pos, dma_len);
|
||||
return dma_pos;
|
||||
}
|
||||
|
||||
/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
|
||||
static void dma_init2(struct dma_cont *d, int base, int dshift,
|
||||
int page_base, int pageh_base)
|
||||
@@ -471,6 +478,9 @@ static void dma_init2(struct dma_cont *d, int base, int dshift,
|
||||
}
|
||||
qemu_register_reset(dma_reset, d);
|
||||
dma_reset(d);
|
||||
for (i = 0; i < LENOFA (d->regs); ++i) {
|
||||
d->regs[i].transfer_handler = dma_phony_handler;
|
||||
}
|
||||
}
|
||||
|
||||
static void dma_save (QEMUFile *f, void *opaque)
|
||||
|
||||
@@ -1193,6 +1193,12 @@ static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
|
||||
SB16State *s = opaque;
|
||||
int till, copy, written, free;
|
||||
|
||||
if (s->block_size <= 0) {
|
||||
dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
|
||||
s->block_size, nchan, dma_pos, dma_len);
|
||||
return dma_pos;
|
||||
}
|
||||
|
||||
if (s->left_till_irq < 0) {
|
||||
s->left_till_irq = s->block_size;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user