Commit 00e07679 authored by Michael Walle's avatar Michael Walle Committed by malc

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: default avatarMichael Walle <michael@walle.cc>
Signed-off-by: default avatarmalc <av1474@comtv.ru>
parent 0f136d9e
......@@ -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;
......
......@@ -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) {
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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
}
......@@ -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 */
......@@ -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
......@@ -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) {
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment