af_volume: use only one volume setting for all channels

In theory, af_volume could use separate volume levels for each channel.
But this was never used anywhere.

MPlayer implemented something similar before (svn r36498), but kept the
old path for some reason.
This commit is contained in:
wm4 2013-11-09 23:25:31 +01:00
parent 0f82107535
commit d6abfcd578
2 changed files with 22 additions and 34 deletions

View File

@ -30,7 +30,7 @@
#include "af.h"
struct priv {
float level[AF_NCH]; // Gain level for each channel
float level; // Gain level for each channel
int soft; // Enable/disable soft clipping
int fast; // Use fix-point volume control
float cfg_volume;
@ -51,10 +51,10 @@ static int control(struct af_instance *af, int cmd, void *arg)
}
return af_test_output(af, (struct mp_audio *)arg);
case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET:
memcpy(s->level, arg, sizeof(float) * AF_NCH);
s->level = *(float *)arg;
return AF_OK;
case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET:
memcpy(arg, s->level, sizeof(float) * AF_NCH);
*(float *)arg = s->level;
return AF_OK;
}
return AF_UNKNOWN;
@ -64,30 +64,25 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
{
struct mp_audio *c = data;
struct priv *s = af->priv;
int nch = c->nch;
if (af->data->format == AF_FORMAT_S16_NE) {
int16_t *a = c->audio;
int len = c->len / 2;
for (int ch = 0; ch < nch; ch++) {
int vol = 256.0 * s->level[ch];
if (vol != 256) {
for (int i = ch; i < len; i += nch) {
int x = (a[i] * vol) >> 8;
a[i] = MPCLAMP(x, SHRT_MIN, SHRT_MAX);
}
int vol = 256.0 * s->level;
if (vol != 256) {
for (int i = 0; i < len; i++) {
int x = (a[i] * vol) >> 8;
a[i] = MPCLAMP(x, SHRT_MIN, SHRT_MAX);
}
}
} else if (af->data->format == AF_FORMAT_FLOAT_NE) {
float *a = c->audio;
int len = c->len / 4;
for (int ch = 0; ch < nch; ch++) {
if (s->level[ch] != 1.0) {
for (int i = ch; i < len; i += nch) {
float x = a[i];
x *= s->level[ch];
a[i] = s->soft ? af_softclip(x) : MPCLAMP(x, -1.0, 1.0);
}
float vol = s->level;
if (vol != 1.0) {
for (int i = 0; i < len; i++) {
float x = a[i] * vol;
a[i] = s->soft ? af_softclip(x) : MPCLAMP(x, -1.0, 1.0);
}
}
}
@ -101,10 +96,7 @@ static int af_open(struct af_instance *af)
af->play = play;
af->mul = 1;
af->data = talloc_zero(af, struct mp_audio);
float level;
af_from_dB(1, &s->cfg_volume, &level, 20.0, -200.0, 60.0);
for (int i = 0; i < AF_NCH; i++)
s->level[i] = level;
af_from_dB(1, &s->cfg_volume, &s->level, 20.0, -200.0, 60.0);
return AF_OK;
}

View File

@ -71,12 +71,12 @@ static void checkvolume(struct mixer *mixer)
ao_control_vol_t vol = {mixer->vol_l, mixer->vol_r};
if (mixer->softvol) {
float vals[AF_NCH];
float gain;
if (!af_control_any_rev(mixer->af,
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET, vals))
vals[0] = vals[1] = 1.0;
vol.left = (vals[0] / (mixer->opts->softvol_max / 100.0)) * 100.0;
vol.right = (vals[1] / (mixer->opts->softvol_max / 100.0)) * 100.0;
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET, &gain))
gain = 1.0;
vol.left = (gain / (mixer->opts->softvol_max / 100.0)) * 100.0;
vol.right = (gain / (mixer->opts->softvol_max / 100.0)) * 100.0;
} else {
// Rely on the values not changing if the query is not supported
ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol);
@ -118,20 +118,16 @@ static void setvolume_internal(struct mixer *mixer, float l, float r)
"[Mixer] Failed to change audio output volume.\n");
return;
}
float vals[AF_NCH];
vals[0] = l / 100.0 * mixer->opts->softvol_max / 100.0;
vals[1] = r / 100.0 * mixer->opts->softvol_max / 100.0;
for (int i = 2; i < AF_NCH; i++)
vals[i] = (vals[0] + vals[1]) / 2.0;
float gain = (l + r) / 2.0 / 100.0 * mixer->opts->softvol_max / 100.0;
if (!af_control_any_rev(mixer->af,
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET,
vals))
&gain))
{
mp_tmsg(MSGT_GLOBAL, MSGL_V, "[Mixer] Inserting volume filter.\n");
if (!(af_add(mixer->af, "volume", NULL)
&& af_control_any_rev(mixer->af,
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET,
vals)))
&gain)))
mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
"[Mixer] No volume control available.\n");
}