summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Walle <michael@walle.cc>2011-01-05 01:05:47 +0100
committermalc <av1474@comtv.ru>2011-01-12 18:36:22 +0300
commit00e076795f2d6dfa0c078ff5d5ee5d77190cb4b9 (patch)
tree125088eea53cc55083a5b69e927937b89db22645
parent0f136d9e060ad879d0b840274ddfd1955e24fc10 (diff)
downloadqemu-00e076795f2d6dfa0c078ff5d5ee5d77190cb4b9.tar.gz
qemu-00e076795f2d6dfa0c078ff5d5ee5d77190cb4b9.tar.bz2
qemu-00e076795f2d6dfa0c078ff5d5ee5d77190cb4b9.zip
audio: split sample conversion and volume mixing
Refactor the volume mixing, so it can be reused for capturing devices. Additionally, it removes superfluous multiplications with the nominal volume within the hardware voice code path. Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: malc <av1474@comtv.ru>
-rw-r--r--audio/alsaaudio.c2
-rw-r--r--audio/audio.c11
-rw-r--r--audio/audio_int.h2
-rw-r--r--audio/dsoundaudio.c4
-rw-r--r--audio/esdaudio.c3
-rw-r--r--audio/fmodaudio.c4
-rw-r--r--audio/mixeng.c25
-rw-r--r--audio/mixeng.h4
-rw-r--r--audio/mixeng_template.h39
-rw-r--r--audio/ossaudio.c3
-rw-r--r--audio/paaudio.c2
-rw-r--r--audio/spiceaudio.c5
-rw-r--r--audio/winwaveaudio.c3
13 files changed, 52 insertions, 55 deletions
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 727b9f84c3..4d720146df 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -1097,7 +1097,7 @@ static int alsa_run_in (HWVoiceIn *hw)
}
}
- hw->conv (dst, src, nread, &nominal_volume);
+ hw->conv (dst, src, nread);
src = advance (src, nread << hwshift);
dst += nread;
diff --git a/audio/audio.c b/audio/audio.c
index 17074469b2..1729c0be2c 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -104,7 +104,7 @@ static struct {
static AudioState glob_audio_state;
-struct mixeng_volume nominal_volume = {
+const struct mixeng_volume nominal_volume = {
.mute = 0,
#ifdef FLOAT_MIXENG
.r = 1.0,
@@ -702,13 +702,11 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
/*
* Capture
*/
-static void noop_conv (struct st_sample *dst, const void *src,
- int samples, struct mixeng_volume *vol)
+static void noop_conv (struct st_sample *dst, const void *src, int samples)
{
(void) src;
(void) dst;
(void) samples;
- (void) vol;
}
static CaptureVoiceOut *audio_pcm_capture_find_specific (
@@ -956,6 +954,8 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
total += isamp;
}
+ mixeng_volume (sw->buf, ret, &sw->vol);
+
sw->clip (buf, sw->buf, ret);
sw->total_hw_samples_acquired += total;
return ret << sw->info.shift;
@@ -1037,7 +1037,8 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
swlim = ((int64_t) dead << 32) / sw->ratio;
swlim = audio_MIN (swlim, samples);
if (swlim) {
- sw->conv (sw->buf, buf, swlim, &sw->vol);
+ sw->conv (sw->buf, buf, swlim);
+ mixeng_volume (sw->buf, swlim, &sw->vol);
}
while (swlim) {
diff --git a/audio/audio_int.h b/audio/audio_int.h
index d66f2c3bf6..2003f8bf20 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -211,7 +211,7 @@ extern struct audio_driver esd_audio_driver;
extern struct audio_driver pa_audio_driver;
extern struct audio_driver spice_audio_driver;
extern struct audio_driver winwave_audio_driver;
-extern struct mixeng_volume nominal_volume;
+extern const struct mixeng_volume nominal_volume;
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index e5479555fa..e2d89fd5d5 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -831,11 +831,11 @@ static int dsound_run_in (HWVoiceIn *hw)
decr = len1 + len2;
if (p1 && len1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
+ hw->conv (hw->conv_buf + hw->wpos, p1, len1);
}
if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
+ hw->conv (hw->conv_buf, p2, len2);
}
dsound_unlock_in (dscb, p1, p2, blen1, blen2);
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
index 9a1f2f8617..ff97b397d2 100644
--- a/audio/esdaudio.c
+++ b/audio/esdaudio.c
@@ -346,8 +346,7 @@ static void *qesd_thread_in (void *arg)
break;
}
- hw->conv (hw->conv_buf + wpos, buf, nread >> hw->info.shift,
- &nominal_volume);
+ hw->conv (hw->conv_buf + wpos, buf, nread >> hw->info.shift);
wpos = (wpos + chunk) % hw->samples;
to_grab -= chunk;
}
diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c
index 7f08e14718..c34cf53567 100644
--- a/audio/fmodaudio.c
+++ b/audio/fmodaudio.c
@@ -488,10 +488,10 @@ static int fmod_run_in (HWVoiceIn *hw)
decr = len1 + len2;
if (p1 && blen1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
+ hw->conv (hw->conv_buf + hw->wpos, p1, len1);
}
if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
+ hw->conv (hw->conv_buf, p2, len2);
}
fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 9f1d93fcfc..4a9e8ebe2a 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -333,3 +333,28 @@ void mixeng_clear (struct st_sample *buf, int len)
{
memset (buf, 0, len * sizeof (struct st_sample));
}
+
+void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
+{
+#ifdef CONFIG_MIXEMU
+ if (vol->mute) {
+ mixeng_clear (buf, len);
+ return;
+ }
+
+ while (len--) {
+#ifdef FLOAT_MIXENG
+ buf->l = buf->l * vol->l;
+ buf->r = buf->r * vol->r;
+#else
+ buf->l = (buf->l * vol->l) >> 32;
+ buf->r = (buf->r * vol->r) >> 32;
+#endif
+ buf += 1;
+ }
+#else
+ (void) buf;
+ (void) len;
+ (void) vol;
+#endif
+}
diff --git a/audio/mixeng.h b/audio/mixeng.h
index 4af1dd9891..9de443b01d 100644
--- a/audio/mixeng.h
+++ b/audio/mixeng.h
@@ -33,8 +33,7 @@ struct mixeng_volume { int mute; int64_t r; int64_t l; };
struct st_sample { int64_t l; int64_t r; };
#endif
-typedef void (t_sample) (struct st_sample *dst, const void *src,
- int samples, struct mixeng_volume *vol);
+typedef void (t_sample) (struct st_sample *dst, const void *src, int samples);
typedef void (f_sample) (void *dst, const struct st_sample *src, int samples);
extern t_sample *mixeng_conv[2][2][2][3];
@@ -47,5 +46,6 @@ void st_rate_flow_mix (void *opaque, struct st_sample *ibuf, struct st_sample *o
int *isamp, int *osamp);
void st_rate_stop (void *opaque);
void mixeng_clear (struct st_sample *buf, int len);
+void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol);
#endif /* mixeng.h */
diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h
index 56177056ce..a2d0ef84fd 100644
--- a/audio/mixeng_template.h
+++ b/audio/mixeng_template.h
@@ -31,16 +31,6 @@
#define HALF (IN_MAX >> 1)
#endif
-#ifdef CONFIG_MIXEMU
-#ifdef FLOAT_MIXENG
-#define VOL(a, b) ((a) * (b))
-#else
-#define VOL(a, b) ((a) * (b)) >> 32
-#endif
-#else
-#define VOL(a, b) a
-#endif
-
#define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
#ifdef FLOAT_MIXENG
@@ -109,40 +99,26 @@ static inline IN_T glue (clip_, ET) (int64_t v)
#endif
static void glue (glue (conv_, ET), _to_stereo)
- (struct st_sample *dst, const void *src, int samples, struct mixeng_volume *vol)
+ (struct st_sample *dst, const void *src, int samples)
{
struct st_sample *out = dst;
IN_T *in = (IN_T *) src;
-#ifdef CONFIG_MIXEMU
- if (vol->mute) {
- mixeng_clear (dst, samples);
- return;
- }
-#else
- (void) vol;
-#endif
+
while (samples--) {
- out->l = VOL (glue (conv_, ET) (*in++), vol->l);
- out->r = VOL (glue (conv_, ET) (*in++), vol->r);
+ out->l = glue (conv_, ET) (*in++);
+ out->r = glue (conv_, ET) (*in++);
out += 1;
}
}
static void glue (glue (conv_, ET), _to_mono)
- (struct st_sample *dst, const void *src, int samples, struct mixeng_volume *vol)
+ (struct st_sample *dst, const void *src, int samples)
{
struct st_sample *out = dst;
IN_T *in = (IN_T *) src;
-#ifdef CONFIG_MIXEMU
- if (vol->mute) {
- mixeng_clear (dst, samples);
- return;
- }
-#else
- (void) vol;
-#endif
+
while (samples--) {
- out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
+ out->l = glue (conv_, ET) (in[0]);
out->r = out->l;
out += 1;
in += 1;
@@ -174,4 +150,3 @@ static void glue (glue (clip_, ET), _from_mono)
#undef ET
#undef HALF
-#undef VOL
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index d7a55e5441..b49e102747 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -788,8 +788,7 @@ static int oss_run_in (HWVoiceIn *hw)
hw->info.align + 1);
}
read_samples += nread >> hwshift;
- hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift,
- &nominal_volume);
+ hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift);
}
if (bufs[i].len - nread) {
diff --git a/audio/paaudio.c b/audio/paaudio.c
index ff71dac2a5..9cf685d30f 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -195,7 +195,7 @@ static void *qpa_thread_in (void *arg)
return NULL;
}
- hw->conv (hw->conv_buf + wpos, buf, chunk, &nominal_volume);
+ hw->conv (hw->conv_buf + wpos, buf, chunk);
wpos = (wpos + chunk) % hw->samples;
to_grab -= chunk;
}
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index 373e4c43ed..a5c0d6bc66 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -268,11 +268,10 @@ static int line_in_run (HWVoiceIn *hw)
len[1] = 0;
}
- hw->conv (hw->conv_buf + hw->wpos, samples, len[0], &nominal_volume);
+ hw->conv (hw->conv_buf + hw->wpos, samples, len[0]);
if (len[1]) {
- hw->conv (hw->conv_buf, samples + len[0], len[1],
- &nominal_volume);
+ hw->conv (hw->conv_buf, samples + len[0], len[1]);
}
hw->wpos = (hw->wpos + num_samples) % hw->samples;
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
index cdf483b89a..e5ad3c6604 100644
--- a/audio/winwaveaudio.c
+++ b/audio/winwaveaudio.c
@@ -581,8 +581,7 @@ static int winwave_run_in (HWVoiceIn *hw)
int conv = audio_MIN (left, decr);
hw->conv (hw->conv_buf + hw->wpos,
advance (wave->pcm_buf, wave->rpos << hw->info.shift),
- conv,
- &nominal_volume);
+ conv);
wave->rpos = (wave->rpos + conv) % hw->samples;
hw->wpos = (hw->wpos + conv) % hw->samples;