@@ -46,6 +46,7 @@ struct pollhlp {
typedef struct ALSAVoiceOut {
HWVoiceOut hw;
snd_pcm_t *handle;
+ size_t samples;
struct pollhlp pollhlp;
Audiodev *dev;
} ALSAVoiceOut;
@@ -53,6 +54,7 @@ typedef struct ALSAVoiceOut {
typedef struct ALSAVoiceIn {
HWVoiceIn hw;
snd_pcm_t *handle;
+ size_t samples;
struct pollhlp pollhlp;
Audiodev *dev;
} ALSAVoiceIn;
@@ -697,7 +699,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
obt_as.endianness = obt.endianness;
audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
+ alsa->samples = obt.samples;
alsa->pollhlp.s = hw->s;
alsa->handle = handle;
@@ -705,6 +707,12 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
return 0;
}
+static size_t alsa_buffer_size_out(HWVoiceOut *hw)
+{
+ ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
+ return alsa->samples;
+}
+
#define VOICE_CTL_PAUSE 0
#define VOICE_CTL_PREPARE 1
#define VOICE_CTL_START 2
@@ -791,7 +799,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
obt_as.endianness = obt.endianness;
audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
+ alsa->samples = obt.samples;
alsa->pollhlp.s = hw->s;
alsa->handle = handle;
@@ -799,6 +807,12 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
return 0;
}
+static size_t alsa_buffer_size_in(HWVoiceIn *hw)
+{
+ ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
+ return alsa->samples;
+}
+
static void alsa_fini_in (HWVoiceIn *hw)
{
ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
@@ -912,11 +926,13 @@ static void alsa_audio_fini (void *opaque)
static struct audio_pcm_ops alsa_pcm_ops = {
.init_out = alsa_init_out,
.fini_out = alsa_fini_out,
+ .buffer_size_out = alsa_buffer_size_out,
.write = alsa_write,
.ctl_out = alsa_ctl_out,
.init_in = alsa_init_in,
.fini_in = alsa_fini_in,
+ .buffer_size_in = alsa_buffer_size_in,
.read = alsa_read,
.ctl_in = alsa_ctl_in,
};
@@ -69,7 +69,6 @@ typedef struct HWVoiceOut {
void *buf_emul;
size_t pos_emul, pending_emul, size_emul;
- size_t samples;
QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
int ctl_caps;
@@ -92,7 +91,6 @@ typedef struct HWVoiceIn {
void *buf_emul;
size_t pos_emul, pending_emul, size_emul;
- size_t samples;
QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
int ctl_caps;
struct audio_pcm_ops *pcm_ops;
@@ -152,6 +150,8 @@ struct audio_pcm_ops {
int (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque);
void (*fini_out)(HWVoiceOut *hw);
size_t (*write) (HWVoiceOut *hw, void *buf, size_t size);
+ /* get the optimal buffer size in samples; optional */
+ size_t (*buffer_size_out)(HWVoiceOut *hw);
/* get a buffer that after later can be passed to put_buffer_out; optional
* returns the buffer, and writes it's size to size (in bytes)
* this is unrelated to the above buffer_size_out function */
@@ -165,6 +165,7 @@ struct audio_pcm_ops {
int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque);
void (*fini_in) (HWVoiceIn *hw);
size_t (*read) (HWVoiceIn *hw, void *buf, size_t size);
+ size_t (*buffer_size_in)(HWVoiceIn *hw);
void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size);
void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size);
int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
@@ -78,7 +78,12 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw)
{
- size_t samples = hw->samples;
+ size_t samples;
+ if (hw->pcm_ops->glue(buffer_size_, TYPE)) {
+ samples = hw->pcm_ops->glue(buffer_size_, TYPE)(hw);
+ } else {
+ samples = 1024; /* todo better default */
+ }
HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample)*samples);
HWBUF->size = samples;
@@ -261,11 +266,6 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
goto err0;
}
- if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
- dolog("hw->samples=%zu\n", hw->samples);
- goto err1;
- }
-
#ifdef DAC
hw->clip = mixeng_clip
#else
@@ -285,9 +285,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
#endif
return hw;
- err1:
- glue (hw->pcm_ops->fini_, TYPE) (hw);
- err0:
+err0:
g_free (hw);
return NULL;
}
@@ -40,6 +40,7 @@ typedef struct coreaudioVoiceOut {
AudioDeviceID outputDeviceID;
UInt32 audioDevicePropertyBufferFrameSize;
AudioStreamBasicDescription outputStreamBasicDescription;
+ size_t samples;
} coreaudioVoiceOut;
static void coreaudio_logstatus (OSStatus status)
@@ -366,7 +367,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
"Could not get device buffer frame size\n");
return -1;
}
- hw->samples = (pdo->has_buffer_count ? pdo->buffer_count : 4) *
+ core->samples = (pdo->has_buffer_count ? pdo->buffer_count : 4) *
core->audioDevicePropertyBufferFrameSize;
/* get StreamFormat */
@@ -435,6 +436,12 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
return 0;
}
+static size_t coreaudio_buffer_size_out(HWVoiceOut *hw)
+{
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
+ return core->samples;
+}
+
static void coreaudio_fini_out (HWVoiceOut *hw)
{
OSStatus status;
@@ -511,6 +518,7 @@ static struct audio_pcm_ops coreaudio_pcm_ops = {
.init_out = coreaudio_init_out,
.fini_out = coreaudio_fini_out,
.write = coreaudio_write,
+ .buffer_size_out = coreaudio_buffer_size_out,
.get_buffer_out = coreaudio_get_buffer_out,
.put_buffer_out = coreaudio_put_buffer_out_nowrite,
.ctl_out = coreaudio_ctl_out
@@ -254,7 +254,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
);
}
hw->size_emul = bc.dwBufferBytes;
- hw->samples = bc.dwBufferBytes >> hw->info.shift;
+ ds->samples = bc.dwBufferBytes >> hw->info.shift;
ds->s = s;
#ifdef DEBUG_DSOUND
@@ -268,6 +268,12 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
return -1;
}
+static size_t glue(dsound_buffer_size_, TYPE)(HWVOICE *hw)
+{
+ DSOUNDVOICE *ds = (DSOUNDVOICE *) hw;
+ return ds->samples;
+}
+
#undef NAME
#undef NAME2
#undef TYPE
@@ -53,12 +53,14 @@ typedef struct {
HWVoiceOut hw;
LPDIRECTSOUNDBUFFER dsound_buffer;
dsound *s;
+ size_t samples;
} DSoundVoiceOut;
typedef struct {
HWVoiceIn hw;
LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
dsound *s;
+ size_t samples;
} DSoundVoiceIn;
static void dsound_log_hresult (HRESULT hr)
@@ -671,6 +673,7 @@ static struct audio_pcm_ops dsound_pcm_ops = {
.init_out = dsound_init_out,
.fini_out = dsound_fini_out,
.write = audio_generic_write,
+ .buffer_size_out = dsound_buffer_size_out,
.get_buffer_out = dsound_get_buffer_out,
.put_buffer_out = dsound_put_buffer_out,
.ctl_out = dsound_ctl_out,
@@ -678,6 +681,7 @@ static struct audio_pcm_ops dsound_pcm_ops = {
.init_in = dsound_init_in,
.fini_in = dsound_fini_in,
.read = audio_generic_read,
+ .buffer_size_in = dsound_buffer_size_in,
.get_buffer_in = dsound_get_buffer_in,
.put_buffer_in = dsound_put_buffer_in,
.ctl_in = dsound_ctl_in
@@ -56,7 +56,6 @@ static size_t no_write(HWVoiceOut *hw, void *buf, size_t len)
static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
{
audio_pcm_init_info (&hw->info, as);
- hw->samples = 1024;
return 0;
}
@@ -75,7 +74,6 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
audio_pcm_init_info (&hw->info, as);
- hw->samples = 1024;
return 0;
}
@@ -46,6 +46,7 @@ typedef struct OSSVoiceOut {
int nfrags;
int fragsize;
int mmapped;
+ size_t samples;
Audiodev *dev;
} OSSVoiceOut;
@@ -54,6 +55,7 @@ typedef struct OSSVoiceIn {
int fd;
int nfrags;
int fragsize;
+ size_t samples;
Audiodev *dev;
} OSSVoiceIn;
@@ -513,11 +515,11 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
obt.nfrags * obt.fragsize, hw->info.align + 1);
}
- hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
+ oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
oss->mmapped = 0;
if (oopts->has_try_mmap && oopts->try_mmap) {
- hw->size_emul = hw->samples << hw->info.shift;
+ hw->size_emul = oss->samples << hw->info.shift;
hw->buf_emul = mmap (
NULL,
hw->size_emul,
@@ -565,6 +567,12 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
return 0;
}
+static size_t oss_buffer_size_out(HWVoiceOut *hw)
+{
+ OSSVoiceOut *oss = (OSSVoiceOut *) hw;
+ return oss->samples;
+}
+
static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
int trig;
@@ -587,7 +595,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
return 0;
}
- audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->samples);
+ audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, oss->samples);
trig = PCM_ENABLE_OUTPUT;
if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
oss_logerr (
@@ -660,13 +668,19 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
obt.nfrags * obt.fragsize, hw->info.align + 1);
}
- hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
+ oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
oss->fd = fd;
oss->dev = dev;
return 0;
}
+static size_t oss_buffer_size_in(HWVoiceIn *hw)
+{
+ OSSVoiceIn *oss = (OSSVoiceIn *) hw;
+ return oss->samples;
+}
+
static void oss_fini_in (HWVoiceIn *hw)
{
OSSVoiceIn *oss = (OSSVoiceIn *) hw;
@@ -755,6 +769,7 @@ static struct audio_pcm_ops oss_pcm_ops = {
.init_out = oss_init_out,
.fini_out = oss_fini_out,
.write = oss_write,
+ .buffer_size_out = oss_buffer_size_out,
.get_buffer_out = oss_get_buffer_out,
.put_buffer_out = oss_put_buffer_out,
.ctl_out = oss_ctl_out,
@@ -762,6 +777,7 @@ static struct audio_pcm_ops oss_pcm_ops = {
.init_in = oss_init_in,
.fini_in = oss_fini_in,
.read = oss_read,
+ .buffer_size_in = oss_buffer_size_in,
.ctl_in = oss_ctl_in
};
@@ -362,6 +362,13 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
return -1;
}
+static size_t qpa_buffer_size_out(HWVoiceOut *hw)
+{
+ PAVoiceOut *pa = (PAVoiceOut *) hw;
+ return pa->samples;
+}
+
+
static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
int error;
@@ -403,6 +410,12 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
return -1;
}
+static size_t qpa_buffer_size_in(HWVoiceIn *hw)
+{
+ PAVoiceIn *pa = (PAVoiceIn *) hw;
+ return pa->samples;
+}
+
static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
{
int err;
@@ -679,11 +692,13 @@ static struct audio_pcm_ops qpa_pcm_ops = {
.init_out = qpa_init_out,
.fini_out = qpa_fini_out,
.write = qpa_write,
+ .buffer_size_out = qpa_buffer_size_out,
.ctl_out = qpa_ctl_out,
.init_in = qpa_init_in,
.fini_in = qpa_fini_in,
.read = qpa_read,
+ .buffer_size_in = qpa_buffer_size_in,
.ctl_in = qpa_ctl_in
};
@@ -39,6 +39,7 @@
typedef struct SDLVoiceOut {
HWVoiceOut hw;
+ size_t samples;
} SDLVoiceOut;
static struct SDLAudioState {
@@ -335,7 +336,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
obt_as.endianness = endianness;
audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
+ sdl->samples = obt.samples;
s->initialized = 1;
s->exit = 0;
@@ -343,6 +344,12 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
return 0;
}
+static size_t sdl_buffer_size_out(HWVoiceOut *hw)
+{
+ SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
+ return sdl->samples;
+}
+
static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
(void) hw;
@@ -407,6 +414,7 @@ static struct audio_pcm_ops sdl_pcm_ops = {
.init_out = sdl_init_out,
.fini_out = sdl_fini_out,
.write = sdl_write,
+ .buffer_size_out = sdl_buffer_size_out,
.get_buffer_out = sdl_get_buffer_out,
.put_buffer_out = sdl_put_buffer_out_nowrite,
.ctl_out = sdl_ctl_out,
@@ -131,7 +131,6 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as,
settings.endianness = AUDIO_HOST_ENDIANNESS;
audio_pcm_init_info (&hw->info, &settings);
- hw->samples = LINE_OUT_SAMPLES;
out->active = 0;
out->sin.base.sif = &playback_sif.base;
@@ -142,6 +141,11 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as,
return 0;
}
+static size_t line_out_buffer_size(HWVoiceOut *hw)
+{
+ return LINE_OUT_SAMPLES;
+}
+
static void line_out_fini (HWVoiceOut *hw)
{
SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
@@ -246,7 +250,6 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
settings.endianness = AUDIO_HOST_ENDIANNESS;
audio_pcm_init_info (&hw->info, &settings);
- hw->samples = LINE_IN_SAMPLES;
in->active = 0;
in->sin.base.sif = &record_sif.base;
@@ -257,6 +260,11 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
return 0;
}
+static size_t line_in_buffer_size(HWVoiceIn *hw)
+{
+ return LINE_IN_SAMPLES;
+}
+
static void line_in_fini (HWVoiceIn *hw)
{
SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
@@ -327,6 +335,7 @@ static struct audio_pcm_ops audio_callbacks = {
.init_out = line_out_init,
.fini_out = line_out_fini,
.write = audio_generic_write,
+ .buffer_size_out = line_out_buffer_size,
.get_buffer_out = line_out_get_buffer,
.put_buffer_out = line_out_put_buffer,
.ctl_out = line_out_ctl,
@@ -334,6 +343,7 @@ static struct audio_pcm_ops audio_callbacks = {
.init_in = line_in_init,
.fini_in = line_in_fini,
.read = line_in_read,
+ .buffer_size_in = line_in_buffer_size,
.ctl_in = line_in_ctl,
};
@@ -108,7 +108,6 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as,
wav_as.endianness = 0;
audio_pcm_init_info (&hw->info, &wav_as);
- hw->samples = 1024;
le_store (hdr + 22, hw->info.nchannels, 2);
le_store (hdr + 24, hw->info.freq, 4);
le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
This patch removes the samples member from HWVoiceIn and HWVoiceOut. Backends can specify buffer size via the newly added buffer_size_in and buffer_size_out functions in audio_pcm_ops. They are optional, if not defined qemu will fall back to some built-in constant. Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com> --- Not sure if this is necessary. At first it seemed like a good idea to have a function so that backends can compute the size on demand when needed and things like that, but currently it's just a burden. The only good feature is that it allows a backend to not define a function and let the audio subsystem choose a default value, but the same could be achieved by specifying that hw->samples = 0 means use a default value. So if you guys agree, I'll remove this patch. Maybe add an -audiodev parameter to change it, overriding whatever the backends supplies. audio/alsaaudio.c | 20 ++++++++++++++++++-- audio/audio_int.h | 5 +++-- audio/audio_template.h | 16 +++++++--------- audio/coreaudio.c | 10 +++++++++- audio/dsound_template.h | 8 +++++++- audio/dsoundaudio.c | 4 ++++ audio/noaudio.c | 2 -- audio/ossaudio.c | 24 ++++++++++++++++++++---- audio/paaudio.c | 15 +++++++++++++++ audio/sdlaudio.c | 10 +++++++++- audio/spiceaudio.c | 14 ++++++++++++-- audio/wavaudio.c | 1 - 12 files changed, 104 insertions(+), 25 deletions(-)