103#define OFFSET(x) offsetof(LoudNormContext, x)
104#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
133static inline int frame_size(
int sample_rate,
int frame_len_msec)
135 const int frame_size =
round((
double)sample_rate * (frame_len_msec / 1000.0));
141 double total_weight = 0.0;
142 const double sigma = 3.5;
146 const int offset = 21 / 2;
147 const double c1 = 1.0 / (sigma * sqrt(2.0 *
M_PI));
148 const double c2 = 2.0 * pow(sigma, 2.0);
150 for (
i = 0;
i < 21;
i++) {
152 s->weights[
i] =
c1 *
exp(-(pow(x, 2.0) /
c2));
153 total_weight +=
s->weights[
i];
156 adjust = 1.0 / total_weight;
157 for (
i = 0;
i < 21;
i++)
167 for (
i = 0;
i < 21;
i++)
180 buf =
s->limiter_buf;
181 ceiling =
s->target_tp;
184 if (
index >=
s->limiter_buf_size)
185 index -=
s->limiter_buf_size;
192 for (n = 0; n < nb_samples; n++) {
194 double this, next, max_peak;
199 if ((
s->prev_smp[
c] <=
this) && (next <=
this) && (
this > ceiling) && (n > 0)) {
203 for (
i = 2;
i < 12;
i++) {
223 *peak_value = max_peak;
227 s->prev_smp[
c] =
this;
231 if (
index >=
s->limiter_buf_size)
232 index -=
s->limiter_buf_size;
238 int n,
c,
index, peak_delta, smp_cnt;
239 double ceiling, peak_value;
242 buf =
s->limiter_buf;
243 ceiling =
s->target_tp;
244 index =
s->limiter_buf_index;
251 for (n = 0; n < 1920; n++) {
259 s->gain_reduction[1] = ceiling /
max;
261 buf =
s->limiter_buf;
263 for (n = 0; n < 1920; n++) {
266 env =
s->gain_reduction[1];
273 buf =
s->limiter_buf;
278 switch(
s->limiter_state) {
281 if (peak_delta != -1) {
283 smp_cnt += (peak_delta -
s->attack_length);
284 s->gain_reduction[0] = 1.;
285 s->gain_reduction[1] = ceiling / peak_value;
288 s->env_index =
s->peak_index - (
s->attack_length *
channels);
289 if (
s->env_index < 0)
290 s->env_index +=
s->limiter_buf_size;
293 if (
s->env_index >
s->limiter_buf_size)
294 s->env_index -=
s->limiter_buf_size;
297 smp_cnt = nb_samples;
302 for (;
s->env_cnt <
s->attack_length;
s->env_cnt++) {
305 env =
s->gain_reduction[0] - ((
double)
s->env_cnt / (
s->attack_length - 1) * (
s->gain_reduction[0] -
s->gain_reduction[1]));
306 buf[
s->env_index +
c] *= env;
310 if (
s->env_index >=
s->limiter_buf_size)
311 s->env_index -=
s->limiter_buf_size;
314 if (smp_cnt >= nb_samples) {
320 if (smp_cnt < nb_samples) {
322 s->attack_length = 1920;
329 if (peak_delta == -1) {
331 s->gain_reduction[0] =
s->gain_reduction[1];
332 s->gain_reduction[1] = 1.;
336 double gain_reduction;
337 gain_reduction = ceiling / peak_value;
339 if (gain_reduction < s->gain_reduction[1]) {
342 s->attack_length = peak_delta;
343 if (
s->attack_length <= 1)
344 s->attack_length = 2;
346 s->gain_reduction[0] =
s->gain_reduction[1];
347 s->gain_reduction[1] = gain_reduction;
352 for (
s->env_cnt = 0;
s->env_cnt < peak_delta;
s->env_cnt++) {
355 env =
s->gain_reduction[1];
356 buf[
s->env_index +
c] *= env;
360 if (
s->env_index >=
s->limiter_buf_size)
361 s->env_index -=
s->limiter_buf_size;
364 if (smp_cnt >= nb_samples) {
373 for (;
s->env_cnt <
s->release_length;
s->env_cnt++) {
376 env =
s->gain_reduction[0] + (((
double)
s->env_cnt / (
s->release_length - 1)) * (
s->gain_reduction[1] -
s->gain_reduction[0]));
377 buf[
s->env_index +
c] *= env;
381 if (
s->env_index >=
s->limiter_buf_size)
382 s->env_index -=
s->limiter_buf_size;
385 if (smp_cnt >= nb_samples) {
391 if (smp_cnt < nb_samples) {
393 s->limiter_state =
OUT;
399 }
while (smp_cnt < nb_samples);
401 for (n = 0; n < nb_samples; n++) {
405 out[
c] = ceiling * (
out[
c] < 0 ? -1 : 1);
410 if (
index >=
s->limiter_buf_size)
411 index -=
s->limiter_buf_size;
425 int i, n,
c, subframe_length, src_index;
426 double gain, gain_next, env_global, env_shortterm,
427 global, shortterm, lra, relative_threshold;
440 out->pts =
s->pts[0];
443 src = (
const double *)in->
data[0];
444 dst = (
double *)
out->data[0];
446 limiter_buf =
s->limiter_buf;
451 double offset, offset_tp, true_peak;
457 if (
c == 0 ||
tmp > true_peak)
461 offset = pow(10., (
s->target_i - global) / 20.);
462 offset_tp = true_peak *
offset;
463 s->offset = offset_tp <
s->target_tp ?
offset :
s->target_tp / true_peak;
467 switch (
s->frame_type) {
471 buf[
s->buf_index +
c] =
src[
c];
479 if (shortterm < s->measured_thresh) {
480 s->above_threshold = 0;
481 env_shortterm = shortterm <= -70. ? 0. :
s->target_i -
s->measured_i;
483 s->above_threshold = 1;
484 env_shortterm = shortterm <= -70. ? 0. :
s->target_i - shortterm;
487 for (n = 0; n < 30; n++)
488 s->delta[n] = pow(10., env_shortterm / 20.);
489 s->prev_delta =
s->delta[
s->index];
492 s->limiter_buf_index = 0;
496 limiter_buf[
s->limiter_buf_index +
c] = buf[
s->buf_index +
c] *
s->delta[
s->index] *
s->offset;
499 if (
s->limiter_buf_index >=
s->limiter_buf_size)
500 s->limiter_buf_index -=
s->limiter_buf_size;
509 out->nb_samples = subframe_length;
520 buf[
s->prev_buf_index +
c] =
src[
c];
521 limiter_buf[
s->limiter_buf_index +
c] = buf[
s->buf_index +
c] * (gain + (((
double) n / in->
nb_samples) * (gain_next - gain))) *
s->offset;
526 if (
s->limiter_buf_index >=
s->limiter_buf_size)
527 s->limiter_buf_index -=
s->limiter_buf_size;
530 if (
s->prev_buf_index >=
s->buf_size)
531 s->prev_buf_index -=
s->buf_size;
534 if (
s->buf_index >=
s->buf_size)
535 s->buf_index -=
s->buf_size;
539 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;
549 if (
s->above_threshold == 0) {
550 double shortterm_out;
552 if (shortterm >
s->measured_thresh)
553 s->prev_delta *= 1.0058;
556 if (shortterm_out >=
s->target_i)
557 s->above_threshold = 1;
560 if (shortterm < relative_threshold || shortterm <= -70. || s->above_threshold == 0) {
561 s->delta[
s->index] =
s->prev_delta;
563 env_global =
fabs(shortterm - global) < (
s->target_lra / 2.) ? shortterm - global : (
s->target_lra / 2.) * ((shortterm - global) < 0 ? -1 : 1);
564 env_shortterm =
s->target_i - shortterm;
565 s->delta[
s->index] = pow(10., (env_global + env_shortterm) / 20.);
568 s->prev_delta =
s->delta[
s->index];
577 s->limiter_buf_index = 0;
582 s->limiter_buf[
s->limiter_buf_index +
c] =
src[src_index +
c] * gain *
s->offset;
587 if (
s->limiter_buf_index >=
s->limiter_buf_size)
588 s->limiter_buf_index -=
s->limiter_buf_size;
595 for (n = 0; n < subframe_length; n++) {
598 limiter_buf[
s->limiter_buf_index +
c] =
src[src_index +
c] * gain *
s->offset;
600 limiter_buf[
s->limiter_buf_index +
c] = 0.;
608 if (
s->limiter_buf_index >=
s->limiter_buf_size)
609 s->limiter_buf_index -=
s->limiter_buf_size;
615 dst = (
double *)
out->data[0];
628 dst = (
double *)
out->data[0];
657 frame->nb_samples = nb_samples;
666 for (n = 0; n < nb_samples; n++) {
668 src[
c] = buf[
s->buf_index +
c];
672 if (
s->buf_index >=
s->buf_size)
673 s->buf_index -=
s->buf_size;
714 s->pts[
i] = in->
pts +
i * nb_samples;
740 static const int input_srate[] = {192000, -1};
793 s->limiter_buf_index = 0;
796 s->limiter_state =
OUT;
797 s->offset = pow(10.,
s->offset / 20.);
798 s->target_tp = pow(10.,
s->target_tp / 20.);
810 if (
s->stats_file_str &&
s->print_format ==
NONE) {
817 offset =
s->target_i -
s->measured_i;
818 offset_tp =
s->measured_tp +
offset;
820 if (
s->measured_tp != 99 &&
s->measured_thresh != -70 &&
s->measured_lra != 0 &&
s->measured_i != 0) {
821 if ((offset_tp <= s->target_tp) && (
s->measured_lra <=
s->target_lra)) {
834 double i_in, i_out, lra_in, lra_out, thresh_in, thresh_out, tp_in, tp_out;
836 FILE *stats_file =
NULL;
838 if (!
s->r128_in || !
s->r128_out)
844 for (
c = 0;
c <
s->channels;
c++) {
847 if ((
c == 0) || (
tmp > tp_in))
854 for (
c = 0;
c <
s->channels;
c++) {
857 if ((
c == 0) || (
tmp > tp_out))
862 if (
s->stats_file_str) {
863 if (!strcmp(
s->stats_file_str,
"-")) {
876 switch(
s->print_format) {
883 const char *
const format =
s->print_format ==
JSON ?
885 "\t\"input_i\" : \"%.2f\",\n"
886 "\t\"input_tp\" : \"%.2f\",\n"
887 "\t\"input_lra\" : \"%.2f\",\n"
888 "\t\"input_thresh\" : \"%.2f\",\n"
889 "\t\"output_i\" : \"%.2f\",\n"
890 "\t\"output_tp\" : \"%+.2f\",\n"
891 "\t\"output_lra\" : \"%.2f\",\n"
892 "\t\"output_thresh\" : \"%.2f\",\n"
893 "\t\"normalization_type\" : \"%s\",\n"
894 "\t\"target_offset\" : \"%.2f\"\n"
896 "Input Integrated: %+6.1f LUFS\n"
897 "Input True Peak: %+6.1f dBTP\n"
898 "Input LRA: %6.1f LU\n"
899 "Input Threshold: %+6.1f LUFS\n"
901 "Output Integrated: %+6.1f LUFS\n"
902 "Output True Peak: %+6.1f dBTP\n"
903 "Output LRA: %6.1f LU\n"
904 "Output Threshold: %+6.1f LUFS\n"
906 "Normalization Type: %s\n"
907 "Target Offset: %+6.1f LU\n";
919 : (
s->print_format ==
JSON ?
"dynamic" :
"Dynamic"),
924 fprintf(stats_file,
"%s",
stats);
930 if (stats_file && stats_file != stdout)
950 .p.name =
"loudnorm",
952 .p.priv_class = &loudnorm_class,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static enum AVSampleFormat sample_fmts[]
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static int config_input(AVFilterLink *inlink)
static const char *const format[]
static const AVOption loudnorm_options[]
static void true_peak_limiter(LoudNormContext *s, double *out, int nb_samples, int channels)
static const AVFilterPad avfilter_af_loudnorm_inputs[]
const FFFilter ff_af_loudnorm
static int config_input(AVFilterLink *inlink)
static int flush_frame(AVFilterLink *outlink)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static void init_gaussian_filter(LoudNormContext *s)
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static void detect_peak(LoudNormContext *s, int offset, int nb_samples, int channels, int *peak_delta, double *peak_value)
static int activate(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static double gaussian_filter(LoudNormContext *s, int index)
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
static __device__ float fabs(float a)
int(* init)(AVBSFContext *ctx)
int ff_ebur128_set_channel(FFEBUR128State *st, unsigned int channel_number, int value)
Set channel type.
int ff_ebur128_loudness_range(FFEBUR128State *st, double *out)
Get loudness range (LRA) of programme in LU.
int ff_ebur128_sample_peak(FFEBUR128State *st, unsigned int channel_number, double *out)
Get maximum sample peak of selected channel in float format.
int ff_ebur128_relative_threshold(FFEBUR128State *st, double *out)
Get relative threshold in LUFS.
FFEBUR128State * ff_ebur128_init(unsigned int channels, unsigned long samplerate, unsigned long window, int mode)
Initialize library state.
void ff_ebur128_destroy(FFEBUR128State **st)
Destroy library state.
int ff_ebur128_loudness_global(FFEBUR128State *st, double *out)
Get global integrated loudness in LUFS.
int ff_ebur128_loudness_shortterm(FFEBUR128State *st, double *out)
Get short-term loudness (last 3s) in LUFS.
libebur128 - a library for loudness measurement according to the EBU R128 standard.
@ FF_EBUR128_MODE_I
can call ff_ebur128_loudness_global_* and ff_ebur128_relative_threshold
@ FF_EBUR128_MODE_LRA
can call ff_ebur128_loudness_range
@ FF_EBUR128_MODE_S
can call ff_ebur128_loudness_shortterm
@ FF_EBUR128_MODE_SAMPLE_PEAK
can call ff_ebur128_sample_peak
void ff_ebur128_add_frames_double(FFEBUR128State *st, const double *src, size_t frames)
Add frames to be processed.
@ FF_EBUR128_DUAL_MONO
a channel that is counted twice
static CheckasmStats stats
static const uint8_t frame_size[4]
FrameType
G723.1 frame types.
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVSampleFormat
Audio sample formats.
@ AV_SAMPLE_FMT_DBL
double
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
#define AVFILTER_DEFINE_CLASS(fname)
#define FILTER_QUERY_FUNC2(func)
FILE * avpriv_fopen_utf8(const char *path, const char *mode)
Open a file using a UTF-8 filename.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static av_always_inline av_const double round(double x)
Memory handling functions.
static int adjust(int x, int size)
#define FF_ARRAY_ELEMS(a)
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
A link between two filters.
AVFilterContext * src
source filter
int sample_rate
samples per second
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
AVFilterContext * dst
dest filter
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
int nb_samples
number of audio samples (per channel) described by this frame
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Contains information about the state of a loudness measurement.
enum FrameType frame_type
enum LimiterState limiter_state
FFEBUR128State * r128_out
#define av_malloc_array(a, b)
static AVFormatContext * ctx