summaryrefslogtreecommitdiffstats
path: root/libavcodec/aacpsy.c
diff options
context:
space:
mode:
authorClaudio Freire <klaussfreire@gmail.com>2015-07-20 22:53:24 -0300
committerMichael Niedermayer <michael@niedermayer.cc>2015-07-27 19:13:48 +0200
commit59216e0525a58714be4207be6ae8744750e62867 (patch)
tree8c5b41b3471b08e17396c159001da6deff7ce347 /libavcodec/aacpsy.c
parentc8c86b8f9b8c166633a7324c8646f38866801b88 (diff)
downloadffmpeg-streaming-59216e0525a58714be4207be6ae8744750e62867.zip
ffmpeg-streaming-59216e0525a58714be4207be6ae8744750e62867.tar.gz
AAC Encoder: clipping avoidance
Avoid clipping due to quantization noise to produce audible artifacts, by detecting near-clipping signals and both attenuating them a little and encoding escape-encoded bands (usually the loudest) rounding towards zero instead of nearest, which tends to decrease overall energy and thus clipping. Currently fate tests measure numerical error so this change makes tests using asynth (which are near clipping) report higher error not less, because of window attenuation. Yet, they sound better, not worse (albeit subtle, other samples aren't subtle at all). Only measuring psychoacoustically weighted error would make for a representative test, so that will be left for a future patch. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec/aacpsy.c')
-rw-r--r--libavcodec/aacpsy.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index b16f6b9..a5474b9 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -837,6 +837,7 @@ static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio,
int grouping = 0;
int uselongblock = 1;
int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
+ float clippings[AAC_NUM_BLOCKS_SHORT];
int i;
FFPsyWindowInfo wi = { { 0 } };
@@ -926,14 +927,35 @@ static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio,
lame_apply_block_type(pch, &wi, uselongblock);
+ /* Calculate input sample maximums and evaluate clipping risk */
+ if (audio) {
+ for (i = 0; i < AAC_NUM_BLOCKS_SHORT; i++) {
+ const float *wbuf = audio + i * AAC_BLOCK_SIZE_SHORT;
+ float max = 0;
+ int j;
+ for (j = 0; j < AAC_BLOCK_SIZE_SHORT; j++)
+ max = FFMAX(max, fabsf(wbuf[j]));
+ clippings[i] = max;
+ }
+ } else {
+ for (i = 0; i < 8; i++)
+ clippings[i] = 0;
+ }
+
wi.window_type[1] = prev_type;
if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
+ float clipping = 0.0f;
+
wi.num_windows = 1;
wi.grouping[0] = 1;
if (wi.window_type[0] == LONG_START_SEQUENCE)
wi.window_shape = 0;
else
wi.window_shape = 1;
+
+ for (i = 0; i < 8; i++)
+ clipping = FFMAX(clipping, clippings[i]);
+ wi.clipping[0] = clipping;
} else {
int lastgrp = 0;
@@ -944,6 +966,14 @@ static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio,
lastgrp = i;
wi.grouping[lastgrp]++;
}
+
+ for (i = 0; i < 8; i += wi.grouping[i]) {
+ int w;
+ float clipping = 0.0f;
+ for (w = 0; w < wi.grouping[i] && !clipping; w++)
+ clipping = FFMAX(clipping, clippings[i+w]);
+ wi.clipping[i] = clipping;
+ }
}
/* Determine grouping, based on the location of the first attack, and save for
OpenPOWER on IntegriCloud