summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlessandro Ghedini <alessandro@ghedini.me>2014-03-12 11:14:10 +0100
committerwm4 <wm4@nowhere>2014-03-13 14:36:20 +0100
commit3f0139e5db88b447a408547e0a59e071214e0cec (patch)
tree2723e682b0b7bcfdcc944ac274db2c885ab9792b
parent04e14ec8f69c66681808609046111bc225119e8e (diff)
downloadmpv-3f0139e5db88b447a408547e0a59e071214e0cec.tar.bz2
mpv-3f0139e5db88b447a408547e0a59e071214e0cec.tar.xz
af_volume: add replaygain support
This adds the options replaygain-track and replaygain-album. If either is set, the replaygain track or album gain will be automatically read from the track metadata and the volume adjusted accordingly. This only supports reading REPLAYGAIN_(TRACK|ALBUM)_GAIN tags. Other formats like LAME's info header would probably require support from libav.
-rw-r--r--DOCS/man/en/af.rst6
-rw-r--r--audio/filter/af_volume.c22
2 files changed, 28 insertions, 0 deletions
diff --git a/DOCS/man/en/af.rst b/DOCS/man/en/af.rst
index 65fa578dbe..902b9803fb 100644
--- a/DOCS/man/en/af.rst
+++ b/DOCS/man/en/af.rst
@@ -279,6 +279,12 @@ Available filters are:
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).
+ ``replaygain-track``
+ Adjust volume gain according to the track-gain replaygain value stored
+ in the file metadata. Note that this only supports reading REPLAYGAIN_*
+ tags, as written by mp3gain, metaflac, etc...
+ ``replaygain-album``
+ Like replaygain-track, but using the album-gain value instead.
``<softclip>``
Turns soft clipping on. Soft-clipping can make the
sound more smooth if very high volume levels are used. Enable this
diff --git a/audio/filter/af_volume.c b/audio/filter/af_volume.c
index 6a27081b28..ca331bf9b0 100644
--- a/audio/filter/af_volume.c
+++ b/audio/filter/af_volume.c
@@ -28,9 +28,12 @@
#include "common/common.h"
#include "af.h"
+#include "demux/demux.h"
struct priv {
float level; // Gain level for each channel
+ int rgain_track; // Enable/disable track based replaygain
+ int rgain_album; // Enable/disable album based replaygain
int soft; // Enable/disable soft clipping
int fast; // Use fix-point volume control
float cfg_volume;
@@ -54,6 +57,23 @@ static int control(struct af_instance *af, int cmd, void *arg)
}
if (af_fmt_is_planar(in->format))
mp_audio_set_format(af->data, af_fmt_to_planar(af->data->format));
+ if ((s->rgain_track || s->rgain_album) && af->metadata) {
+ char *rgain = NULL, *rest;
+ if (s->rgain_track) {
+ rgain = mp_tags_get_str(af->metadata, "REPLAYGAIN_TRACK_GAIN");
+ } else if (s->rgain_album) {
+ rgain = mp_tags_get_str(af->metadata, "REPLAYGAIN_ALBUM_GAIN");
+ }
+ if (rgain) {
+ float db = strtod(rgain, &rest);
+ if (rest && (rest != rgain) && isfinite(db))
+ af_from_dB(1, &db, &s->level, 20.0, -200.0, 60.0);
+ else
+ mp_msg(af->log, MSGL_ERR, "Invalid replaygain value\n");
+ } else {
+ mp_msg(af->log, MSGL_ERR, "Replaygain tags not found\n");
+ }
+ }
return af_test_output(af, in);
}
case AF_CONTROL_SET_VOLUME:
@@ -119,6 +139,8 @@ struct af_info af_info_volume = {
.priv_size = sizeof(struct priv),
.options = (const struct m_option[]) {
OPT_FLOATRANGE("volumedb", cfg_volume, 0, -200, 60),
+ OPT_FLAG("replaygain-track", rgain_track, 0),
+ OPT_FLAG("replaygain-album", rgain_album, 0),
OPT_FLAG("softclip", soft, 0),
OPT_FLAG("s16", fast, 0),
{0}