Go to the documentation of this file.
54 #define CHECK_ERROR(condition, errorcode, goto_point) \
56 errcode = (errorcode); \
60 #define ALMOST_ZERO 0.000001
62 #define RELATIVE_GATE (-10.0)
63 #define RELATIVE_GATE_FACTOR pow(10.0, RELATIVE_GATE / 10.0)
64 #define MINUS_20DB pow(10.0, -20.0 / 10.0)
108 double f0 = 1681.974450955533;
109 double G = 3.999843853973347;
110 double Q = 0.7071752369554196;
113 double Vh = pow(10.0,
G / 20.0);
114 double Vb = pow(Vh, 0.4996667741545416);
116 double pb[3] = { 0.0, 0.0, 0.0 };
117 double pa[3] = { 1.0, 0.0, 0.0 };
118 double rb[3] = { 1.0, -2.0, 1.0 };
119 double ra[3] = { 1.0, 0.0, 0.0 };
121 double a0 = 1.0 + K / Q + K * K;
122 pb[0] = (Vh + Vb * K / Q + K * K) /
a0;
123 pb[1] = 2.0 * (K * K - Vh) /
a0;
124 pb[2] = (Vh - Vb * K / Q + K * K) /
a0;
125 pa[1] = 2.0 * (K * K - 1.0) /
a0;
126 pa[2] = (1.0 - K / Q + K * K) /
a0;
128 f0 = 38.13547087602444;
129 Q = 0.5003270373238773;
132 ra[1] = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K);
133 ra[2] = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K);
135 st->
d->
b[0] = pb[0] * rb[0];
136 st->
d->
b[1] = pb[0] * rb[1] + pb[1] * rb[0];
137 st->
d->
b[2] = pb[0] * rb[2] + pb[1] * rb[1] + pb[2] * rb[0];
138 st->
d->
b[3] = pb[1] * rb[2] + pb[2] * rb[1];
139 st->
d->
b[4] = pb[2] * rb[2];
141 st->
d->
a[0] = pa[0] *
ra[0];
142 st->
d->
a[1] = pa[0] *
ra[1] + pa[1] *
ra[0];
143 st->
d->
a[2] = pa[0] *
ra[2] + pa[1] *
ra[1] + pa[2] *
ra[0];
144 st->
d->
a[3] = pa[1] *
ra[2] + pa[2] *
ra[1];
145 st->
d->
a[4] = pa[2] *
ra[2];
147 for (
i = 0;
i < 5; ++
i) {
148 for (j = 0; j < 5; ++j) {
149 st->
d->
v[
i][j] = 0.0;
207 for (
i = 0;
i < 1000; ++
i) {
209 pow(10.0, ((
double)
i / 10.0 - 69.95 + 0.691) / 10.0);
211 for (
i = 1;
i < 1001; ++
i) {
213 pow(10.0, ((
double)
i / 10.0 - 70.0 + 0.691) / 10.0);
218 unsigned long samplerate,
245 goto free_sample_peak;
267 free_block_energy_histogram)
276 goto free_short_term_block_energy_histogram;
280 free_short_term_block_energy_histogram);
284 free_short_term_block_energy_histogram:
286 free_block_energy_histogram:
304 av_free((*st)->d->block_energy_histogram);
305 av_free((*st)->d->short_term_block_energy_histogram);
307 av_free((*st)->d->channel_map);
308 av_free((*st)->d->sample_peak);
315 #define EBUR128_FILTER(type, scaling_factor) \
316 static void ebur128_filter_##type(FFEBUR128State* st, const type** srcs, \
317 size_t src_index, size_t frames, \
319 double* audio_data = st->d->audio_data + st->d->audio_data_index; \
322 if ((st->mode & FF_EBUR128_MODE_SAMPLE_PEAK) == FF_EBUR128_MODE_SAMPLE_PEAK) { \
323 for (c = 0; c < st->channels; ++c) { \
325 for (i = 0; i < frames; ++i) { \
326 type v = srcs[c][src_index + i * stride]; \
329 } else if (-v > max) { \
333 max /= scaling_factor; \
334 if (max > st->d->sample_peak[c]) st->d->sample_peak[c] = max; \
337 for (c = 0; c < st->channels; ++c) { \
338 int ci = st->d->channel_map[c] - 1; \
339 if (ci < 0) continue; \
340 else if (ci == FF_EBUR128_DUAL_MONO - 1) ci = 0; \
341 for (i = 0; i < frames; ++i) { \
342 st->d->v[ci][0] = (double) (srcs[c][src_index + i * stride] / scaling_factor) \
343 - st->d->a[1] * st->d->v[ci][1] \
344 - st->d->a[2] * st->d->v[ci][2] \
345 - st->d->a[3] * st->d->v[ci][3] \
346 - st->d->a[4] * st->d->v[ci][4]; \
347 audio_data[i * st->channels + c] = \
348 st->d->b[0] * st->d->v[ci][0] \
349 + st->d->b[1] * st->d->v[ci][1] \
350 + st->d->b[2] * st->d->v[ci][2] \
351 + st->d->b[3] * st->d->v[ci][3] \
352 + st->d->b[4] * st->d->v[ci][4]; \
353 st->d->v[ci][4] = st->d->v[ci][3]; \
354 st->d->v[ci][3] = st->d->v[ci][2]; \
355 st->d->v[ci][2] = st->d->v[ci][1]; \
356 st->d->v[ci][1] = st->d->v[ci][0]; \
358 st->d->v[ci][4] = fabs(st->d->v[ci][4]) < DBL_MIN ? 0.0 : st->d->v[ci][4]; \
359 st->d->v[ci][3] = fabs(st->d->v[ci][3]) < DBL_MIN ? 0.0 : st->d->v[ci][3]; \
360 st->d->v[ci][2] = fabs(st->d->v[ci][2]) < DBL_MIN ? 0.0 : st->d->v[ci][2]; \
361 st->d->v[ci][1] = fabs(st->d->v[ci][1]) < DBL_MIN ? 0.0 : st->d->v[ci][1]; \
369 static
double ebur128_energy_to_loudness(
double energy)
371 return 10 * log10(energy) - 0.691;
376 size_t index_min = 0;
377 size_t index_max = 1000;
381 index_mid = (index_min + index_max) / 2;
383 index_min = index_mid;
385 index_max = index_mid;
387 }
while (index_max - index_min != 1);
393 size_t frames_per_block,
394 double *optional_output)
411 i < st->d->audio_data_frames; ++
i) {
418 i < st->d->audio_data_index / st->
channels; ++
i) {
438 sum /= (double) frames_per_block;
439 if (optional_output) {
440 *optional_output = sum;
447 unsigned int channel_number,
int value)
449 if (channel_number >= st->
channels) {
453 (st->
channels != 1 || channel_number != 0)) {
461 #define FF_EBUR128_ADD_FRAMES_PLANAR(type) \
462 void ff_ebur128_add_frames_planar_##type(FFEBUR128State* st, const type** srcs, \
463 size_t frames, int stride) { \
464 size_t src_index = 0; \
465 while (frames > 0) { \
466 if (frames >= st->d->needed_frames) { \
467 ebur128_filter_##type(st, srcs, src_index, st->d->needed_frames, stride); \
468 src_index += st->d->needed_frames * stride; \
469 frames -= st->d->needed_frames; \
470 st->d->audio_data_index += st->d->needed_frames * st->channels; \
472 if ((st->mode & FF_EBUR128_MODE_I) == FF_EBUR128_MODE_I) { \
473 ebur128_calc_gating_block(st, st->d->samples_in_100ms * 4, NULL); \
475 if ((st->mode & FF_EBUR128_MODE_LRA) == FF_EBUR128_MODE_LRA) { \
476 st->d->short_term_frame_counter += st->d->needed_frames; \
477 if (st->d->short_term_frame_counter == st->d->samples_in_100ms * 30) { \
479 ebur128_energy_shortterm(st, &st_energy); \
480 if (st_energy >= histogram_energy_boundaries[0]) { \
481 ++st->d->short_term_block_energy_histogram[ \
482 find_histogram_index(st_energy)]; \
484 st->d->short_term_frame_counter = st->d->samples_in_100ms * 20; \
488 st->d->needed_frames = st->d->samples_in_100ms; \
490 if (st->d->audio_data_index == st->d->audio_data_frames * st->channels) { \
491 st->d->audio_data_index = 0; \
494 ebur128_filter_##type(st, srcs, src_index, frames, stride); \
495 st->d->audio_data_index += frames * st->channels; \
496 if ((st->mode & FF_EBUR128_MODE_LRA) == FF_EBUR128_MODE_LRA) { \
497 st->d->short_term_frame_counter += frames; \
499 st->d->needed_frames -= frames; \
508 #define FF_EBUR128_ADD_FRAMES(type) \
509 void ff_ebur128_add_frames_##type(FFEBUR128State* st, const type* src, \
512 const type **buf = (const type**)st->d->data_ptrs; \
513 for (i = 0; i < st->channels; i++) \
515 ff_ebur128_add_frames_planar_##type(st, buf, frames, st->channels); \
523 double *relative_threshold)
526 int above_thresh_counter = 0;
527 *relative_threshold = 0.0;
531 for (j = 0; j < 1000; ++j) {
537 if (above_thresh_counter != 0) {
538 *relative_threshold /= (double)above_thresh_counter;
542 return above_thresh_counter;
548 double gated_loudness = 0.0;
549 double relative_threshold;
550 size_t above_thresh_counter;
551 size_t i, j, start_index;
562 above_thresh_counter = 0;
572 for (j = start_index; j < 1000; ++j) {
578 if (!above_thresh_counter) {
582 gated_loudness /= (double) above_thresh_counter;
583 *
out = ebur128_energy_to_loudness(gated_loudness);
589 double relative_threshold;
599 *
out = ebur128_energy_to_loudness(relative_threshold);
615 size_t interval_frames,
double *
out)
637 }
else if (energy <= 0.0) {
641 *
out = ebur128_energy_to_loudness(energy);
651 }
else if (energy <= 0.0) {
655 *
out = ebur128_energy_to_loudness(energy);
667 }
else if (energy <= 0.0) {
671 *
out = ebur128_energy_to_loudness(energy);
681 double stl_power, stl_integrated;
684 unsigned long hist[1000] = { 0 };
685 size_t percentile_low, percentile_high;
702 for (j = 0; j < 1000; ++j) {
714 stl_power /= stl_size;
726 for (j =
index; j < 1000; ++j) {
734 percentile_low = (size_t) ((stl_size - 1) * 0.1 + 0.5);
735 percentile_high = (size_t) ((stl_size - 1) * 0.95 + 0.5);
739 while (stl_size <= percentile_low) {
740 stl_size += hist[j++];
743 while (stl_size <= percentile_high) {
744 stl_size += hist[j++];
748 ebur128_energy_to_loudness(h_en) -
749 ebur128_energy_to_loudness(l_en);
759 unsigned int channel_number,
double *
out)
764 }
else if (channel_number >= st->
channels) {
unsigned long samples_in_100ms
How many samples fit in 100ms (rounded).
@ FF_EBUR128_RIGHT_SURROUND
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
struct FFEBUR128StateInternal * d
Internal state.
#define FF_EBUR128_ADD_FRAMES(type)
static int ebur128_calc_relative_threshold(FFEBUR128State **sts, size_t size, double *relative_threshold)
static int ebur128_gated_loudness(FFEBUR128State **sts, size_t size, double *out)
int ff_ebur128_loudness_range_multiple(FFEBUR128State **sts, size_t size, double *out)
Get loudness range (LRA) in LU across multiple instances.
int ff_ebur128_loudness_momentary(FFEBUR128State *st, double *out)
Get momentary loudness (last 400ms) in LUFS.
#define FF_EBUR128_ADD_FRAMES_PLANAR(type)
@ FF_EBUR128_LEFT_SURROUND
unsigned long * block_energy_histogram
Histograms, used to calculate LRA.
static int ebur128_energy_in_interval(FFEBUR128State *st, size_t interval_frames, double *out)
unsigned long needed_frames
How many frames are needed for a gating block.
static AVOnce histogram_init
size_t audio_data_index
Current index for audio_data.
static size_t find_histogram_index(double energy)
int ff_ebur128_loudness_global_multiple(FFEBUR128State **sts, size_t size, double *out)
Get global integrated loudness in LUFS across multiple instances.
int * channel_map
The channel map.
void * av_mallocz_array(size_t nmemb, size_t size)
@ FF_EBUR128_MODE_I
can call ff_ebur128_loudness_global_* and ff_ebur128_relative_threshold
static int ebur128_energy_shortterm(FFEBUR128State *st, double *out)
int ff_ebur128_loudness_window(FFEBUR128State *st, unsigned long window, double *out)
Get loudness of the specified window in LUFS.
size_t audio_data_frames
Size of audio_data array.
int ff_ebur128_loudness_range(FFEBUR128State *st, double *out)
Get loudness range (LRA) of programme in LU.
static SDL_Window * window
double * audio_data
Filtered audio data (used as ring buffer).
void ff_ebur128_destroy(FFEBUR128State **st)
Destroy library state.
@ FF_EBUR128_UNUSED
unused channel (for example LFE channel)
double a[5]
BS.1770 filter coefficients (denominator).
@ FF_EBUR128_DUAL_MONO
a channel that is counted twice
unsigned long samplerate
The sample rate.
static int ff_thread_once(char *control, void(*routine)(void))
double v[5][5]
BS.1770 filter state.
@ FF_EBUR128_MODE_LRA
can call ff_ebur128_loudness_range
@ FF_EBUR128_Mm060
itu M-060
double b[5]
BS.1770 filter coefficients (nominator).
int mode
The current mode.
@ FF_EBUR128_Mm110
itu M-110
unsigned long * short_term_block_energy_histogram
static void ebur128_init_filter(FFEBUR128State *st)
void ** data_ptrs
Data pointer array for interleaved data.
static double histogram_energy_boundaries[1001]
static double histogram_energies[1000]
int ff_ebur128_sample_peak(FFEBUR128State *st, unsigned int channel_number, double *out)
Get maximum sample peak of selected channel in float format.
#define CHECK_ERROR(condition, errorcode, goto_point)
@ FF_EBUR128_Mp060
itu M+060
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static void error(const char *err)
static void ebur128_calc_gating_block(FFEBUR128State *st, size_t frames_per_block, double *optional_output)
static void init_histogram(void)
int ff_ebur128_loudness_shortterm(FFEBUR128State *st, double *out)
Get short-term loudness (last 3s) in LUFS.
@ FF_EBUR128_Mp090
itu M+090
@ FF_EBUR128_MODE_S
can call ff_ebur128_loudness_shortterm
FFEBUR128State * ff_ebur128_init(unsigned int channels, unsigned long samplerate, unsigned long window, int mode)
Initialize library state.
@ FF_EBUR128_Mm090
itu M-090
#define DECLARE_ALIGNED(n, t, v)
unsigned int channels
The number of channels.
#define i(width, name, range_min, range_max)
int ff_ebur128_set_channel(FFEBUR128State *st, unsigned int channel_number, int value)
Set channel type.
libebur128 - a library for loudness measurement according to the EBU R128 standard.
@ FF_EBUR128_MODE_M
can call ff_ebur128_loudness_momentary
#define av_malloc_array(a, b)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Contains information about the state of a loudness measurement.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
size_t short_term_frame_counter
Keeps track of when a new short term block is needed.
double * sample_peak
Maximum sample peak, one per channel.
#define EBUR128_FILTER(type, scaling_factor)
@ FF_EBUR128_Mp110
itu M+110
#define RELATIVE_GATE_FACTOR
int ff_ebur128_relative_threshold(FFEBUR128State *st, double *out)
Get relative threshold in LUFS.
static int ebur128_init_channel_map(FFEBUR128State *st)
@ FF_EBUR128_MODE_SAMPLE_PEAK
can call ff_ebur128_sample_peak
unsigned long window
The maximum window duration in ms.
int ff_ebur128_loudness_global(FFEBUR128State *st, double *out)
Get global integrated loudness in LUFS.