1
0
Fork 0

swresample: add a "clipping protection" mode when mixing

This mode normalizes audio down to stay below 1.0 after mixing, so no clipping occurs when converting to integer formats.
This commit is contained in:
Hendrik Leppkes 2012-12-16 10:03:27 +01:00
parent 1f36d01d46
commit 6cb3b0e303
Signed by: hendrik
GPG Key ID: 846079A4B0A7C1B5
3 changed files with 23 additions and 1 deletions

View File

@ -122,6 +122,7 @@ static const AVOption options[]={
{ "kaiser_beta" , "set swr Kaiser window beta" , OFFSET(kaiser_beta) , AV_OPT_TYPE_DOUBLE , {.dbl=9 }, 2 , 16 , PARAM },
{ "output_sample_bits" , "set swr number of output sample bits", OFFSET(dither.output_sample_bits), AV_OPT_TYPE_INT , {.i64=0 }, 0 , 64 , PARAM },
{ "clip_protection" , "Clipping Protection" , OFFSET(clip_protection), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, PARAM },
{0}
};

View File

@ -452,6 +452,7 @@ av_cold int swri_rematrix_init(SwrContext *s){
int nb_out = s->out.ch_count;
s->mix_any_f = NULL;
s->clip_max = 1.0f;
if (!s->rematrix_custom) {
int r = auto_matrix(s);
@ -566,7 +567,7 @@ int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mus
if(s->mix_any_f) {
s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
return 0;
goto clip_protection;
}
if(s->mix_2_1_simd || s->mix_1_1_simd){
@ -637,5 +638,22 @@ int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mus
}
}
}
clip_protection:
if (s->clip_protection && s->int_sample_fmt == AV_SAMPLE_FMT_FLTP)
{
for(j = 0; j < out->ch_count; j++) {
for(i = 0; i < len; i++) {
const float sample = fabsf(((float *)out->ch[j])[i]);
if (sample > s->clip_max) {
s->clip_max = sample;
av_log(s, AV_LOG_INFO, "Clipping protection at %.3f\n", sample);
}
if (s->clip_max > 1.0f)
((float *)out->ch[j])[i] /= s->clip_max;
}
}
}
return 0;
}

View File

@ -183,6 +183,9 @@ struct SwrContext {
mix_any_func_type *mix_any_f;
/* TODO: callbacks for ASM optimizations */
int clip_protection;
float clip_max;
};
av_warn_unused_result