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:
parent
1f36d01d46
commit
6cb3b0e303
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue