Commit 878f8b0d authored by Michael Niedermayer's avatar Michael Niedermayer

Merge commit 'aaab192d'

* commit 'aaab192d':
  af_volume: implement replaygain clipping prevention

Conflicts:
	doc/filters.texi
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents c11aa9d2 aaab192d
...@@ -1911,6 +1911,11 @@ The command accepts the same syntax of the corresponding option. ...@@ -1911,6 +1911,11 @@ The command accepts the same syntax of the corresponding option.
If the specified expression is not valid, it is kept at its current If the specified expression is not valid, it is kept at its current
value. value.
@item replaygain_noclip
Prevent clipping by limiting the gain applied.
Default value for @var{replaygain_noclip} is 1.
@end table @end table
@subsection Examples @subsection Examples
......
...@@ -81,6 +81,8 @@ static const AVOption volume_options[] = { ...@@ -81,6 +81,8 @@ static const AVOption volume_options[] = {
{ "album", "album gain is preferred", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_ALBUM }, 0, 0, A, "replaygain" }, { "album", "album gain is preferred", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_ALBUM }, 0, 0, A, "replaygain" },
{ "replaygain_preamp", "Apply replaygain pre-amplification", { "replaygain_preamp", "Apply replaygain pre-amplification",
OFFSET(replaygain_preamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, -15.0, 15.0, A }, OFFSET(replaygain_preamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, -15.0, 15.0, A },
{ "replaygain_noclip", "Apply replaygain clipping prevention",
OFFSET(replaygain_noclip), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, A },
{ NULL }, { NULL },
}; };
...@@ -342,25 +344,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) ...@@ -342,25 +344,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
if (sd && vol->replaygain != REPLAYGAIN_IGNORE) { if (sd && vol->replaygain != REPLAYGAIN_IGNORE) {
if (vol->replaygain != REPLAYGAIN_DROP) { if (vol->replaygain != REPLAYGAIN_DROP) {
AVReplayGain *replaygain = (AVReplayGain*)sd->data; AVReplayGain *replaygain = (AVReplayGain*)sd->data;
int32_t gain; int32_t gain = 100000;
float g; uint32_t peak = 100000;
float g, p;
if (vol->replaygain == REPLAYGAIN_TRACK && if (vol->replaygain == REPLAYGAIN_TRACK &&
replaygain->track_gain != INT32_MIN) replaygain->track_gain != INT32_MIN) {
gain = replaygain->track_gain; gain = replaygain->track_gain;
else if (replaygain->album_gain != INT32_MIN)
if (replaygain->track_peak != 0)
peak = replaygain->track_peak;
} else if (replaygain->album_gain != INT32_MIN) {
gain = replaygain->album_gain; gain = replaygain->album_gain;
else {
if (replaygain->album_peak != 0)
peak = replaygain->album_peak;
} else {
av_log(inlink->dst, AV_LOG_WARNING, "Both ReplayGain gain " av_log(inlink->dst, AV_LOG_WARNING, "Both ReplayGain gain "
"values are unknown.\n"); "values are unknown.\n");
gain = 100000;
} }
g = gain / 100000.0f; g = gain / 100000.0f;
p = peak / 100000.0f;
av_log(inlink->dst, AV_LOG_VERBOSE, av_log(inlink->dst, AV_LOG_VERBOSE,
"Using gain %f dB from replaygain side data.\n", g); "Using gain %f dB from replaygain side data.\n", g);
vol->volume = pow(10, (g + vol->replaygain_preamp) / 20); vol->volume = pow(10, (g + vol->replaygain_preamp) / 20);
if (vol->replaygain_noclip)
vol->volume = FFMIN(vol->volume, 1.0 / p);
vol->volume_i = (int)(vol->volume * 256 + 0.5); vol->volume_i = (int)(vol->volume * 256 + 0.5);
volume_init(vol); volume_init(vol);
......
...@@ -76,6 +76,7 @@ typedef struct VolumeContext { ...@@ -76,6 +76,7 @@ typedef struct VolumeContext {
enum ReplayGainType replaygain; enum ReplayGainType replaygain;
double replaygain_preamp; double replaygain_preamp;
int replaygain_noclip;
double volume; double volume;
int volume_i; int volume_i;
int channels; int channels;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment