From f04727145bf0e7c651e08592360fb22a101d3f43 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Sun, 17 Dec 2023 14:43:38 -0500 Subject: [PATCH] audio: add --volume-gain options to control volume in decibels This adds volume-gain, volume-gain-max, volume-gain-min options, which can be used to control audio volume and target dynamic range in decibels. The gain is applied on top of the existing volume setting. --- options/options.c | 7 +++++++ options/options.h | 3 +++ player/audio.c | 1 + player/command.c | 27 +++++++++++++++++++++++++-- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/options/options.c b/options/options.c index fcf2c9f1d0..c94ca891a6 100644 --- a/options/options.c +++ b/options/options.c @@ -705,6 +705,10 @@ static const m_option_t mp_opts[] = { // values <0 for volume and mute are legacy and ignored {"volume", OPT_FLOAT(softvol_volume), .flags = UPDATE_VOL, M_RANGE(-1, 1000)}, + {"volume-gain-max", OPT_FLOAT(softvol_gain_max), M_RANGE(0, 150)}, + {"volume-gain-min", OPT_FLOAT(softvol_gain_min), M_RANGE(-150, 0)}, + {"volume-gain", OPT_FLOAT(softvol_gain), .flags = UPDATE_VOL, + M_RANGE(-150, 150)}, {"mute", OPT_CHOICE(softvol_mute, {"no", 0}, {"auto", 0}, @@ -928,6 +932,9 @@ static const struct MPOpts mp_default_opts = { .msg_color = true, .softvol_max = 130, .softvol_volume = 100, + .softvol_gain_max = 12, + .softvol_gain_min = -96, + .softvol_gain = 0, .gapless_audio = -1, .wintitle = "${?media-title:${media-title}}${!media-title:No file} - mpv", .stop_screensaver = 1, diff --git a/options/options.h b/options/options.h index 36bf1812c6..c951bcb748 100644 --- a/options/options.h +++ b/options/options.h @@ -186,6 +186,9 @@ typedef struct MPOpts { float rgain_fallback; int softvol_mute; float softvol_max; + float softvol_gain; + float softvol_gain_min; + float softvol_gain_max; int gapless_audio; mp_vo_opts *vo; diff --git a/player/audio.c b/player/audio.c index ca17d3325b..344fbdb744 100644 --- a/player/audio.c +++ b/player/audio.c @@ -175,6 +175,7 @@ void audio_update_volume(struct MPContext *mpctx) float gain = MPMAX(opts->softvol_volume / 100.0, 0); gain = pow(gain, 3); gain *= compute_replaygain(mpctx); + gain *= db_gain(opts->softvol_gain); if (opts->softvol_mute == 1) gain = 0.0; diff --git a/player/command.c b/player/command.c index c080e779fa..315ebf77c1 100644 --- a/player/command.c +++ b/player/command.c @@ -1625,6 +1625,28 @@ static int mp_property_volume(void *ctx, struct m_property *prop, return mp_property_generic_option(mpctx, prop, action, arg); } +static int mp_property_volume_gain(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + struct MPOpts *opts = mpctx->opts; + + switch (action) { + case M_PROPERTY_GET_CONSTRICTED_TYPE: + *(struct m_option *)arg = (struct m_option){ + .type = CONF_TYPE_FLOAT, + .min = opts->softvol_gain_min, + .max = opts->softvol_gain_max, + }; + return M_PROPERTY_OK; + case M_PROPERTY_PRINT: + *(char **)arg = talloc_asprintf(NULL, "%.1f", opts->softvol_gain); + return M_PROPERTY_OK; + } + + return mp_property_generic_option(mpctx, prop, action, arg); +} + static int mp_property_ao_volume(void *ctx, struct m_property *prop, int action, void *arg) { @@ -3872,6 +3894,7 @@ static const struct m_property mp_properties_base[] = { // Audio {"mixer-active", mp_property_mixer_active}, {"volume", mp_property_volume}, + {"volume-gain", mp_property_volume_gain}, {"ao-volume", mp_property_ao_volume}, {"ao-mute", mp_property_ao_mute}, {"audio-delay", mp_property_audio_delay}, @@ -4033,9 +4056,9 @@ static const char *const *const mp_event_property_change[] = { "video-dec-params", "osd-dimensions", "hwdec", "hwdec-current", "hwdec-interop"), E(MPV_EVENT_AUDIO_RECONFIG, "audio-format", "audio-codec", "audio-bitrate", - "samplerate", "channels", "audio", "volume", "mute", + "samplerate", "channels", "audio", "volume", "volume-gain", "mute", "current-ao", "audio-codec-name", "audio-params", - "audio-out-params", "volume-max", "mixer-active"), + "audio-out-params", "volume-max", "volume-gain-min", "volume-gain-max", "mixer-active"), E(MPV_EVENT_SEEK, "seeking", "core-idle", "eof-reached"), E(MPV_EVENT_PLAYBACK_RESTART, "seeking", "core-idle", "eof-reached"), E(MP_EVENT_METADATA_UPDATE, "metadata", "filtered-metadata", "media-title"),