Update to latest libebur128

This commit is contained in:
Craig Drummond
2017-05-21 20:17:39 +01:00
parent 1049fee1c0
commit 4d19907ae3
8 changed files with 680 additions and 276 deletions

View File

@@ -1,57 +1,10 @@
include(MacroLogFeature)
find_package(SPEEXDSP)
macro_log_feature(SPEEXDSP_FOUND "SpeexDSP" "Used to speedup/improve ReplayGain calculation." "http://www.speex.org")
set(USE_SPEEX_RESAMPLER ${SPEEXDSP_FOUND})
configure_file(ebur128-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/ebur128-config.h)
macro(ebur128_check_for_sse)
# check for SSE extensions
include(CheckCXXSourceRuns)
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_REQUIRED_FLAGS "-msse3")
check_cxx_source_runs("
#include <pmmintrin.h>
int main() { __m128d a, b; double vals[2] = {0}; a = _mm_loadu_pd(vals); b = _mm_hadd_pd(a,a); _mm_storeu_pd(vals, b); return 0; }"
HAS_SSE3_EXTENSIONS)
if (HAS_SSE3_EXTENSIONS)
add_definitions("-msse3 -mfpmath=sse")
else ()
# No sse3, check sse2
set(CMAKE_REQUIRED_FLAGS "-msse2")
check_cxx_source_runs("
#include <emmintrin.h>
int main() { __m128d a, b; double vals[2] = {0}; a = _mm_loadu_pd(vals); b = _mm_add_pd(a,a); _mm_storeu_pd(vals,b); return 0; }"
HAS_SSE2_EXTENSIONS)
if (HAS_SSE2_EXTENSIONS)
add_definitions("-msse2 -mfpmath=sse")
else ()
# No sse2, check sse
set(CMAKE_REQUIRED_FLAGS "-msse")
check_cxx_source_runs("
#include <xmmintrin.h>
int main() { __m128 a, b; float vals[4] = {0}; a = _mm_loadu_ps(vals); b = a; b = _mm_add_ps(a,b); _mm_storeu_ps(vals,b); return 0; }"
HAS_SSE_EXTENSIONS)
if (HAS_SSE_EXTENSIONS)
add_definitions("-msse -mfpmath=sse")
endif ()
endif ()
endif ()
set(CMAKE_REQUIRED_FLAGS)
else ()
check_cxx_source_runs("
#include <emmintrin.h>
int main() { __m128d a, b; double vals[2] = {0}; a = _mm_loadu_pd(vals); b = _mm_add_pd(a,a); _mm_storeu_pd(vals,b); return 0; }"
HAS_SSE2_EXTENSIONS)
endif ()
endmacro(ebur128_check_for_sse)
ebur128_check_for_sse()
if(MSVC)
add_definitions(-D_USE_MATH_DEFINES)
add_definitions(/arch:SSE2)
add_definitions(-D __SSE2_MATH__)
endif()
set (ebur128_SRCS ebur128.c)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
add_library (ebur128 STATIC ${ebur128_SRCS})
if (SPEEXDSP_FOUND)
include_directories(${SPEEXDSP_INCLUDE_DIRS})
target_link_libraries(ebur128 ${SPEEXDSP_LIBRARIES})
endif ()

View File

@@ -1,7 +0,0 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#cmakedefine USE_SPEEX_RESAMPLER 1
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
/* See LICENSE file for copyright and license details. */
/* See COPYING file for copyright and license details. */
#ifndef EBUR128_H_
#define EBUR128_H_
@@ -11,19 +12,54 @@
extern "C" {
#endif
#define EBUR128_VERSION_MAJOR 1
#define EBUR128_VERSION_MINOR 2
#define EBUR128_VERSION_PATCH 2
#include <stddef.h> /* for size_t */
/** \enum channel
* Use these values when setting the channel map with ebur128_set_channel().
* See definitions in ITU R-REC-BS 1770-4
*/
enum channel {
EBUR128_UNUSED = 0, /**< unused channel (for example LFE channel) */
EBUR128_LEFT, /**< left channel */
EBUR128_RIGHT, /**< right channel */
EBUR128_CENTER, /**< center channel */
EBUR128_LEFT_SURROUND, /**< left surround channel */
EBUR128_RIGHT_SURROUND, /**< right surround channel */
EBUR128_DUAL_MONO /**< a channel that is counted twice */
EBUR128_LEFT = 1,
EBUR128_Mp030 = 1, /**< itu M+030 */
EBUR128_RIGHT = 2,
EBUR128_Mm030 = 2, /**< itu M-030 */
EBUR128_CENTER = 3,
EBUR128_Mp000 = 3, /**< itu M+000 */
EBUR128_LEFT_SURROUND = 4,
EBUR128_Mp110 = 4, /**< itu M+110 */
EBUR128_RIGHT_SURROUND = 5,
EBUR128_Mm110 = 5, /**< itu M-110 */
EBUR128_DUAL_MONO, /**< a channel that is counted twice */
EBUR128_MpSC, /**< itu M+SC */
EBUR128_MmSC, /**< itu M-SC */
EBUR128_Mp060, /**< itu M+060 */
EBUR128_Mm060, /**< itu M-060 */
EBUR128_Mp090, /**< itu M+090 */
EBUR128_Mm090, /**< itu M-090 */
EBUR128_Mp135, /**< itu M+135 */
EBUR128_Mm135, /**< itu M-135 */
EBUR128_Mp180, /**< itu M+180 */
EBUR128_Up000, /**< itu U+000 */
EBUR128_Up030, /**< itu U+030 */
EBUR128_Um030, /**< itu U-030 */
EBUR128_Up045, /**< itu U+045 */
EBUR128_Um045, /**< itu U-030 */
EBUR128_Up090, /**< itu U+090 */
EBUR128_Um090, /**< itu U-090 */
EBUR128_Up110, /**< itu U+110 */
EBUR128_Um110, /**< itu U-110 */
EBUR128_Up135, /**< itu U+135 */
EBUR128_Um135, /**< itu U-135 */
EBUR128_Up180, /**< itu U+180 */
EBUR128_Tp000, /**< itu T+000 */
EBUR128_Bp000, /**< itu B+000 */
EBUR128_Bp045, /**< itu B+045 */
EBUR128_Bm045 /**< itu B-045 */
};
/** \enum error
@@ -46,7 +82,7 @@ enum mode {
EBUR128_MODE_M = (1 << 0),
/** can call ebur128_loudness_shortterm */
EBUR128_MODE_S = (1 << 1) | EBUR128_MODE_M,
/** can call ebur128_gated_loudness_* */
/** can call ebur128_loudness_global_* and ebur128_relative_threshold */
EBUR128_MODE_I = (1 << 2) | EBUR128_MODE_M,
/** can call ebur128_loudness_range */
EBUR128_MODE_LRA = (1 << 3) | EBUR128_MODE_S,
@@ -73,12 +109,20 @@ typedef struct {
struct ebur128_state_internal* d; /**< Internal state. */
} ebur128_state;
/** \brief Get library version number. Do not pass null pointers here.
*
* @param major major version number of library
* @param minor minor version number of library
* @param patch patch version number of library
*/
void ebur128_get_version(int* major, int* minor, int* patch);
/** \brief Initialize library state.
*
* @param channels the number of channels.
* @param samplerate the sample rate.
* @param mode see the mode enum for possible values.
* @return an initialized library state.
* @return an initialized library state, or NULL on error.
*/
ebur128_state* ebur128_init(unsigned int channels,
unsigned long samplerate,
@@ -129,6 +173,40 @@ int ebur128_change_parameters(ebur128_state* st,
unsigned int channels,
unsigned long samplerate);
/** \brief Set the maximum window duration.
*
* Set the maximum duration that will be used for ebur128_window_loudness().
* Note that this destroys the current content of the audio buffer.
*
* @param st library state.
* @param window duration of the window in ms.
* @return
* - EBUR128_SUCCESS on success.
* - EBUR128_ERROR_NOMEM on memory allocation error. The state will be
* invalid and must be destroyed.
* - EBUR128_ERROR_NO_CHANGE if window duration not changed.
*/
int ebur128_set_max_window(ebur128_state* st, unsigned long window);
/** \brief Set the maximum history.
*
* Set the maximum history that will be stored for loudness integration.
* More history provides more accurate results, but requires more resources.
*
* Applies to ebur128_loudness_range() and ebur128_loudness_global() when
* EBUR128_MODE_HISTOGRAM is not set.
*
* Default is ULONG_MAX (at least ~50 days).
* Minimum is 3000ms for EBUR128_MODE_LRA and 400ms for EBUR128_MODE_M.
*
* @param st library state.
* @param history duration of history in ms.
* @return
* - EBUR128_SUCCESS on success.
* - EBUR128_ERROR_NO_CHANGE if history not changed.
*/
int ebur128_set_max_history(ebur128_state* st, unsigned long history);
/** \brief Add frames to be processed.
*
* @param st library state.
@@ -198,6 +276,22 @@ int ebur128_loudness_momentary(ebur128_state* st, double* out);
*/
int ebur128_loudness_shortterm(ebur128_state* st, double* out);
/** \brief Get loudness of the specified window in LUFS.
*
* window must not be larger than the current window set in st.
* The current window can be changed by calling ebur128_set_max_window().
*
* @param st library state.
* @param window window in ms to calculate loudness.
* @param out loudness in LUFS. -HUGE_VAL if result is negative infinity.
* @return
* - EBUR128_SUCCESS on success.
* - EBUR128_ERROR_INVALID_MODE if window larger than current window in st.
*/
int ebur128_loudness_window(ebur128_state* st,
unsigned long window,
double* out);
/** \brief Get loudness range (LRA) of programme in LU.
*
* Calculates loudness range according to EBU 3342.
@@ -230,7 +324,9 @@ int ebur128_loudness_range_multiple(ebur128_state** sts,
size_t size,
double* out);
/** \brief Get maximum sample peak of selected channel in float format.
/** \brief Get maximum sample peak from all frames that have been processed.
*
* The equation to convert to dBFS is: 20 * log10(out)
*
* @param st library state
* @param channel_number channel to analyse
@@ -245,15 +341,38 @@ int ebur128_sample_peak(ebur128_state* st,
unsigned int channel_number,
double* out);
/** \brief Get maximum true peak of selected channel in float format.
/** \brief Get maximum sample peak from the last call to add_frames().
*
* Uses the Speex resampler with quality level 8 to calculate true peak. Will
* oversample 4x for sample rates < 96000 Hz, 2x for sample rates < 192000 Hz
* and leave the signal unchanged for 192000 Hz.
* The equation to convert to dBFS is: 20 * log10(out)
*
* @param st library state
* @param channel_number channel to analyse
* @param out maximum true peak in float format (1.0 is 0 dBFS)
* @param out maximum sample peak in float format (1.0 is 0 dBFS)
* @return
* - EBUR128_SUCCESS on success.
* - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_SAMPLE_PEAK" has not
* been set.
* - EBUR128_ERROR_INVALID_CHANNEL_INDEX if invalid channel index.
*/
int ebur128_prev_sample_peak(ebur128_state* st,
unsigned int channel_number,
double* out);
/** \brief Get maximum true peak from all frames that have been processed.
*
* Uses an implementation defined algorithm to calculate the true peak. Do not
* try to compare resulting values across different versions of the library,
* as the algorithm may change.
*
* The current implementation uses a custom polyphase FIR interpolator to
* calculate true peak. Will oversample 4x for sample rates < 96000 Hz, 2x for
* sample rates < 192000 Hz and leave the signal unchanged for 192000 Hz.
*
* The equation to convert to dBTP is: 20 * log10(out)
*
* @param st library state
* @param channel_number channel to analyse
* @param out maximum true peak in float format (1.0 is 0 dBTP)
* @return
* - EBUR128_SUCCESS on success.
* - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_TRUE_PEAK" has not
@@ -264,6 +383,42 @@ int ebur128_true_peak(ebur128_state* st,
unsigned int channel_number,
double* out);
/** \brief Get maximum true peak from the last call to add_frames().
*
* Uses an implementation defined algorithm to calculate the true peak. Do not
* try to compare resulting values across different versions of the library,
* as the algorithm may change.
*
* The current implementation uses a custom polyphase FIR interpolator to
* calculate true peak. Will oversample 4x for sample rates < 96000 Hz, 2x for
* sample rates < 192000 Hz and leave the signal unchanged for 192000 Hz.
*
* The equation to convert to dBTP is: 20 * log10(out)
*
* @param st library state
* @param channel_number channel to analyse
* @param out maximum true peak in float format (1.0 is 0 dBTP)
* @return
* - EBUR128_SUCCESS on success.
* - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_TRUE_PEAK" has not
* been set.
* - EBUR128_ERROR_INVALID_CHANNEL_INDEX if invalid channel index.
*/
int ebur128_prev_true_peak(ebur128_state* st,
unsigned int channel_number,
double* out);
/** \brief Get relative threshold in LUFS.
*
* @param st library state
* @param out relative threshold in LUFS.
* @return
* - EBUR128_SUCCESS on success.
* - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_I" has not
* been set.
*/
int ebur128_relative_threshold(ebur128_state* st, double* out);
#ifdef __cplusplus
}
#endif

View File

@@ -77,6 +77,7 @@
details.
60. Add support for OriginalDate tag.
61. Bundle newer openSSL with macOS builds.
62. Update copy of libebur128
2.0.1
-----

13
README
View File

@@ -83,12 +83,11 @@ Cantata may also use the following optional libraries:
support.
2. LibMTP - MTP devices.
3. FFMPEG (libavcodec) - ReplayGain detection code.
4. SpeexDSP - ReplayGain detection code.
5. MPG123 - ReplayGain detection code.
6. CDParanoia - Read/rip Audio CDs.
7. CDDB - either this or MusicBrainz5 required for Audio CDs
8. MusicBrainz5 - either this or CDDB required for Audio CDs
9. LibEbur128 - ReplayGain detection code. If this is not found on the
4. MPG123 - ReplayGain detection code.
5. CDParanoia - Read/rip Audio CDs.
6. CDDB - either this or MusicBrainz5 required for Audio CDs
7. MusicBrainz5 - either this or CDDB required for Audio CDs
8. LibEbur128 - ReplayGain detection code. If this is not found on the
system then Cantata will use its own bundled copy.
@@ -834,7 +833,7 @@ These steps assume the following structure:
2. Install HomeBrew
3. brew install cmake taglib ffmpeg speex openssl
3. brew install cmake taglib ffmpeg openssl
4. Load cantata's CMakeLists.txt in QtCreator, and pass the following to cmake:
../src -DCMAKE_PREFIX_PATH=/Users/$USER/Qt/5.3/clang_64/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`pwd`/../install

View File

@@ -1,14 +0,0 @@
find_package(PkgConfig)
pkg_check_modules(PC_SPEEXDSP QUIET speexdsp)
find_path(SPEEXDSP_INCLUDE_DIR speex/speex_resampler.h
HINTS ${PC_SPEEXDSP_INCLUDEDIR} ${PC_SPEEXDSP_INCLUDE_DIRS})
find_library(SPEEXDSP_LIBRARY speexdsp
HINTS ${PC_SPEEXDSP_LIBDIR} ${PC_SPEEXDSP_LIBRARY_DIRS})
set(SPEEXDSP_LIBRARIES ${SPEEXDSP_LIBRARY})
set(SPEEXDSP_INCLUDE_DIRS ${SPEEXDSP_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SPEEXDSP DEFAULT_MSG SPEEXDSP_LIBRARY SPEEXDSP_INCLUDE_DIR)
mark_as_advanced(SPEEXDSP_INCLUDE_DIR SPEEXDSP_LIBRARY)

View File

@@ -73,12 +73,6 @@ TrackScanner::Data TrackScanner::global(const QList<TrackScanner *> &scanners)
}
}
#ifdef EBUR128_USE_SPEEX_RESAMPLER
static int constEbur128Mode=EBUR128_MODE_M|EBUR128_MODE_I|EBUR128_MODE_TRUE_PEAK;
#else
static int constEbur128Mode=EBUR128_MODE_M|EBUR128_MODE_I|EBUR128_MODE_SAMPLE_PEAK;
#endif
void TrackScanner::init()
{
static bool doneInit=false;
@@ -150,7 +144,7 @@ void TrackScanner::run()
return;
}
state=ebur128_init(input->channels(), input->sampleRate(), constEbur128Mode);
state=ebur128_init(input->channels(), input->sampleRate(), EBUR128_MODE_M|EBUR128_MODE_I|EBUR128_MODE_SAMPLE_PEAK);
int *channelMap=new int [state->channels];
if (input->setChannelMap(channelMap)) {
@@ -201,7 +195,6 @@ void TrackScanner::run()
}
}
}
#ifdef EBUR128_USE_SPEEX_RESAMPLER
if (EBUR128_MODE_TRUE_PEAK==(state->mode & EBUR128_MODE_TRUE_PEAK)) {
for (unsigned i = 0; i < state->channels; ++i) {
double tp;
@@ -211,7 +204,6 @@ void TrackScanner::run()
}
}
}
#endif
setFinishedStatus(true);
}