summaryrefslogtreecommitdiffstats
path: root/player/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/audio.c')
-rw-r--r--player/audio.c49
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;