mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-28 23:13:18 +08:00
af_volume: switch to new option parsing
This commit is contained in:
+7
-7
@@ -259,7 +259,7 @@ Available filters are:
|
||||
Filter for internal use only. Converts between signed/unsigned formats
|
||||
and formats with different endian.
|
||||
|
||||
``volume[=v[:sc[:fast]]]``
|
||||
``volume[=volumedb[:softclip[:s16]]]``
|
||||
Implements software volume control. Use this filter with caution since it
|
||||
can reduce the signal to noise ratio of the sound. In most cases it is
|
||||
best to use the *Master* volume control of your sound card or the volume
|
||||
@@ -268,24 +268,24 @@ Available filters are:
|
||||
*NOTE*: This filter is not reentrant and can therefore only be enabled
|
||||
once for every audio stream.
|
||||
|
||||
``<v>``
|
||||
``<volumedb>``
|
||||
Sets the desired gain in dB for all channels in the stream from -200dB
|
||||
to +60dB, where -200dB mutes the sound completely and +60dB equals a
|
||||
gain of 1000 (default: 0).
|
||||
``<sc>``
|
||||
Turns soft clipping on (1) or off (0). Soft-clipping can make the
|
||||
``<softclip>``
|
||||
Turns soft clipping on. Soft-clipping can make the
|
||||
sound more smooth if very high volume levels are used. Enable this
|
||||
option if the dynamic range of the loudspeakers is very low.
|
||||
|
||||
*WARNING*: This feature creates distortion and should be considered a
|
||||
last resort.
|
||||
``<fast>``
|
||||
Force S16 sample format if set to 1. Lower quality, but might be faster
|
||||
``<s16>``
|
||||
Force S16 sample format if set. Lower quality, but might be faster
|
||||
in some situations.
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv --af=volume=10.1:0 media.avi``
|
||||
``mpv --af=volume=10.1 media.avi``
|
||||
Would amplify the sound by 10.1dB and hard-clip if the sound level
|
||||
is too high.
|
||||
|
||||
|
||||
+18
-31
@@ -34,12 +34,13 @@ typedef struct af_volume_s
|
||||
float level[AF_NCH]; // Gain level for each channel
|
||||
int soft; // Enable/disable soft clipping
|
||||
int fast; // Use fix-point volume control
|
||||
float cfg_volume;
|
||||
} af_volume_t;
|
||||
|
||||
// Initialization and runtime control
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
af_volume_t *s = (af_volume_t *)af->setup;
|
||||
af_volume_t *s = af->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT:
|
||||
@@ -49,25 +50,12 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
mp_audio_copy_config(af->data, (struct mp_audio *)arg);
|
||||
|
||||
if (s->fast && (((struct mp_audio *)arg)->format != (AF_FORMAT_FLOAT_NE)))
|
||||
if (s->fast && (((struct mp_audio *)arg)->format != AF_FORMAT_FLOAT_NE))
|
||||
mp_audio_set_format(af->data, AF_FORMAT_S16_NE);
|
||||
else {
|
||||
// Cutoff set to 10Hz for forgetting factor
|
||||
mp_audio_set_format(af->data, AF_FORMAT_FLOAT_NE);
|
||||
}
|
||||
return af_test_output(af, (struct mp_audio *)arg);
|
||||
case AF_CONTROL_COMMAND_LINE: {
|
||||
float v = 1000.0;
|
||||
float vol[AF_NCH];
|
||||
int i;
|
||||
sscanf((char *)arg, "%f:%i:%i", &v, &s->soft, &s->fast);
|
||||
float dest = 0.0;
|
||||
if (v < 1000)
|
||||
af_from_dB(1, &v, &dest, 20.0, -200.0, 60.0);
|
||||
for (i = 0; i < AF_NCH; i++)
|
||||
vol[i] = dest;
|
||||
return control(af, AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol);
|
||||
}
|
||||
case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET:
|
||||
memcpy(s->level, arg, sizeof(float) * AF_NCH);
|
||||
return AF_OK;
|
||||
@@ -78,18 +66,11 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
// Deallocate memory
|
||||
static void uninit(struct af_instance *af)
|
||||
{
|
||||
free(af->data);
|
||||
free(af->setup);
|
||||
}
|
||||
|
||||
// Filter data through filter
|
||||
static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
struct mp_audio *c = data; // Current working data
|
||||
af_volume_t *s = (af_volume_t *)af->setup; // Setup for this instance
|
||||
af_volume_t *s = af->priv;
|
||||
int nch = c->nch; // Number of channels
|
||||
|
||||
if (af->data->format == AF_FORMAT_S16_NE) {
|
||||
@@ -124,27 +105,33 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
return c;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
struct af_volume_s *priv = af->priv;
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
af->data = calloc(1, sizeof(struct mp_audio));
|
||||
af->setup = calloc(1, sizeof(af_volume_t));
|
||||
if (af->data == NULL || af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
// Enable volume control and set initial volume to 0dB.
|
||||
af->data = talloc_zero(af, struct mp_audio);
|
||||
float level;
|
||||
af_from_dB(1, &priv->cfg_volume, &level, 20.0, -200.0, 60.0);
|
||||
for (int i = 0; i < AF_NCH; i++)
|
||||
((af_volume_t *)af->setup)->level[i] = 1.0;
|
||||
priv->level[i] = level;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct af_volume_s
|
||||
|
||||
// Description of this filter
|
||||
struct af_info af_info_volume = {
|
||||
.info = "Volume control audio filter",
|
||||
.name = "volume",
|
||||
.flags = AF_FLAGS_NOT_REENTRANT,
|
||||
.open = af_open,
|
||||
.priv_size = sizeof(struct af_volume_s),
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_FLOATRANGE("volumedb", cfg_volume, 0, -200, 60),
|
||||
OPT_FLAG("softclip", soft, 0),
|
||||
OPT_FLAG("s16", fast, 0),
|
||||
{0}
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user