diff options
Diffstat (limited to 'lib/libebur128/ebur128/ebur128.c')
-rw-r--r-- | lib/libebur128/ebur128/ebur128.c | 1333 |
1 files changed, 0 insertions, 1333 deletions
diff --git a/lib/libebur128/ebur128/ebur128.c b/lib/libebur128/ebur128/ebur128.c deleted file mode 100644 index e05165b096..0000000000 --- a/lib/libebur128/ebur128/ebur128.c +++ /dev/null @@ -1,1333 +0,0 @@ -/* See COPYING file for copyright and license details. */ - -#include "ebur128.h" - -#include <float.h> -#include <limits.h> -#include <math.h> /* You may have to define _USE_MATH_DEFINES if you use MSVC */ -#include <stdio.h> -#include <stdlib.h> - -/* This can be replaced by any BSD-like queue implementation. */ -#include <sys/queue.h> - -#define CHECK_ERROR(condition, errorcode, goto_point) \ - if ((condition)) { \ - errcode = (errorcode); \ - goto goto_point; \ - } - -STAILQ_HEAD(ebur128_double_queue, ebur128_dq_entry); -struct ebur128_dq_entry { - double z; - STAILQ_ENTRY(ebur128_dq_entry) entries; -}; - -#define ALMOST_ZERO 0.000001 - -typedef struct { /* Data structure for polyphase FIR interpolator */ - unsigned int factor; /* Interpolation factor of the interpolator */ - unsigned int taps; /* Taps (prefer odd to increase zero coeffs) */ - unsigned int channels; /* Number of channels */ - unsigned int delay; /* Size of delay buffer */ - struct { - unsigned int count; /* Number of coefficients in this subfilter */ - unsigned int* index; /* Delay index of corresponding filter coeff */ - double* coeff; /* List of subfilter coefficients */ - }* filter; /* List of subfilters (one for each factor) */ - float** z; /* List of delay buffers (one for each channel) */ - unsigned int zi; /* Current delay buffer index */ -} interpolator; - -struct ebur128_state_internal { - /** Filtered audio data (used as ring buffer). */ - double* audio_data; - /** Size of audio_data array. */ - size_t audio_data_frames; - /** Current index for audio_data. */ - size_t audio_data_index; - /** How many frames are needed for a gating block. Will correspond to 400ms - * of audio at initialization, and 100ms after the first block (75% overlap - * as specified in the 2011 revision of BS1770). */ - unsigned long needed_frames; - /** The channel map. Has as many elements as there are channels. */ - int* channel_map; - /** How many samples fit in 100ms (rounded). */ - unsigned long samples_in_100ms; - /** BS.1770 filter coefficients (nominator). */ - double b[5]; - /** BS.1770 filter coefficients (denominator). */ - double a[5]; - /** BS.1770 filter state. */ - double v[5][5]; - /** Linked list of block energies. */ - struct ebur128_double_queue block_list; - unsigned long block_list_max; - unsigned long block_list_size; - /** Linked list of 3s-block energies, used to calculate LRA. */ - struct ebur128_double_queue short_term_block_list; - unsigned long st_block_list_max; - unsigned long st_block_list_size; - int use_histogram; - unsigned long *block_energy_histogram; - unsigned long *short_term_block_energy_histogram; - /** Keeps track of when a new short term block is needed. */ - size_t short_term_frame_counter; - /** Maximum sample peak, one per channel */ - double* sample_peak; - double* prev_sample_peak; - /** Maximum true peak, one per channel */ - double* true_peak; - double* prev_true_peak; - interpolator* interp; - float* resampler_buffer_input; - size_t resampler_buffer_input_frames; - float* resampler_buffer_output; - size_t resampler_buffer_output_frames; - /** The maximum window duration in ms. */ - unsigned long window; - unsigned long history; -}; - -static double relative_gate = -10.0; - -/* Those will be calculated when initializing the library */ -static double relative_gate_factor; -static double minus_twenty_decibels; -static double histogram_energies[1000]; -static double histogram_energy_boundaries[1001]; - -static interpolator* interp_create(unsigned int taps, unsigned int factor, unsigned int channels) { - interpolator* interp = calloc(1, sizeof(interpolator)); - unsigned int j = 0; - - interp->taps = taps; - interp->factor = factor; - interp->channels = channels; - interp->delay = (interp->taps + interp->factor - 1) / interp->factor; - - /* Initialize the filter memory - * One subfilter per interpolation factor. */ - interp->filter = calloc(interp->factor, sizeof(*interp->filter)); - for (j = 0; j < interp->factor; j++) { - interp->filter[j].index = calloc(interp->delay, sizeof(unsigned int)); - interp->filter[j].coeff = calloc(interp->delay, sizeof(double)); - } - /* One delay buffer per channel. */ - interp->z = calloc(interp->channels, sizeof(float*)); - for (j = 0; j < interp->channels; j++) { - interp->z[j] = calloc( interp->delay, sizeof(float) ); - } - - /* Calculate the filter coefficients */ - for (j = 0; j < interp->taps; j++) { - /* Calculate sinc */ - double m = (double)j - (double)(interp->taps - 1) / 2.0; - double c = 1.0; - if (fabs(m) > ALMOST_ZERO) { - c = sin(m * M_PI / interp->factor) / (m * M_PI / interp->factor); - } - /* Apply Hanning window */ - c *= 0.5 * (1 - cos(2 * M_PI * j / (interp->taps - 1))); - - if (fabs(c) > ALMOST_ZERO) { /* Ignore any zero coeffs. */ - /* Put the coefficient into the correct subfilter */ - unsigned int f = j % interp->factor; - unsigned int t = interp->filter[f].count++; - interp->filter[f].coeff[t] = c; - interp->filter[f].index[t] = j / interp->factor; - } - } - return interp; -} - -static void interp_destroy(interpolator* interp) { - unsigned int j = 0; - if (!interp) { - return; - } - for (j = 0; j < interp->factor; j++) { - free(interp->filter[j].index); - free(interp->filter[j].coeff); - } - free(interp->filter); - for (j = 0; j < interp->channels; j++) { - free(interp->z[j]); - } - free(interp->z); - free(interp); -} - -static size_t interp_process(interpolator* interp, size_t frames, float* in, float* out) { - size_t frame = 0; - unsigned int chan = 0; - unsigned int f = 0; - unsigned int t = 0; - unsigned int out_stride = interp->channels * interp->factor; - float* outp = 0; - double acc = 0; - double c = 0; - - for (frame = 0; frame < frames; frame++) { - for (chan = 0; chan < interp->channels; chan++) { - /* Add sample to delay buffer */ - interp->z[chan][interp->zi] = *in++; - /* Apply coefficients */ - outp = out + chan; - for (f = 0; f < interp->factor; f++) { - acc = 0.0; - for (t = 0; t < interp->filter[f].count; t++) { - int i = (int)interp->zi - (int)interp->filter[f].index[t]; - if (i < 0) { - i += interp->delay; - } - c = interp->filter[f].coeff[t]; - acc += interp->z[chan][i] * c; - } - *outp = (float)acc; - outp += interp->channels; - } - } - out += out_stride; - interp->zi++; - if (interp->zi == interp->delay) { - interp->zi = 0; - } - } - - return frames * interp->factor; -} - -static void ebur128_init_filter(ebur128_state* st) { - int i, j; - - double f0 = 1681.974450955533; - double G = 3.999843853973347; - double Q = 0.7071752369554196; - - double K = tan(M_PI * f0 / (double) st->samplerate); - double Vh = pow(10.0, G / 20.0); - double Vb = pow(Vh, 0.4996667741545416); - - double pb[3] = {0.0, 0.0, 0.0}; - double pa[3] = {1.0, 0.0, 0.0}; - double rb[3] = {1.0, -2.0, 1.0}; - double ra[3] = {1.0, 0.0, 0.0}; - - double a0 = 1.0 + K / Q + K * K ; - pb[0] = (Vh + Vb * K / Q + K * K) / a0; - pb[1] = 2.0 * (K * K - Vh) / a0; - pb[2] = (Vh - Vb * K / Q + K * K) / a0; - pa[1] = 2.0 * (K * K - 1.0) / a0; - pa[2] = (1.0 - K / Q + K * K) / a0; - - /* fprintf(stderr, "%.14f %.14f %.14f %.14f %.14f\n", - b1[0], b1[1], b1[2], a1[1], a1[2]); */ - - f0 = 38.13547087602444; - Q = 0.5003270373238773; - K = tan(M_PI * f0 / (double) st->samplerate); - - ra[1] = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K); - ra[2] = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K); - - /* fprintf(stderr, "%.14f %.14f\n", a2[1], a2[2]); */ - - st->d->b[0] = pb[0] * rb[0]; - st->d->b[1] = pb[0] * rb[1] + pb[1] * rb[0]; - st->d->b[2] = pb[0] * rb[2] + pb[1] * rb[1] + pb[2] * rb[0]; - st->d->b[3] = pb[1] * rb[2] + pb[2] * rb[1]; - st->d->b[4] = pb[2] * rb[2]; - - st->d->a[0] = pa[0] * ra[0]; - st->d->a[1] = pa[0] * ra[1] + pa[1] * ra[0]; - st->d->a[2] = pa[0] * ra[2] + pa[1] * ra[1] + pa[2] * ra[0]; - st->d->a[3] = pa[1] * ra[2] + pa[2] * ra[1]; - st->d->a[4] = pa[2] * ra[2]; - - for (i = 0; i < 5; ++i) { - for (j = 0; j < 5; ++j) { - st->d->v[i][j] = 0.0; - } - } -} - -static int ebur128_init_channel_map(ebur128_state* st) { - size_t i; - st->d->channel_map = (int*) malloc(st->channels * sizeof(int)); - if (!st->d->channel_map) { - return EBUR128_ERROR_NOMEM; - } - if (st->channels == 4) { - st->d->channel_map[0] = EBUR128_LEFT; - st->d->channel_map[1] = EBUR128_RIGHT; - st->d->channel_map[2] = EBUR128_LEFT_SURROUND; - st->d->channel_map[3] = EBUR128_RIGHT_SURROUND; - } else if (st->channels == 5) { - st->d->channel_map[0] = EBUR128_LEFT; - st->d->channel_map[1] = EBUR128_RIGHT; - st->d->channel_map[2] = EBUR128_CENTER; - st->d->channel_map[3] = EBUR128_LEFT_SURROUND; - st->d->channel_map[4] = EBUR128_RIGHT_SURROUND; - } else { - for (i = 0; i < st->channels; ++i) { - switch (i) { - case 0: st->d->channel_map[i] = EBUR128_LEFT; break; - case 1: st->d->channel_map[i] = EBUR128_RIGHT; break; - case 2: st->d->channel_map[i] = EBUR128_CENTER; break; - case 3: st->d->channel_map[i] = EBUR128_UNUSED; break; - case 4: st->d->channel_map[i] = EBUR128_LEFT_SURROUND; break; - case 5: st->d->channel_map[i] = EBUR128_RIGHT_SURROUND; break; - default: st->d->channel_map[i] = EBUR128_UNUSED; break; - } - } - } - return EBUR128_SUCCESS; -} - -static int ebur128_init_resampler(ebur128_state* st) { - int errcode = EBUR128_SUCCESS; - - if (st->samplerate < 96000) { - st->d->interp = interp_create(49, 4, st->channels); - CHECK_ERROR(!st->d->interp, EBUR128_ERROR_NOMEM, exit) - } else if (st->samplerate < 192000) { - st->d->interp = interp_create(49, 2, st->channels); - CHECK_ERROR(!st->d->interp, EBUR128_ERROR_NOMEM, exit) - } else { - st->d->resampler_buffer_input = NULL; - st->d->resampler_buffer_output = NULL; - st->d->interp = NULL; - goto exit; - } - - st->d->resampler_buffer_input_frames = st->d->samples_in_100ms * 4; - st->d->resampler_buffer_input = malloc(st->d->resampler_buffer_input_frames * - st->channels * - sizeof(float)); - CHECK_ERROR(!st->d->resampler_buffer_input, EBUR128_ERROR_NOMEM, free_interp) - - st->d->resampler_buffer_output_frames = - st->d->resampler_buffer_input_frames * - st->d->interp->factor; - st->d->resampler_buffer_output = malloc - (st->d->resampler_buffer_output_frames * - st->channels * - sizeof(float)); - CHECK_ERROR(!st->d->resampler_buffer_output, EBUR128_ERROR_NOMEM, free_input) - - return errcode; - -free_interp: - interp_destroy(st->d->interp); - st->d->interp = NULL; -free_input: - free(st->d->resampler_buffer_input); - st->d->resampler_buffer_input = NULL; -exit: - return errcode; -} - -static void ebur128_destroy_resampler(ebur128_state* st) { - free(st->d->resampler_buffer_input); - st->d->resampler_buffer_input = NULL; - free(st->d->resampler_buffer_output); - st->d->resampler_buffer_output = NULL; - interp_destroy(st->d->interp); - st->d->interp = NULL; -} - -void ebur128_get_version(int* major, int* minor, int* patch) { - *major = EBUR128_VERSION_MAJOR; - *minor = EBUR128_VERSION_MINOR; - *patch = EBUR128_VERSION_PATCH; -} - -ebur128_state* ebur128_init(unsigned int channels, - unsigned long samplerate, - int mode) { - int result; - int errcode; - ebur128_state* st; - unsigned int i; - size_t j; - - if (channels == 0 || samplerate < 5) { - return NULL; - } - - st = (ebur128_state*) malloc(sizeof(ebur128_state)); - CHECK_ERROR(!st, 0, exit) - st->d = (struct ebur128_state_internal*) - malloc(sizeof(struct ebur128_state_internal)); - CHECK_ERROR(!st->d, 0, free_state) - st->channels = channels; - errcode = ebur128_init_channel_map(st); - CHECK_ERROR(errcode, 0, free_internal) - - st->d->sample_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->sample_peak, 0, free_channel_map) - st->d->prev_sample_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->prev_sample_peak, 0, free_sample_peak) - st->d->true_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->true_peak, 0, free_prev_sample_peak) - st->d->prev_true_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->prev_true_peak, 0, free_true_peak) - for (i = 0; i < channels; ++i) { - st->d->sample_peak[i] = 0.0; - st->d->prev_sample_peak[i] = 0.0; - st->d->true_peak[i] = 0.0; - st->d->prev_true_peak[i] = 0.0; - } - - st->d->use_histogram = mode & EBUR128_MODE_HISTOGRAM ? 1 : 0; - st->d->history = ULONG_MAX; - st->samplerate = samplerate; - st->d->samples_in_100ms = (st->samplerate + 5) / 10; - st->mode = mode; - if ((mode & EBUR128_MODE_S) == EBUR128_MODE_S) { - st->d->window = 3000; - } else if ((mode & EBUR128_MODE_M) == EBUR128_MODE_M) { - st->d->window = 400; - } else { - goto free_prev_true_peak; - } - st->d->audio_data_frames = st->samplerate * st->d->window / 1000; - if (st->d->audio_data_frames % st->d->samples_in_100ms) { - /* round up to multiple of samples_in_100ms */ - st->d->audio_data_frames = st->d->audio_data_frames - + st->d->samples_in_100ms - - (st->d->audio_data_frames % st->d->samples_in_100ms); - } - st->d->audio_data = (double*) malloc(st->d->audio_data_frames * - st->channels * - sizeof(double)); - CHECK_ERROR(!st->d->audio_data, 0, free_true_peak) - for (j = 0; j < st->d->audio_data_frames * st->channels; ++j) { - st->d->audio_data[j] = 0.0; - } - - ebur128_init_filter(st); - - if (st->d->use_histogram) { - st->d->block_energy_histogram = malloc(1000 * sizeof(unsigned long)); - CHECK_ERROR(!st->d->block_energy_histogram, 0, free_audio_data) - for (i = 0; i < 1000; ++i) { - st->d->block_energy_histogram[i] = 0; - } - } else { - st->d->block_energy_histogram = NULL; - } - if (st->d->use_histogram) { - st->d->short_term_block_energy_histogram = malloc(1000 * sizeof(unsigned long)); - CHECK_ERROR(!st->d->short_term_block_energy_histogram, 0, free_block_energy_histogram) - for (i = 0; i < 1000; ++i) { - st->d->short_term_block_energy_histogram[i] = 0; - } - } else { - st->d->short_term_block_energy_histogram = NULL; - } - STAILQ_INIT(&st->d->block_list); - st->d->block_list_size = 0; - st->d->block_list_max = st->d->history / 100; - STAILQ_INIT(&st->d->short_term_block_list); - st->d->st_block_list_size = 0; - st->d->st_block_list_max = st->d->history / 3000; - st->d->short_term_frame_counter = 0; - - result = ebur128_init_resampler(st); - CHECK_ERROR(result, 0, free_short_term_block_energy_histogram) - - /* the first block needs 400ms of audio data */ - st->d->needed_frames = st->d->samples_in_100ms * 4; - /* start at the beginning of the buffer */ - st->d->audio_data_index = 0; - - /* initialize static constants */ - relative_gate_factor = pow(10.0, relative_gate / 10.0); - minus_twenty_decibels = pow(10.0, -20.0 / 10.0); - histogram_energy_boundaries[0] = pow(10.0, (-70.0 + 0.691) / 10.0); - if (st->d->use_histogram) { - for (i = 0; i < 1000; ++i) { - histogram_energies[i] = pow(10.0, ((double) i / 10.0 - 69.95 + 0.691) / 10.0); - } - for (i = 1; i < 1001; ++i) { - histogram_energy_boundaries[i] = pow(10.0, ((double) i / 10.0 - 70.0 + 0.691) / 10.0); - } - } - - return st; - -free_short_term_block_energy_histogram: - free(st->d->short_term_block_energy_histogram); -free_block_energy_histogram: - free(st->d->block_energy_histogram); -free_audio_data: - free(st->d->audio_data); -free_prev_true_peak: - free(st->d->prev_true_peak); -free_true_peak: - free(st->d->true_peak); -free_prev_sample_peak: - free(st->d->prev_sample_peak); -free_sample_peak: - free(st->d->sample_peak); -free_channel_map: - free(st->d->channel_map); -free_internal: - free(st->d); -free_state: - free(st); -exit: - return NULL; -} - -void ebur128_destroy(ebur128_state** st) { - struct ebur128_dq_entry* entry; - free((*st)->d->block_energy_histogram); - free((*st)->d->short_term_block_energy_histogram); - free((*st)->d->audio_data); - free((*st)->d->channel_map); - free((*st)->d->sample_peak); - free((*st)->d->prev_sample_peak); - free((*st)->d->true_peak); - free((*st)->d->prev_true_peak); - while (!STAILQ_EMPTY(&(*st)->d->block_list)) { - entry = STAILQ_FIRST(&(*st)->d->block_list); - STAILQ_REMOVE_HEAD(&(*st)->d->block_list, entries); - free(entry); - } - while (!STAILQ_EMPTY(&(*st)->d->short_term_block_list)) { - entry = STAILQ_FIRST(&(*st)->d->short_term_block_list); - STAILQ_REMOVE_HEAD(&(*st)->d->short_term_block_list, entries); - free(entry); - } - ebur128_destroy_resampler(*st); - free((*st)->d); - free(*st); - *st = NULL; -} - -static void ebur128_check_true_peak(ebur128_state* st, size_t frames) { - size_t c, i, frames_out; - - frames_out = interp_process(st->d->interp, frames, - st->d->resampler_buffer_input, - st->d->resampler_buffer_output); - - for (i = 0; i < frames_out; ++i) { - for (c = 0; c < st->channels; ++c) { - float val = st->d->resampler_buffer_output[i * st->channels + c]; - - if (val > st->d->prev_true_peak[c]) { - st->d->prev_true_peak[c] = val; - } else if (-val > st->d->prev_true_peak[c]) { - st->d->prev_true_peak[c] = -val; - } - } - } -} - -#if defined(__SSE2_MATH__) || defined(_M_X64) || _M_IX86_FP >= 2 -#include <xmmintrin.h> -#define TURN_ON_FTZ \ - unsigned int mxcsr = _mm_getcsr(); \ - _mm_setcsr(mxcsr | _MM_FLUSH_ZERO_ON); -#define TURN_OFF_FTZ _mm_setcsr(mxcsr); -#define FLUSH_MANUALLY -#else -#warning "manual FTZ is being used, please enable SSE2 (-msse2 -mfpmath=sse)" -#define TURN_ON_FTZ -#define TURN_OFF_FTZ -#define FLUSH_MANUALLY \ - st->d->v[ci][4] = fabs(st->d->v[ci][4]) < DBL_MIN ? 0.0 : st->d->v[ci][4]; \ - st->d->v[ci][3] = fabs(st->d->v[ci][3]) < DBL_MIN ? 0.0 : st->d->v[ci][3]; \ - st->d->v[ci][2] = fabs(st->d->v[ci][2]) < DBL_MIN ? 0.0 : st->d->v[ci][2]; \ - st->d->v[ci][1] = fabs(st->d->v[ci][1]) < DBL_MIN ? 0.0 : st->d->v[ci][1]; -#endif - -#define EBUR128_FILTER(type, min_scale, max_scale) \ -static void ebur128_filter_##type(ebur128_state* st, const type* src, \ - size_t frames) { \ - static double scaling_factor = \ - -((double) (min_scale)) > (double) (max_scale) ? \ - -((double) (min_scale)) : (double) (max_scale); \ - double* audio_data = st->d->audio_data + st->d->audio_data_index; \ - size_t i, c; \ - \ - TURN_ON_FTZ \ - \ - if ((st->mode & EBUR128_MODE_SAMPLE_PEAK) == EBUR128_MODE_SAMPLE_PEAK) { \ - for (c = 0; c < st->channels; ++c) { \ - double max = 0.0; \ - for (i = 0; i < frames; ++i) { \ - if (src[i * st->channels + c] > max) { \ - max = src[i * st->channels + c]; \ - } else if (-src[i * st->channels + c] > max) { \ - max = -1.0 * src[i * st->channels + c]; \ - } \ - } \ - max /= scaling_factor; \ - if (max > st->d->prev_sample_peak[c]) st->d->prev_sample_peak[c] = max; \ - } \ - } \ - if ((st->mode & EBUR128_MODE_TRUE_PEAK) == EBUR128_MODE_TRUE_PEAK && \ - st->d->interp) { \ - for (c = 0; c < st->channels; ++c) { \ - for (i = 0; i < frames; ++i) { \ - st->d->resampler_buffer_input[i * st->channels + c] = \ - (float) (src[i * st->channels + c] / scaling_factor); \ - } \ - } \ - ebur128_check_true_peak(st, frames); \ - } \ - for (c = 0; c < st->channels; ++c) { \ - int ci = st->d->channel_map[c] - 1; \ - if (ci < 0) continue; \ - else if (ci == EBUR128_DUAL_MONO - 1) ci = 0; /*dual mono */ \ - for (i = 0; i < frames; ++i) { \ - st->d->v[ci][0] = (double) (src[i * st->channels + c] / scaling_factor) \ - - st->d->a[1] * st->d->v[ci][1] \ - - st->d->a[2] * st->d->v[ci][2] \ - - st->d->a[3] * st->d->v[ci][3] \ - - st->d->a[4] * st->d->v[ci][4]; \ - audio_data[i * st->channels + c] = \ - st->d->b[0] * st->d->v[ci][0] \ - + st->d->b[1] * st->d->v[ci][1] \ - + st->d->b[2] * st->d->v[ci][2] \ - + st->d->b[3] * st->d->v[ci][3] \ - + st->d->b[4] * st->d->v[ci][4]; \ - st->d->v[ci][4] = st->d->v[ci][3]; \ - st->d->v[ci][3] = st->d->v[ci][2]; \ - st->d->v[ci][2] = st->d->v[ci][1]; \ - st->d->v[ci][1] = st->d->v[ci][0]; \ - } \ - FLUSH_MANUALLY \ - } \ - TURN_OFF_FTZ \ -} -EBUR128_FILTER(short, SHRT_MIN, SHRT_MAX) -EBUR128_FILTER(int, INT_MIN, INT_MAX) -EBUR128_FILTER(float, -1.0f, 1.0f) -EBUR128_FILTER(double, -1.0, 1.0) - -static double ebur128_energy_to_loudness(double energy) { - return 10 * (log(energy) / log(10.0)) - 0.691; -} - -static size_t find_histogram_index(double energy) { - size_t index_min = 0; - size_t index_max = 1000; - size_t index_mid; - - do { - index_mid = (index_min + index_max) / 2; - if (energy >= histogram_energy_boundaries[index_mid]) { - index_min = index_mid; - } else { - index_max = index_mid; - } - } while (index_max - index_min != 1); - - return index_min; -} - -static int ebur128_calc_gating_block(ebur128_state* st, size_t frames_per_block, - double* optional_output) { - size_t i, c; - double sum = 0.0; - double channel_sum; - for (c = 0; c < st->channels; ++c) { - if (st->d->channel_map[c] == EBUR128_UNUSED) { - continue; - } - channel_sum = 0.0; - if (st->d->audio_data_index < frames_per_block * st->channels) { - for (i = 0; i < st->d->audio_data_index / st->channels; ++i) { - channel_sum += st->d->audio_data[i * st->channels + c] * - st->d->audio_data[i * st->channels + c]; - } - for (i = st->d->audio_data_frames - - (frames_per_block - - st->d->audio_data_index / st->channels); - i < st->d->audio_data_frames; ++i) { - channel_sum += st->d->audio_data[i * st->channels + c] * - st->d->audio_data[i * st->channels + c]; - } - } else { - for (i = st->d->audio_data_index / st->channels - frames_per_block; - i < st->d->audio_data_index / st->channels; - ++i) { - channel_sum += st->d->audio_data[i * st->channels + c] * - st->d->audio_data[i * st->channels + c]; - } - } - if (st->d->channel_map[c] == EBUR128_Mp110 || - st->d->channel_map[c] == EBUR128_Mm110 || - st->d->channel_map[c] == EBUR128_Mp060 || - st->d->channel_map[c] == EBUR128_Mm060 || - st->d->channel_map[c] == EBUR128_Mp090 || - st->d->channel_map[c] == EBUR128_Mm090) { - channel_sum *= 1.41; - } else if (st->d->channel_map[c] == EBUR128_DUAL_MONO) { - channel_sum *= 2.0; - } - sum += channel_sum; - } - sum /= (double) frames_per_block; - if (optional_output) { - *optional_output = sum; - return EBUR128_SUCCESS; - } else if (sum >= histogram_energy_boundaries[0]) { - if (st->d->use_histogram) { - ++st->d->block_energy_histogram[find_histogram_index(sum)]; - } else { - struct ebur128_dq_entry* block; - if (st->d->block_list_size == st->d->block_list_max) { - block = STAILQ_FIRST(&st->d->block_list); - STAILQ_REMOVE_HEAD(&st->d->block_list, entries); - } else { - block = (struct ebur128_dq_entry*) malloc(sizeof(struct ebur128_dq_entry)); - if (!block) { - return EBUR128_ERROR_NOMEM; - } - st->d->block_list_size++; - } - block->z = sum; - STAILQ_INSERT_TAIL(&st->d->block_list, block, entries); - } - return EBUR128_SUCCESS; - } else { - return EBUR128_SUCCESS; - } -} - -int ebur128_set_channel(ebur128_state* st, - unsigned int channel_number, - int value) { - if (channel_number >= st->channels) { - return 1; - } - if (value == EBUR128_DUAL_MONO && - (st->channels != 1 || channel_number != 0)) { - fprintf(stderr, "EBUR128_DUAL_MONO only works with mono files!\n"); - return 1; - } - st->d->channel_map[channel_number] = value; - return 0; -} - -int ebur128_change_parameters(ebur128_state* st, - unsigned int channels, - unsigned long samplerate) { - int errcode = EBUR128_SUCCESS; - size_t j; - - if (channels == 0 || samplerate < 5) { - return EBUR128_ERROR_NOMEM; - } - - if (channels == st->channels && - samplerate == st->samplerate) { - return EBUR128_ERROR_NO_CHANGE; - } - - free(st->d->audio_data); - st->d->audio_data = NULL; - - if (channels != st->channels) { - unsigned int i; - - free(st->d->channel_map); st->d->channel_map = NULL; - free(st->d->sample_peak); st->d->sample_peak = NULL; - free(st->d->prev_sample_peak); st->d->prev_sample_peak = NULL; - free(st->d->true_peak); st->d->true_peak = NULL; - free(st->d->prev_true_peak); st->d->prev_true_peak = NULL; - st->channels = channels; - - errcode = ebur128_init_channel_map(st); - CHECK_ERROR(errcode, EBUR128_ERROR_NOMEM, exit) - - st->d->sample_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->sample_peak, EBUR128_ERROR_NOMEM, exit) - st->d->prev_sample_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->prev_sample_peak, EBUR128_ERROR_NOMEM, exit) - st->d->true_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->true_peak, EBUR128_ERROR_NOMEM, exit) - st->d->prev_true_peak = (double*) malloc(channels * sizeof(double)); - CHECK_ERROR(!st->d->prev_true_peak, EBUR128_ERROR_NOMEM, exit) - for (i = 0; i < channels; ++i) { - st->d->sample_peak[i] = 0.0; - st->d->prev_sample_peak[i] = 0.0; - st->d->true_peak[i] = 0.0; - st->d->prev_true_peak[i] = 0.0; - } - } - if (samplerate != st->samplerate) { - st->samplerate = samplerate; - st->d->samples_in_100ms = (st->samplerate + 5) / 10; - ebur128_init_filter(st); - } - st->d->audio_data_frames = st->samplerate * st->d->window / 1000; - if (st->d->audio_data_frames % st->d->samples_in_100ms) { - /* round up to multiple of samples_in_100ms */ - st->d->audio_data_frames = st->d->audio_data_frames - + st->d->samples_in_100ms - - (st->d->audio_data_frames % st->d->samples_in_100ms); - } - st->d->audio_data = (double*) malloc(st->d->audio_data_frames * - st->channels * - sizeof(double)); - CHECK_ERROR(!st->d->audio_data, EBUR128_ERROR_NOMEM, exit) - for (j = 0; j < st->d->audio_data_frames * st->channels; ++j) { - st->d->audio_data[j] = 0.0; - } - - ebur128_destroy_resampler(st); - errcode = ebur128_init_resampler(st); - CHECK_ERROR(errcode, EBUR128_ERROR_NOMEM, exit) - - /* the first block needs 400ms of audio data */ - st->d->needed_frames = st->d->samples_in_100ms * 4; - /* start at the beginning of the buffer */ - st->d->audio_data_index = 0; - /* reset short term frame counter */ - st->d->short_term_frame_counter = 0; - -exit: - return errcode; -} - -int ebur128_set_max_window(ebur128_state* st, unsigned long window) -{ - int errcode = EBUR128_SUCCESS; - size_t j; - - if ((st->mode & EBUR128_MODE_S) == EBUR128_MODE_S && window < 3000) { - window = 3000; - } else if ((st->mode & EBUR128_MODE_M) == EBUR128_MODE_M && window < 400) { - window = 400; - } - if (window == st->d->window) { - return EBUR128_ERROR_NO_CHANGE; - } - - st->d->window = window; - free(st->d->audio_data); - st->d->audio_data = NULL; - st->d->audio_data_frames = st->samplerate * st->d->window / 1000; - if (st->d->audio_data_frames % st->d->samples_in_100ms) { - /* round up to multiple of samples_in_100ms */ - st->d->audio_data_frames = st->d->audio_data_frames - + st->d->samples_in_100ms - - (st->d->audio_data_frames % st->d->samples_in_100ms); - } - st->d->audio_data = (double*) malloc(st->d->audio_data_frames * - st->channels * - sizeof(double)); - CHECK_ERROR(!st->d->audio_data, EBUR128_ERROR_NOMEM, exit) - for (j = 0; j < st->d->audio_data_frames * st->channels; ++j) { - st->d->audio_data[j] = 0.0; - } - - /* the first block needs 400ms of audio data */ - st->d->needed_frames = st->d->samples_in_100ms * 4; - /* start at the beginning of the buffer */ - st->d->audio_data_index = 0; - /* reset short term frame counter */ - st->d->short_term_frame_counter = 0; - -exit: - return errcode; -} - -int ebur128_set_max_history(ebur128_state* st, unsigned long history) -{ - if ((st->mode & EBUR128_MODE_LRA) == EBUR128_MODE_LRA && history < 3000) { - history = 3000; - } else if ((st->mode & EBUR128_MODE_M) == EBUR128_MODE_M && history < 400) { - history = 400; - } - if (history == st->d->history) { - return EBUR128_ERROR_NO_CHANGE; - } - st->d->history = history; - st->d->block_list_max = st->d->history / 100; - st->d->st_block_list_max = st->d->history / 3000; - while (st->d->block_list_size > st->d->block_list_max) { - struct ebur128_dq_entry* block = STAILQ_FIRST(&st->d->block_list); - STAILQ_REMOVE_HEAD(&st->d->block_list, entries); - free(block); - st->d->block_list_size--; - } - while (st->d->st_block_list_size > st->d->st_block_list_max) { - struct ebur128_dq_entry* block = STAILQ_FIRST(&st->d->short_term_block_list); - STAILQ_REMOVE_HEAD(&st->d->short_term_block_list, entries); - free(block); - st->d->st_block_list_size--; - } - return EBUR128_SUCCESS; -} - -static int ebur128_energy_shortterm(ebur128_state* st, double* out); -#define EBUR128_ADD_FRAMES(type) \ -int ebur128_add_frames_##type(ebur128_state* st, \ - const type* src, size_t frames) { \ - size_t src_index = 0; \ - unsigned int c = 0; \ - for (c = 0; c < st->channels; c++) { \ - st->d->prev_sample_peak[c] = 0.0; \ - st->d->prev_true_peak[c] = 0.0; \ - } \ - while (frames > 0) { \ - if (frames >= st->d->needed_frames) { \ - ebur128_filter_##type(st, src + src_index, st->d->needed_frames); \ - src_index += st->d->needed_frames * st->channels; \ - frames -= st->d->needed_frames; \ - st->d->audio_data_index += st->d->needed_frames * st->channels; \ - /* calculate the new gating block */ \ - if ((st->mode & EBUR128_MODE_I) == EBUR128_MODE_I) { \ - if (ebur128_calc_gating_block(st, st->d->samples_in_100ms * 4, NULL)) {\ - return EBUR128_ERROR_NOMEM; \ - } \ - } \ - if ((st->mode & EBUR128_MODE_LRA) == EBUR128_MODE_LRA) { \ - st->d->short_term_frame_counter += st->d->needed_frames; \ - if (st->d->short_term_frame_counter == st->d->samples_in_100ms * 30) { \ - struct ebur128_dq_entry* block; \ - double st_energy; \ - if (ebur128_energy_shortterm(st, &st_energy) == EBUR128_SUCCESS && \ - st_energy >= histogram_energy_boundaries[0]) { \ - if (st->d->use_histogram) { \ - ++st->d->short_term_block_energy_histogram[ \ - find_histogram_index(st_energy)];\ - } else { \ - if (st->d->st_block_list_size == st->d->st_block_list_max) { \ - block = STAILQ_FIRST(&st->d->short_term_block_list); \ - STAILQ_REMOVE_HEAD(&st->d->short_term_block_list, entries); \ - } else { |