summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBe <be@mixxx.org>2021-08-14 18:00:42 -0500
committerBe <be@mixxx.org>2021-09-30 01:13:10 -0500
commit094405545d03784da04d2725aa87bef84d728957 (patch)
tree899a5fb17c5be50a7fb6858729b14a77d6a5f051
parentbea70ca134dd45f500c20307b9e11114f877aa0d (diff)
devendor libebur128
-rw-r--r--CMakeLists.txt38
-rw-r--r--lib/libebur128/.gitignore1
-rw-r--r--lib/libebur128/CMakeLists.txt40
-rw-r--r--lib/libebur128/COPYING19
-rw-r--r--lib/libebur128/README.md86
-rw-r--r--lib/libebur128/cmake/utils.cmake55
-rw-r--r--lib/libebur128/doc/license/R128Scan.txt23
-rw-r--r--lib/libebur128/doc/license/queue.txt26
-rw-r--r--lib/libebur128/ebur128/CMakeLists.txt71
-rw-r--r--lib/libebur128/ebur128/ebur128.c1333
-rw-r--r--lib/libebur128/ebur128/ebur128.def26
-rw-r--r--lib/libebur128/ebur128/ebur128.h426
-rw-r--r--lib/libebur128/ebur128/libebur128.pc.cmake11
-rw-r--r--lib/libebur128/ebur128/queue/sys/queue.h574
-rw-r--r--lib/libebur128/test/CMakeLists.txt20
-rw-r--r--lib/libebur128/test/minimal-example.c71
-rw-r--r--lib/libebur128/test/tests.c426
17 files changed, 2 insertions, 3244 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 26df0e6472..0b9de0c53c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1922,42 +1922,8 @@ if(ENGINEPRIME)
endif()
# Ebur128
-find_package(Ebur128)
-default_option(EBUR128_STATIC "Link libebur128 statically" "NOT Ebur128_FOUND")
-if(EBUR128_STATIC)
- message(STATUS "Preparing internal Ebur128")
- set(EBUR128_CMAKE_ARGS "-DBUILD_STATIC_LIBS=ON")
- check_symbol_exists(STAILQ_HEAD sys/queue.h HAVE_STAILQ)
- if(NOT HAVE_STAILQ)
- list(APPEND EBUR128_CMAKE_ARGS "-DENABLE_INTERNAL_QUEUE_H=ON")
- endif()
- if(MSVC)
- set(EBUR128_LIBRARY "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}ebur128_static${CMAKE_STATIC_LIBRARY_SUFFIX}")
- else()
- set(EBUR128_LIBRARY "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}ebur128${CMAKE_STATIC_LIBRARY_SUFFIX}")
- endif()
- ExternalProject_Add(libebur128
- SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib/libebur128"
- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/lib/libebur128"
- INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/lib/libebur128-install"
- CMAKE_ARGS "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ${EBUR128_CMAKE_ARGS}
- BUILD_BYPRODUCTS <INSTALL_DIR>/${EBUR128_LIBRARY}
- )
- set_target_properties(libebur128 PROPERTIES EXCLUDE_FROM_ALL TRUE)
-
- add_library(mixxx-libebur128 STATIC IMPORTED)
- add_dependencies(mixxx-libebur128 libebur128)
- set(EBUR128_LIBRARY_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/lib/libebur128-install/${EBUR128_LIBRARY}")
- message(STATUS "Linking internal libebur128 statically: ${EBUR128_LIBRARY_LOCATION}")
- set_target_properties(mixxx-libebur128 PROPERTIES
- IMPORTED_LOCATION "${EBUR128_LIBRARY_LOCATION}"
- INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libebur128/ebur128"
- )
- target_link_libraries(mixxx-lib PRIVATE mixxx-libebur128)
-else()
- message(STATUS "Linking libebur128 dynamically")
- target_link_libraries(mixxx-lib PRIVATE Ebur128::Ebur128)
-endif()
+find_package(Ebur128 REQUIRED)
+target_link_libraries(mixxx-lib PRIVATE Ebur128::Ebur128)
# FidLib
add_library(fidlib STATIC EXCLUDE_FROM_ALL lib/fidlib/fidlib.c)
diff --git a/lib/libebur128/.gitignore b/lib/libebur128/.gitignore
deleted file mode 100644
index 567609b123..0000000000
--- a/lib/libebur128/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build/
diff --git a/lib/libebur128/CMakeLists.txt b/lib/libebur128/CMakeLists.txt
deleted file mode 100644
index f741317f50..0000000000
--- a/lib/libebur128/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
-project(libebur128 C)
-
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
-set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
-
-include(utils)
-include(GNUInstallDirs)
-
-add_subdirectory(ebur128)
-add_subdirectory(test)
-
-to_yes_no(SUMMARY_HAS_QUEUE)
-
-if(ENABLE_INTERNAL_QUEUE_H)
- set(USE_QUEUE "using own copy of queue.h")
-else()
- set(USE_QUEUE "using system copy of queue.h")
-endif()
-
-##### Print status
-message(STATUS "Status found / disabled --")
-message(STATUS "queue.h: ${SUMMARY_HAS_QUEUE}" " ${USE_QUEUE}")
-
-if(BUILD_STATIC_LIBS)
- message(STATUS "build static library and shared library!")
-else()
- message(STATUS "not building static library, set BUILD_STATIC_LIBS to ON to enable")
-endif()
-
-if(NOT ${SUMMARY_HAS_QUEUE} AND NOT ${ENABLE_INTERNAL_QUEUE_H})
- message(FATAL_ERROR "queue.h not found, please set ENABLE_INTERNAL_QUEUE_H to ON")
-endif()
-
-if(ENABLE_TESTS)
- message(STATUS "building tests!")
-else()
- message(STATUS "not building tests, set ENABLE_TESTS to ON to enable")
-endif()
diff --git a/lib/libebur128/COPYING b/lib/libebur128/COPYING
deleted file mode 100644
index e3cebca683..0000000000
--- a/lib/libebur128/COPYING
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011 Jan Kokemüller
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/lib/libebur128/README.md b/lib/libebur128/README.md
deleted file mode 100644
index 42e958192e..0000000000
--- a/lib/libebur128/README.md
+++ /dev/null
@@ -1,86 +0,0 @@
-libebur128
-==========
-
-libebur128 is a library that implements the EBU R 128 standard for loudness
-normalisation.
-
-All source code is licensed under the MIT license. See COPYING file for
-details.
-
-See also [loudness-scanner tool](https://github.com/jiixyj/loudness-scanner).
-
-News
-----
-
-v1.2.4 released:
- * Fix broken `ebur128_loudness_global_multiple()` function. Since v1.1.0 it
- calculated the relative threshold just from the last state given to it,
- resulting in wrong values.
- * More tests
- * Fix some minor build issues
- * Fix uninitialized memory in `ebur128_init()`, possibly resulting in wrong
- values
-
-v1.2.3 released:
- * Fix uninitialized memory access during true peak scanning (bug #72)
-
-v1.2.2 released (v1.2.1 was mistagged):
- * Fix a null pointer dereference when doing true peak scanning of 192kHz data
-
-v1.2.0 released:
-
- * New functions for real time loudness/peak monitoring:
- * `ebur128_loudness_window()`
- * `ebur128_set_max_window()`
- * `ebur128_set_max_history()`
- * `ebur128_prev_sample_peak()`
- * `ebur128_prev_true_peak()`
- * New FIR resampler for true peak calculation, removing Speex dependency
- * Add true peak conformance tests
- * Bug fixes
-
-v1.1.0 released:
-
- * Add `ebur128_relative_threshold()`
- * Add channel definitions from ITU R-REC-BS 1770-4 to channel enum
- * Fix some minor build issues
-
-v1.0.3 released:
-
- * Fix build with recent speexdsp
- * Correct license file name
- * CMake option to disable static library
- * minimal-example.c: do not hard code program name in usage
-
-Features
---------
-
-* Portable ANSI C code
-* Implements M, S and I modes
-* Implements loudness range measurement (EBU - TECH 3342)
-* True peak scanning
-* Supports all samplerates by recalculation of the filter coefficients
-
-Installation
-------------
-
-In the root folder, type:
-
- mkdir build
- cd build
- cmake ..
- make
-
-If you want the git version, run simply:
-
- git clone git://github.com/jiixyj/libebur128.git
-
-Usage
------
-
-Library usage should be pretty straightforward. All exported symbols are
-documented in the ebur128.h header file. For a usage example, see
-minimal-example.c in the tests folder.
-
-On some operating systems, static libraries should be compiled as position
-independent code. You can enable that by turning on `WITH_STATIC_PIC`.
diff --git a/lib/libebur128/cmake/utils.cmake b/lib/libebur128/cmake/utils.cmake
deleted file mode 100644
index b27c57bd51..0000000000
--- a/lib/libebur128/cmake/utils.cmake
+++ /dev/null
@@ -1,55 +0,0 @@
-macro(to_yes_no vars)
- foreach(var ${ARGV})
- if(${var})
- set(${var} "yes")
- else()
- set(${var} "no ")
- endif()
- endforeach()
-endmacro()
-
-macro(if_empty_print_missing vars)
- foreach(var ${ARGV})
- if(NOT ${var})
- set(${var} "<not set>")
- endif()
- endforeach()
-endmacro()
-
-function(to_space_list sc_list)
- set(ret)
- foreach(val ${${sc_list}})
- set(ret "${ret} ${val}")
- endforeach()
- if(ret)
- string(STRIP ${ret} ret)
- set(${sc_list} "${ret}" PARENT_SCOPE)
- endif()
-endfunction()
-
-macro(find_pkg_config prefix pkgname)
- find_package(PkgConfig ${ARGV2})
- if(PKG_CONFIG_FOUND)
- pkg_check_modules(${prefix}_PKGCONF ${ARGV2} ${pkgname})
- if(${${prefix}_PKGCONF_FOUND})
- message(STATUS "${pkgname} library dirs: ${${prefix}_PKGCONF_LIBRARY_DIRS}")
- message(STATUS "${pkgname} cflags: ${${prefix}_PKGCONF_CFLAGS_OTHER}")
- message(STATUS "${pkgname} include dirs: ${${prefix}_PKGCONF_INCLUDE_DIRS}")
- message(STATUS "${pkgname} libraries: ${${prefix}_PKGCONF_LIBRARIES}")
- message(STATUS "${pkgname} ldflags: ${${prefix}_PKGCONF_LDFLAGS_OTHER}")
-
- set(${prefix}_FOUND ${${prefix}_PKGCONF_FOUND})
- set(${prefix}_CFLAGS ${${prefix}_PKGCONF_CFLAGS_OTHER})
- to_space_list(${prefix}_CFLAGS)
- set(${prefix}_INCLUDE_DIRS ${${prefix}_PKGCONF_INCLUDE_DIRS})
- foreach(lib ${${prefix}_PKGCONF_LIBRARIES})
- string(TOUPPER ${lib} LIB)
- find_library(${prefix}_${LIB}_LIBRARY ${lib}
- HINTS ${${prefix}_PKGCONF_LIBRARY_DIRS})
- mark_as_advanced(${prefix}_${LIB}_LIBRARY)
- list(APPEND ${prefix}_LIBRARIES ${${prefix}_${LIB}_LIBRARY})
- endforeach()
- list(APPEND ${prefix}_LIBRARIES ${${prefix}_PKGCONF_LDFLAGS_OTHER})
- endif()
- endif()
-endmacro()
diff --git a/lib/libebur128/doc/license/R128Scan.txt b/lib/libebur128/doc/license/R128Scan.txt
deleted file mode 100644
index 305b5e1d85..0000000000
--- a/lib/libebur128/doc/license/R128Scan.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-EBU R128 Gain processor.
-
-Copyright (C) 2011 Chris Moeller
-
-Portions copyright (c) 2011 Jan Kokemüller
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE."
diff --git a/lib/libebur128/doc/license/queue.txt b/lib/libebur128/doc/license/queue.txt
deleted file mode 100644
index 87fb4d13ba..0000000000
--- a/lib/libebur128/doc/license/queue.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 1991, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
diff --git a/lib/libebur128/ebur128/CMakeLists.txt b/lib/libebur128/ebur128/CMakeLists.txt
deleted file mode 100644
index 420caa5b7e..0000000000
--- a/lib/libebur128/ebur128/CMakeLists.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-set(BUILD_STATIC_LIBS ON CACHE BOOL "Build static library")
-set(WITH_STATIC_PIC OFF CACHE BOOL "Compile static library with -fPIC flag")
-set(ENABLE_INTERNAL_QUEUE_H OFF CACHE BOOL "Use own queue.h")
-
-#### queue.h
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/queuetest.c
-"#include <sys/queue.h>\nLIST_HEAD(listhead, entry) head;\nint main() { return 0; }")
-try_compile(HAS_QUEUE ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/queuetest.c)
-
-set(SUMMARY_HAS_QUEUE ${HAS_QUEUE} CACHE INTERNAL "")
-
-if(ENABLE_INTERNAL_QUEUE_H)
- include_directories(SYSTEM queue)
-endif()
-
-
-if(MSVC)
- add_definitions(-D_USE_MATH_DEFINES)
- if(CMAKE_SIZEOF_VOID_P LESS 8)
- add_definitions(/arch:SSE2)
- endif()
-endif()
-
-
-set(EBUR128_VERSION_MAJOR 1)
-set(EBUR128_VERSION 1.2.4)
-
-#### static
-if(BUILD_STATIC_LIBS)
- add_library(ebur128_static STATIC ebur128.c)
- if(NOT MSVC)
- set_property(TARGET ebur128_static PROPERTY OUTPUT_NAME ebur128)
- endif()
-endif()
-
-if(WITH_STATIC_PIC)
- set_property(TARGET ebur128_static PROPERTY POSITION_INDEPENDENT_CODE ON)
-endif()
-
-#### shared
-# set source file for library, which includes def file if using MSVC
-set(EBUR128_SHARED_SOURCE ebur128.c)
-if(MSVC)
- set(EBUR128_SHARED_SOURCE ${EBUR128_SHARED_SOURCE} ebur128.def)
-endif()
-
-add_library(ebur128 SHARED ${EBUR128_SHARED_SOURCE})
-set_target_properties(ebur128 PROPERTIES
- SOVERSION ${EBUR128_VERSION_MAJOR}
- VERSION ${EBUR128_VERSION})
-
-find_library(MATH_LIBRARY m)
-if(MATH_LIBRARY)
- target_link_libraries(ebur128 ${MATH_LIBRARY})
-endif()
-
-set(EBUR128_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
-
-install(FILES ebur128.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
-if(BUILD_STATIC_LIBS)
- install(TARGETS ebur128 ebur128_static DESTINATION ${CMAKE_INSTALL_LIBDIR})
-else()
- install(TARGETS ebur128 DESTINATION ${CMAKE_INSTALL_LIBDIR})
-endif()
-
-#### pkg-config
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libebur128.pc.cmake
- ${CMAKE_CURRENT_BINARY_DIR}/libebur128.pc @ONLY)
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libebur128.pc"
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
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;