summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-03-14 22:19:22 +0100
committerwm4 <wm4@nowhere>2014-03-14 22:37:46 +0100
commitb72ba3f7440c7c8ac811079303e69287f03ddd90 (patch)
tree1778b31be3d63fa91c730f4f0e6f61155222ba8e /audio
parent66bfb17979b42bc6e2437ad0bc04fa036da4f3de (diff)
downloadmpv-b72ba3f7440c7c8ac811079303e69287f03ddd90.tar.bz2
mpv-b72ba3f7440c7c8ac811079303e69287f03ddd90.tar.xz
af_volume: separate softvol volume control from replaygain level
Currently, both replaygain adjustment and user volume control (if softvol is enabled) share the same variable. Sharing the variable would cause especially if --volume is used; then the replaygain volume would always be overwritten. Now both gain values are simple added right before doing filtering.
Diffstat (limited to 'audio')
-rw-r--r--audio/filter/af_volume.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/audio/filter/af_volume.c b/audio/filter/af_volume.c
index a25e5204ea..4abbded822 100644
--- a/audio/filter/af_volume.c
+++ b/audio/filter/af_volume.c
@@ -31,7 +31,8 @@
#include "demux/demux.h"
struct priv {
- float level; // Gain level for each channel
+ float level; // User-specified gain level for each channel
+ float rgain; // Replaygain level
int rgain_track; // Enable/disable track based replaygain
int rgain_album; // Enable/disable album based replaygain
float rgain_preamp; // Set replaygain pre-amplification
@@ -129,10 +130,10 @@ static int control(struct af_instance *af, int cmd, void *arg)
!decode_peak(af, peak_tag, &peak))
{
gain += s->rgain_preamp;
- af_from_dB(1, &gain, &s->level, 20.0, -200.0, 60.0);
+ af_from_dB(1, &gain, &s->rgain, 20.0, -200.0, 60.0);
if (!s->rgain_clip) // clipping prevention
- s->level = MPMIN(s->level, 1.0 / peak);
+ s->rgain = MPMIN(s->rgain, 1.0 / peak);
}
}
return af_test_output(af, in);
@@ -151,9 +152,11 @@ static void filter_plane(struct af_instance *af, void *ptr, int num_samples)
{
struct priv *s = af->priv;
+ float level = s->level + s->rgain;
+
if (af_fmt_from_planar(af->data->format) == AF_FORMAT_S16) {
int16_t *a = ptr;
- int vol = 256.0 * s->level;
+ int vol = 256.0 * level;
if (vol != 256) {
for (int i = 0; i < num_samples; i++) {
int x = (a[i] * vol) >> 8;
@@ -162,7 +165,7 @@ static void filter_plane(struct af_instance *af, void *ptr, int num_samples)
}
} else if (af_fmt_from_planar(af->data->format) == AF_FORMAT_FLOAT) {
float *a = ptr;
- float vol = s->level;
+ float vol = level;
if (vol != 1.0) {
for (int i = 0; i < num_samples; i++) {
float x = a[i] * vol;