提交 c0fe3827 编写于 作者: B bellard

audio merge (malc)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1601 c046a42c-6fe2-441c-8c8c-71466251a162
上级 f04308e4
...@@ -453,8 +453,8 @@ ifneq ($(wildcard .depend),) ...@@ -453,8 +453,8 @@ ifneq ($(wildcard .depend),)
include .depend include .depend
endif endif
ifeq (0, 1) ifeq (1, 0)
audio.o sdlaudio.o dsoundaudio.o ossaudio.o wavaudio.o noaudio.o \ audio.o sdlaudio.o dsoundaudio.o ossaudio.o wavaudio.o noaudio.o \
fmodaudio.o alsaaudio.o mixeng.o: \ fmodaudio.o alsaaudio.o mixeng.o sb16.o es1370.o gus.o adlib.o: \
CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare
endif endif
...@@ -98,7 +98,7 @@ struct alsa_params_obt { ...@@ -98,7 +98,7 @@ struct alsa_params_obt {
audfmt_e fmt; audfmt_e fmt;
int nchannels; int nchannels;
int can_pause; int can_pause;
snd_pcm_uframes_t buffer_size; snd_pcm_uframes_t samples;
}; };
static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...) static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
...@@ -121,7 +121,7 @@ static void GCC_FMT_ATTR (3, 4) alsa_logerr2 ( ...@@ -121,7 +121,7 @@ static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
{ {
va_list ap; va_list ap;
AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ); AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
va_start (ap, fmt); va_start (ap, fmt);
AUD_vlog (AUDIO_CAP, fmt, ap); AUD_vlog (AUDIO_CAP, fmt, ap);
...@@ -209,7 +209,7 @@ static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness) ...@@ -209,7 +209,7 @@ static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness)
return 0; return 0;
} }
#ifdef DEBUG_MISMATCHES #if defined DEBUG_MISMATCHES || defined DEBUG
static void alsa_dump_info (struct alsa_params_req *req, static void alsa_dump_info (struct alsa_params_req *req,
struct alsa_params_obt *obt) struct alsa_params_obt *obt)
{ {
...@@ -221,7 +221,7 @@ static void alsa_dump_info (struct alsa_params_req *req, ...@@ -221,7 +221,7 @@ static void alsa_dump_info (struct alsa_params_req *req,
dolog ("============================================\n"); dolog ("============================================\n");
dolog ("requested: buffer size %d period size %d\n", dolog ("requested: buffer size %d period size %d\n",
req->buffer_size, req->period_size); req->buffer_size, req->period_size);
dolog ("obtained: buffer size %ld\n", obt->buffer_size); dolog ("obtained: samples %ld\n", obt->samples);
} }
#endif #endif
...@@ -234,14 +234,14 @@ static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold) ...@@ -234,14 +234,14 @@ static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
err = snd_pcm_sw_params_current (handle, sw_params); err = snd_pcm_sw_params_current (handle, sw_params);
if (err < 0) { if (err < 0) {
dolog ("Can not fully initialize DAC\n"); dolog ("Could not fully initialize DAC\n");
alsa_logerr (err, "Failed to get current software parameters\n"); alsa_logerr (err, "Failed to get current software parameters\n");
return; return;
} }
err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold); err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
if (err < 0) { if (err < 0) {
dolog ("Can not fully initialize DAC\n"); dolog ("Could not fully initialize DAC\n");
alsa_logerr (err, "Failed to set software threshold to %ld\n", alsa_logerr (err, "Failed to set software threshold to %ld\n",
threshold); threshold);
return; return;
...@@ -249,7 +249,7 @@ static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold) ...@@ -249,7 +249,7 @@ static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
err = snd_pcm_sw_params (handle, sw_params); err = snd_pcm_sw_params (handle, sw_params);
if (err < 0) { if (err < 0) {
dolog ("Can not fully initialize DAC\n"); dolog ("Could not fully initialize DAC\n");
alsa_logerr (err, "Failed to set software parameters\n"); alsa_logerr (err, "Failed to set software parameters\n");
return; return;
} }
...@@ -344,7 +344,8 @@ static int alsa_open (int in, struct alsa_params_req *req, ...@@ -344,7 +344,8 @@ static int alsa_open (int in, struct alsa_params_req *req,
handle, handle,
hw_params, hw_params,
&period_size, &period_size,
0); 0
);
if (err < 0) { if (err < 0) {
alsa_logerr2 (err, typ, alsa_logerr2 (err, typ,
"Failed to set period time %d\n", "Failed to set period time %d\n",
...@@ -357,7 +358,8 @@ static int alsa_open (int in, struct alsa_params_req *req, ...@@ -357,7 +358,8 @@ static int alsa_open (int in, struct alsa_params_req *req,
handle, handle,
hw_params, hw_params,
&buffer_size, &buffer_size,
0); 0
);
if (err < 0) { if (err < 0) {
alsa_logerr2 (err, typ, alsa_logerr2 (err, typ,
...@@ -382,7 +384,7 @@ static int alsa_open (int in, struct alsa_params_req *req, ...@@ -382,7 +384,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
if (err < 0) { if (err < 0) {
alsa_logerr ( alsa_logerr (
err, err,
"Can not get minmal period size for %s\n", "Could not get minmal period size for %s\n",
typ typ
); );
} }
...@@ -419,7 +421,7 @@ static int alsa_open (int in, struct alsa_params_req *req, ...@@ -419,7 +421,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
&minval &minval
); );
if (err < 0) { if (err < 0) {
alsa_logerr (err, "Can not get minmal buffer size for %s\n", alsa_logerr (err, "Could not get minmal buffer size for %s\n",
typ); typ);
} }
else { else {
...@@ -451,7 +453,7 @@ static int alsa_open (int in, struct alsa_params_req *req, ...@@ -451,7 +453,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
} }
} }
else { else {
dolog ("warning: buffer size is not set\n"); dolog ("warning: Buffer size is not set\n");
} }
err = snd_pcm_hw_params (handle, hw_params); err = snd_pcm_hw_params (handle, hw_params);
...@@ -468,13 +470,13 @@ static int alsa_open (int in, struct alsa_params_req *req, ...@@ -468,13 +470,13 @@ static int alsa_open (int in, struct alsa_params_req *req,
err = snd_pcm_prepare (handle); err = snd_pcm_prepare (handle);
if (err < 0) { if (err < 0) {
alsa_logerr2 (err, typ, "Can not prepare handle %p\n", handle); alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
goto err; goto err;
} }
obt->can_pause = snd_pcm_hw_params_can_pause (hw_params); obt->can_pause = snd_pcm_hw_params_can_pause (hw_params);
if (obt->can_pause < 0) { if (obt->can_pause < 0) {
alsa_logerr (err, "Can not get pause capability for %s\n", typ); alsa_logerr (err, "Could not get pause capability for %s\n", typ);
obt->can_pause = 0; obt->can_pause = 0;
} }
...@@ -493,17 +495,17 @@ static int alsa_open (int in, struct alsa_params_req *req, ...@@ -493,17 +495,17 @@ static int alsa_open (int in, struct alsa_params_req *req,
obt->fmt = req->fmt; obt->fmt = req->fmt;
obt->nchannels = nchannels; obt->nchannels = nchannels;
obt->freq = freq; obt->freq = freq;
obt->buffer_size = snd_pcm_frames_to_bytes (handle, obt_buffer_size); obt->samples = obt_buffer_size;
*handlep = handle; *handlep = handle;
#if defined DEBUG_MISMATCHES || defined DEBUG
if (obt->fmt != req->fmt || if (obt->fmt != req->fmt ||
obt->nchannels != req->nchannels || obt->nchannels != req->nchannels ||
obt->freq != req->freq) { obt->freq != req->freq) {
#ifdef DEBUG_MISMATCHES
dolog ("Audio paramters mismatch for %s\n", typ); dolog ("Audio paramters mismatch for %s\n", typ);
alsa_dump_info (req, obt); alsa_dump_info (req, obt);
#endif
} }
#endif
#ifdef DEBUG #ifdef DEBUG
alsa_dump_info (req, obt); alsa_dump_info (req, obt);
...@@ -550,7 +552,7 @@ static int alsa_run_out (HWVoiceOut *hw) ...@@ -550,7 +552,7 @@ static int alsa_run_out (HWVoiceOut *hw)
} }
} }
alsa_logerr (avail, "Can not get amount free space\n"); alsa_logerr (avail, "Could not get amount free space\n");
return 0; return 0;
} }
...@@ -618,7 +620,7 @@ static void alsa_fini_out (HWVoiceOut *hw) ...@@ -618,7 +620,7 @@ static void alsa_fini_out (HWVoiceOut *hw)
} }
} }
static int alsa_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
{ {
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
struct alsa_params_req req; struct alsa_params_req req;
...@@ -627,10 +629,11 @@ static int alsa_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -627,10 +629,11 @@ static int alsa_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
int endianness; int endianness;
int err; int err;
snd_pcm_t *handle; snd_pcm_t *handle;
audsettings_t obt_as;
req.fmt = aud_to_alsafmt (fmt); req.fmt = aud_to_alsafmt (as->fmt);
req.freq = freq; req.freq = as->freq;
req.nchannels = nchannels; req.nchannels = as->nchannels;
req.period_size = conf.period_size_out; req.period_size = conf.period_size_out;
req.buffer_size = conf.buffer_size_out; req.buffer_size = conf.buffer_size_out;
...@@ -644,18 +647,22 @@ static int alsa_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -644,18 +647,22 @@ static int alsa_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
return -1; return -1;
} }
obt_as.freq = obt.freq;
obt_as.nchannels = obt.nchannels;
obt_as.fmt = effective_fmt;
audio_pcm_init_info ( audio_pcm_init_info (
&hw->info, &hw->info,
obt.freq, &obt_as,
obt.nchannels,
effective_fmt,
audio_need_to_swap_endian (endianness) audio_need_to_swap_endian (endianness)
); );
alsa->can_pause = obt.can_pause; alsa->can_pause = obt.can_pause;
hw->bufsize = obt.buffer_size; hw->samples = obt.samples;
alsa->pcm_buf = qemu_mallocz (hw->bufsize); alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
if (!alsa->pcm_buf) { if (!alsa->pcm_buf) {
dolog ("Could not allocate DAC buffer (%d bytes)\n",
hw->samples << hw->info.shift);
alsa_anal_close (&handle); alsa_anal_close (&handle);
return -1; return -1;
} }
...@@ -703,8 +710,7 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -703,8 +710,7 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
return 0; return 0;
} }
static int alsa_init_in (HWVoiceIn *hw, static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
int freq, int nchannels, audfmt_e fmt)
{ {
ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
struct alsa_params_req req; struct alsa_params_req req;
...@@ -713,10 +719,11 @@ static int alsa_init_in (HWVoiceIn *hw, ...@@ -713,10 +719,11 @@ static int alsa_init_in (HWVoiceIn *hw,
int err; int err;
audfmt_e effective_fmt; audfmt_e effective_fmt;
snd_pcm_t *handle; snd_pcm_t *handle;
audsettings_t obt_as;
req.fmt = aud_to_alsafmt (fmt); req.fmt = aud_to_alsafmt (as->fmt);
req.freq = freq; req.freq = as->freq;
req.nchannels = nchannels; req.nchannels = as->nchannels;
req.period_size = conf.period_size_in; req.period_size = conf.period_size_in;
req.buffer_size = conf.buffer_size_in; req.buffer_size = conf.buffer_size_in;
...@@ -730,17 +737,22 @@ static int alsa_init_in (HWVoiceIn *hw, ...@@ -730,17 +737,22 @@ static int alsa_init_in (HWVoiceIn *hw,
return -1; return -1;
} }
obt_as.freq = obt.freq;
obt_as.nchannels = obt.nchannels;
obt_as.fmt = effective_fmt;
audio_pcm_init_info ( audio_pcm_init_info (
&hw->info, &hw->info,
obt.freq, &obt_as,
obt.nchannels,
effective_fmt,
audio_need_to_swap_endian (endianness) audio_need_to_swap_endian (endianness)
); );
alsa->can_pause = obt.can_pause; alsa->can_pause = obt.can_pause;
hw->bufsize = obt.buffer_size; hw->samples = obt.samples;
alsa->pcm_buf = qemu_mallocz (hw->bufsize);
alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
if (!alsa->pcm_buf) { if (!alsa->pcm_buf) {
dolog ("Could not allocate ADC buffer (%d bytes)\n",
hw->samples << hw->info.shift);
alsa_anal_close (&handle); alsa_anal_close (&handle);
return -1; return -1;
} }
......
此差异已折叠。
...@@ -24,18 +24,33 @@ ...@@ -24,18 +24,33 @@
#ifndef QEMU_AUDIO_H #ifndef QEMU_AUDIO_H
#define QEMU_AUDIO_H #define QEMU_AUDIO_H
#include "sys-queue.h"
typedef void (*audio_callback_fn_t) (void *opaque, int avail); typedef void (*audio_callback_fn_t) (void *opaque, int avail);
typedef enum { typedef enum {
AUD_FMT_U8, AUD_FMT_U8,
AUD_FMT_S8, AUD_FMT_S8,
AUD_FMT_U16, AUD_FMT_U16,
AUD_FMT_S16 AUD_FMT_S16
} audfmt_e; } audfmt_e;
typedef struct {
int freq;
int nchannels;
audfmt_e fmt;
} audsettings_t;
typedef struct AudioState AudioState;
typedef struct SWVoiceOut SWVoiceOut; typedef struct SWVoiceOut SWVoiceOut;
typedef struct SWVoiceIn SWVoiceIn; typedef struct SWVoiceIn SWVoiceIn;
typedef struct QEMUSoundCard {
AudioState *audio;
char *name;
LIST_ENTRY (QEMUSoundCard) entries;
} QEMUSoundCard;
typedef struct QEMUAudioTimeStamp { typedef struct QEMUAudioTimeStamp {
uint64_t old_ts; uint64_t old_ts;
} QEMUAudioTimeStamp; } QEMUAudioTimeStamp;
...@@ -47,46 +62,45 @@ void AUD_log (const char *cap, const char *fmt, ...) ...@@ -47,46 +62,45 @@ void AUD_log (const char *cap, const char *fmt, ...)
#endif #endif
; ;
void AUD_init (void); AudioState *AUD_init (void);
void AUD_help (void); void AUD_help (void);
void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card);
void AUD_remove_card (QEMUSoundCard *card);
SWVoiceOut *AUD_open_out ( SWVoiceOut *AUD_open_out (
QEMUSoundCard *card,
SWVoiceOut *sw, SWVoiceOut *sw,
const char *name, const char *name,
void *callback_opaque, void *callback_opaque,
audio_callback_fn_t callback_fn, audio_callback_fn_t callback_fn,
int freq, audsettings_t *settings
int nchannels,
audfmt_e fmt
); );
void AUD_close_out (SWVoiceOut *sw);
int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size); void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
int AUD_get_buffer_size_out (SWVoiceOut *sw); int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size);
void AUD_set_active_out (SWVoiceOut *sw, int on); int AUD_get_buffer_size_out (SWVoiceOut *sw);
int AUD_is_active_out (SWVoiceOut *sw); void AUD_set_active_out (SWVoiceOut *sw, int on);
void AUD_init_time_stamp_out (SWVoiceOut *sw, int AUD_is_active_out (SWVoiceOut *sw);
QEMUAudioTimeStamp *ts);
uint64_t AUD_time_stamp_get_elapsed_usec_out (SWVoiceOut *sw, void AUD_init_time_stamp_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
QEMUAudioTimeStamp *ts); uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
SWVoiceIn *AUD_open_in ( SWVoiceIn *AUD_open_in (
QEMUSoundCard *card,
SWVoiceIn *sw, SWVoiceIn *sw,
const char *name, const char *name,
void *callback_opaque, void *callback_opaque,
audio_callback_fn_t callback_fn, audio_callback_fn_t callback_fn,
int freq, audsettings_t *settings
int nchannels,
audfmt_e fmt
); );
void AUD_close_in (SWVoiceIn *sw);
int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size); void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
void AUD_adjust_in (SWVoiceIn *sw, int leftover); int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
void AUD_set_active_in (SWVoiceIn *sw, int on); void AUD_set_active_in (SWVoiceIn *sw, int on);
int AUD_is_active_in (SWVoiceIn *sw); int AUD_is_active_in (SWVoiceIn *sw);
void AUD_init_time_stamp_in (SWVoiceIn *sw,
QEMUAudioTimeStamp *ts); void AUD_init_time_stamp_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
uint64_t AUD_time_stamp_get_elapsed_usec_in (SWVoiceIn *sw, uint64_t AUD_get_elapsed_usec_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
QEMUAudioTimeStamp *ts);
static inline void *advance (void *p, int incr) static inline void *advance (void *p, int incr)
{ {
......
...@@ -24,16 +24,12 @@ ...@@ -24,16 +24,12 @@
#ifndef QEMU_AUDIO_INT_H #ifndef QEMU_AUDIO_INT_H
#define QEMU_AUDIO_INT_H #define QEMU_AUDIO_INT_H
#include "sys-queue.h"
#ifdef CONFIG_COREAUDIO #ifdef CONFIG_COREAUDIO
#define FLOAT_MIXENG #define FLOAT_MIXENG
/* #define RECIPROCAL */ /* #define RECIPROCAL */
#endif #endif
#include "mixeng.h" #include "mixeng.h"
int audio_bug (const char *funcname, int cond);
struct audio_pcm_ops; struct audio_pcm_ops;
typedef enum { typedef enum {
...@@ -69,7 +65,6 @@ struct audio_pcm_info { ...@@ -69,7 +65,6 @@ struct audio_pcm_info {
}; };
typedef struct HWVoiceOut { typedef struct HWVoiceOut {
int active;
int enabled; int enabled;
int pending_disable; int pending_disable;
int valid; int valid;
...@@ -78,7 +73,6 @@ typedef struct HWVoiceOut { ...@@ -78,7 +73,6 @@ typedef struct HWVoiceOut {
f_sample *clip; f_sample *clip;
int rpos; int rpos;
int bufsize;
uint64_t ts_helper; uint64_t ts_helper;
st_sample_t *mix_buf; st_sample_t *mix_buf;
...@@ -91,13 +85,11 @@ typedef struct HWVoiceOut { ...@@ -91,13 +85,11 @@ typedef struct HWVoiceOut {
typedef struct HWVoiceIn { typedef struct HWVoiceIn {
int enabled; int enabled;
int active;
struct audio_pcm_info info; struct audio_pcm_info info;
t_sample *conv; t_sample *conv;
int wpos; int wpos;
int bufsize;
int total_samples_captured; int total_samples_captured;
uint64_t ts_helper; uint64_t ts_helper;
...@@ -109,58 +101,6 @@ typedef struct HWVoiceIn { ...@@ -109,58 +101,6 @@ typedef struct HWVoiceIn {
LIST_ENTRY (HWVoiceIn) entries; LIST_ENTRY (HWVoiceIn) entries;
} HWVoiceIn; } HWVoiceIn;
extern struct audio_driver no_audio_driver;
extern struct audio_driver oss_audio_driver;
extern struct audio_driver sdl_audio_driver;
extern struct audio_driver wav_audio_driver;
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 volume_t nominal_volume;
struct audio_driver {
const char *name;
const char *descr;
struct audio_option *options;
void *(*init) (void);
void (*fini) (void *);
struct audio_pcm_ops *pcm_ops;
int can_be_default;
int max_voices_out;
int max_voices_in;
int voice_size_out;
int voice_size_in;
};
typedef struct AudioState {
int fixed_settings_out;
int fixed_freq_out;
int fixed_channels_out;
int fixed_fmt_out;
int nb_hw_voices_out;
int greedy_out;
int fixed_settings_in;
int fixed_freq_in;
int fixed_channels_in;
int fixed_fmt_in;
int nb_hw_voices_in;
int greedy_in;
void *opaque;
struct audio_driver *drv;
QEMUTimer *ts;
union {
int usec;
int64_t ticks;
} period;
int plive;
} AudioState;
extern AudioState audio_state;
struct SWVoiceOut { struct SWVoiceOut {
struct audio_pcm_info info; struct audio_pcm_info info;
t_sample *conv; t_sample *conv;
...@@ -192,22 +132,58 @@ struct SWVoiceIn { ...@@ -192,22 +132,58 @@ struct SWVoiceIn {
LIST_ENTRY (SWVoiceIn) entries; LIST_ENTRY (SWVoiceIn) entries;
}; };
struct audio_driver {
const char *name;
const char *descr;
struct audio_option *options;
void *(*init) (void);
void (*fini) (void *);
struct audio_pcm_ops *pcm_ops;
int can_be_default;
int max_voices_out;
int max_voices_in;
int voice_size_out;
int voice_size_in;
};
struct audio_pcm_ops { struct audio_pcm_ops {
int (*init_out)(HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt); int (*init_out)(HWVoiceOut *hw, audsettings_t *as);
void (*fini_out)(HWVoiceOut *hw); void (*fini_out)(HWVoiceOut *hw);
int (*run_out) (HWVoiceOut *hw); int (*run_out) (HWVoiceOut *hw);
int (*write) (SWVoiceOut *sw, void *buf, int size); int (*write) (SWVoiceOut *sw, void *buf, int size);
int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
int (*init_in) (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt); int (*init_in) (HWVoiceIn *hw, audsettings_t *as);
void (*fini_in) (HWVoiceIn *hw); void (*fini_in) (HWVoiceIn *hw);
int (*run_in) (HWVoiceIn *hw); int (*run_in) (HWVoiceIn *hw);
int (*read) (SWVoiceIn *sw, void *buf, int size); int (*read) (SWVoiceIn *sw, void *buf, int size);
int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
}; };
void audio_pcm_init_info (struct audio_pcm_info *info, int freq, struct AudioState {
int nchannels, audfmt_e fmt, int swap_endian); struct audio_driver *drv;
void *drv_opaque;
QEMUTimer *ts;
LIST_HEAD (card_head, QEMUSoundCard) card_head;
LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
int nb_hw_voices_out;
int nb_hw_voices_in;
};
extern struct audio_driver no_audio_driver;
extern struct audio_driver oss_audio_driver;
extern struct audio_driver sdl_audio_driver;
extern struct audio_driver wav_audio_driver;
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 volume_t nominal_volume;
void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as,
int swap_endian);
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len); void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len); int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
...@@ -217,6 +193,9 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len); ...@@ -217,6 +193,9 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
int audio_pcm_hw_get_live_out (HWVoiceOut *hw); int audio_pcm_hw_get_live_out (HWVoiceOut *hw);
int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live); int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live);
int audio_bug (const char *funcname, int cond);
void *audio_calloc (const char *funcname, int nmemb, size_t size);
#define VOICE_ENABLE 1 #define VOICE_ENABLE 1
#define VOICE_DISABLE 2 #define VOICE_DISABLE 2
......
...@@ -32,6 +32,43 @@ ...@@ -32,6 +32,43 @@
#define SW glue (SWVoice, In) #define SW glue (SWVoice, In)
#endif #endif
static int glue (audio_pcm_hw_init_, TYPE) (
HW *hw,
audsettings_t *as
)
{
glue (audio_pcm_hw_free_resources_, TYPE) (hw);
if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
return -1;
}
if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
dolog ("hw->samples=%d\n", hw->samples);
return -1;
}
LIST_INIT (&hw->sw_head);
#ifdef DAC
hw->clip =
mixeng_clip
#else
hw->conv =
mixeng_conv
#endif
[hw->info.nchannels == 2]
[hw->info.sign]
[hw->info.swap_endian]
[hw->info.bits == 16];
if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
glue (hw->pcm_ops->fini_, TYPE) (hw);
return -1;
}
return 0;
}
static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw) static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
{ {
glue (audio_pcm_sw_free_resources_, TYPE) (sw); glue (audio_pcm_sw_free_resources_, TYPE) (sw);
...@@ -51,89 +88,86 @@ static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw) ...@@ -51,89 +88,86 @@ static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
LIST_REMOVE (sw, entries); LIST_REMOVE (sw, entries);
} }
static void glue (audio_pcm_hw_fini_, TYPE) (HW *hw) static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
{ {
if (hw->active) { HW *hw = *hwp;
glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
glue (hw->pcm_ops->fini_, TYPE) (hw);
memset (hw, 0, glue (audio_state.drv->voice_size_, TYPE));
}
}
static void glue (audio_pcm_hw_gc_, TYPE) (HW *hw)
{
if (!hw->sw_head.lh_first) { if (!hw->sw_head.lh_first) {
glue (audio_pcm_hw_fini_, TYPE) (hw); LIST_REMOVE (hw, entries);
glue (s->nb_hw_voices_, TYPE) += 1;
glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
glue (hw->pcm_ops->fini_, TYPE) (hw);
qemu_free (hw);
*hwp = NULL;
} }
} }
static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw) static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
{ {
return hw ? hw->entries.le_next : glue (hw_head_, TYPE).lh_first; return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
} }
static HW *glue (audio_pcm_hw_find_any_active_, TYPE) (HW *hw) static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
{ {
while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
if (hw->active) { if (hw->enabled) {
return hw; return hw;
} }
} }
return NULL; return NULL;
} }
static HW *glue (audio_pcm_hw_find_any_active_enabled_, TYPE) (HW *hw) static HW *glue (audio_pcm_hw_find_any_passive_, TYPE) (AudioState *s)
{ {
while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { if (glue (s->nb_hw_voices_, TYPE)) {
if (hw->active && hw->enabled) { struct audio_driver *drv = s->drv;
return hw;
if (audio_bug (AUDIO_FUNC, !drv)) {
dolog ("No host audio driver\n");
return NULL;
} }
}
return NULL;
}
static HW *glue (audio_pcm_hw_find_any_passive_, TYPE) (HW *hw) HW *hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
{ if (!hw) {
while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { dolog ("Can not allocate voice `%s' size %d\n",
if (!hw->active) { drv->name, glue (drv->voice_size_, TYPE));
return hw;
} }
LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
glue (s->nb_hw_voices_, TYPE) -= 1;
return hw;
} }
return NULL; return NULL;
} }
static HW *glue (audio_pcm_hw_find_specific_, TYPE) ( static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
AudioState *s,
HW *hw, HW *hw,
int freq, audsettings_t *as
int nchannels,
audfmt_e fmt
) )
{ {
while ((hw = glue (audio_pcm_hw_find_any_active_, TYPE) (hw))) { while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
if (audio_pcm_info_eq (&hw->info, freq, nchannels, fmt)) { if (audio_pcm_info_eq (&hw->info, as)) {
return hw; return hw;
} }
} }
return NULL; return NULL;
} }
static HW *glue (audio_pcm_hw_add_new_, TYPE) ( static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
int freq,
int nchannels,
audfmt_e fmt
)
{ {
HW *hw; HW *hw;
hw = glue (audio_pcm_hw_find_any_passive_, TYPE) (NULL); hw = glue (audio_pcm_hw_find_any_passive_, TYPE) (s);
if (hw) { if (hw) {
hw->pcm_ops = audio_state.drv->pcm_ops; hw->pcm_ops = s->drv->pcm_ops;
if (!hw->pcm_ops) { if (!hw->pcm_ops) {
return NULL; return NULL;
} }
if (glue (audio_pcm_hw_init_, TYPE) (hw, freq, nchannels, fmt)) { if (glue (audio_pcm_hw_init_, TYPE) (hw, as)) {
glue (audio_pcm_hw_gc_, TYPE) (hw); glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
return NULL; return NULL;
} }
else { else {
...@@ -144,66 +178,62 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) ( ...@@ -144,66 +178,62 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (
return NULL; return NULL;
} }
static HW *glue (audio_pcm_hw_add_, TYPE) ( static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
int freq,
int nchannels,
audfmt_e fmt
)
{ {
HW *hw; HW *hw;
if (glue (audio_state.greedy_, TYPE)) { if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
hw = glue (audio_pcm_hw_add_new_, TYPE) (freq, nchannels, fmt); hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
if (hw) { if (hw) {
return hw; return hw;
} }
} }
hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, freq, nchannels, fmt); hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
if (hw) { if (hw) {
return hw; return hw;
} }
hw = glue (audio_pcm_hw_add_new_, TYPE) (freq, nchannels, fmt); hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
if (hw) { if (hw) {
return hw; return hw;
} }
return glue (audio_pcm_hw_find_any_active_, TYPE) (NULL); return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
} }
static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
const char *name, AudioState *s,
int freq, const char *sw_name,
int nchannels, audsettings_t *as
audfmt_e fmt
) )
{ {
SW *sw; SW *sw;
HW *hw; HW *hw;
int hw_freq = freq; audsettings_t hw_as;
int hw_nchannels = nchannels;
int hw_fmt = fmt;
if (glue (audio_state.fixed_settings_, TYPE)) { if (glue (conf.fixed_, TYPE).enabled) {
hw_freq = glue (audio_state.fixed_freq_, TYPE); hw_as = glue (conf.fixed_, TYPE).settings;
hw_nchannels = glue (audio_state.fixed_channels_, TYPE); }
hw_fmt = glue (audio_state.fixed_fmt_, TYPE); else {
hw_as = *as;
} }
sw = qemu_mallocz (sizeof (*sw)); sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
if (!sw) { if (!sw) {
dolog ("Could not allocate soft voice `%s' (%d bytes)\n",
sw_name ? sw_name : "unknown", sizeof (*sw));
goto err1; goto err1;
} }
hw = glue (audio_pcm_hw_add_, TYPE) (hw_freq, hw_nchannels, hw_fmt); hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
if (!hw) { if (!hw) {
goto err2; goto err2;
} }
glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw); glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, freq, nchannels, fmt)) { if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
goto err3; goto err3;
} }
...@@ -211,67 +241,86 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( ...@@ -211,67 +241,86 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
err3: err3:
glue (audio_pcm_hw_del_sw_, TYPE) (sw); glue (audio_pcm_hw_del_sw_, TYPE) (sw);
glue (audio_pcm_hw_gc_, TYPE) (hw); glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
err2: err2:
qemu_free (sw); qemu_free (sw);
err1: err1:
return NULL; return NULL;
} }
void glue (AUD_close_, TYPE) (SW *sw) static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
{
glue (audio_pcm_sw_fini_, TYPE) (sw);
glue (audio_pcm_hw_del_sw_, TYPE) (sw);
glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
qemu_free (sw);
}
void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
{ {
if (sw) { if (sw) {
glue (audio_pcm_sw_fini_, TYPE) (sw); if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
glue (audio_pcm_hw_del_sw_, TYPE) (sw); dolog ("card=%p card->audio=%p\n",
glue (audio_pcm_hw_gc_, TYPE) (sw->hw); card, card ? card->audio : NULL);
qemu_free (sw); return;
}
glue (audio_close_, TYPE) (card->audio, sw);
} }
} }
SW *glue (AUD_open_, TYPE) ( SW *glue (AUD_open_, TYPE) (
QEMUSoundCard *card,
SW *sw, SW *sw,
const char *name, const char *name,
void *callback_opaque , void *callback_opaque ,
audio_callback_fn_t callback_fn, audio_callback_fn_t callback_fn,
int freq, audsettings_t *as
int nchannels,
audfmt_e fmt
) )
{ {
AudioState *s;
#ifdef DAC #ifdef DAC
int live = 0; int live = 0;
SW *old_sw = NULL; SW *old_sw = NULL;
#endif #endif
if (!callback_fn) { ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
dolog ("No callback specifed for voice `%s'\n", name); name, as->freq, as->nchannels, as->fmt);
if (audio_bug (AUDIO_FUNC,
!card || !card->audio || !name || !callback_fn || !as)) {
dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
card, card ? card->audio : NULL, name, callback_fn, as);
goto fail; goto fail;
} }
if (nchannels != 1 && nchannels != 2) { s = card->audio;
dolog ("Bogus channel count %d for voice `%s'\n", nchannels, name);
if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
audio_print_settings (as);
goto fail; goto fail;
} }
if (!audio_state.drv) { if (audio_bug (AUDIO_FUNC, !s->drv)) {
dolog ("No audio driver defined\n"); dolog ("Can not open `%s' (no host audio driver)\n", name);
goto fail; goto fail;
} }
if (sw && audio_pcm_info_eq (&sw->info, freq, nchannels, fmt)) { if (sw && audio_pcm_info_eq (&sw->info, as)) {
return sw; return sw;
} }
#ifdef DAC #ifdef DAC
if (audio_state.plive && sw && (!sw->active && !sw->empty)) { if (conf.plive && sw && (!sw->active && !sw->empty)) {
live = sw->total_hw_samples_mixed; live = sw->total_hw_samples_mixed;
#ifdef DEBUG_PLIVE #ifdef DEBUG_PLIVE
dolog ("Replacing voice %s with %d live samples\n", sw->name, live); dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
dolog ("Old %s freq %d, bits %d, channels %d\n", dolog ("Old %s freq %d, bits %d, channels %d\n",
sw->name, sw->info.freq, sw->info.bits, sw->info.nchannels); SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
dolog ("New %s freq %d, bits %d, channels %d\n", dolog ("New %s freq %d, bits %d, channels %d\n",
name, freq, (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8, name,
freq,
(fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
nchannels); nchannels);
#endif #endif
...@@ -283,8 +332,8 @@ SW *glue (AUD_open_, TYPE) ( ...@@ -283,8 +332,8 @@ SW *glue (AUD_open_, TYPE) (
} }
#endif #endif
if (!glue (audio_state.fixed_settings_, TYPE) && sw) { if (!glue (conf.fixed_, TYPE).enabled && sw) {
glue (AUD_close_, TYPE) (sw); glue (AUD_close_, TYPE) (card, sw);
sw = NULL; sw = NULL;
} }
...@@ -292,30 +341,19 @@ SW *glue (AUD_open_, TYPE) ( ...@@ -292,30 +341,19 @@ SW *glue (AUD_open_, TYPE) (
HW *hw = sw->hw; HW *hw = sw->hw;
if (!hw) { if (!hw) {
dolog ("Internal logic error voice %s has no hardware store\n", dolog ("Internal logic error voice `%s' has no hardware store\n",
name); SW_NAME (sw));
goto fail; goto fail;
} }
if (glue (audio_pcm_sw_init_, TYPE) ( if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
sw,
hw,
name,
freq,
nchannels,
fmt
)) {
goto fail; goto fail;
} }
} }
else { else {
sw = glue (audio_pcm_create_voice_pair_, TYPE) ( sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
name,
freq,
nchannels,
fmt);
if (!sw) { if (!sw) {
dolog ("Failed to create voice %s\n", name); dolog ("Failed to create voice `%s'\n", name);
goto fail; goto fail;
} }
} }
...@@ -349,7 +387,7 @@ SW *glue (AUD_open_, TYPE) ( ...@@ -349,7 +387,7 @@ SW *glue (AUD_open_, TYPE) (
return sw; return sw;
fail: fail:
glue (AUD_close_, TYPE) (sw); glue (AUD_close_, TYPE) (card, sw);
return NULL; return NULL;
} }
...@@ -367,10 +405,7 @@ void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts) ...@@ -367,10 +405,7 @@ void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
ts->old_ts = sw->hw->ts_helper; ts->old_ts = sw->hw->ts_helper;
} }
uint64_t glue (AUD_time_stamp_get_elapsed_usec_, TYPE) ( uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
SW *sw,
QEMUAudioTimeStamp *ts
)
{ {
uint64_t delta, cur_ts, old_ts; uint64_t delta, cur_ts, old_ts;
......
...@@ -31,8 +31,6 @@ ...@@ -31,8 +31,6 @@
#define AUDIO_CAP "coreaudio" #define AUDIO_CAP "coreaudio"
#include "audio_int.h" #include "audio_int.h"
#define DEVICE_BUFFER_FRAMES (512)
struct { struct {
int buffer_frames; int buffer_frames;
} conf = { } conf = {
...@@ -132,7 +130,7 @@ static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 ( ...@@ -132,7 +130,7 @@ static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
{ {
va_list ap; va_list ap;
AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ); AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
va_start (ap, fmt); va_start (ap, fmt);
AUD_vlog (AUDIO_CAP, fmt, ap); AUD_vlog (AUDIO_CAP, fmt, ap);
...@@ -147,7 +145,7 @@ static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name) ...@@ -147,7 +145,7 @@ static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
err = pthread_mutex_lock (&core->mutex); err = pthread_mutex_lock (&core->mutex);
if (err) { if (err) {
dolog ("Can not lock voice for %s\nReason: %s\n", dolog ("Could not lock voice for %s\nReason: %s\n",
fn_name, strerror (err)); fn_name, strerror (err));
return -1; return -1;
} }
...@@ -160,7 +158,7 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name) ...@@ -160,7 +158,7 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
err = pthread_mutex_unlock (&core->mutex); err = pthread_mutex_unlock (&core->mutex);
if (err) { if (err) {
dolog ("Can not unlock voice for %s\nReason: %s\n", dolog ("Could not unlock voice for %s\nReason: %s\n",
fn_name, strerror (err)); fn_name, strerror (err));
return -1; return -1;
} }
...@@ -268,8 +266,7 @@ static int coreaudio_write (SWVoiceOut *sw, void *buf, int len) ...@@ -268,8 +266,7 @@ static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
return audio_pcm_sw_write (sw, buf, len); return audio_pcm_sw_write (sw, buf, len);
} }
static int coreaudio_init_out (HWVoiceOut *hw, int freq, static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
int nchannels, audfmt_e fmt)
{ {
OSStatus status; OSStatus status;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
...@@ -282,25 +279,22 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -282,25 +279,22 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
/* create mutex */ /* create mutex */
err = pthread_mutex_init(&core->mutex, NULL); err = pthread_mutex_init(&core->mutex, NULL);
if (err) { if (err) {
dolog("Can not create mutex\nReason: %s\n", strerror (err)); dolog("Could not create mutex\nReason: %s\n", strerror (err));
return -1; return -1;
} }
if (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) { if (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) {
bits = 16; bits = 16;
endianess = 1; endianess = 1;
} }
audio_pcm_init_info ( audio_pcm_init_info (
&hw->info, &hw->info,
freq, as,
nchannels,
fmt,
/* Following is irrelevant actually since we do not use /* Following is irrelevant actually since we do not use
mixengs clipping routines */ mixengs clipping routines */
audio_need_to_swap_endian (endianess) audio_need_to_swap_endian (endianess)
); );
hw->bufsize = 4 * conf.buffer_frames * nchannels * bits;
/* open default output device */ /* open default output device */
propertySize = sizeof(core->outputDeviceID); propertySize = sizeof(core->outputDeviceID);
...@@ -310,18 +304,18 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -310,18 +304,18 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
&core->outputDeviceID); &core->outputDeviceID);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Can not get default output Device\n"); "Could not get default output Device\n");
return -1; return -1;
} }
if (core->outputDeviceID == kAudioDeviceUnknown) { if (core->outputDeviceID == kAudioDeviceUnknown) {
dolog ("Can not initialize %s - Unknown Audiodevice\n", typ); dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
return -1; return -1;
} }
/* set Buffersize to conf.buffer_frames frames */ /* set Buffersize to conf.buffer_frames frames */
propertySize = sizeof(core->audioDevicePropertyBufferSize); propertySize = sizeof(core->audioDevicePropertyBufferSize);
core->audioDevicePropertyBufferSize = core->audioDevicePropertyBufferSize =
conf.buffer_frames * sizeof(float) * 2; conf.buffer_frames * sizeof(float) << (as->nchannels == 2);
status = AudioDeviceSetProperty( status = AudioDeviceSetProperty(
core->outputDeviceID, core->outputDeviceID,
NULL, NULL,
...@@ -332,7 +326,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -332,7 +326,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
&core->audioDevicePropertyBufferSize); &core->audioDevicePropertyBufferSize);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Can not set device buffer size %d\n", "Could not set device buffer size %d\n",
kAudioDevicePropertyBufferSize); kAudioDevicePropertyBufferSize);
return -1; return -1;
} }
...@@ -347,9 +341,11 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -347,9 +341,11 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
&propertySize, &propertySize,
&core->audioDevicePropertyBufferSize); &core->audioDevicePropertyBufferSize);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Can not get device buffer size\n"); coreaudio_logerr2 (status, typ, "Could not get device buffer size\n");
return -1; return -1;
} }
hw->samples = (core->audioDevicePropertyBufferSize / sizeof (float))
>> (as->nchannels == 2);
/* get StreamFormat */ /* get StreamFormat */
propertySize = sizeof(core->outputStreamBasicDescription); propertySize = sizeof(core->outputStreamBasicDescription);
...@@ -362,13 +358,13 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -362,13 +358,13 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
&core->outputStreamBasicDescription); &core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Can not get Device Stream properties\n"); "Could not get Device Stream properties\n");
core->outputDeviceID = kAudioDeviceUnknown; core->outputDeviceID = kAudioDeviceUnknown;
return -1; return -1;
} }
/* set Samplerate */ /* set Samplerate */
core->outputStreamBasicDescription.mSampleRate = (Float64)freq; core->outputStreamBasicDescription.mSampleRate = (Float64)as->freq;
propertySize = sizeof(core->outputStreamBasicDescription); propertySize = sizeof(core->outputStreamBasicDescription);
status = AudioDeviceSetProperty( status = AudioDeviceSetProperty(
core->outputDeviceID, core->outputDeviceID,
...@@ -379,7 +375,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -379,7 +375,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
propertySize, propertySize,
&core->outputStreamBasicDescription); &core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Can not set samplerate %d\n", freq); coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n", freq);
core->outputDeviceID = kAudioDeviceUnknown; core->outputDeviceID = kAudioDeviceUnknown;
return -1; return -1;
} }
...@@ -387,7 +383,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -387,7 +383,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
/* set Callback */ /* set Callback */
status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw); status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Can not set IOProc\n"); coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
core->outputDeviceID = kAudioDeviceUnknown; core->outputDeviceID = kAudioDeviceUnknown;
return -1; return -1;
} }
...@@ -396,7 +392,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq, ...@@ -396,7 +392,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, int freq,
if (!core->isPlaying) { if (!core->isPlaying) {
status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Can not start playback\n"); coreaudio_logerr2 (status, typ, "Could not start playback\n");
AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc); AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
core->outputDeviceID = kAudioDeviceUnknown; core->outputDeviceID = kAudioDeviceUnknown;
return -1; return -1;
...@@ -417,7 +413,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw) ...@@ -417,7 +413,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
if (core->isPlaying) { if (core->isPlaying) {
status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Can not stop playback\n"); coreaudio_logerr (status, "Could not stop playback\n");
} }
core->isPlaying = 0; core->isPlaying = 0;
} }
...@@ -425,14 +421,14 @@ static void coreaudio_fini_out (HWVoiceOut *hw) ...@@ -425,14 +421,14 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
/* remove callback */ /* remove callback */
status = AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Can not remove IOProc\n"); coreaudio_logerr (status, "Could not remove IOProc\n");
} }
core->outputDeviceID = kAudioDeviceUnknown; core->outputDeviceID = kAudioDeviceUnknown;
/* destroy mutex */ /* destroy mutex */
err = pthread_mutex_destroy(&core->mutex); err = pthread_mutex_destroy(&core->mutex);
if (err) { if (err) {
dolog("Can not destroy mutex\nReason: %s\n", strerror (err)); dolog("Could not destroy mutex\nReason: %s\n", strerror (err));
} }
} }
...@@ -447,7 +443,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -447,7 +443,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
if (!core->isPlaying) { if (!core->isPlaying) {
status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Can not unpause playback\n"); coreaudio_logerr (status, "Could not unpause playback\n");
} }
core->isPlaying = 1; core->isPlaying = 1;
} }
...@@ -458,7 +454,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -458,7 +454,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
if (core->isPlaying) { if (core->isPlaying) {
status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Can not pause playback\n"); coreaudio_logerr (status, "Could not pause playback\n");
} }
core->isPlaying = 0; core->isPlaying = 0;
} }
......
...@@ -47,7 +47,7 @@ static int glue (dsound_unlock_, TYPE) ( ...@@ -47,7 +47,7 @@ static int glue (dsound_unlock_, TYPE) (
hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2); hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not unlock " NAME "\n"); dsound_logerr (hr, "Could not unlock " NAME "\n");
return -1; return -1;
} }
...@@ -93,13 +93,13 @@ static int glue (dsound_lock_, TYPE) ( ...@@ -93,13 +93,13 @@ static int glue (dsound_lock_, TYPE) (
#ifndef DSBTYPE_IN #ifndef DSBTYPE_IN
if (hr == DSERR_BUFFERLOST) { if (hr == DSERR_BUFFERLOST) {
if (glue (dsound_restore_, TYPE) (buf)) { if (glue (dsound_restore_, TYPE) (buf)) {
dsound_logerr (hr, "Can not lock " NAME "\n"); dsound_logerr (hr, "Could not lock " NAME "\n");
goto fail; goto fail;
} }
continue; continue;
} }
#endif #endif
dsound_logerr (hr, "Can not lock " NAME "\n"); dsound_logerr (hr, "Could not lock " NAME "\n");
goto fail; goto fail;
} }
...@@ -158,38 +158,28 @@ static void dsound_fini_out (HWVoiceOut *hw) ...@@ -158,38 +158,28 @@ static void dsound_fini_out (HWVoiceOut *hw)
if (ds->FIELD) { if (ds->FIELD) {
hr = glue (IFACE, _Stop) (ds->FIELD); hr = glue (IFACE, _Stop) (ds->FIELD);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not stop " NAME "\n"); dsound_logerr (hr, "Could not stop " NAME "\n");
} }
hr = glue (IFACE, _Release) (ds->FIELD); hr = glue (IFACE, _Release) (ds->FIELD);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not release " NAME "\n"); dsound_logerr (hr, "Could not release " NAME "\n");
} }
ds->FIELD = NULL; ds->FIELD = NULL;
} }
} }
#ifdef DSBTYPE_IN #ifdef DSBTYPE_IN
static int dsound_init_in ( static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
HWVoiceIn *hw,
int freq,
int nchannels,
audfmt_e fmt
)
#else #else
static int dsound_init_out ( static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
HWVoiceOut *hw,
int freq,
int nchannels,
audfmt_e fmt
)
#endif #endif
{ {
int err; int err;
HRESULT hr; HRESULT hr;
dsound *s = &glob_dsound; dsound *s = &glob_dsound;
WAVEFORMATEX wfx; WAVEFORMATEX wfx;
struct full_fmt full_fmt; audsettings_t obt_as;
#ifdef DSBTYPE_IN #ifdef DSBTYPE_IN
const char *typ = "ADC"; const char *typ = "ADC";
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
...@@ -202,10 +192,7 @@ static int dsound_init_out ( ...@@ -202,10 +192,7 @@ static int dsound_init_out (
DSBCAPS bc; DSBCAPS bc;
#endif #endif
full_fmt.freq = freq; err = waveformat_from_audio_settings (&wfx, as);
full_fmt.nchannels = nchannels;
full_fmt.fmt = fmt;
err = waveformat_from_full_fmt (&wfx, &full_fmt);
if (err) { if (err) {
return -1; return -1;
} }
...@@ -233,18 +220,13 @@ static int dsound_init_out ( ...@@ -233,18 +220,13 @@ static int dsound_init_out (
#endif #endif
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr2 (hr, typ, "Can not create " NAME "\n"); dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
return -1; return -1;
} }
hr = glue (IFACE, _GetFormat) ( hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
ds->FIELD,
&wfx,
sizeof (wfx),
NULL
);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr2 (hr, typ, "Can not get " NAME " format\n"); dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
goto fail0; goto fail0;
} }
...@@ -258,31 +240,33 @@ static int dsound_init_out ( ...@@ -258,31 +240,33 @@ static int dsound_init_out (
hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc); hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr2 (hr, typ, "Can not get " NAME " format\n"); dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
goto fail0; goto fail0;
} }
err = waveformat_to_full_fmt (&wfx, &full_fmt); err = waveformat_to_audio_settings (&wfx, &obt_as);
if (err) { if (err) {
goto fail0; goto fail0;
} }
ds->first_time = 1; ds->first_time = 1;
hw->bufsize = bc.dwBufferBytes;
audio_pcm_init_info ( audio_pcm_init_info (&hw->info, &obt_as, audio_need_to_swap_endian (0));
&hw->info,
full_fmt.freq, if (bc.dwBufferBytes & hw->info.align) {
full_fmt.nchannels, dolog (
full_fmt.fmt, "GetCaps returned misaligned buffer size %ld, alignment %d\n",
audio_need_to_swap_endian (0) bc.dwBufferBytes, hw->info.align + 1
); );
}
hw->samples = bc.dwBufferBytes >> hw->info.shift;
#ifdef DEBUG_DSOUND #ifdef DEBUG_DSOUND
dolog ("caps %ld, desc %ld\n", dolog ("caps %ld, desc %ld\n",
bc.dwBufferBytes, bd.dwBufferBytes); bc.dwBufferBytes, bd.dwBufferBytes);
dolog ("bufsize %d, freq %d, chan %d, fmt %d\n", dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
hw->bufsize, full_fmt.freq, full_fmt.nchannels, full_fmt.fmt); hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
#endif #endif
return 0; return 0;
......
...@@ -37,12 +37,6 @@ ...@@ -37,12 +37,6 @@
/* #define DEBUG_DSOUND */ /* #define DEBUG_DSOUND */
struct full_fmt {
int freq;
int nchannels;
audfmt_e fmt;
};
static struct { static struct {
int lock_retries; int lock_retries;
int restore_retries; int restore_retries;
...@@ -50,7 +44,7 @@ static struct { ...@@ -50,7 +44,7 @@ static struct {
int set_primary; int set_primary;
int bufsize_in; int bufsize_in;
int bufsize_out; int bufsize_out;
struct full_fmt full_fmt; audsettings_t settings;
int latency_millis; int latency_millis;
} conf = { } conf = {
1, 1,
...@@ -71,7 +65,7 @@ typedef struct { ...@@ -71,7 +65,7 @@ typedef struct {
LPDIRECTSOUND dsound; LPDIRECTSOUND dsound;
LPDIRECTSOUNDCAPTURE dsound_capture; LPDIRECTSOUNDCAPTURE dsound_capture;
LPDIRECTSOUNDBUFFER dsound_primary_buffer; LPDIRECTSOUNDBUFFER dsound_primary_buffer;
struct full_fmt fmt; audsettings_t settings;
} dsound; } dsound;
static dsound glob_dsound; static dsound glob_dsound;
...@@ -259,7 +253,7 @@ static void GCC_FMT_ATTR (3, 4) dsound_logerr2 ( ...@@ -259,7 +253,7 @@ static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
{ {
va_list ap; va_list ap;
AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ); AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
va_start (ap, fmt); va_start (ap, fmt);
AUD_vlog (AUDIO_CAP, fmt, ap); AUD_vlog (AUDIO_CAP, fmt, ap);
va_end (ap); va_end (ap);
...@@ -301,7 +295,7 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb) ...@@ -301,7 +295,7 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
continue; continue;
default: default:
dsound_logerr (hr, "Can not restore playback buffer\n"); dsound_logerr (hr, "Could not restore playback buffer\n");
return -1; return -1;
} }
} }
...@@ -310,19 +304,18 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb) ...@@ -310,19 +304,18 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
return -1; return -1;
} }
static int waveformat_from_full_fmt (WAVEFORMATEX *wfx, static int waveformat_from_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
struct full_fmt *full_fmt)
{ {
memset (wfx, 0, sizeof (*wfx)); memset (wfx, 0, sizeof (*wfx));
wfx->wFormatTag = WAVE_FORMAT_PCM; wfx->wFormatTag = WAVE_FORMAT_PCM;
wfx->nChannels = full_fmt->nchannels; wfx->nChannels = as->nchannels;
wfx->nSamplesPerSec = full_fmt->freq; wfx->nSamplesPerSec = as->freq;
wfx->nAvgBytesPerSec = full_fmt->freq << (full_fmt->nchannels == 2); wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
wfx->nBlockAlign = 1 << (full_fmt->nchannels == 2); wfx->nBlockAlign = 1 << (as->nchannels == 2);
wfx->cbSize = 0; wfx->cbSize = 0;
switch (full_fmt->fmt) { switch (as->fmt) {
case AUD_FMT_S8: case AUD_FMT_S8:
wfx->wBitsPerSample = 8; wfx->wBitsPerSample = 8;
break; break;
...@@ -344,16 +337,14 @@ static int waveformat_from_full_fmt (WAVEFORMATEX *wfx, ...@@ -344,16 +337,14 @@ static int waveformat_from_full_fmt (WAVEFORMATEX *wfx,
break; break;
default: default:
dolog ("Internal logic error: Bad audio format %d\n", dolog ("Internal logic error: Bad audio format %d\n", as->freq);
full_fmt->freq);
return -1; return -1;
} }
return 0; return 0;
} }
static int waveformat_to_full_fmt (WAVEFORMATEX *wfx, static int waveformat_to_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
struct full_fmt *full_fmt)
{ {
if (wfx->wFormatTag != WAVE_FORMAT_PCM) { if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
dolog ("Invalid wave format, tag is not PCM, but %d\n", dolog ("Invalid wave format, tag is not PCM, but %d\n",
...@@ -365,15 +356,15 @@ static int waveformat_to_full_fmt (WAVEFORMATEX *wfx, ...@@ -365,15 +356,15 @@ static int waveformat_to_full_fmt (WAVEFORMATEX *wfx,
dolog ("Invalid wave format, frequency is zero\n"); dolog ("Invalid wave format, frequency is zero\n");
return -1; return -1;
} }
full_fmt->freq = wfx->nSamplesPerSec; as->freq = wfx->nSamplesPerSec;
switch (wfx->nChannels) { switch (wfx->nChannels) {
case 1: case 1:
full_fmt->nchannels = 1; as->nchannels = 1;
break; break;
case 2: case 2:
full_fmt->nchannels = 2; as->nchannels = 2;
break; break;
default: default:
...@@ -386,11 +377,11 @@ static int waveformat_to_full_fmt (WAVEFORMATEX *wfx, ...@@ -386,11 +377,11 @@ static int waveformat_to_full_fmt (WAVEFORMATEX *wfx,
switch (wfx->wBitsPerSample) { switch (wfx->wBitsPerSample) {
case 8: case 8:
full_fmt->fmt = AUD_FMT_U8; as->fmt = AUD_FMT_U8;
break; break;
case 16: case 16:
full_fmt->fmt = AUD_FMT_S16; as->fmt = AUD_FMT_S16;
break; break;
default: default:
...@@ -415,7 +406,7 @@ static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp) ...@@ -415,7 +406,7 @@ static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
for (i = 0; i < conf.getstatus_retries; ++i) { for (i = 0; i < conf.getstatus_retries; ++i) {
hr = IDirectSoundBuffer_GetStatus (dsb, statusp); hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not get playback buffer status\n"); dsound_logerr (hr, "Could not get playback buffer status\n");
return -1; return -1;
} }
...@@ -438,7 +429,7 @@ static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb, ...@@ -438,7 +429,7 @@ static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
hr = IDirectSoundCaptureBuffer_GetStatus (dscb, statusp); hr = IDirectSoundCaptureBuffer_GetStatus (dscb, statusp);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not get capture buffer status\n"); dsound_logerr (hr, "Could not get capture buffer status\n");
return -1; return -1;
} }
...@@ -520,7 +511,7 @@ static void dsound_close (dsound *s) ...@@ -520,7 +511,7 @@ static void dsound_close (dsound *s)
if (s->dsound_primary_buffer) { if (s->dsound_primary_buffer) {
hr = IDirectSoundBuffer_Release (s->dsound_primary_buffer); hr = IDirectSoundBuffer_Release (s->dsound_primary_buffer);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not release primary buffer\n"); dsound_logerr (hr, "Could not release primary buffer\n");
} }
s->dsound_primary_buffer = NULL; s->dsound_primary_buffer = NULL;
} }
...@@ -542,7 +533,7 @@ static int dsound_open (dsound *s) ...@@ -542,7 +533,7 @@ static int dsound_open (dsound *s)
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not set cooperative level for window %p\n", dsound_logerr (hr, "Could not set cooperative level for window %p\n",
hwnd); hwnd);
return -1; return -1;
} }
...@@ -551,7 +542,7 @@ static int dsound_open (dsound *s) ...@@ -551,7 +542,7 @@ static int dsound_open (dsound *s)
return 0; return 0;
} }
err = waveformat_from_full_fmt (&wfx, &conf.full_fmt); err = waveformat_from_audio_settings (&wfx, &conf.settings);
if (err) { if (err) {
return -1; return -1;
} }
...@@ -569,13 +560,13 @@ static int dsound_open (dsound *s) ...@@ -569,13 +560,13 @@ static int dsound_open (dsound *s)
NULL NULL
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not create primary playback buffer\n"); dsound_logerr (hr, "Could not create primary playback buffer\n");
return -1; return -1;
} }
hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx); hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not set primary playback buffer format\n"); dsound_logerr (hr, "Could not set primary playback buffer format\n");
} }
hr = IDirectSoundBuffer_GetFormat ( hr = IDirectSoundBuffer_GetFormat (
...@@ -585,7 +576,7 @@ static int dsound_open (dsound *s) ...@@ -585,7 +576,7 @@ static int dsound_open (dsound *s)
NULL NULL
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not get primary playback buffer format\n"); dsound_logerr (hr, "Could not get primary playback buffer format\n");
goto fail0; goto fail0;
} }
...@@ -594,7 +585,7 @@ static int dsound_open (dsound *s) ...@@ -594,7 +585,7 @@ static int dsound_open (dsound *s)
print_wave_format (&wfx); print_wave_format (&wfx);
#endif #endif
err = waveformat_to_full_fmt (&wfx, &s->fmt); err = waveformat_to_audio_settings (&wfx, &s->settings);
if (err) { if (err) {
goto fail0; goto fail0;
} }
...@@ -625,7 +616,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -625,7 +616,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
} }
if (status & DSBSTATUS_PLAYING) { if (status & DSBSTATUS_PLAYING) {
dolog ("warning: voice is already playing\n"); dolog ("warning: Voice is already playing\n");
return 0; return 0;
} }
...@@ -633,7 +624,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -633,7 +624,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING); hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not start playing buffer\n"); dsound_logerr (hr, "Could not start playing buffer\n");
return -1; return -1;
} }
break; break;
...@@ -646,12 +637,12 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -646,12 +637,12 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
if (status & DSBSTATUS_PLAYING) { if (status & DSBSTATUS_PLAYING) {
hr = IDirectSoundBuffer_Stop (dsb); hr = IDirectSoundBuffer_Stop (dsb);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not stop playing buffer\n"); dsound_logerr (hr, "Could not stop playing buffer\n");
return -1; return -1;
} }
} }
else { else {
dolog ("warning: voice is not playing\n"); dolog ("warning: Voice is not playing\n");
} }
break; break;
} }
...@@ -675,6 +666,7 @@ static int dsound_run_out (HWVoiceOut *hw) ...@@ -675,6 +666,7 @@ static int dsound_run_out (HWVoiceOut *hw)
DWORD decr; DWORD decr;
DWORD wpos, ppos, old_pos; DWORD wpos, ppos, old_pos;
LPVOID p1, p2; LPVOID p1, p2;
int bufsize;
if (!dsb) { if (!dsb) {
dolog ("Attempt to run empty with playback buffer\n"); dolog ("Attempt to run empty with playback buffer\n");
...@@ -682,6 +674,7 @@ static int dsound_run_out (HWVoiceOut *hw) ...@@ -682,6 +674,7 @@ static int dsound_run_out (HWVoiceOut *hw)
} }
hwshift = hw->info.shift; hwshift = hw->info.shift;
bufsize = hw->samples << hwshift;
live = audio_pcm_hw_get_live_out (hw); live = audio_pcm_hw_get_live_out (hw);
...@@ -691,7 +684,7 @@ static int dsound_run_out (HWVoiceOut *hw) ...@@ -691,7 +684,7 @@ static int dsound_run_out (HWVoiceOut *hw)
ds->first_time ? &wpos : NULL ds->first_time ? &wpos : NULL
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not get playback buffer position\n"); dsound_logerr (hr, "Could not get playback buffer position\n");
return 0; return 0;
} }
...@@ -699,13 +692,14 @@ static int dsound_run_out (HWVoiceOut *hw) ...@@ -699,13 +692,14 @@ static int dsound_run_out (HWVoiceOut *hw)
if (ds->first_time) { if (ds->first_time) {
if (conf.latency_millis) { if (conf.latency_millis) {
DWORD cur_blat = audio_ring_dist (wpos, ppos, hw->bufsize); DWORD cur_blat;
cur_blat = audio_ring_dist (wpos, ppos, bufsize);
ds->first_time = 0; ds->first_time = 0;
old_pos = wpos; old_pos = wpos;
old_pos += old_pos +=
millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat; millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat;
old_pos %= hw->bufsize; old_pos %= bufsize;
old_pos &= ~hw->info.align; old_pos &= ~hw->info.align;
} }
else { else {
...@@ -734,14 +728,14 @@ static int dsound_run_out (HWVoiceOut *hw) ...@@ -734,14 +728,14 @@ static int dsound_run_out (HWVoiceOut *hw)
len = ppos - old_pos; len = ppos - old_pos;
} }
else { else {
if ((old_pos > ppos) && ((old_pos + len) > (ppos + hw->bufsize))) { if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
len = hw->bufsize - old_pos + ppos; len = bufsize - old_pos + ppos;
} }
} }
if (audio_bug (AUDIO_FUNC, len < 0 || len > hw->bufsize)) { if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
dolog ("len=%d hw->bufsize=%d old_pos=%ld ppos=%ld\n", dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
len, hw->bufsize, old_pos, ppos); len, bufsize, old_pos, ppos);
return 0; return 0;
} }
...@@ -779,7 +773,7 @@ static int dsound_run_out (HWVoiceOut *hw) ...@@ -779,7 +773,7 @@ static int dsound_run_out (HWVoiceOut *hw)
} }
dsound_unlock_out (dsb, p1, p2, blen1, blen2); dsound_unlock_out (dsb, p1, p2, blen1, blen2);
ds->old_pos = (old_pos + (decr << hwshift)) % hw->bufsize; ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;
#ifdef DEBUG_DSOUND #ifdef DEBUG_DSOUND
ds->mixed += decr << hwshift; ds->mixed += decr << hwshift;
...@@ -812,7 +806,7 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) ...@@ -812,7 +806,7 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
} }
if (status & DSCBSTATUS_CAPTURING) { if (status & DSCBSTATUS_CAPTURING) {
dolog ("warning: voice is already capturing\n"); dolog ("warning: Voice is already capturing\n");
return 0; return 0;
} }
...@@ -820,7 +814,7 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) ...@@ -820,7 +814,7 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING); hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not start capturing\n"); dsound_logerr (hr, "Could not start capturing\n");
return -1; return -1;
} }
break; break;
...@@ -833,12 +827,12 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) ...@@ -833,12 +827,12 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
if (status & DSCBSTATUS_CAPTURING) { if (status & DSCBSTATUS_CAPTURING) {
hr = IDirectSoundCaptureBuffer_Stop (dscb); hr = IDirectSoundCaptureBuffer_Stop (dscb);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not stop capturing\n"); dsound_logerr (hr, "Could not stop capturing\n");
return -1; return -1;
} }
} }
else { else {
dolog ("warning: voice is not capturing\n"); dolog ("warning: Voice is not capturing\n");
} }
break; break;
} }
...@@ -883,21 +877,21 @@ static int dsound_run_in (HWVoiceIn *hw) ...@@ -883,21 +877,21 @@ static int dsound_run_in (HWVoiceIn *hw)
ds->first_time ? &rpos : NULL ds->first_time ? &rpos : NULL
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not get capture buffer position\n"); dsound_logerr (hr, "Could not get capture buffer position\n");
return 0; return 0;
} }
if (ds->first_time) { if (ds->first_time) {
ds->first_time = 0; ds->first_time = 0;
if (rpos & hw->info.align) { if (rpos & hw->info.align) {
ldebug ("warning: misaligned capture read position %ld(%d)\n", ldebug ("warning: Misaligned capture read position %ld(%d)\n",
rpos, hw->info.align); rpos, hw->info.align);
} }
hw->wpos = rpos >> hwshift; hw->wpos = rpos >> hwshift;
} }
if (cpos & hw->info.align) { if (cpos & hw->info.align) {
ldebug ("warning: misaligned capture position %ld(%d)\n", ldebug ("warning: Misaligned capture position %ld(%d)\n",
cpos, hw->info.align); cpos, hw->info.align);
} }
cpos >>= hwshift; cpos >>= hwshift;
...@@ -951,7 +945,7 @@ static void dsound_audio_fini (void *opaque) ...@@ -951,7 +945,7 @@ static void dsound_audio_fini (void *opaque)
hr = IDirectSound_Release (s->dsound); hr = IDirectSound_Release (s->dsound);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not release DirectSound\n"); dsound_logerr (hr, "Could not release DirectSound\n");
} }
s->dsound = NULL; s->dsound = NULL;
...@@ -961,7 +955,7 @@ static void dsound_audio_fini (void *opaque) ...@@ -961,7 +955,7 @@ static void dsound_audio_fini (void *opaque)
hr = IDirectSoundCapture_Release (s->dsound_capture); hr = IDirectSoundCapture_Release (s->dsound_capture);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not release DirectSoundCapture\n"); dsound_logerr (hr, "Could not release DirectSoundCapture\n");
} }
s->dsound_capture = NULL; s->dsound_capture = NULL;
} }
...@@ -974,7 +968,7 @@ static void *dsound_audio_init (void) ...@@ -974,7 +968,7 @@ static void *dsound_audio_init (void)
hr = CoInitialize (NULL); hr = CoInitialize (NULL);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not initialize COM\n"); dsound_logerr (hr, "Could not initialize COM\n");
return NULL; return NULL;
} }
...@@ -986,13 +980,13 @@ static void *dsound_audio_init (void) ...@@ -986,13 +980,13 @@ static void *dsound_audio_init (void)
(void **) &s->dsound (void **) &s->dsound
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not create DirectSound instance\n"); dsound_logerr (hr, "Could not create DirectSound instance\n");
return NULL; return NULL;
} }
hr = IDirectSound_Initialize (s->dsound, NULL); hr = IDirectSound_Initialize (s->dsound, NULL);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not initialize DirectSound\n"); dsound_logerr (hr, "Could not initialize DirectSound\n");
return NULL; return NULL;
} }
...@@ -1004,16 +998,16 @@ static void *dsound_audio_init (void) ...@@ -1004,16 +998,16 @@ static void *dsound_audio_init (void)
(void **) &s->dsound_capture (void **) &s->dsound_capture
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not create DirectSoundCapture instance\n"); dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
} }
else { else {
hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL); hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not initialize DirectSoundCapture\n"); dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
hr = IDirectSoundCapture_Release (s->dsound_capture); hr = IDirectSoundCapture_Release (s->dsound_capture);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Can not release DirectSoundCapture\n"); dsound_logerr (hr, "Could not release DirectSoundCapture\n");
} }
s->dsound_capture = NULL; s->dsound_capture = NULL;
} }
...@@ -1039,11 +1033,11 @@ static struct audio_option dsound_options[] = { ...@@ -1039,11 +1033,11 @@ static struct audio_option dsound_options[] = {
"Set the parameters of primary buffer", NULL, 0}, "Set the parameters of primary buffer", NULL, 0},
{"LATENCY_MILLIS", AUD_OPT_INT, &conf.latency_millis, {"LATENCY_MILLIS", AUD_OPT_INT, &conf.latency_millis,
"(undocumented)", NULL, 0}, "(undocumented)", NULL, 0},
{"PRIMARY_FREQ", AUD_OPT_INT, &conf.full_fmt.freq, {"PRIMARY_FREQ", AUD_OPT_INT, &conf.settings.freq,
"Primary buffer frequency", NULL, 0}, "Primary buffer frequency", NULL, 0},
{"PRIMARY_CHANNELS", AUD_OPT_INT, &conf.full_fmt.nchannels, {"PRIMARY_CHANNELS", AUD_OPT_INT, &conf.settings.nchannels,
"Primary buffer number of channels (1 - mono, 2 - stereo)", NULL, 0}, "Primary buffer number of channels (1 - mono, 2 - stereo)", NULL, 0},
{"PRIMARY_FMT", AUD_OPT_FMT, &conf.full_fmt.fmt, {"PRIMARY_FMT", AUD_OPT_FMT, &conf.settings.fmt,
"Primary buffer format", NULL, 0}, "Primary buffer format", NULL, 0},
{"BUFSIZE_OUT", AUD_OPT_INT, &conf.bufsize_out, {"BUFSIZE_OUT", AUD_OPT_INT, &conf.bufsize_out,
"(undocumented)", NULL, 0}, "(undocumented)", NULL, 0},
......
...@@ -78,7 +78,7 @@ static void GCC_FMT_ATTR (2, 3) fmod_logerr2 ( ...@@ -78,7 +78,7 @@ static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
{ {
va_list ap; va_list ap;
AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ); AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
va_start (ap, fmt); va_start (ap, fmt);
AUD_vlog (AUDIO_CAP, fmt, ap); AUD_vlog (AUDIO_CAP, fmt, ap);
...@@ -356,17 +356,17 @@ static void fmod_fini_out (HWVoiceOut *hw) ...@@ -356,17 +356,17 @@ static void fmod_fini_out (HWVoiceOut *hw)
} }
} }
static int fmod_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) static int fmod_init_out (HWVoiceOut *hw, audsettings_t *as)
{ {
int bits16, mode, channel; int bits16, mode, channel;
FMODVoiceOut *fmd = (FMODVoiceOut *) hw; FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
mode = aud_to_fmodfmt (fmt, nchannels == 2 ? 1 : 0); mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
fmd->fmod_sample = FSOUND_Sample_Alloc ( fmd->fmod_sample = FSOUND_Sample_Alloc (
FSOUND_FREE, /* index */ FSOUND_FREE, /* index */
conf.nb_samples, /* length */ conf.nb_samples, /* length */
mode, /* mode */ mode, /* mode */
freq, /* freq */ as->freq, /* freq */
255, /* volume */ 255, /* volume */
128, /* pan */ 128, /* pan */
255 /* priority */ 255 /* priority */
...@@ -386,10 +386,9 @@ static int fmod_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -386,10 +386,9 @@ static int fmod_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
fmd->channel = channel; fmd->channel = channel;
/* FMOD always operates on little endian frames? */ /* FMOD always operates on little endian frames? */
audio_pcm_init_info (&hw->info, freq, nchannels, fmt, audio_pcm_init_info (&hw->info, as, audio_need_to_swap_endian (0));
audio_need_to_swap_endian (0));
bits16 = (mode & FSOUND_16BITS) != 0; bits16 = (mode & FSOUND_16BITS) != 0;
hw->bufsize = conf.nb_samples << (nchannels == 2) << bits16; hw->samples = conf.nb_samples;
return 0; return 0;
} }
...@@ -417,7 +416,7 @@ static int fmod_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -417,7 +416,7 @@ static int fmod_ctl_out (HWVoiceOut *hw, int cmd, ...)
return 0; return 0;
} }
static int fmod_init_in (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt) static int fmod_init_in (HWVoiceIn *hw, audsettings_t *as)
{ {
int bits16, mode; int bits16, mode;
FMODVoiceIn *fmd = (FMODVoiceIn *) hw; FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
...@@ -426,12 +425,12 @@ static int fmod_init_in (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -426,12 +425,12 @@ static int fmod_init_in (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt)
return -1; return -1;
} }
mode = aud_to_fmodfmt (fmt, nchannels == 2 ? 1 : 0); mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
fmd->fmod_sample = FSOUND_Sample_Alloc ( fmd->fmod_sample = FSOUND_Sample_Alloc (
FSOUND_FREE, /* index */ FSOUND_FREE, /* index */
conf.nb_samples, /* length */ conf.nb_samples, /* length */
mode, /* mode */ mode, /* mode */
freq, /* freq */ as->freq, /* freq */
255, /* volume */ 255, /* volume */
128, /* pan */ 128, /* pan */
255 /* priority */ 255 /* priority */
...@@ -443,10 +442,9 @@ static int fmod_init_in (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -443,10 +442,9 @@ static int fmod_init_in (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt)
} }
/* FMOD always operates on little endian frames? */ /* FMOD always operates on little endian frames? */
audio_pcm_init_info (&hw->info, freq, nchannels, fmt, audio_pcm_init_info (&hw->info, as, audio_need_to_swap_endian (0));
audio_need_to_swap_endian (0));
bits16 = (mode & FSOUND_16BITS) != 0; bits16 = (mode & FSOUND_16BITS) != 0;
hw->bufsize = conf.nb_samples << (nchannels == 2) << bits16; hw->samples = conf.nb_samples;
return 0; return 0;
} }
...@@ -479,7 +477,7 @@ static int fmod_run_in (HWVoiceIn *hw) ...@@ -479,7 +477,7 @@ static int fmod_run_in (HWVoiceIn *hw)
new_pos = FSOUND_Record_GetPosition (); new_pos = FSOUND_Record_GetPosition ();
if (new_pos < 0) { if (new_pos < 0) {
fmod_logerr ("Can not get recording position\n"); fmod_logerr ("Could not get recording position\n");
return 0; return 0;
} }
......
...@@ -228,21 +228,22 @@ f_sample *mixeng_clip[2][2][2][2] = { ...@@ -228,21 +228,22 @@ f_sample *mixeng_clip[2][2][2][2] = {
*/ */
/* Private data */ /* Private data */
typedef struct ratestuff { struct rate {
uint64_t opos; uint64_t opos;
uint64_t opos_inc; uint64_t opos_inc;
uint32_t ipos; /* position in the input stream (integer) */ uint32_t ipos; /* position in the input stream (integer) */
st_sample_t ilast; /* last sample in the input stream */ st_sample_t ilast; /* last sample in the input stream */
} *rate_t; };
/* /*
* Prepare processing. * Prepare processing.
*/ */
void *st_rate_start (int inrate, int outrate) void *st_rate_start (int inrate, int outrate)
{ {
rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff)); struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
if (!rate) { if (!rate) {
dolog ("Could not allocate resampler (%d bytes)\n", sizeof (*rate));
return NULL; return NULL;
} }
......
...@@ -67,11 +67,10 @@ static int no_write (SWVoiceOut *sw, void *buf, int len) ...@@ -67,11 +67,10 @@ static int no_write (SWVoiceOut *sw, void *buf, int len)
return audio_pcm_sw_write (sw, buf, len); return audio_pcm_sw_write (sw, buf, len);
} }
static int no_init_out (HWVoiceOut *hw, int freq, static int no_init_out (HWVoiceOut *hw, audsettings_t *as)
int nchannels, audfmt_e fmt)
{ {
audio_pcm_init_info (&hw->info, freq, nchannels, fmt, 0); audio_pcm_init_info (&hw->info, as, 0);
hw->bufsize = 4096; hw->samples = 1024;
return 0; return 0;
} }
...@@ -87,11 +86,10 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -87,11 +86,10 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
return 0; return 0;
} }
static int no_init_in (HWVoiceIn *hw, int freq, static int no_init_in (HWVoiceIn *hw, audsettings_t *as)
int nchannels, audfmt_e fmt)
{ {
audio_pcm_init_info (&hw->info, freq, nchannels, fmt, 0); audio_pcm_init_info (&hw->info, as, 0);
hw->bufsize = 4096; hw->samples = 1024;
return 0; return 0;
} }
......
...@@ -91,7 +91,7 @@ static void GCC_FMT_ATTR (3, 4) oss_logerr2 ( ...@@ -91,7 +91,7 @@ static void GCC_FMT_ATTR (3, 4) oss_logerr2 (
{ {
va_list ap; va_list ap;
AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ); AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
va_start (ap, fmt); va_start (ap, fmt);
AUD_vlog (AUDIO_CAP, fmt, ap); AUD_vlog (AUDIO_CAP, fmt, ap);
...@@ -179,7 +179,7 @@ static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness) ...@@ -179,7 +179,7 @@ static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness)
return 0; return 0;
} }
#ifdef DEBUG_MISMATCHES #if defined DEBUG_MISMATCHES || defined DEBUG
static void oss_dump_info (struct oss_params *req, struct oss_params *obt) static void oss_dump_info (struct oss_params *req, struct oss_params *obt)
{ {
dolog ("parameter | requested value | obtained value\n"); dolog ("parameter | requested value | obtained value\n");
...@@ -253,16 +253,16 @@ static int oss_open (int in, struct oss_params *req, ...@@ -253,16 +253,16 @@ static int oss_open (int in, struct oss_params *req,
obt->fragsize = abinfo.fragsize; obt->fragsize = abinfo.fragsize;
*pfd = fd; *pfd = fd;
#ifdef DEBUG_MISMATCHES
if ((req->fmt != obt->fmt) || if ((req->fmt != obt->fmt) ||
(req->nchannels != obt->nchannels) || (req->nchannels != obt->nchannels) ||
(req->freq != obt->freq) || (req->freq != obt->freq) ||
(req->fragsize != obt->fragsize) || (req->fragsize != obt->fragsize) ||
(req->nfrags != obt->nfrags)) { (req->nfrags != obt->nfrags)) {
#ifdef DEBUG_MISMATCHES
dolog ("Audio parameters mismatch\n"); dolog ("Audio parameters mismatch\n");
oss_dump_info (req, obt); oss_dump_info (req, obt);
#endif
} }
#endif
#ifdef DEBUG #ifdef DEBUG
oss_dump_info (req, obt); oss_dump_info (req, obt);
...@@ -283,12 +283,15 @@ static int oss_run_out (HWVoiceOut *hw) ...@@ -283,12 +283,15 @@ static int oss_run_out (HWVoiceOut *hw)
st_sample_t *src; st_sample_t *src;
struct audio_buf_info abinfo; struct audio_buf_info abinfo;
struct count_info cntinfo; struct count_info cntinfo;
int bufsize;
live = audio_pcm_hw_get_live_out (hw); live = audio_pcm_hw_get_live_out (hw);
if (!live) { if (!live) {
return 0; return 0;
} }
bufsize = hw->samples << hw->info.shift;
if (oss->mmapped) { if (oss->mmapped) {
int bytes; int bytes;
...@@ -300,7 +303,7 @@ static int oss_run_out (HWVoiceOut *hw) ...@@ -300,7 +303,7 @@ static int oss_run_out (HWVoiceOut *hw)
if (cntinfo.ptr == oss->old_optr) { if (cntinfo.ptr == oss->old_optr) {
if (abs (hw->samples - live) < 64) { if (abs (hw->samples - live) < 64) {
dolog ("warning: overrun\n"); dolog ("warning: Overrun\n");
} }
return 0; return 0;
} }
...@@ -309,7 +312,7 @@ static int oss_run_out (HWVoiceOut *hw) ...@@ -309,7 +312,7 @@ static int oss_run_out (HWVoiceOut *hw)
bytes = cntinfo.ptr - oss->old_optr; bytes = cntinfo.ptr - oss->old_optr;
} }
else { else {
bytes = hw->bufsize + cntinfo.ptr - oss->old_optr; bytes = bufsize + cntinfo.ptr - oss->old_optr;
} }
decr = audio_MIN (bytes >> hw->info.shift, live); decr = audio_MIN (bytes >> hw->info.shift, live);
...@@ -321,9 +324,9 @@ static int oss_run_out (HWVoiceOut *hw) ...@@ -321,9 +324,9 @@ static int oss_run_out (HWVoiceOut *hw)
return 0; return 0;
} }
if (abinfo.bytes < 0 || abinfo.bytes > hw->bufsize) { if (abinfo.bytes < 0 || abinfo.bytes > bufsize) {
ldebug ("warning: invalid available size, size=%d bufsize=%d\n", ldebug ("warning: Invalid available size, size=%d bufsize=%d\n",
abinfo.bytes, hw->bufsize); abinfo.bytes, bufsize);
return 0; return 0;
} }
...@@ -362,7 +365,7 @@ static int oss_run_out (HWVoiceOut *hw) ...@@ -362,7 +365,7 @@ static int oss_run_out (HWVoiceOut *hw)
int wsamples = written >> hw->info.shift; int wsamples = written >> hw->info.shift;
int wbytes = wsamples << hw->info.shift; int wbytes = wsamples << hw->info.shift;
if (wbytes != written) { if (wbytes != written) {
dolog ("warning: misaligned write %d (requested %d), " dolog ("warning: Misaligned write %d (requested %d), "
"alignment %d\n", "alignment %d\n",
wbytes, written, hw->info.align + 1); wbytes, written, hw->info.align + 1);
} }
...@@ -396,10 +399,10 @@ static void oss_fini_out (HWVoiceOut *hw) ...@@ -396,10 +399,10 @@ static void oss_fini_out (HWVoiceOut *hw)
if (oss->pcm_buf) { if (oss->pcm_buf) {
if (oss->mmapped) { if (oss->mmapped) {
err = munmap (oss->pcm_buf, hw->bufsize); err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
if (err) { if (err) {
oss_logerr (errno, "Failed to unmap buffer %p, size %d\n", oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",
oss->pcm_buf, hw->bufsize); oss->pcm_buf, hw->samples << hw->info.shift);
} }
} }
else { else {
...@@ -409,7 +412,7 @@ static void oss_fini_out (HWVoiceOut *hw) ...@@ -409,7 +412,7 @@ static void oss_fini_out (HWVoiceOut *hw)
} }
} }
static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) static int oss_init_out (HWVoiceOut *hw, audsettings_t *as)
{ {
OSSVoiceOut *oss = (OSSVoiceOut *) hw; OSSVoiceOut *oss = (OSSVoiceOut *) hw;
struct oss_params req, obt; struct oss_params req, obt;
...@@ -417,10 +420,11 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -417,10 +420,11 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
int err; int err;
int fd; int fd;
audfmt_e effective_fmt; audfmt_e effective_fmt;
audsettings_t obt_as;
req.fmt = aud_to_ossfmt (fmt); req.fmt = aud_to_ossfmt (as->fmt);
req.freq = freq; req.freq = as->freq;
req.nchannels = nchannels; req.nchannels = as->nchannels;
req.fragsize = conf.fragsize; req.fragsize = conf.fragsize;
req.nfrags = conf.nfrags; req.nfrags = conf.nfrags;
...@@ -434,24 +438,38 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -434,24 +438,38 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
return -1; return -1;
} }
obt_as.freq = obt.freq;
obt_as.nchannels = obt.nchannels;
obt_as.fmt = effective_fmt;
audio_pcm_init_info ( audio_pcm_init_info (
&hw->info, &hw->info,
obt.freq, &obt_as,
obt.nchannels,
effective_fmt,
audio_need_to_swap_endian (endianness) audio_need_to_swap_endian (endianness)
); );
oss->nfrags = obt.nfrags; oss->nfrags = obt.nfrags;
oss->fragsize = obt.fragsize; oss->fragsize = obt.fragsize;
hw->bufsize = obt.nfrags * obt.fragsize;
if (obt.nfrags * obt.fragsize & hw->info.align) {
dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",
obt.nfrags * obt.fragsize, hw->info.align + 1);
}
hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
oss->mmapped = 0; oss->mmapped = 0;
if (conf.try_mmap) { if (conf.try_mmap) {
oss->pcm_buf = mmap (0, hw->bufsize, PROT_READ | PROT_WRITE, oss->pcm_buf = mmap (
MAP_SHARED, fd, 0); 0,
hw->samples << hw->info.shift,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
0
);
if (oss->pcm_buf == MAP_FAILED) { if (oss->pcm_buf == MAP_FAILED) {
oss_logerr (errno, "Failed to map %d bytes of DAC\n", oss_logerr (errno, "Failed to map %d bytes of DAC\n",
hw->bufsize); hw->samples << hw->info.shift);
} else { } else {
int err; int err;
int trig = 0; int trig = 0;
...@@ -472,18 +490,24 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -472,18 +490,24 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
} }
if (!oss->mmapped) { if (!oss->mmapped) {
err = munmap (oss->pcm_buf, hw->bufsize); err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
if (err) { if (err) {
oss_logerr (errno, "Failed to unmap buffer %p size %d\n", oss_logerr (errno, "Failed to unmap buffer %p size %d\n",
oss->pcm_buf, hw->bufsize); oss->pcm_buf, hw->samples << hw->info.shift);
} }
} }
} }
} }
if (!oss->mmapped) { if (!oss->mmapped) {
oss->pcm_buf = qemu_mallocz (hw->bufsize); oss->pcm_buf = audio_calloc (
AUDIO_FUNC,
hw->samples,
1 << hw->info.shift
);
if (!oss->pcm_buf) { if (!oss->pcm_buf) {
dolog ("Could not allocate DAC buffer (%d bytes)\n",
hw->samples << hw->info.shift);
oss_anal_close (&fd); oss_anal_close (&fd);
return -1; return -1;
} }
...@@ -528,8 +552,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) ...@@ -528,8 +552,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
return 0; return 0;
} }
static int oss_init_in (HWVoiceIn *hw, static int oss_init_in (HWVoiceIn *hw, audsettings_t *as)
int freq, int nchannels, audfmt_e fmt)
{ {
OSSVoiceIn *oss = (OSSVoiceIn *) hw; OSSVoiceIn *oss = (OSSVoiceIn *) hw;
struct oss_params req, obt; struct oss_params req, obt;
...@@ -537,10 +560,11 @@ static int oss_init_in (HWVoiceIn *hw, ...@@ -537,10 +560,11 @@ static int oss_init_in (HWVoiceIn *hw,
int err; int err;
int fd; int fd;
audfmt_e effective_fmt; audfmt_e effective_fmt;
audsettings_t obt_as;
req.fmt = aud_to_ossfmt (fmt); req.fmt = aud_to_ossfmt (as->fmt);
req.freq = freq; req.freq = as->freq;
req.nchannels = nchannels; req.nchannels = as->nchannels;
req.fragsize = conf.fragsize; req.fragsize = conf.fragsize;
req.nfrags = conf.nfrags; req.nfrags = conf.nfrags;
if (oss_open (1, &req, &obt, &fd)) { if (oss_open (1, &req, &obt, &fd)) {
...@@ -553,18 +577,28 @@ static int oss_init_in (HWVoiceIn *hw, ...@@ -553,18 +577,28 @@ static int oss_init_in (HWVoiceIn *hw,
return -1; return -1;
} }
obt_as.freq = obt.freq;
obt_as.nchannels = obt.nchannels;
obt_as.fmt = effective_fmt;
audio_pcm_init_info ( audio_pcm_init_info (
&hw->info, &hw->info,
obt.freq, &obt_as,
obt.nchannels,
effective_fmt,
audio_need_to_swap_endian (endianness) audio_need_to_swap_endian (endianness)
); );
oss->nfrags = obt.nfrags; oss->nfrags = obt.nfrags;
oss->fragsize = obt.fragsize; oss->fragsize = obt.fragsize;
hw->bufsize = obt.nfrags * obt.fragsize;
oss->pcm_buf = qemu_mallocz (hw->bufsize); if (obt.nfrags * obt.fragsize & hw->info.align) {
dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n",
obt.nfrags * obt.fragsize, hw->info.align + 1);
}
hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
oss->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
if (!oss->pcm_buf) { if (!oss->pcm_buf) {
dolog ("Could not allocate ADC buffer (%d bytes)\n",
hw->samples << hw->info.shift);
oss_anal_close (&fd); oss_anal_close (&fd);
return -1; return -1;
} }
...@@ -623,7 +657,7 @@ static int oss_run_in (HWVoiceIn *hw) ...@@ -623,7 +657,7 @@ static int oss_run_in (HWVoiceIn *hw)
if (nread > 0) { if (nread > 0) {
if (nread & hw->info.align) { if (nread & hw->info.align) {
dolog ("warning: misaligned read %d (requested %d), " dolog ("warning: Misaligned read %d (requested %d), "
"alignment %d\n", nread, bufs[i].add << hwshift, "alignment %d\n", nread, bufs[i].add << hwshift,
hw->info.align + 1); hw->info.align + 1);
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
void NAME (void *opaque, st_sample_t *ibuf, st_sample_t *obuf, void NAME (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
int *isamp, int *osamp) int *isamp, int *osamp)
{ {
rate_t rate = (rate_t) opaque; struct rate *rate = opaque;
st_sample_t *istart, *iend; st_sample_t *istart, *iend;
st_sample_t *ostart, *oend; st_sample_t *ostart, *oend;
st_sample_t ilast, icur, out; st_sample_t ilast, icur, out;
......
...@@ -303,7 +303,7 @@ static void sdl_fini_out (HWVoiceOut *hw) ...@@ -303,7 +303,7 @@ static void sdl_fini_out (HWVoiceOut *hw)
sdl_close (&glob_sdl); sdl_close (&glob_sdl);
} }
static int sdl_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) static int sdl_init_out (HWVoiceOut *hw, audsettings_t *as)
{ {
SDLVoiceOut *sdl = (SDLVoiceOut *) hw; SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
SDLAudioState *s = &glob_sdl; SDLAudioState *s = &glob_sdl;
...@@ -312,18 +312,14 @@ static int sdl_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -312,18 +312,14 @@ static int sdl_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
int endianess; int endianess;
int err; int err;
audfmt_e effective_fmt; audfmt_e effective_fmt;
audsettings_t obt_as;
if (nchannels != 2) { shift <<= as->nchannels == 2;
dolog ("Can not init DAC. Bogus channel count %d\n", nchannels);
return -1;
}
req.freq = freq; req.freq = as->freq;
req.format = aud_to_sdlfmt (fmt, &shift); req.format = aud_to_sdlfmt (as->fmt, &shift);
req.channels = nchannels; req.channels = as->nchannels;
req.samples = conf.nb_samples; req.samples = conf.nb_samples;
shift <<= nchannels == 2;
req.callback = sdl_callback; req.callback = sdl_callback;
req.userdata = sdl; req.userdata = sdl;
...@@ -337,14 +333,16 @@ static int sdl_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -337,14 +333,16 @@ static int sdl_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
return -1; return -1;
} }
obt_as.freq = obt.freq;
obt_as.nchannels = obt.channels;
obt_as.fmt = effective_fmt;
audio_pcm_init_info ( audio_pcm_init_info (
&hw->info, &hw->info,
obt.freq, &obt_as,
obt.channels,
effective_fmt,
audio_need_to_swap_endian (endianess) audio_need_to_swap_endian (endianess)
); );
hw->bufsize = obt.samples << shift; hw->samples = obt.samples;
s->initialized = 1; s->initialized = 1;
s->exit = 0; s->exit = 0;
......
...@@ -35,9 +35,15 @@ typedef struct WAVVoiceOut { ...@@ -35,9 +35,15 @@ typedef struct WAVVoiceOut {
} WAVVoiceOut; } WAVVoiceOut;
static struct { static struct {
audsettings_t settings;
const char *wav_path; const char *wav_path;
} conf = { } conf = {
.wav_path = "qemu.wav" {
44100,
2,
AUD_FMT_S16
},
"qemu.wav"
}; };
static int wav_run_out (HWVoiceOut *hw) static int wav_run_out (HWVoiceOut *hw)
...@@ -101,22 +107,22 @@ static void le_store (uint8_t *buf, uint32_t val, int len) ...@@ -101,22 +107,22 @@ static void le_store (uint8_t *buf, uint32_t val, int len)
} }
} }
static int wav_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) static int wav_init_out (HWVoiceOut *hw, audsettings_t *as)
{ {
WAVVoiceOut *wav = (WAVVoiceOut *) hw; WAVVoiceOut *wav = (WAVVoiceOut *) hw;
int bits16; int bits16 = 0, stereo = 0;
uint8_t hdr[] = { uint8_t hdr[] = {
0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
}; };
audsettings_t wav_as = conf.settings;
freq = audio_state.fixed_freq_out; (void) as;
fmt = audio_state.fixed_fmt_out;
nchannels = audio_state.fixed_channels_out;
switch (fmt) { stereo = wav_as.nchannels == 2;
switch (wav_as.fmt) {
case AUD_FMT_S8: case AUD_FMT_S8:
case AUD_FMT_U8: case AUD_FMT_U8:
bits16 = 0; bits16 = 0;
...@@ -126,32 +132,24 @@ static int wav_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) ...@@ -126,32 +132,24 @@ static int wav_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt)
case AUD_FMT_U16: case AUD_FMT_U16:
bits16 = 1; bits16 = 1;
break; break;
default:
dolog ("Internal logic error bad format %d\n", fmt);
return -1;
} }
hdr[34] = bits16 ? 0x10 : 0x08; hdr[34] = bits16 ? 0x10 : 0x08;
audio_pcm_init_info (
&hw->info, audio_pcm_init_info (&hw->info, &wav_as, audio_need_to_swap_endian (0));
freq,
nchannels, hw->samples = 1024;
bits16 ? AUD_FMT_S16 : AUD_FMT_U8, wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
audio_need_to_swap_endian (0)
);
hw->bufsize = 4096;
wav->pcm_buf = qemu_mallocz (hw->bufsize);
if (!wav->pcm_buf) { if (!wav->pcm_buf) {
dolog ("Can not initialize WAV buffer of %d bytes\n", dolog ("Could not allocate buffer (%d bytes)\n",
hw->bufsize); hw->samples << hw->info.shift);
return -1; return -1;
} }
le_store (hdr + 22, hw->info.nchannels, 2); le_store (hdr + 22, hw->info.nchannels, 2);
le_store (hdr + 24, hw->info.freq, 4); le_store (hdr + 24, hw->info.freq, 4);
le_store (hdr + 28, hw->info.freq << (bits16 + (nchannels == 2)), 4); le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
le_store (hdr + 32, 1 << (bits16 + (nchannels == 2)), 2); le_store (hdr + 32, 1 << (bits16 + stereo), 2);
wav->f = fopen (conf.wav_path, "wb"); wav->f = fopen (conf.wav_path, "wb");
if (!wav->f) { if (!wav->f) {
...@@ -175,7 +173,7 @@ static void wav_fini_out (HWVoiceOut *hw) ...@@ -175,7 +173,7 @@ static void wav_fini_out (HWVoiceOut *hw)
uint32_t rifflen = (wav->total_samples << stereo) + 36; uint32_t rifflen = (wav->total_samples << stereo) + 36;
uint32_t datalen = wav->total_samples << stereo; uint32_t datalen = wav->total_samples << stereo;
if (!wav->f || !hw->active) { if (!wav->f) {
return; return;
} }
...@@ -214,6 +212,15 @@ static void wav_audio_fini (void *opaque) ...@@ -214,6 +212,15 @@ static void wav_audio_fini (void *opaque)
} }
struct audio_option wav_options[] = { struct audio_option wav_options[] = {
{"FREQUENCY", AUD_OPT_INT, &conf.settings.freq,
"Frequency", NULL, 0},
{"FORMAT", AUD_OPT_FMT, &conf.settings.fmt,
"Format", NULL, 0},
{"DAC_FIXED_CHANNELS", AUD_OPT_INT, &conf.settings.nchannels,
"Number of channels (1 - mono, 2 - stereo)", NULL, 0},
{"PATH", AUD_OPT_STR, &conf.wav_path, {"PATH", AUD_OPT_STR, &conf.wav_path,
"Path to wave file", NULL, 0}, "Path to wave file", NULL, 0},
{NULL, 0, NULL, NULL, NULL, 0} {NULL, 0, NULL, NULL, NULL, 0}
......
...@@ -53,6 +53,7 @@ static struct { ...@@ -53,6 +53,7 @@ static struct {
} conf = {0x220, 44100}; } conf = {0x220, 44100};
typedef struct { typedef struct {
QEMUSoundCard card;
int ticking[2]; int ticking[2];
int enabled; int enabled;
int active; int active;
...@@ -70,7 +71,7 @@ typedef struct { ...@@ -70,7 +71,7 @@ typedef struct {
#endif #endif
} AdlibState; } AdlibState;
static AdlibState adlib; static AdlibState glob_adlib;
static void adlib_stop_opl_timer (AdlibState *s, size_t n) static void adlib_stop_opl_timer (AdlibState *s, size_t n)
{ {
...@@ -90,7 +91,7 @@ static void adlib_kill_timers (AdlibState *s) ...@@ -90,7 +91,7 @@ static void adlib_kill_timers (AdlibState *s)
if (s->ticking[i]) { if (s->ticking[i]) {
uint64_t delta; uint64_t delta;
delta = AUD_time_stamp_get_elapsed_usec_out (s->voice, &s->ats); delta = AUD_get_elapsed_usec_out (s->voice, &s->ats);
ldebug ( ldebug (
"delta = %f dexp = %f expired => %d\n", "delta = %f dexp = %f expired => %d\n",
delta / 1000000.0, delta / 1000000.0,
...@@ -141,10 +142,11 @@ static IO_READ_PROTO(adlib_read) ...@@ -141,10 +142,11 @@ static IO_READ_PROTO(adlib_read)
static void timer_handler (int c, double interval_Sec) static void timer_handler (int c, double interval_Sec)
{ {
AdlibState *s = &adlib; AdlibState *s = &glob_adlib;
unsigned n = c & 1; unsigned n = c & 1;
#ifdef DEBUG #ifdef DEBUG
double interval; double interval;
int64_t exp;
#endif #endif
if (interval_Sec == 0.0) { if (interval_Sec == 0.0) {
...@@ -262,16 +264,23 @@ static void Adlib_fini (AdlibState *s) ...@@ -262,16 +264,23 @@ static void Adlib_fini (AdlibState *s)
s->active = 0; s->active = 0;
s->enabled = 0; s->enabled = 0;
AUD_remove_card (&s->card);
} }
void Adlib_init (void) int Adlib_init (AudioState *audio)
{ {
AdlibState *s = &adlib; AdlibState *s = &glob_adlib;
audsettings_t as;
if (!audio) {
dolog ("No audio state\n");
return -1;
}
#ifdef HAS_YMF262 #ifdef HAS_YMF262
if (YMF262Init (1, 14318180, conf.freq)) { if (YMF262Init (1, 14318180, conf.freq)) {
dolog ("YMF262Init %d failed\n", conf.freq); dolog ("YMF262Init %d failed\n", conf.freq);
return; return -1;
} }
else { else {
YMF262SetTimerHandler (0, timer_handler, 0); YMF262SetTimerHandler (0, timer_handler, 0);
...@@ -281,7 +290,7 @@ void Adlib_init (void) ...@@ -281,7 +290,7 @@ void Adlib_init (void)
s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq); s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq);
if (!s->opl) { if (!s->opl) {
dolog ("OPLCreate %d failed\n", conf.freq); dolog ("OPLCreate %d failed\n", conf.freq);
return; return -1;
} }
else { else {
OPLSetTimerHandler (s->opl, timer_handler, 0); OPLSetTimerHandler (s->opl, timer_handler, 0);
...@@ -289,18 +298,23 @@ void Adlib_init (void) ...@@ -289,18 +298,23 @@ void Adlib_init (void)
} }
#endif #endif
as.freq = conf.freq;
as.nchannels = SHIFT;
as.fmt = AUD_FMT_S16;
AUD_register_card (audio, "adlib", &s->card);
s->voice = AUD_open_out ( s->voice = AUD_open_out (
&s->card,
s->voice, s->voice,
"adlib", "adlib",
s, s,
adlib_callback, adlib_callback,
conf.freq, &as
SHIFT,
AUD_FMT_S16
); );
if (!s->voice) { if (!s->voice) {
Adlib_fini (s); Adlib_fini (s);
return; return -1;
} }
s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT; s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT;
...@@ -310,7 +324,7 @@ void Adlib_init (void) ...@@ -310,7 +324,7 @@ void Adlib_init (void)
dolog ("not enough memory for adlib mixing buffer (%d)\n", dolog ("not enough memory for adlib mixing buffer (%d)\n",
s->samples << SHIFT); s->samples << SHIFT);
Adlib_fini (s); Adlib_fini (s);
return; return -1;
} }
register_ioport_read (0x388, 4, 1, adlib_read, s); register_ioport_read (0x388, 4, 1, adlib_read, s);
...@@ -321,4 +335,6 @@ void Adlib_init (void) ...@@ -321,4 +335,6 @@ void Adlib_init (void)
register_ioport_read (conf.port + 8, 2, 1, adlib_read, s); register_ioport_read (conf.port + 8, 2, 1, adlib_read, s);
register_ioport_write (conf.port + 8, 2, 1, adlib_write, s); register_ioport_write (conf.port + 8, 2, 1, adlib_write, s);
return 0;
} }
...@@ -265,6 +265,7 @@ struct chan { ...@@ -265,6 +265,7 @@ struct chan {
typedef struct ES1370State { typedef struct ES1370State {
PCIDevice *pci_dev; PCIDevice *pci_dev;
QEMUSoundCard card;
struct chan chan[NB_CHANNELS]; struct chan chan[NB_CHANNELS];
SWVoiceOut *dac_voice[2]; SWVoiceOut *dac_voice[2];
SWVoiceIn *adc_voice; SWVoiceIn *adc_voice;
...@@ -341,11 +342,11 @@ static void es1370_reset (ES1370State *s) ...@@ -341,11 +342,11 @@ static void es1370_reset (ES1370State *s)
d->scount = 0; d->scount = 0;
d->leftover = 0; d->leftover = 0;
if (i == ADC_CHANNEL) { if (i == ADC_CHANNEL) {
AUD_close_in (s->adc_voice); AUD_close_in (&s->card, s->adc_voice);
s->adc_voice = NULL; s->adc_voice = NULL;
} }
else { else {
AUD_close_out (s->dac_voice[i]); AUD_close_out (&s->card, s->dac_voice[i]);
s->dac_voice[i] = NULL; s->dac_voice[i] = NULL;
} }
} }
...@@ -417,28 +418,32 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl) ...@@ -417,28 +418,32 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl)
(new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8, (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8,
d->shift); d->shift);
if (new_freq) { if (new_freq) {
audsettings_t as;
as.freq = new_freq;
as.nchannels = 1 << (new_fmt & 1);
as.fmt = (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8;
if (i == ADC_CHANNEL) { if (i == ADC_CHANNEL) {
s->adc_voice = s->adc_voice =
AUD_open_in ( AUD_open_in (
&s->card,
s->adc_voice, s->adc_voice,
"es1370.adc", "es1370.adc",
s, s,
es1370_adc_callback, es1370_adc_callback,
new_freq, &as
1 << (new_fmt & 1),
(new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8
); );
} }
else { else {
s->dac_voice[i] = s->dac_voice[i] =
AUD_open_out ( AUD_open_out (
&s->card,
s->dac_voice[i], s->dac_voice[i],
i ? "es1370.dac2" : "es1370.dac1", i ? "es1370.dac2" : "es1370.dac1",
s, s,
i ? es1370_dac2_callback : es1370_dac1_callback, i ? es1370_dac2_callback : es1370_dac1_callback,
new_freq, &as
1 << (new_fmt & 1),
(new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8
); );
} }
} }
...@@ -761,7 +766,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, ...@@ -761,7 +766,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
while (temp) { while (temp) {
int acquired, to_copy; int acquired, to_copy;
to_copy = audio_MIN (temp, sizeof (tmpbuf)); to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf));
acquired = AUD_read (s->adc_voice, tmpbuf, to_copy); acquired = AUD_read (s->adc_voice, tmpbuf, to_copy);
if (!acquired) if (!acquired)
break; break;
...@@ -779,7 +784,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, ...@@ -779,7 +784,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
while (temp) { while (temp) {
int copied, to_copy; int copied, to_copy;
to_copy = audio_MIN (temp, sizeof (tmpbuf)); to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf));
cpu_physical_memory_read (addr, tmpbuf, to_copy); cpu_physical_memory_read (addr, tmpbuf, to_copy);
copied = AUD_write (voice, tmpbuf, to_copy); copied = AUD_write (voice, tmpbuf, to_copy);
if (!copied) if (!copied)
...@@ -812,7 +817,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, ...@@ -812,7 +817,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
else { else {
d->frame_cnt = size; d->frame_cnt = size;
if (cnt <= d->frame_cnt) if ((uint32_t) cnt <= d->frame_cnt)
d->frame_cnt |= cnt << 16; d->frame_cnt |= cnt << 16;
} }
...@@ -876,6 +881,10 @@ static void es1370_map (PCIDevice *pci_dev, int region_num, ...@@ -876,6 +881,10 @@ static void es1370_map (PCIDevice *pci_dev, int region_num,
PCIES1370State *d = (PCIES1370State *) pci_dev; PCIES1370State *d = (PCIES1370State *) pci_dev;
ES1370State *s = &d->es1370; ES1370State *s = &d->es1370;
(void) region_num;
(void) size;
(void) type;
register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s); register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s);
register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s); register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s);
register_ioport_write (addr, 0x40, 4, es1370_writel, s); register_ioport_write (addr, 0x40, 4, es1370_writel, s);
...@@ -923,13 +932,13 @@ static int es1370_load (QEMUFile *f, void *opaque, int version_id) ...@@ -923,13 +932,13 @@ static int es1370_load (QEMUFile *f, void *opaque, int version_id)
qemu_get_be32s (f, &d->frame_cnt); qemu_get_be32s (f, &d->frame_cnt);
if (i == ADC_CHANNEL) { if (i == ADC_CHANNEL) {
if (s->adc_voice) { if (s->adc_voice) {
AUD_close_in (s->adc_voice); AUD_close_in (&s->card, s->adc_voice);
s->adc_voice = NULL; s->adc_voice = NULL;
} }
} }
else { else {
if (s->dac_voice[i]) { if (s->dac_voice[i]) {
AUD_close_out (s->dac_voice[i]); AUD_close_out (&s->card, s->dac_voice[i]);
s->dac_voice[i] = NULL; s->dac_voice[i] = NULL;
} }
} }
...@@ -953,12 +962,22 @@ static void es1370_on_reset (void *opaque) ...@@ -953,12 +962,22 @@ static void es1370_on_reset (void *opaque)
es1370_reset (s); es1370_reset (s);
} }
int es1370_init (PCIBus *bus) int es1370_init (PCIBus *bus, AudioState *audio)
{ {
PCIES1370State *d; PCIES1370State *d;
ES1370State *s; ES1370State *s;
uint8_t *c; uint8_t *c;
if (!bus) {
dolog ("No PCI bus\n");
return -1;
}
if (!audio) {
dolog ("No audio state\n");
return -1;
}
d = (PCIES1370State *) pci_register_device (bus, "ES1370", d = (PCIES1370State *) pci_register_device (bus, "ES1370",
sizeof (PCIES1370State), sizeof (PCIES1370State),
-1, NULL, NULL); -1, NULL, NULL);
...@@ -1002,6 +1021,8 @@ int es1370_init (PCIBus *bus) ...@@ -1002,6 +1021,8 @@ int es1370_init (PCIBus *bus)
pci_register_io_region (&d->dev, 0, 256, PCI_ADDRESS_SPACE_IO, es1370_map); pci_register_io_region (&d->dev, 0, 256, PCI_ADDRESS_SPACE_IO, es1370_map);
register_savevm ("es1370", 0, 1, es1370_save, es1370_load, s); register_savevm ("es1370", 0, 1, es1370_save, es1370_load, s);
qemu_register_reset (es1370_on_reset, s); qemu_register_reset (es1370_on_reset, s);
AUD_register_card (audio, "es1370", &s->card);
es1370_reset (s); es1370_reset (s);
return 0; return 0;
} }
...@@ -601,19 +601,23 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, ...@@ -601,19 +601,23 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
DMA_init(0); DMA_init(0);
if (audio_enabled) { if (audio_enabled) {
AUD_init(); AudioState *audio;
if (sb16_enabled)
SB16_init (); audio = AUD_init();
if (audio) {
if (sb16_enabled)
SB16_init (audio);
#ifdef CONFIG_ADLIB #ifdef CONFIG_ADLIB
if (adlib_enabled) if (adlib_enabled)
Adlib_init (); Adlib_init (audio);
#endif #endif
#ifdef CONFIG_GUS #ifdef CONFIG_GUS
if (gus_enabled) if (gus_enabled)
GUS_init (); GUS_init (audio);
#endif #endif
if (pci_enabled && es1370_enabled) if (pci_enabled && es1370_enabled)
es1370_init (pci_bus); es1370_init (pci_bus, audio);
}
} }
floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
......
...@@ -53,6 +53,7 @@ static struct { ...@@ -53,6 +53,7 @@ static struct {
} conf = {5, 4, 5, 1, 5, 0x220}; } conf = {5, 4, 5, 1, 5, 0x220};
typedef struct SB16State { typedef struct SB16State {
QEMUSoundCard card;
int irq; int irq;
int dma; int dma;
int hdma; int hdma;
...@@ -108,9 +109,6 @@ typedef struct SB16State { ...@@ -108,9 +109,6 @@ typedef struct SB16State {
uint8_t mixer_regs[256]; uint8_t mixer_regs[256];
} SB16State; } SB16State;
/* XXX: suppress that and use a context */
static struct SB16State dsp;
static void SB_audio_callback (void *opaque, int free); static void SB_audio_callback (void *opaque, int free);
static int magic_of_irq (int irq) static int magic_of_irq (int irq)
...@@ -242,15 +240,21 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len) ...@@ -242,15 +240,21 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len)
s->block_size, s->dma_auto, s->fifo, s->highspeed); s->block_size, s->dma_auto, s->fifo, s->highspeed);
if (s->freq) { if (s->freq) {
audsettings_t as;
s->audio_free = 0; s->audio_free = 0;
as.freq = s->freq;
as.nchannels = 1 << s->fmt_stereo;
as.fmt = s->fmt;
s->voice = AUD_open_out ( s->voice = AUD_open_out (
&s->card,
s->voice, s->voice,
"sb16", "sb16",
s, s,
SB_audio_callback, SB_audio_callback,
s->freq, &as
1 << s->fmt_stereo,
s->fmt
); );
} }
...@@ -330,15 +334,21 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len) ...@@ -330,15 +334,21 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
} }
if (s->freq) { if (s->freq) {
audsettings_t as;
s->audio_free = 0; s->audio_free = 0;
as.freq = s->freq;
as.nchannels = 1 << s->fmt_stereo;
as.fmt = s->fmt;
s->voice = AUD_open_out ( s->voice = AUD_open_out (
&s->card,
s->voice, s->voice,
"sb16", "sb16",
s, s,
SB_audio_callback, SB_audio_callback,
s->freq, &as
1 << s->fmt_stereo,
s->fmt
); );
} }
...@@ -349,7 +359,7 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len) ...@@ -349,7 +359,7 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
static inline void dsp_out_data (SB16State *s, uint8_t val) static inline void dsp_out_data (SB16State *s, uint8_t val)
{ {
ldebug ("outdata %#x\n", val); ldebug ("outdata %#x\n", val);
if (s->out_data_len < sizeof (s->out_data)) { if ((size_t) s->out_data_len < sizeof (s->out_data)) {
s->out_data[s->out_data_len++] = val; s->out_data[s->out_data_len++] = val;
} }
} }
...@@ -1018,6 +1028,7 @@ static void reset_mixer (SB16State *s) ...@@ -1018,6 +1028,7 @@ static void reset_mixer (SB16State *s)
static IO_WRITE_PROTO(mixer_write_indexb) static IO_WRITE_PROTO(mixer_write_indexb)
{ {
SB16State *s = opaque; SB16State *s = opaque;
(void) nport;
s->mixer_nreg = val; s->mixer_nreg = val;
} }
...@@ -1025,10 +1036,8 @@ static IO_WRITE_PROTO(mixer_write_datab) ...@@ -1025,10 +1036,8 @@ static IO_WRITE_PROTO(mixer_write_datab)
{ {
SB16State *s = opaque; SB16State *s = opaque;
(void) nport;
ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val); ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
if (s->mixer_nreg > sizeof (s->mixer_regs)) {
return;
}
switch (s->mixer_nreg) { switch (s->mixer_nreg) {
case 0x00: case 0x00:
...@@ -1088,6 +1097,8 @@ static IO_WRITE_PROTO(mixer_write_indexw) ...@@ -1088,6 +1097,8 @@ static IO_WRITE_PROTO(mixer_write_indexw)
static IO_READ_PROTO(mixer_read) static IO_READ_PROTO(mixer_read)
{ {
SB16State *s = opaque; SB16State *s = opaque;
(void) nport;
#ifndef DEBUG_SB16_MOST #ifndef DEBUG_SB16_MOST
if (s->mixer_nreg != 0x82) { if (s->mixer_nreg != 0x82) {
ldebug ("mixer_read[%#x] -> %#x\n", ldebug ("mixer_read[%#x] -> %#x\n",
...@@ -1111,11 +1122,12 @@ static int write_audio (SB16State *s, int nchan, int dma_pos, ...@@ -1111,11 +1122,12 @@ static int write_audio (SB16State *s, int nchan, int dma_pos,
while (temp) { while (temp) {
int left = dma_len - dma_pos; int left = dma_len - dma_pos;
int to_copy, copied; int copied;
size_t to_copy;
to_copy = audio_MIN (temp, left); to_copy = audio_MIN (temp, left);
if (to_copy > sizeof(tmpbuf)) { if (to_copy > sizeof (tmpbuf)) {
to_copy = sizeof(tmpbuf); to_copy = sizeof (tmpbuf);
} }
copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy); copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
...@@ -1308,21 +1320,27 @@ static int SB_load (QEMUFile *f, void *opaque, int version_id) ...@@ -1308,21 +1320,27 @@ static int SB_load (QEMUFile *f, void *opaque, int version_id)
qemu_get_buffer (f, s->mixer_regs, 256); qemu_get_buffer (f, s->mixer_regs, 256);
if (s->voice) { if (s->voice) {
AUD_close_out (s->voice); AUD_close_out (&s->card, s->voice);
s->voice = NULL; s->voice = NULL;
} }
if (s->dma_running) { if (s->dma_running) {
if (s->freq) { if (s->freq) {
audsettings_t as;
s->audio_free = 0; s->audio_free = 0;
as.freq = s->freq;
as.nchannels = 1 << s->fmt_stereo;
as.fmt = s->fmt;
s->voice = AUD_open_out ( s->voice = AUD_open_out (
&s->card,
s->voice, s->voice,
"sb16", "sb16",
s, s,
SB_audio_callback, SB_audio_callback,
s->freq, &as
1 << s->fmt_stereo,
s->fmt
); );
} }
...@@ -1332,13 +1350,25 @@ static int SB_load (QEMUFile *f, void *opaque, int version_id) ...@@ -1332,13 +1350,25 @@ static int SB_load (QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
void SB16_init (void) int SB16_init (AudioState *audio)
{ {
SB16State *s = &dsp; SB16State *s;
int i; int i;
static const uint8_t dsp_write_ports[] = {0x6, 0xc}; static const uint8_t dsp_write_ports[] = {0x6, 0xc};
static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf}; static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
if (!audio) {
dolog ("No audio state\n");
return -1;
}
s = qemu_mallocz (sizeof (*s));
if (!s) {
dolog ("Could not allocate memory for SB16 (%d bytes)\n",
sizeof (*s));
return -1;
}
s->cmd = -1; s->cmd = -1;
s->irq = conf.irq; s->irq = conf.irq;
s->dma = conf.dma; s->dma = conf.dma;
...@@ -1356,7 +1386,7 @@ void SB16_init (void) ...@@ -1356,7 +1386,7 @@ void SB16_init (void)
reset_mixer (s); reset_mixer (s);
s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s); s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
if (!s->aux_ts) { if (!s->aux_ts) {
dolog ("Can not create auxiliary timer\n"); dolog ("warning: Could not create auxiliary timer\n");
} }
for (i = 0; i < LENOFA (dsp_write_ports); i++) { for (i = 0; i < LENOFA (dsp_write_ports); i++) {
...@@ -1377,4 +1407,6 @@ void SB16_init (void) ...@@ -1377,4 +1407,6 @@ void SB16_init (void)
s->can_write = 1; s->can_write = 1;
register_savevm ("sb16", 0, 1, SB_save, SB_load, s); register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
AUD_register_card (audio, "sb16", &s->card);
return 0;
} }
...@@ -95,12 +95,21 @@ NE2000 PCI network adapters ...@@ -95,12 +95,21 @@ NE2000 PCI network adapters
@item @item
Serial ports Serial ports
@item @item
Soundblaster 16 card Creative SoundBlaster 16 sound card
@item
ENSONIQ AudioPCI ES1370 sound card
@item
Adlib(OPL2) - Yamaha YM3812 compatible chip
@end itemize @end itemize
Note that adlib is only available when QEMU was configured with
-enable-adlib
QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
VGA BIOS. VGA BIOS.
QEMU uses YM3812 emulation by Tatsuyuki Satoh.
@c man end @c man end
@section Quick Start @section Quick Start
......
...@@ -2842,10 +2842,11 @@ void help(void) ...@@ -2842,10 +2842,11 @@ void help(void)
"-k language use keyboard layout (for example \"fr\" for French)\n" "-k language use keyboard layout (for example \"fr\" for French)\n"
#endif #endif
#ifdef HAS_AUDIO #ifdef HAS_AUDIO
"-enable-audio enable audio support\n" "-enable-audio enable audio support, and all the sound cars\n"
"-audio-help print list of audio drivers and their options\n" "-audio-help print list of audio drivers and their options\n"
"-soundhw c1,... comma separated list of sound card names\n" "-soundhw c1,... enable audio support\n"
" use -soundhw ? to get the list of supported sound cards\n" " and only specified sound cards (comma separated list)\n"
" use -soundhw ? to get the list of supported cards\n"
#endif #endif
"-localtime set the real time clock to local time [default=utc]\n" "-localtime set the real time clock to local time [default=utc]\n"
"-full-screen start in full screen\n" "-full-screen start in full screen\n"
...@@ -3145,9 +3146,9 @@ static void select_soundhw (const char *optarg) ...@@ -3145,9 +3146,9 @@ static void select_soundhw (const char *optarg)
printf ("sb16 Creative Sound Blaster 16\n"); printf ("sb16 Creative Sound Blaster 16\n");
#ifdef CONFIG_ADLIB #ifdef CONFIG_ADLIB
#ifdef HAS_YMF262 #ifdef HAS_YMF262
printf ("adlib Ymaha YMF262 (OPL3)\n"); printf ("adlib Yamaha YMF262 (OPL3)\n");
#else #else
printf ("adlib Ymaha YM3812 (OPL2)\n"); printf ("adlib Yamaha YM3812 (OPL2)\n");
#endif #endif
#endif #endif
#ifdef CONFIG_GUS #ifdef CONFIG_GUS
......
...@@ -631,16 +631,16 @@ int pmac_ide_init (BlockDriverState **hd_table, ...@@ -631,16 +631,16 @@ int pmac_ide_init (BlockDriverState **hd_table,
SetIRQFunc *set_irq, void *irq_opaque, int irq); SetIRQFunc *set_irq, void *irq_opaque, int irq);
/* es1370.c */ /* es1370.c */
int es1370_init (PCIBus *bus); int es1370_init (PCIBus *bus, AudioState *s);
/* sb16.c */ /* sb16.c */
void SB16_init (void); int SB16_init (AudioState *s);
/* adlib.c */ /* adlib.c */
void Adlib_init (void); int Adlib_init (AudioState *s);
/* gus.c */ /* gus.c */
void GUS_init (void); int GUS_init (AudioState *s);
/* dma.c */ /* dma.c */
typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size); typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册