1 /*
2 * Copyright (c) 2016 Kyle Swanson <k@ylo.ph>.
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /* http://k.ylo.ph/2016/04/04/loudnorm.html */
22
30
37 };
38
45 };
46
52 };
53
67
72
77
89
95
99
100 #define OFFSET(x) offsetof(LoudNormContext, x)
101 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
102
125 };
126
128
129 static inline int frame_size(
int sample_rate,
int frame_len_msec)
130 {
131 const int frame_size =
round((
double)sample_rate * (frame_len_msec / 1000.0));
133 }
134
136 {
137 double total_weight = 0.0;
138 const double sigma = 3.5;
141
142 const int offset = 21 / 2;
143 const double c1 = 1.0 / (sigma * sqrt(2.0 *
M_PI));
144 const double c2 = 2.0 * pow(sigma, 2.0);
145
146 for (
i = 0;
i < 21;
i++) {
148 s->weights[
i] =
c1 *
exp(-(pow(x, 2.0) /
c2));
149 total_weight +=
s->weights[
i];
150 }
151
152 adjust = 1.0 / total_weight;
153 for (
i = 0;
i < 21;
i++)
155 }
156
158 {
161
163 for (
i = 0;
i < 21;
i++)
165
167 }
168
170 {
172 double ceiling;
173 double *buf;
174
175 *peak_delta = -1;
176 buf =
s->limiter_buf;
177 ceiling =
s->target_tp;
178
180 if (
index >=
s->limiter_buf_size)
181 index -=
s->limiter_buf_size;
182
186 }
187
188 for (n = 0; n < nb_samples; n++) {
190 double this, next, max_peak;
191
194
195 if ((
s->prev_smp[
c] <=
this) && (next <=
this) && (
this > ceiling) && (n > 0)) {
196 int detected;
197
198 detected = 1;
199 for (
i = 2;
i < 12;
i++) {
201 if (next > this) {
202 detected = 0;
203 break;
204 }
205 }
206
207 if (!detected)
208 continue;
209
213
215 }
216
217 *peak_delta = n;
219 *peak_value = max_peak;
220 return;
221 }
222
223 s->prev_smp[
c] =
this;
224 }
225
227 if (
index >=
s->limiter_buf_size)
228 index -=
s->limiter_buf_size;
229 }
230 }
231
233 {
234 int n,
c,
index, peak_delta, smp_cnt;
235 double ceiling, peak_value;
236 double *buf;
237
238 buf =
s->limiter_buf;
239 ceiling =
s->target_tp;
240 index =
s->limiter_buf_index;
241 smp_cnt = 0;
242
245
247 for (n = 0; n < 1920; n++) {
250 }
252 }
253
255 s->gain_reduction[1] = ceiling /
max;
257 buf =
s->limiter_buf;
258
259 for (n = 0; n < 1920; n++) {
261 double env;
262 env =
s->gain_reduction[1];
264 }
266 }
267 }
268
269 buf =
s->limiter_buf;
270 }
271
272 do {
273
274 switch(
s->limiter_state) {
277 if (peak_delta != -1) {
279 smp_cnt += (peak_delta -
s->attack_length);
280 s->gain_reduction[0] = 1.;
281 s->gain_reduction[1] = ceiling / peak_value;
283
284 s->env_index =
s->peak_index - (
s->attack_length *
channels);
285 if (
s->env_index < 0)
286 s->env_index +=
s->limiter_buf_size;
287
289 if (
s->env_index >
s->limiter_buf_size)
290 s->env_index -=
s->limiter_buf_size;
291
292 } else {
293 smp_cnt = nb_samples;
294 }
295 break;
296
298 for (;
s->env_cnt <
s->attack_length;
s->env_cnt++) {
300 double env;
301 env =
s->gain_reduction[0] - ((
double)
s->env_cnt / (
s->attack_length - 1) * (
s->gain_reduction[0] -
s->gain_reduction[1]));
302 buf[
s->env_index +
c] *= env;
303 }
304
306 if (
s->env_index >=
s->limiter_buf_size)
307 s->env_index -=
s->limiter_buf_size;
308
309 smp_cnt++;
310 if (smp_cnt >= nb_samples) {
312 break;
313 }
314 }
315
316 if (smp_cnt < nb_samples) {
318 s->attack_length = 1920;
320 }
321 break;
322
325 if (peak_delta == -1) {
327 s->gain_reduction[0] =
s->gain_reduction[1];
328 s->gain_reduction[1] = 1.;
330 break;
331 } else {
332 double gain_reduction;
333 gain_reduction = ceiling / peak_value;
334
335 if (gain_reduction < s->gain_reduction[1]) {
337
338 s->attack_length = peak_delta;
339 if (
s->attack_length <= 1)
340 s->attack_length = 2;
341
342 s->gain_reduction[0] =
s->gain_reduction[1];
343 s->gain_reduction[1] = gain_reduction;
345 break;
346 }
347
348 for (
s->env_cnt = 0;
s->env_cnt < peak_delta;
s->env_cnt++) {
350 double env;
351 env =
s->gain_reduction[1];
352 buf[
s->env_index +
c] *= env;
353 }
354
356 if (
s->env_index >=
s->limiter_buf_size)
357 s->env_index -=
s->limiter_buf_size;
358
359 smp_cnt++;
360 if (smp_cnt >= nb_samples) {
362 break;
363 }
364 }
365 }
366 break;
367
369 for (;
s->env_cnt <
s->release_length;
s->env_cnt++) {
371 double env;
372 env =
s->gain_reduction[0] + (((
double)
s->env_cnt / (
s->release_length - 1)) * (
s->gain_reduction[1] -
s->gain_reduction[0]));
373 buf[
s->env_index +
c] *= env;
374 }
375
377 if (
s->env_index >=
s->limiter_buf_size)
378 s->env_index -=
s->limiter_buf_size;
379
380 smp_cnt++;
381 if (smp_cnt >= nb_samples) {
383 break;
384 }
385 }
386
387 if (smp_cnt < nb_samples) {
389 s->limiter_state =
OUT;
390 }
391
392 break;
393 }
394
395 } while (smp_cnt < nb_samples);
396
397 for (n = 0; n < nb_samples; n++) {
401 out[
c] = ceiling * (
out[
c] < 0 ? -1 : 1);
402 }
403 }
406 if (
index >=
s->limiter_buf_size)
407 index -=
s->limiter_buf_size;
408 }
409 }
410
412 {
419 double *buf;
420 double *limiter_buf;
421 int i, n,
c, subframe_length, src_index;
422 double gain, gain_next, env_global, env_shortterm,
423 global, shortterm, lra, relative_threshold;
424
427 } else {
432 }
434 }
435
436 out->pts =
s->pts[0];
438
439 src = (
const double *)in->
data[0];
440 dst = (
double *)
out->data[0];
442 limiter_buf =
s->limiter_buf;
443
445
447 double offset, offset_tp, true_peak;
448
450 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
453 if (
c == 0 ||
tmp > true_peak)
455 }
456
457 offset = pow(10., (
s->target_i - global) / 20.);
458 offset_tp = true_peak *
offset;
459 s->offset = offset_tp <
s->target_tp ?
offset :
s->target_tp / true_peak;
461 }
462
463 switch (
s->frame_type) {
466 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
467 buf[
s->buf_index +
c] =
src[
c];
468 }
470 s->buf_index +=
inlink->ch_layout.nb_channels;
471 }
472
474
475 if (shortterm < s->measured_thresh) {
476 s->above_threshold = 0;
477 env_shortterm = shortterm <= -70. ? 0. :
s->target_i -
s->measured_i;
478 } else {
479 s->above_threshold = 1;
480 env_shortterm = shortterm <= -70. ? 0. :
s->target_i - shortterm;
481 }
482
483 for (n = 0; n < 30; n++)
484 s->delta[n] = pow(10., env_shortterm / 20.);
485 s->prev_delta =
s->delta[
s->index];
486
488 s->limiter_buf_index = 0;
489
490 for (n = 0; n < (
s->limiter_buf_size /
inlink->ch_layout.nb_channels); n++) {
491 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
492 limiter_buf[
s->limiter_buf_index +
c] = buf[
s->buf_index +
c] *
s->delta[
s->index] *
s->offset;
493 }
494 s->limiter_buf_index +=
inlink->ch_layout.nb_channels;
495 if (
s->limiter_buf_index >=
s->limiter_buf_size)
496 s->limiter_buf_index -=
s->limiter_buf_size;
497
498 s->buf_index +=
inlink->ch_layout.nb_channels;
499 }
500
504
505 out->nb_samples = subframe_length;
506
508 break;
509
513
515 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
516 buf[
s->prev_buf_index +
c] =
src[
c];
517 limiter_buf[
s->limiter_buf_index +
c] = buf[
s->buf_index +
c] * (gain + (((
double) n / in->
nb_samples) * (gain_next - gain))) *
s->offset;
518 }
520
521 s->limiter_buf_index +=
inlink->ch_layout.nb_channels;
522 if (
s->limiter_buf_index >=
s->limiter_buf_size)
523 s->limiter_buf_index -=
s->limiter_buf_size;
524
525 s->prev_buf_index +=
inlink->ch_layout.nb_channels;
526 if (
s->prev_buf_index >=
s->buf_size)
527 s->prev_buf_index -=
s->buf_size;
528
529 s->buf_index +=
inlink->ch_layout.nb_channels;
530 if (
s->buf_index >=
s->buf_size)
531 s->buf_index -=
s->buf_size;
532 }
533
535 s->limiter_buf_index =
s->limiter_buf_index + subframe_length < s->limiter_buf_size ?
s->limiter_buf_index + subframe_length :
s->limiter_buf_index + subframe_length -
s->limiter_buf_size;
536
539
544
545 if (
s->above_threshold == 0) {
546 double shortterm_out;
547
548 if (shortterm >
s->measured_thresh)
549 s->prev_delta *= 1.0058;
550
552 if (shortterm_out >=
s->target_i)
553 s->above_threshold = 1;
554 }
555
556 if (shortterm < relative_threshold || shortterm <= -70. || s->above_threshold == 0) {
557 s->delta[
s->index] =
s->prev_delta;
558 } else {
559 env_global =
fabs(shortterm - global) < (
s->target_lra / 2.) ? shortterm - global : (
s->target_lra / 2.) * ((shortterm - global) < 0 ? -1 : 1);
560 env_shortterm =
s->target_i - shortterm;
561 s->delta[
s->index] = pow(10., (env_global + env_shortterm) / 20.);
562 }
563
564 s->prev_delta =
s->delta[
s->index];
569 break;
570
573 s->limiter_buf_index = 0;
574 src_index = 0;
575
576 for (n = 0; n <
s->limiter_buf_size /
inlink->ch_layout.nb_channels; n++) {
577 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
578 s->limiter_buf[
s->limiter_buf_index +
c] =
src[src_index +
c] * gain *
s->offset;
579 }
580 src_index +=
inlink->ch_layout.nb_channels;
581
582 s->limiter_buf_index +=
inlink->ch_layout.nb_channels;
583 if (
s->limiter_buf_index >=
s->limiter_buf_size)
584 s->limiter_buf_index -=
s->limiter_buf_size;
585 }
586
590
591 for (n = 0; n < subframe_length; n++) {
592 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
594 limiter_buf[
s->limiter_buf_index +
c] =
src[src_index +
c] * gain *
s->offset;
595 } else {
596 limiter_buf[
s->limiter_buf_index +
c] = 0.;
597 }
598 }
599
601 src_index +=
inlink->ch_layout.nb_channels;
602
603 s->limiter_buf_index +=
inlink->ch_layout.nb_channels;
604 if (
s->limiter_buf_index >=
s->limiter_buf_size)
605 s->limiter_buf_index -=
s->limiter_buf_size;
606 }
607
608 dst += (subframe_length *
inlink->ch_layout.nb_channels);
609 }
610
611 dst = (
double *)
out->data[0];
613 break;
614
617 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
619 }
622 }
623
624 dst = (
double *)
out->data[0];
626 break;
627 }
628
632 }
633
635 {
640
643 double *buf;
646
647 nb_samples = (
s->buf_size /
inlink->ch_layout.nb_channels) -
s->prev_nb_samples;
649
653 frame->nb_samples = nb_samples;
654
657
658 offset = ((
s->limiter_buf_size /
inlink->ch_layout.nb_channels) -
s->prev_nb_samples) *
inlink->ch_layout.nb_channels;
660 s->buf_index =
s->buf_index - offset < 0 ? s->buf_index -
offset +
s->buf_size :
s->buf_index -
offset;
661
662 for (n = 0; n < nb_samples; n++) {
663 for (
c = 0;
c <
inlink->ch_layout.nb_channels;
c++) {
664 src[
c] = buf[
s->buf_index +
c];
665 }
667 s->buf_index +=
inlink->ch_layout.nb_channels;
668 if (
s->buf_index >=
s->buf_size)
669 s->buf_index -=
s->buf_size;
670 }
671
674 }
676 }
677
679 {
686
688
690 int nb_samples;
691
694 } else {
696 }
697
699 } else {
701 }
702
708
710 s->pts[
i] = in->
pts +
i * nb_samples;
713 } else {
715 }
717 }
720
724 }
725
727
729 }
730
734 {
736 static const int input_srate[] = {192000, -1};
740 };
742
746
749 }
750 return 0;
751 }
752
754 {
757
761
765
766 if (
inlink->ch_layout.nb_channels == 1 &&
s->dual_mono) {
769 }
770
775
780
784
786
789 s->limiter_buf_index = 0;
790 s->channels =
inlink->ch_layout.nb_channels;
792 s->limiter_state =
OUT;
793 s->offset = pow(10.,
s->offset / 20.);
794 s->target_tp = pow(10.,
s->target_tp / 20.);
797
798 return 0;
799 }
800
802 {
805
808 offset =
s->target_i -
s->measured_i;
809 offset_tp =
s->measured_tp +
offset;
810
811 if (
s->measured_tp != 99 &&
s->measured_thresh != -70 &&
s->measured_lra != 0 &&
s->measured_i != 0) {
812 if ((offset_tp <= s->target_tp) && (
s->measured_lra <=
s->target_lra)) {
815 }
816 }
817 }
818
819 return 0;
820 }
821
823 {
825 double i_in, i_out, lra_in, lra_out, thresh_in, thresh_out, tp_in, tp_out;
827
828 if (!
s->r128_in || !
s->r128_out)
829 goto end;
830
834 for (
c = 0;
c <
s->channels;
c++) {
837 if ((
c == 0) || (
tmp > tp_in))
839 }
840
844 for (
c = 0;
c <
s->channels;
c++) {
847 if ((
c == 0) || (
tmp > tp_out))
849 }
850
851 switch(
s->print_format) {
853 break;
854
857 "\n{\n"
858 "\t\"input_i\" : \"%.2f\",\n"
859 "\t\"input_tp\" : \"%.2f\",\n"
860 "\t\"input_lra\" : \"%.2f\",\n"
861 "\t\"input_thresh\" : \"%.2f\",\n"
862 "\t\"output_i\" : \"%.2f\",\n"
863 "\t\"output_tp\" : \"%+.2f\",\n"
864 "\t\"output_lra\" : \"%.2f\",\n"
865 "\t\"output_thresh\" : \"%.2f\",\n"
866 "\t\"normalization_type\" : \"%s\",\n"
867 "\t\"target_offset\" : \"%.2f\"\n"
868 "}\n",
869 i_in,
870 20. * log10(tp_in),
871 lra_in,
872 thresh_in,
873 i_out,
874 20. * log10(tp_out),
875 lra_out,
876 thresh_out,
879 );
880 break;
881
884 "\n"
885 "Input Integrated: %+6.1f LUFS\n"
886 "Input True Peak: %+6.1f dBTP\n"
887 "Input LRA: %6.1f LU\n"
888 "Input Threshold: %+6.1f LUFS\n"
889 "\n"
890 "Output Integrated: %+6.1f LUFS\n"
891 "Output True Peak: %+6.1f dBTP\n"
892 "Output LRA: %6.1f LU\n"
893 "Output Threshold: %+6.1f LUFS\n"
894 "\n"
895 "Normalization Type: %s\n"
896 "Target Offset: %+6.1f LU\n",
897 i_in,
898 20. * log10(tp_in),
899 lra_in,
900 thresh_in,
901 i_out,
902 20. * log10(tp_out),
903 lra_out,
904 thresh_out,
907 );
908 break;
909 }
910
911 end:
919 }
920
922 {
926 },
927 };
928
930 .
p.
name =
"loudnorm",
932 .p.priv_class = &loudnorm_class,
940 };