diff options
Diffstat (limited to 'player/audio.c')
-rw-r--r-- | player/audio.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/player/audio.c b/player/audio.c index b2e44c23dd..dd464614d9 100644 --- a/player/audio.c +++ b/player/audio.c @@ -119,6 +119,54 @@ fail: mp_notify(mpctx, MP_EVENT_CHANGE_ALL, NULL); } +// Convert to gain value from dB. input <= -200dB will become 0 gain. +// Copyright (C)2002 Anders Johansson +static float from_dB(float in, float k, float mi, float ma) +{ + if (in <= -200) + return 0.0; + return pow(10.0, MPCLAMP(in, mi, ma) / k); +} + +static float compute_replaygain(struct MPContext *mpctx) +{ + struct MPOpts *opts = mpctx->opts; + struct ao_chain *ao_c = mpctx->ao_chain; + + float rgain = 1.0; + + struct replaygain_data *rg = ao_c->af->replaygain_data; + if ((opts->rgain_track || opts->rgain_album) && rg) { + MP_VERBOSE(mpctx, "Replaygain: Track=%f/%f Album=%f/%f\n", + rg->track_gain, rg->track_peak, + rg->album_gain, rg->album_peak); + + float gain, peak; + if (opts->rgain_track) { + gain = rg->track_gain; + peak = rg->track_peak; + } else { + gain = rg->album_gain; + peak = rg->album_peak; + } + + gain += opts->rgain_preamp; + rgain = from_dB(gain, 20.0, -200.0, 60.0); + + MP_VERBOSE(mpctx, "Applying replay-gain: %f\n", rgain); + + if (!opts->rgain_clip) { // clipping prevention + rgain = MPMIN(rgain, 1.0 / peak); + MP_VERBOSE(mpctx, "...with clipping prevention: %f\n", rgain); + } + } else if (opts->rgain_fallback) { + rgain = from_dB(opts->rgain_fallback, 20.0, -200.0, 60.0); + MP_VERBOSE(mpctx, "Applying fallback gain: %f\n", rgain); + } + + return rgain; +} + // Called when opts->softvol_volume or opts->softvol_mute were changed. void audio_update_volume(struct MPContext *mpctx) { @@ -128,6 +176,7 @@ void audio_update_volume(struct MPContext *mpctx) return; float gain = MPMAX(opts->softvol_volume / 100.0, 0); + gain *= compute_replaygain(mpctx); if (opts->softvol_mute == 1) gain = 0.0; |