mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-31 03:27:40 +01:00
Remove unused bits from 3rdparty/chromaprint
This commit is contained in:
parent
e1804219dc
commit
665b721236
5
3rdparty/chromaprint/CHANGES.txt
vendored
5
3rdparty/chromaprint/CHANGES.txt
vendored
@ -1,5 +0,0 @@
|
||||
Version 0.1 (2010-10-30)
|
||||
========================
|
||||
|
||||
- Initial release.
|
||||
|
48
3rdparty/chromaprint/CMakeLists.txt
vendored
48
3rdparty/chromaprint/CMakeLists.txt
vendored
@ -39,29 +39,10 @@ set(BIN_INSTALL_DIR ${EXEC_INSTALL_PREFIX}/bin CACHE PATH "Installation prefix f
|
||||
set(LIB_INSTALL_DIR ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX} CACHE PATH "Installation prefix for object code libraries" FORCE)
|
||||
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include CACHE PATH "Installation prefix for C header files" FORCE)
|
||||
|
||||
if(APPLE)
|
||||
option(BUILD_FRAMEWORK "Build an OS X framework" OFF)
|
||||
set(FRAMEWORK_INSTALL_DIR "/Library/Frameworks" CACHE STRING "Directory to install frameworks to.")
|
||||
endif()
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
option(BUILD_EXAMPLES "Build the examples" OFF)
|
||||
option(BUILD_TESTS "Build the test suite" OFF)
|
||||
option(BUILD_TOOLS "Build standard tools" OFF)
|
||||
option(BUILD_EXTRA_TOOLS "Build extra tools (only useful for development of this library)" OFF)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
endif()
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND BUILD_SHARED_LIBS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
add_definitions(-DCHROMAPRINT_NODLL)
|
||||
endif()
|
||||
|
||||
option(WITH_AVFFT "Use FFmpeg for FFT calculations" OFF)
|
||||
option(WITH_FFTW3 "Use FFTW3 for FFT calculations" OFF)
|
||||
@ -123,36 +104,7 @@ if(WITH_FFTW3)
|
||||
message(STATUS "Using FFTW3 for FFT calculations")
|
||||
endif(WITH_FFTW3)
|
||||
|
||||
if(NOT APPLE AND NOT BUILD_FRAMEWORK)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libchromaprint.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libchromaprint.pc)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libchromaprint.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
endif()
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
if(BUILD_TOOLS_EXTRA)
|
||||
find_package(PNG REQUIRED)
|
||||
endif(BUILD_TOOLS_EXTRA)
|
||||
|
||||
find_package(Boost COMPONENTS system filesystem)
|
||||
if(BUILD_TOOLS OR BUILD_TOOLS_EXTRA OR BUILD_EXAMPLES)
|
||||
find_package(FFmpeg REQUIRED)
|
||||
endif()
|
||||
|
||||
if(BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if(BUILD_TOOLS OR BUILD_TOOLS_EXTRA)
|
||||
find_package(Taglib REQUIRED)
|
||||
add_subdirectory(tools)
|
||||
endif(BUILD_TOOLS OR BUILD_TOOLS_EXTRA)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
find_package(Threads)
|
||||
find_package(GTest REQUIRED)
|
||||
add_subdirectory(tests)
|
||||
endif(BUILD_TESTS)
|
||||
|
||||
|
44
3rdparty/chromaprint/NEWS.txt
vendored
44
3rdparty/chromaprint/NEWS.txt
vendored
@ -1,44 +0,0 @@
|
||||
Version 0.6 -- December 22, 2011
|
||||
================================
|
||||
|
||||
- Support for 24-bit file formats in fpcalc.
|
||||
- The fpcalc utility now uses 120 seconds of audio data by default.
|
||||
- Python bindings moved to a separate project (pyacoustid).
|
||||
|
||||
Version 0.5 -- October 6, 2011
|
||||
==============================
|
||||
|
||||
- Unicode command line handling in fpcalc.
|
||||
- Fixed a crash in fpcalc when FFmpeg was not able to identify the codec.
|
||||
- Added encode_fingerprint to the Python bindings.
|
||||
|
||||
Version 0.4 -- May 14, 2011
|
||||
===========================
|
||||
|
||||
- Support for building a Mac OS X framework.
|
||||
- Support for building a static library.
|
||||
- Simple C example (fpcalc) that can be used from external applications for
|
||||
fingerprint calculations.
|
||||
|
||||
Version 0.3 -- April 26, 2011
|
||||
=============================
|
||||
|
||||
- Fixed compilation with MSVC 2010.
|
||||
- Added support for calculating FFT using the Accelerate framework on
|
||||
Mac OS X and iOS.
|
||||
- Added Python bindings.
|
||||
|
||||
Version 0.2 -- January 26, 2011
|
||||
===============================
|
||||
|
||||
- New public functions chromaprint_{encode,decode}_fingerprint to
|
||||
encoding/decoding raw fingerprints.
|
||||
- New public function chromaprint_dealloc that should be used for
|
||||
releasing all memory allocated in Chromaprint functions.
|
||||
- Extended fpcollect to allow processing files with MBIDs.
|
||||
|
||||
Version 0.1 -- October 30, 2010
|
||||
===============================
|
||||
|
||||
- Initial release
|
||||
|
96
3rdparty/chromaprint/README.txt
vendored
96
3rdparty/chromaprint/README.txt
vendored
@ -1,96 +0,0 @@
|
||||
Chromaprint
|
||||
===========
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
The library itself only depends on a FFT library, which at the moment can
|
||||
be either FFmpeg [1] (at least r22291, 0.6 is fine), FFTW3 [2] or if you are
|
||||
on iOS or OS X, you can use the Accelerate/vDSP framework. See the next
|
||||
section for details.
|
||||
|
||||
The tools included in the package require FFmpeg (can be older), TagLib [3]
|
||||
and Boost Filesystem [4].
|
||||
|
||||
In order to build the test suite, you will need the Google Test library [5].
|
||||
|
||||
[1] http://www.ffmpeg.org/
|
||||
[2] http://www.fftw.org/
|
||||
[3] http://developer.kde.org/~wheeler/taglib.html
|
||||
[4] http://www.boost.org/
|
||||
[5] http://code.google.com/p/googletest/
|
||||
|
||||
Installing
|
||||
----------
|
||||
|
||||
The most common way to build Chromaprint is like this:
|
||||
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON .
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
This will build Chromaprint as a shared library and also include the fpcalc
|
||||
utility (which is used by MusicBrainz Picard, for example).
|
||||
|
||||
See below for other options.
|
||||
|
||||
FFT Library
|
||||
-----------
|
||||
|
||||
Chromaprint can use three FFT libraries, FFmpeg, FFTW3 and vDSP. FFmpeg is
|
||||
preffered, as it's a little faster for our purposes and it's LGPL-licensed,
|
||||
so it doesn't impact the license of Chromaprint. The FFT interface was added
|
||||
only recently though, so it might not be available in Linux distributions yet.
|
||||
FFTW3 can be used in this case, but this library is released under the GPL
|
||||
license, which makes also the resulting Chromaprint binary GPL licensed.
|
||||
|
||||
If you run simple `cmake .`, it will try to find both FFmpeg and FFTW3 and
|
||||
select the first one it finds. If you have new FFmpeg installed in a separate
|
||||
location, you can let CMake know using the `FFMPEG_ROOT` option:
|
||||
|
||||
$ cmake -DFFMPEG_ROOT=/path/to/local/ffmpeg/install .
|
||||
|
||||
If you have new FFmpeg installed, but for some reason prefer to use FFTW3, you
|
||||
can use the `WITH_FFTW3` option:
|
||||
|
||||
$ cmake -DWITH_FFTW3=ON .
|
||||
|
||||
There is also a `WITH_AVFFT` option, but the script will select the FFmpeg FFT
|
||||
automatically if it's available, so it shouldn't be necessary to use it.
|
||||
|
||||
If you are on Mac, you can use the standard Accelerate framework with the vDSP
|
||||
library. This requires you to install no external libraries. It will use
|
||||
vDSP by default on OS X (but there still is a `WITH_VDSP` option).
|
||||
|
||||
Unit Tests
|
||||
----------
|
||||
|
||||
The test suite can be built and run using the following commands:
|
||||
|
||||
$ cmake -DBUILD_TESTS=ON .
|
||||
$ make check
|
||||
|
||||
Related Projects
|
||||
----------------
|
||||
|
||||
* pyacoustid - https://github.com/sampsyo/pyacoustid
|
||||
* gst-chromaprint - https://github.com/lalinsky/gst-chromaprint
|
||||
|
||||
Standing on the Shoulder of Giants
|
||||
----------------------------------
|
||||
|
||||
I've learned a lot while working on this project, which would not be possible
|
||||
without having information from past research. I've read many papers, but the
|
||||
concrete ideas implemented in this library are based on the following papers:
|
||||
|
||||
* Yan Ke, Derek Hoiem, Rahul Sukthankar. Computer Vision for Music
|
||||
Identification, Proceedings of Computer Vision and Pattern Recognition,
|
||||
2005. http://www.cs.cmu.edu/~yke/musicretrieval/
|
||||
|
||||
* Frank Kurth, Meinard Müller. Efficient Index-Based Audio Matching, 2008.
|
||||
http://dx.doi.org/10.1109/TASL.2007.911552
|
||||
|
||||
* Dalwon Jang, Chang D. Yoo, Sunil Lee, Sungwoong Kim, Ton Kalker.
|
||||
Pairwise Boosted Audio Fingerprint, 2009.
|
||||
http://dx.doi.org/10.1109/TIFS.2009.2034452
|
||||
|
39
3rdparty/chromaprint/examples/CMakeLists.txt
vendored
39
3rdparty/chromaprint/examples/CMakeLists.txt
vendored
@ -1,39 +0,0 @@
|
||||
set(EXTRA_LIBS)
|
||||
if(APPLE)
|
||||
set(EXTRA_LIBS ${EXTRA_LIBS} -lz)
|
||||
endif()
|
||||
if(UNIX)
|
||||
set(EXTRA_LIBS ${EXTRA_LIBS} -lpthread)
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES}
|
||||
${EXTRA_LIBS})
|
||||
check_function_exists(av_audio_convert HAVE_AV_AUDIO_CONVERT)
|
||||
|
||||
if(HAVE_AV_AUDIO_CONVERT)
|
||||
add_definitions(-DHAVE_AV_AUDIO_CONVERT)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
|
||||
${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
|
||||
${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
add_executable(fpcalc fpcalc.c)
|
||||
|
||||
|
||||
target_link_libraries(fpcalc chromaprint
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES}
|
||||
${EXTRA_LIBS})
|
||||
|
||||
install(TARGETS fpcalc
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
)
|
||||
|
118
3rdparty/chromaprint/examples/ffmpeg/audioconvert.h
vendored
118
3rdparty/chromaprint/examples/ffmpeg/audioconvert.h
vendored
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* audio conversion
|
||||
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2008 Peter Ross
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AUDIOCONVERT_H
|
||||
#define AVCODEC_AUDIOCONVERT_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Audio format conversion routines
|
||||
*/
|
||||
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "samplefmt.h"
|
||||
|
||||
#if FF_API_OLD_SAMPLE_FMT
|
||||
/**
|
||||
* @deprecated Use av_get_sample_fmt_string() instead.
|
||||
*/
|
||||
attribute_deprecated
|
||||
void avcodec_sample_fmt_string(char *buf, int buf_size, int sample_fmt);
|
||||
|
||||
/**
|
||||
* @deprecated Use av_get_sample_fmt_name() instead.
|
||||
*/
|
||||
attribute_deprecated
|
||||
const char *avcodec_get_sample_fmt_name(int sample_fmt);
|
||||
|
||||
/**
|
||||
* @deprecated Use av_get_sample_fmt() instead.
|
||||
*/
|
||||
attribute_deprecated
|
||||
enum AVSampleFormat avcodec_get_sample_fmt(const char* name);
|
||||
#endif
|
||||
|
||||
#if FF_API_OLD_AUDIOCONVERT
|
||||
/**
|
||||
* @deprecated Use av_get_channel_layout() instead.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int64_t avcodec_get_channel_layout(const char *name);
|
||||
|
||||
/**
|
||||
* @deprecated Use av_get_channel_layout_string() instead.
|
||||
*/
|
||||
attribute_deprecated
|
||||
void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout);
|
||||
|
||||
/**
|
||||
* @deprecated Use av_get_channel_layout_nb_channels() instead.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int avcodec_channel_layout_num_channels(int64_t channel_layout);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Guess the channel layout
|
||||
* @param nb_channels
|
||||
* @param codec_id Codec identifier, or CODEC_ID_NONE if unknown
|
||||
* @param fmt_name Format name, or NULL if unknown
|
||||
* @return Channel layout mask
|
||||
*/
|
||||
uint64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name);
|
||||
|
||||
struct AVAudioConvert;
|
||||
typedef struct AVAudioConvert AVAudioConvert;
|
||||
|
||||
/**
|
||||
* Create an audio sample format converter context
|
||||
* @param out_fmt Output sample format
|
||||
* @param out_channels Number of output channels
|
||||
* @param in_fmt Input sample format
|
||||
* @param in_channels Number of input channels
|
||||
* @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore.
|
||||
* @param flags See AV_CPU_FLAG_xx
|
||||
* @return NULL on error
|
||||
*/
|
||||
AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
|
||||
enum AVSampleFormat in_fmt, int in_channels,
|
||||
const float *matrix, int flags);
|
||||
|
||||
/**
|
||||
* Free audio sample format converter context
|
||||
*/
|
||||
void av_audio_convert_free(AVAudioConvert *ctx);
|
||||
|
||||
/**
|
||||
* Convert between audio sample formats
|
||||
* @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel.
|
||||
* @param[in] out_stride distance between consecutive output samples (measured in bytes)
|
||||
* @param[in] in array of input buffers for each channel
|
||||
* @param[in] in_stride distance between consecutive input samples (measured in bytes)
|
||||
* @param len length of audio frame size (measured in samples)
|
||||
*/
|
||||
int av_audio_convert(AVAudioConvert *ctx,
|
||||
void * const out[6], const int out_stride[6],
|
||||
const void * const in[6], const int in_stride[6], int len);
|
||||
|
||||
#endif /* AVCODEC_AUDIOCONVERT_H */
|
156
3rdparty/chromaprint/examples/ffmpeg/samplefmt.h
vendored
156
3rdparty/chromaprint/examples/ffmpeg/samplefmt.h
vendored
@ -1,156 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_SAMPLEFMT_H
|
||||
#define AVUTIL_SAMPLEFMT_H
|
||||
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
/**
|
||||
* all in native-endian format
|
||||
*/
|
||||
enum AVSampleFormat {
|
||||
AV_SAMPLE_FMT_NONE = -1,
|
||||
AV_SAMPLE_FMT_U8, ///< unsigned 8 bits
|
||||
AV_SAMPLE_FMT_S16, ///< signed 16 bits
|
||||
AV_SAMPLE_FMT_S32, ///< signed 32 bits
|
||||
AV_SAMPLE_FMT_FLT, ///< float
|
||||
AV_SAMPLE_FMT_DBL, ///< double
|
||||
|
||||
AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar
|
||||
AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar
|
||||
AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar
|
||||
AV_SAMPLE_FMT_FLTP, ///< float, planar
|
||||
AV_SAMPLE_FMT_DBLP, ///< double, planar
|
||||
|
||||
AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the name of sample_fmt, or NULL if sample_fmt is not
|
||||
* recognized.
|
||||
*/
|
||||
const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt);
|
||||
|
||||
/**
|
||||
* Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE
|
||||
* on error.
|
||||
*/
|
||||
enum AVSampleFormat av_get_sample_fmt(const char *name);
|
||||
|
||||
/**
|
||||
* Return the planar<->packed alternative form of the given sample format, or
|
||||
* AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the
|
||||
* requested planar/packed format, the format returned is the same as the
|
||||
* input.
|
||||
*/
|
||||
enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar);
|
||||
|
||||
/**
|
||||
* Generate a string corresponding to the sample format with
|
||||
* sample_fmt, or a header if sample_fmt is negative.
|
||||
*
|
||||
* @param buf the buffer where to write the string
|
||||
* @param buf_size the size of buf
|
||||
* @param sample_fmt the number of the sample format to print the
|
||||
* corresponding info string, or a negative value to print the
|
||||
* corresponding header.
|
||||
* @return the pointer to the filled buffer or NULL if sample_fmt is
|
||||
* unknown or in case of other errors
|
||||
*/
|
||||
char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt);
|
||||
|
||||
#if FF_API_GET_BITS_PER_SAMPLE_FMT
|
||||
/**
|
||||
* @deprecated Use av_get_bytes_per_sample() instead.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return number of bytes per sample.
|
||||
*
|
||||
* @param sample_fmt the sample format
|
||||
* @return number of bytes per sample or zero if unknown for the given
|
||||
* sample format
|
||||
*/
|
||||
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt);
|
||||
|
||||
/**
|
||||
* Check if the sample format is planar.
|
||||
*
|
||||
* @param sample_fmt the sample format to inspect
|
||||
* @return 1 if the sample format is planar, 0 if it is interleaved
|
||||
*/
|
||||
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt);
|
||||
|
||||
/**
|
||||
* Get the required buffer size for the given audio parameters.
|
||||
*
|
||||
* @param[out] linesize calculated linesize, may be NULL
|
||||
* @param nb_channels the number of channels
|
||||
* @param nb_samples the number of samples in a single channel
|
||||
* @param sample_fmt the sample format
|
||||
* @return required buffer size, or negative error code on failure
|
||||
*/
|
||||
int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
|
||||
enum AVSampleFormat sample_fmt, int align);
|
||||
|
||||
/**
|
||||
* Fill channel data pointers and linesize for samples with sample
|
||||
* format sample_fmt.
|
||||
*
|
||||
* The pointers array is filled with the pointers to the samples data:
|
||||
* for planar, set the start point of each channel's data within the buffer,
|
||||
* for packed, set the start point of the entire buffer only.
|
||||
*
|
||||
* The linesize array is filled with the aligned size of each channel's data
|
||||
* buffer for planar layout, or the aligned size of the buffer for all channels
|
||||
* for packed layout.
|
||||
*
|
||||
* @param[out] audio_data array to be filled with the pointer for each channel
|
||||
* @param[out] linesize calculated linesize
|
||||
* @param buf the pointer to a buffer containing the samples
|
||||
* @param nb_channels the number of channels
|
||||
* @param nb_samples the number of samples in a single channel
|
||||
* @param sample_fmt the sample format
|
||||
* @param align buffer size alignment (1 = no alignment required)
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf,
|
||||
int nb_channels, int nb_samples,
|
||||
enum AVSampleFormat sample_fmt, int align);
|
||||
|
||||
/**
|
||||
* Allocate a samples buffer for nb_samples samples, and fill data pointers and
|
||||
* linesize accordingly.
|
||||
* The allocated samples buffer can be freed by using av_freep(&audio_data[0])
|
||||
*
|
||||
* @param[out] audio_data array to be filled with the pointer for each channel
|
||||
* @param[out] linesize aligned size for audio buffer(s)
|
||||
* @param nb_channels number of audio channels
|
||||
* @param nb_samples number of samples per channel
|
||||
* @param align buffer size alignment (1 = no alignment required)
|
||||
* @return 0 on success or a negative error code on failure
|
||||
* @see av_samples_fill_arrays()
|
||||
*/
|
||||
int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
|
||||
int nb_samples, enum AVSampleFormat sample_fmt, int align);
|
||||
|
||||
#endif /* AVUTIL_SAMPLEFMT_H */
|
303
3rdparty/chromaprint/examples/fpcalc.c
vendored
303
3rdparty/chromaprint/examples/fpcalc.c
vendored
@ -1,303 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <chromaprint.h>
|
||||
#ifdef HAVE_AV_AUDIO_CONVERT
|
||||
#include "ffmpeg/audioconvert.h"
|
||||
#include "ffmpeg/samplefmt.h"
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define BUFFER_SIZE (AVCODEC_MAX_AUDIO_FRAME_SIZE * 2)
|
||||
|
||||
int decode_audio_file(ChromaprintContext *chromaprint_ctx, int16_t *buffer1, int16_t *buffer2, const char *file_name, int max_length, int *duration)
|
||||
{
|
||||
int i, ok = 0, remaining, length, consumed, buffer_size, codec_ctx_opened = 0;
|
||||
AVFormatContext *format_ctx = NULL;
|
||||
AVCodecContext *codec_ctx = NULL;
|
||||
AVCodec *codec = NULL;
|
||||
AVStream *stream = NULL;
|
||||
AVPacket packet, packet_temp;
|
||||
#ifdef HAVE_AV_AUDIO_CONVERT
|
||||
AVAudioConvert *convert_ctx = NULL;
|
||||
#endif
|
||||
int16_t *buffer;
|
||||
|
||||
if (av_open_input_file(&format_ctx, file_name, NULL, 0, NULL) != 0) {
|
||||
fprintf(stderr, "ERROR: couldn't open the file\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (av_find_stream_info(format_ctx) < 0) {
|
||||
fprintf(stderr, "ERROR: couldn't find stream information in the file\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < format_ctx->nb_streams; i++) {
|
||||
codec_ctx = format_ctx->streams[i]->codec;
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 64, 0)
|
||||
if (codec_ctx && codec_ctx->codec_type == CODEC_TYPE_AUDIO) {
|
||||
#else
|
||||
if (codec_ctx && codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
#endif
|
||||
stream = format_ctx->streams[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!stream) {
|
||||
fprintf(stderr, "ERROR: couldn't find any audio stream in the file\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
codec = avcodec_find_decoder(codec_ctx->codec_id);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "ERROR: unknown codec\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (avcodec_open(codec_ctx, codec) < 0) {
|
||||
fprintf(stderr, "ERROR: couldn't open the codec\n");
|
||||
goto done;
|
||||
}
|
||||
codec_ctx_opened = 1;
|
||||
|
||||
if (codec_ctx->channels <= 0) {
|
||||
fprintf(stderr, "ERROR: no channels found in the audio stream\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (codec_ctx->sample_fmt != SAMPLE_FMT_S16) {
|
||||
#ifdef HAVE_AV_AUDIO_CONVERT
|
||||
convert_ctx = av_audio_convert_alloc(SAMPLE_FMT_S16, codec_ctx->channels,
|
||||
codec_ctx->sample_fmt, codec_ctx->channels, NULL, 0);
|
||||
if (!convert_ctx) {
|
||||
fprintf(stderr, "ERROR: couldn't create sample format converter\n");
|
||||
goto done;
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "ERROR: unsupported sample format\n");
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
|
||||
*duration = stream->time_base.num * stream->duration / stream->time_base.den;
|
||||
|
||||
av_init_packet(&packet);
|
||||
av_init_packet(&packet_temp);
|
||||
|
||||
remaining = max_length * codec_ctx->channels * codec_ctx->sample_rate;
|
||||
chromaprint_start(chromaprint_ctx, codec_ctx->sample_rate, codec_ctx->channels);
|
||||
|
||||
while (1) {
|
||||
if (av_read_frame(format_ctx, &packet) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
packet_temp.data = packet.data;
|
||||
packet_temp.size = packet.size;
|
||||
|
||||
while (packet_temp.size > 0) {
|
||||
buffer_size = BUFFER_SIZE;
|
||||
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(52, 25, 0)
|
||||
consumed = avcodec_decode_audio2(codec_ctx,
|
||||
buffer1, &buffer_size, packet_temp.data, packet_temp.size);
|
||||
#else
|
||||
consumed = avcodec_decode_audio3(codec_ctx,
|
||||
buffer1, &buffer_size, &packet_temp);
|
||||
#endif
|
||||
|
||||
if (consumed < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
packet_temp.data += consumed;
|
||||
packet_temp.size -= consumed;
|
||||
|
||||
if (buffer_size <= 0) {
|
||||
if (buffer_size < 0) {
|
||||
fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too small\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (buffer_size > BUFFER_SIZE) {
|
||||
fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too large\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef HAVE_AV_AUDIO_CONVERT
|
||||
if (convert_ctx) {
|
||||
const void *ibuf[6] = { buffer1 };
|
||||
void *obuf[6] = { buffer2 };
|
||||
int istride[6] = { av_get_bits_per_sample_format(codec_ctx->sample_fmt) / 8 };
|
||||
int ostride[6] = { 2 };
|
||||
int len = buffer_size / istride[0];
|
||||
if (av_audio_convert(convert_ctx, obuf, ostride, ibuf, istride, len) < 0) {
|
||||
break;
|
||||
}
|
||||
buffer = buffer2;
|
||||
buffer_size = len * ostride[0];
|
||||
}
|
||||
else {
|
||||
buffer = buffer1;
|
||||
}
|
||||
#else
|
||||
buffer = buffer1;
|
||||
#endif
|
||||
|
||||
length = MIN(remaining, buffer_size / 2);
|
||||
if (!chromaprint_feed(chromaprint_ctx, buffer, length)) {
|
||||
fprintf(stderr, "ERROR: fingerprint calculation failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (max_length) {
|
||||
remaining -= length;
|
||||
if (remaining <= 0) {
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.data) {
|
||||
av_free_packet(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
if (!chromaprint_finish(chromaprint_ctx)) {
|
||||
fprintf(stderr, "ERROR: fingerprint calculation failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
done:
|
||||
if (codec_ctx_opened) {
|
||||
avcodec_close(codec_ctx);
|
||||
}
|
||||
if (format_ctx) {
|
||||
av_close_input_file(format_ctx);
|
||||
}
|
||||
#ifdef HAVE_AV_AUDIO_CONVERT
|
||||
if (convert_ctx) {
|
||||
av_audio_convert_free(convert_ctx);
|
||||
}
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
||||
int fpcalc_main(int argc, char **argv)
|
||||
{
|
||||
int i, j, max_length = 120, num_file_names = 0, raw = 0, raw_fingerprint_size, duration;
|
||||
int16_t *buffer1, *buffer2;
|
||||
int32_t *raw_fingerprint;
|
||||
char *file_name, *fingerprint, **file_names;
|
||||
ChromaprintContext *chromaprint_ctx;
|
||||
|
||||
file_names = malloc(argc * sizeof(char *));
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
if (!strcmp(arg, "-length") && i + 1 < argc) {
|
||||
max_length = atoi(argv[++i]);
|
||||
}
|
||||
else if (!strcmp(arg, "-raw")) {
|
||||
raw = 1;
|
||||
}
|
||||
else {
|
||||
file_names[num_file_names++] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!num_file_names) {
|
||||
printf("usage: %s [OPTIONS] FILE...\n\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf(" -length SECS length of the audio data used for fingerprint calculation (default 120)\n");
|
||||
printf(" -raw output the raw uncompressed fingerprint\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
av_register_all();
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
|
||||
buffer1 = av_malloc(BUFFER_SIZE + 16);
|
||||
buffer2 = av_malloc(BUFFER_SIZE + 16);
|
||||
chromaprint_ctx = chromaprint_new(CHROMAPRINT_ALGORITHM_DEFAULT);
|
||||
|
||||
for (i = 0; i < num_file_names; i++) {
|
||||
file_name = file_names[i];
|
||||
if (!decode_audio_file(chromaprint_ctx, buffer1, buffer2, file_name, max_length, &duration)) {
|
||||
fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
|
||||
continue;
|
||||
}
|
||||
if (i > 0) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("FILE=%s\n", file_name);
|
||||
printf("DURATION=%d\n", duration);
|
||||
if (raw) {
|
||||
if (!chromaprint_get_raw_fingerprint(chromaprint_ctx, (void **)&raw_fingerprint, &raw_fingerprint_size)) {
|
||||
fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
|
||||
continue;
|
||||
}
|
||||
printf("FINGERPRINT=");
|
||||
for (j = 0; j < raw_fingerprint_size; j++) {
|
||||
printf("%d%s", raw_fingerprint[j], j + 1 < raw_fingerprint_size ? "," : "\n");
|
||||
}
|
||||
chromaprint_dealloc(raw_fingerprint);
|
||||
}
|
||||
else {
|
||||
if (!chromaprint_get_fingerprint(chromaprint_ctx, &fingerprint)) {
|
||||
fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
|
||||
continue;
|
||||
}
|
||||
printf("FINGERPRINT=%s\n", fingerprint);
|
||||
chromaprint_dealloc(fingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
chromaprint_free(chromaprint_ctx);
|
||||
av_free(buffer1);
|
||||
av_free(buffer2);
|
||||
free(file_names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int main(int win32_argc, char **win32_argv)
|
||||
{
|
||||
int i, argc = 0, buffsize = 0, offset = 0;
|
||||
char **utf8_argv, *utf8_argv_ptr;
|
||||
wchar_t **argv;
|
||||
|
||||
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
|
||||
buffsize = 0;
|
||||
for (i = 0; i < argc; i++) {
|
||||
buffsize += WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
utf8_argv = av_mallocz(sizeof(char *) * (argc + 1) + buffsize);
|
||||
utf8_argv_ptr = (char *)utf8_argv + sizeof(char *) * (argc + 1);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
utf8_argv[i] = &utf8_argv_ptr[offset];
|
||||
offset += WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, &utf8_argv_ptr[offset], buffsize - offset, NULL, NULL);
|
||||
}
|
||||
|
||||
LocalFree(argv);
|
||||
|
||||
return fpcalc_main(argc, utf8_argv);
|
||||
}
|
||||
#else
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return fpcalc_main(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
12
3rdparty/chromaprint/libchromaprint.pc.cmake
vendored
12
3rdparty/chromaprint/libchromaprint.pc.cmake
vendored
@ -1,12 +0,0 @@
|
||||
prefix=${CMAKE_INSTALL_PREFIX}
|
||||
exec_prefix=${EXEC_INSTALL_PREFIX}
|
||||
libdir=${LIB_INSTALL_DIR}
|
||||
includedir=${INCLUDE_INSTALL_DIR}
|
||||
|
||||
Name: ${PROJECT_NAME}
|
||||
Description: Audio fingerprint library
|
||||
URL: http://wiki.acoustid.org/wiki/Chromaprint
|
||||
Version: ${PROJECT_VERSION}
|
||||
Libs: -L${LIB_INSTALL_DIR} -lchromaprint
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}
|
||||
|
41
3rdparty/chromaprint/tests/CMakeLists.txt
vendored
41
3rdparty/chromaprint/tests/CMakeLists.txt
vendored
@ -1,41 +0,0 @@
|
||||
include_directories(
|
||||
${GTEST_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
)
|
||||
|
||||
set(tests_SOURCES
|
||||
main.cpp
|
||||
test_api.cpp
|
||||
test_combined_buffer.cpp
|
||||
test_utils.cpp
|
||||
test_quantizer.cpp
|
||||
test_filter_utils.cpp
|
||||
test_integral_image.cpp
|
||||
test_lloyds.cpp
|
||||
test_audio_processor.cpp
|
||||
test_bit_string_reader.cpp
|
||||
test_bit_string_writer.cpp
|
||||
test_chromaprint.cpp
|
||||
test_chroma.cpp
|
||||
test_chroma_filter.cpp
|
||||
test_chroma_resampler.cpp
|
||||
test_fingerprint_compressor.cpp
|
||||
test_fingerprint_decompressor.cpp
|
||||
test_fingerprint_calculator.cpp
|
||||
test_filter.cpp
|
||||
test_silence_remover.cpp
|
||||
test_base64.cpp
|
||||
)
|
||||
|
||||
add_executable(all_tests ${tests_SOURCES})
|
||||
target_link_libraries(all_tests
|
||||
${GTEST_BOTH_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
chromaprint_p
|
||||
)
|
||||
|
||||
add_custom_target(check
|
||||
./all_tests $ENV{GTEST_FLAGS}
|
||||
DEPENDS all_tests
|
||||
)
|
||||
|
21
3rdparty/chromaprint/tests/audio_buffer.h
vendored
21
3rdparty/chromaprint/tests/audio_buffer.h
vendored
@ -1,21 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "audio_consumer.h"
|
||||
|
||||
class AudioBuffer : public Chromaprint::AudioConsumer
|
||||
{
|
||||
public:
|
||||
void Consume(short *input, int length)
|
||||
{
|
||||
//cout << "AudioBuffer::Consume(" << length << ")\n";
|
||||
int last_size = m_data.size();
|
||||
//cout << "got " << input[0] << " at index " << last_size << "\n";
|
||||
m_data.resize(last_size + length);
|
||||
std::copy(input, input + length, m_data.begin() + last_size);
|
||||
}
|
||||
|
||||
const std::vector<short> &data() { return m_data; }
|
||||
|
||||
private:
|
||||
std::vector<short> m_data;
|
||||
};
|
BIN
3rdparty/chromaprint/tests/data/test_mono_11025.raw
vendored
BIN
3rdparty/chromaprint/tests/data/test_mono_11025.raw
vendored
Binary file not shown.
BIN
3rdparty/chromaprint/tests/data/test_mono_44100.raw
vendored
BIN
3rdparty/chromaprint/tests/data/test_mono_44100.raw
vendored
Binary file not shown.
BIN
3rdparty/chromaprint/tests/data/test_mono_8000.raw
vendored
BIN
3rdparty/chromaprint/tests/data/test_mono_8000.raw
vendored
Binary file not shown.
Binary file not shown.
8
3rdparty/chromaprint/tests/main.cpp
vendored
8
3rdparty/chromaprint/tests/main.cpp
vendored
@ -1,8 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
99
3rdparty/chromaprint/tests/test_api.cpp
vendored
99
3rdparty/chromaprint/tests/test_api.cpp
vendored
@ -1,99 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "chromaprint.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
TEST(API, Test2SilenceFp)
|
||||
{
|
||||
short zeroes[1024];
|
||||
fill(zeroes, zeroes + 1024, 0);
|
||||
|
||||
ChromaprintContext *ctx = chromaprint_new(CHROMAPRINT_ALGORITHM_TEST2);
|
||||
chromaprint_start(ctx, 44100, 1);
|
||||
for (int i = 0; i < 130; i++) {
|
||||
chromaprint_feed(ctx, zeroes, 1024);
|
||||
}
|
||||
|
||||
char *fp;
|
||||
|
||||
chromaprint_finish(ctx);
|
||||
chromaprint_get_fingerprint(ctx, &fp);
|
||||
|
||||
ASSERT_EQ(18, strlen(fp));
|
||||
EXPECT_EQ(string("AQAAA0mUaEkSRZEGAA"), string(fp));
|
||||
}
|
||||
|
||||
TEST(API, Test2SilenceRawFp)
|
||||
{
|
||||
short zeroes[1024];
|
||||
fill(zeroes, zeroes + 1024, 0);
|
||||
|
||||
ChromaprintContext *ctx = chromaprint_new(CHROMAPRINT_ALGORITHM_TEST2);
|
||||
chromaprint_start(ctx, 44100, 1);
|
||||
for (int i = 0; i < 130; i++) {
|
||||
chromaprint_feed(ctx, zeroes, 1024);
|
||||
}
|
||||
|
||||
int32_t *fp;
|
||||
int length;
|
||||
|
||||
chromaprint_finish(ctx);
|
||||
chromaprint_get_raw_fingerprint(ctx, (void **)&fp, &length);
|
||||
|
||||
ASSERT_EQ(3, length);
|
||||
EXPECT_EQ(627964279, fp[0]);
|
||||
EXPECT_EQ(627964279, fp[1]);
|
||||
EXPECT_EQ(627964279, fp[2]);
|
||||
}
|
||||
|
||||
TEST(API, TestEncodeFingerprint)
|
||||
{
|
||||
int32_t fingerprint[] = { 1, 0 };
|
||||
char expected[] = { 55, 0, 0, 2, 65, 0 };
|
||||
|
||||
char *encoded;
|
||||
int encoded_size;
|
||||
chromaprint_encode_fingerprint(fingerprint, 2, 55, (void **)&encoded, &encoded_size, 0);
|
||||
|
||||
ASSERT_EQ(6, encoded_size);
|
||||
for (int i = 0; i < encoded_size; i++) {
|
||||
ASSERT_EQ(expected[i], encoded[i]) << "Different at " << i;
|
||||
}
|
||||
|
||||
free(encoded);
|
||||
}
|
||||
|
||||
TEST(API, TestEncodeFingerprintBase64)
|
||||
{
|
||||
int32_t fingerprint[] = { 1, 0 };
|
||||
char expected[] = "NwAAAkEA";
|
||||
|
||||
char *encoded;
|
||||
int encoded_size;
|
||||
chromaprint_encode_fingerprint(fingerprint, 2, 55, (void **)&encoded, &encoded_size, 1);
|
||||
|
||||
ASSERT_EQ(8, encoded_size);
|
||||
ASSERT_STREQ(expected, encoded);
|
||||
|
||||
free(encoded);
|
||||
}
|
||||
|
||||
TEST(API, TestDecodeFingerprint)
|
||||
{
|
||||
char data[] = { 55, 0, 0, 2, 65, 0 };
|
||||
|
||||
int32_t *fingerprint;
|
||||
int size;
|
||||
int algorithm;
|
||||
chromaprint_decode_fingerprint(data, 6, (void **)&fingerprint, &size, &algorithm, 0);
|
||||
|
||||
ASSERT_EQ(2, size);
|
||||
ASSERT_EQ(55, algorithm);
|
||||
ASSERT_EQ(1, fingerprint[0]);
|
||||
ASSERT_EQ(0, fingerprint[1]);
|
||||
}
|
||||
|
114
3rdparty/chromaprint/tests/test_audio_processor.cpp
vendored
114
3rdparty/chromaprint/tests/test_audio_processor.cpp
vendored
@ -1,114 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "test_utils.h"
|
||||
#include "audio_processor.h"
|
||||
#include "audio_buffer.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(AudioProcessor, Accessors)
|
||||
{
|
||||
vector<short> data = LoadAudioFile("data/test_mono_44100.raw");
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<AudioBuffer> buffer2(new AudioBuffer());
|
||||
boost::scoped_ptr<AudioProcessor> processor(new AudioProcessor(44100, buffer.get()));
|
||||
|
||||
EXPECT_EQ(44100, processor->target_sample_rate());
|
||||
EXPECT_EQ(buffer.get(), processor->consumer());
|
||||
|
||||
processor->set_target_sample_rate(11025);
|
||||
EXPECT_EQ(11025, processor->target_sample_rate());
|
||||
|
||||
processor->set_consumer(buffer2.get());
|
||||
EXPECT_EQ(buffer2.get(), processor->consumer());
|
||||
}
|
||||
|
||||
TEST(AudioProcessor, PassThrough)
|
||||
{
|
||||
vector<short> data = LoadAudioFile("data/test_mono_44100.raw");
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<AudioProcessor> processor(new AudioProcessor(44100, buffer.get()));
|
||||
processor->Reset(44100, 1);
|
||||
processor->Consume(&data[0], data.size());
|
||||
processor->Flush();
|
||||
|
||||
ASSERT_EQ(data.size(), buffer->data().size());
|
||||
for (size_t i = 0; i < data.size(); i++) {
|
||||
ASSERT_EQ(data[i], buffer->data()[i]) << "Signals differ at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(AudioProcessor, StereoToMono)
|
||||
{
|
||||
vector<short> data1 = LoadAudioFile("data/test_stereo_44100.raw");
|
||||
vector<short> data2 = LoadAudioFile("data/test_mono_44100.raw");
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<AudioProcessor> processor(new AudioProcessor(44100, buffer.get()));
|
||||
processor->Reset(44100, 2);
|
||||
processor->Consume(&data1[0], data1.size());
|
||||
processor->Flush();
|
||||
|
||||
ASSERT_EQ(data2.size(), buffer->data().size());
|
||||
for (size_t i = 0; i < data2.size(); i++) {
|
||||
ASSERT_EQ(data2[i], buffer->data()[i]) << "Signals differ at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(AudioProcessor, ResampleMono)
|
||||
{
|
||||
vector<short> data1 = LoadAudioFile("data/test_mono_44100.raw");
|
||||
vector<short> data2 = LoadAudioFile("data/test_mono_11025.raw");
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<AudioProcessor> processor(new AudioProcessor(11025, buffer.get()));
|
||||
processor->Reset(44100, 1);
|
||||
processor->Consume(&data1[0], data1.size());
|
||||
processor->Flush();
|
||||
|
||||
ASSERT_EQ(data2.size(), buffer->data().size());
|
||||
for (size_t i = 0; i < data2.size(); i++) {
|
||||
ASSERT_EQ(data2[i], buffer->data()[i]) << "Signals differ at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(AudioProcessor, ResampleMonoNonInteger)
|
||||
{
|
||||
vector<short> data1 = LoadAudioFile("data/test_mono_44100.raw");
|
||||
vector<short> data2 = LoadAudioFile("data/test_mono_8000.raw");
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<AudioProcessor> processor(new AudioProcessor(8000, buffer.get()));
|
||||
processor->Reset(44100, 1);
|
||||
processor->Consume(&data1[0], data1.size());
|
||||
processor->Flush();
|
||||
|
||||
ASSERT_EQ(data2.size(), buffer->data().size());
|
||||
for (size_t i = 0; i < data2.size(); i++) {
|
||||
ASSERT_EQ(data2[i], buffer->data()[i]) << "Signals differ at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(AudioProcessor, StereoToMonoAndResample)
|
||||
{
|
||||
vector<short> data1 = LoadAudioFile("data/test_stereo_44100.raw");
|
||||
vector<short> data2 = LoadAudioFile("data/test_mono_11025.raw");
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<AudioProcessor> processor(new AudioProcessor(11025, buffer.get()));
|
||||
processor->Reset(44100, 2);
|
||||
processor->Consume(&data1[0], data1.size());
|
||||
processor->Flush();
|
||||
|
||||
ASSERT_EQ(data2.size(), buffer->data().size());
|
||||
for (size_t i = 0; i < data2.size(); i++) {
|
||||
ASSERT_EQ(data2[i], buffer->data()[i]) << "Signals differ at index " << i;
|
||||
}
|
||||
}
|
56
3rdparty/chromaprint/tests/test_base64.cpp
vendored
56
3rdparty/chromaprint/tests/test_base64.cpp
vendored
@ -1,56 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "base64.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(Base64, Base64Encode)
|
||||
{
|
||||
ASSERT_EQ("eA", Base64Encode("x"));
|
||||
ASSERT_EQ("eHg", Base64Encode("xx"));
|
||||
ASSERT_EQ("eHh4", Base64Encode("xxx"));
|
||||
ASSERT_EQ("eHh4eA", Base64Encode("xxxx"));
|
||||
ASSERT_EQ("eHh4eHg", Base64Encode("xxxxx"));
|
||||
ASSERT_EQ("eHh4eHh4", Base64Encode("xxxxxx"));
|
||||
ASSERT_EQ("_-4", Base64Encode("\xff\xee"));
|
||||
}
|
||||
|
||||
TEST(Base64, Base64Decode)
|
||||
{
|
||||
ASSERT_EQ("x", Base64Decode("eA"));
|
||||
ASSERT_EQ("xx", Base64Decode("eHg"));
|
||||
ASSERT_EQ("xxx", Base64Decode("eHh4"));
|
||||
ASSERT_EQ("xxxx", Base64Decode("eHh4eA"));
|
||||
ASSERT_EQ("xxxxx", Base64Decode("eHh4eHg"));
|
||||
ASSERT_EQ("xxxxxx", Base64Decode("eHh4eHh4"));
|
||||
ASSERT_EQ("\xff\xee", Base64Decode("_-4"));
|
||||
}
|
||||
|
||||
TEST(Base64, Base64EncodeLong)
|
||||
{
|
||||
char original[] = {
|
||||
1, 0, 1, 207, 17, 181, 36, 18, 19, 37, 65, 15, 31, 197, 149, 161, 63, 33, 22,
|
||||
60, 141, 27, 202, 35, 184, 47, 254, 227, 135, 135, 11, 58, 139, 208, 65, 127,
|
||||
52, 167, 241, 31, 99, 182, 25, 159, 96, 70, 71, 160, 251, 168, 75, 132, 185,
|
||||
112, 230, 193, 133, 252, 42, 126, 66, 91, 121, 60, 135, 79, 24, 185, 210, 28,
|
||||
199, 133, 255, 240, 113, 101, 67, 199, 23, 225, 181, 160, 121, 140, 67, 123,
|
||||
161, 229, 184, 137, 30, 205, 135, 119, 70, 94, 252, 71, 120, 150
|
||||
};
|
||||
char encoded[] = "AQABzxG1JBITJUEPH8WVoT8hFjyNG8ojuC_-44eHCzqL0EF_NKfxH2O2GZ9gRkeg-6hLhLlw5sGF_Cp-Qlt5PIdPGLnSHMeF__BxZUPHF-G1oHmMQ3uh5biJHs2Hd0Ze_Ed4lg";
|
||||
ASSERT_EQ(encoded, Base64Encode(string(original, NELEMS(original))));
|
||||
}
|
||||
|
||||
TEST(Base64, Base64DecodeLong)
|
||||
{
|
||||
char original[] = {
|
||||
1, 0, 1, 207, 17, 181, 36, 18, 19, 37, 65, 15, 31, 197, 149, 161, 63, 33, 22,
|
||||
60, 141, 27, 202, 35, 184, 47, 254, 227, 135, 135, 11, 58, 139, 208, 65, 127,
|
||||
52, 167, 241, 31, 99, 182, 25, 159, 96, 70, 71, 160, 251, 168, 75, 132, 185,
|
||||
112, 230, 193, 133, 252, 42, 126, 66, 91, 121, 60, 135, 79, 24, 185, 210, 28,
|
||||
199, 133, 255, 240, 113, 101, 67, 199, 23, 225, 181, 160, 121, 140, 67, 123,
|
||||
161, 229, 184, 137, 30, 205, 135, 119, 70, 94, 252, 71, 120, 150
|
||||
};
|
||||
char encoded[] = "AQABzxG1JBITJUEPH8WVoT8hFjyNG8ojuC_-44eHCzqL0EF_NKfxH2O2GZ9gRkeg-6hLhLlw5sGF_Cp-Qlt5PIdPGLnSHMeF__BxZUPHF-G1oHmMQ3uh5biJHs2Hd0Ze_Ed4lg";
|
||||
ASSERT_EQ(string(original, NELEMS(original)), Base64Decode(string(encoded)));
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "image.h"
|
||||
#include "classifier.h"
|
||||
#include "bit_string_reader.h"
|
||||
#include "utils.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(BitStringReader, OneByte)
|
||||
{
|
||||
char data[] = { -28 };
|
||||
BitStringReader reader(string(data, 1));
|
||||
|
||||
ASSERT_EQ(0, reader.Read(2));
|
||||
ASSERT_EQ(1, reader.Read(2));
|
||||
ASSERT_EQ(2, reader.Read(2));
|
||||
ASSERT_EQ(3, reader.Read(2));
|
||||
}
|
||||
|
||||
TEST(BitStringReader, TwoBytesIncomplete)
|
||||
{
|
||||
char data[] = { -28, 1 };
|
||||
BitStringReader reader(string(data, 2));
|
||||
|
||||
ASSERT_EQ(0, reader.Read(2));
|
||||
ASSERT_EQ(1, reader.Read(2));
|
||||
ASSERT_EQ(2, reader.Read(2));
|
||||
ASSERT_EQ(3, reader.Read(2));
|
||||
ASSERT_EQ(1, reader.Read(2));
|
||||
}
|
||||
|
||||
TEST(BitStringReader, TwoBytesSplit)
|
||||
{
|
||||
char data[] = { -120, 6 };
|
||||
BitStringReader reader(string(data, 2));
|
||||
|
||||
ASSERT_EQ(0, reader.Read(3));
|
||||
ASSERT_EQ(1, reader.Read(3));
|
||||
ASSERT_EQ(2, reader.Read(3));
|
||||
ASSERT_EQ(3, reader.Read(3));
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "image.h"
|
||||
#include "classifier.h"
|
||||
#include "bit_string_writer.h"
|
||||
#include "utils.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(BitStringWriter, OneByte)
|
||||
{
|
||||
BitStringWriter writer;
|
||||
writer.Write(0, 2);
|
||||
writer.Write(1, 2);
|
||||
writer.Write(2, 2);
|
||||
writer.Write(3, 2);
|
||||
writer.Flush();
|
||||
|
||||
char expected[] = { -28 };
|
||||
CheckString(writer.value(), expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
||||
|
||||
TEST(BitStringWriter, TwoBytesIncomplete)
|
||||
{
|
||||
BitStringWriter writer;
|
||||
writer.Write(0, 2);
|
||||
writer.Write(1, 2);
|
||||
writer.Write(2, 2);
|
||||
writer.Write(3, 2);
|
||||
writer.Write(1, 2);
|
||||
writer.Flush();
|
||||
|
||||
char expected[] = { -28, 1 };
|
||||
CheckString(writer.value(), expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
||||
|
||||
TEST(BitStringWriter, TwoBytesSplit)
|
||||
{
|
||||
BitStringWriter writer;
|
||||
writer.Write(0, 3);
|
||||
writer.Write(1, 3);
|
||||
writer.Write(2, 3);
|
||||
writer.Write(3, 3);
|
||||
writer.Flush();
|
||||
|
||||
char expected[] = { -120, 6 };
|
||||
CheckString(writer.value(), expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
125
3rdparty/chromaprint/tests/test_chroma.cpp
vendored
125
3rdparty/chromaprint/tests/test_chroma.cpp
vendored
@ -1,125 +0,0 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <gtest/gtest.h>
|
||||
#include "fft_frame.h"
|
||||
#include "chroma.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
class FeatureVectorBuffer : public FeatureVectorConsumer
|
||||
{
|
||||
public:
|
||||
void Consume(std::vector<double> &features)
|
||||
{
|
||||
m_features = features;
|
||||
}
|
||||
|
||||
std::vector<double> m_features;
|
||||
};
|
||||
|
||||
TEST(Chroma, NormalA) {
|
||||
FeatureVectorBuffer buffer;
|
||||
Chroma chroma(10, 510, 256, 1000, &buffer);
|
||||
FFTFrame frame(128);
|
||||
std::fill(frame.data(), frame.data() + frame.size(), 0.0);
|
||||
frame.data()[113] = 1.0;
|
||||
chroma.Consume(frame);
|
||||
ASSERT_EQ(12, buffer.m_features.size());
|
||||
double expected_features[12] = {
|
||||
1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
};
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_NEAR(expected_features[i], buffer.m_features[i], 0.0001) << "Different value at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Chroma, NormalGSharp) {
|
||||
FeatureVectorBuffer buffer;
|
||||
Chroma chroma(10, 510, 256, 1000, &buffer);
|
||||
FFTFrame frame(128);
|
||||
std::fill(frame.data(), frame.data() + frame.size(), 0.0);
|
||||
frame.data()[112] = 1.0;
|
||||
chroma.Consume(frame);
|
||||
ASSERT_EQ(12, buffer.m_features.size());
|
||||
double expected_features[12] = {
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
};
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_NEAR(expected_features[i], buffer.m_features[i], 0.0001) << "Different value at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Chroma, NormalB) {
|
||||
FeatureVectorBuffer buffer;
|
||||
Chroma chroma(10, 510, 256, 1000, &buffer);
|
||||
FFTFrame frame(128);
|
||||
std::fill(frame.data(), frame.data() + frame.size(), 0.0);
|
||||
frame.data()[64] = 1.0; // 250 Hz
|
||||
chroma.Consume(frame);
|
||||
ASSERT_EQ(12, buffer.m_features.size());
|
||||
double expected_features[12] = {
|
||||
0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
};
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_NEAR(expected_features[i], buffer.m_features[i], 0.0001) << "Different value at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Chroma, InterpolatedB) {
|
||||
FeatureVectorBuffer buffer;
|
||||
Chroma chroma(10, 510, 256, 1000, &buffer);
|
||||
chroma.set_interpolate(true);
|
||||
FFTFrame frame(128);
|
||||
std::fill(frame.data(), frame.data() + frame.size(), 0.0);
|
||||
frame.data()[64] = 1.0;
|
||||
chroma.Consume(frame);
|
||||
ASSERT_EQ(12, buffer.m_features.size());
|
||||
double expected_features[12] = {
|
||||
0.0, 0.286905, 0.713095, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
};
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_NEAR(expected_features[i], buffer.m_features[i], 0.0001) << "Different value at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Chroma, InterpolatedA) {
|
||||
FeatureVectorBuffer buffer;
|
||||
Chroma chroma(10, 510, 256, 1000, &buffer);
|
||||
chroma.set_interpolate(true);
|
||||
FFTFrame frame(128);
|
||||
std::fill(frame.data(), frame.data() + frame.size(), 0.0);
|
||||
frame.data()[113] = 1.0;
|
||||
chroma.Consume(frame);
|
||||
ASSERT_EQ(12, buffer.m_features.size());
|
||||
double expected_features[12] = {
|
||||
0.555242, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.444758,
|
||||
};
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_NEAR(expected_features[i], buffer.m_features[i], 0.0001) << "Different value at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Chroma, InterpolatedGSharp) {
|
||||
FeatureVectorBuffer buffer;
|
||||
Chroma chroma(10, 510, 256, 1000, &buffer);
|
||||
chroma.set_interpolate(true);
|
||||
FFTFrame frame(128);
|
||||
std::fill(frame.data(), frame.data() + frame.size(), 0.0);
|
||||
frame.data()[112] = 1.0;
|
||||
chroma.Consume(frame);
|
||||
ASSERT_EQ(12, buffer.m_features.size());
|
||||
double expected_features[12] = {
|
||||
0.401354, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.598646,
|
||||
};
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_NEAR(expected_features[i], buffer.m_features[i], 0.0001) << "Different value at index " << i;
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "image.h"
|
||||
#include "image_builder.h"
|
||||
#include "chroma_filter.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(ChromaFilter, Blur2) {
|
||||
double coefficients[] = { 0.5, 0.5 };
|
||||
Image image(12);
|
||||
ImageBuilder builder(&image);
|
||||
ChromaFilter filter(coefficients, 2, &builder);
|
||||
double d1[] = { 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d2[] = { 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d3[] = { 2.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
std::vector<double> v1(d1, d1 + 12);
|
||||
std::vector<double> v2(d2, d2 + 12);
|
||||
std::vector<double> v3(d3, d3 + 12);
|
||||
filter.Consume(v1);
|
||||
filter.Consume(v2);
|
||||
filter.Consume(v3);
|
||||
ASSERT_EQ(2, image.NumRows());
|
||||
EXPECT_EQ(0.5, image[0][0]);
|
||||
EXPECT_EQ(1.5, image[1][0]);
|
||||
EXPECT_EQ(5.5, image[0][1]);
|
||||
EXPECT_EQ(6.5, image[1][1]);
|
||||
}
|
||||
|
||||
TEST(ChromaFilter, Blur3) {
|
||||
double coefficients[] = { 0.5, 0.7, 0.5 };
|
||||
Image image(12);
|
||||
ImageBuilder builder(&image);
|
||||
ChromaFilter filter(coefficients, 3, &builder);
|
||||
double d1[] = { 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d2[] = { 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d3[] = { 2.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d4[] = { 3.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
std::vector<double> v1(d1, d1 + 12);
|
||||
std::vector<double> v2(d2, d2 + 12);
|
||||
std::vector<double> v3(d3, d3 + 12);
|
||||
std::vector<double> v4(d4, d4 + 12);
|
||||
filter.Consume(v1);
|
||||
filter.Consume(v2);
|
||||
filter.Consume(v3);
|
||||
filter.Consume(v4);
|
||||
ASSERT_EQ(2, image.NumRows());
|
||||
EXPECT_FLOAT_EQ(1.7, image[0][0]);
|
||||
EXPECT_FLOAT_EQ(3.399999999999999, image[1][0]);
|
||||
EXPECT_FLOAT_EQ(10.199999999999999, image[0][1]);
|
||||
EXPECT_FLOAT_EQ(11.899999999999999, image[1][1]);
|
||||
}
|
||||
|
||||
TEST(ChromaFilter, Diff) {
|
||||
double coefficients[] = { 1.0, -1.0 };
|
||||
Image image(12);
|
||||
ImageBuilder builder(&image);
|
||||
ChromaFilter filter(coefficients, 2, &builder);
|
||||
double d1[] = { 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d2[] = { 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d3[] = { 2.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
std::vector<double> v1(d1, d1 + 12);
|
||||
std::vector<double> v2(d2, d2 + 12);
|
||||
std::vector<double> v3(d3, d3 + 12);
|
||||
filter.Consume(v1);
|
||||
filter.Consume(v2);
|
||||
filter.Consume(v3);
|
||||
ASSERT_EQ(2, image.NumRows());
|
||||
EXPECT_EQ(-1.0, image[0][0]);
|
||||
EXPECT_EQ(-1.0, image[1][0]);
|
||||
EXPECT_EQ(-1.0, image[0][1]);
|
||||
EXPECT_EQ(-1.0, image[1][1]);
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "image.h"
|
||||
#include "image_builder.h"
|
||||
#include "chroma_resampler.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(ChromaResampler, Test1) {
|
||||
Image image(12);
|
||||
ImageBuilder builder(&image);
|
||||
ChromaResampler resampler(2, &builder);
|
||||
double d1[] = { 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d2[] = { 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d3[] = { 2.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
std::vector<double> v1(d1, d1 + 12);
|
||||
std::vector<double> v2(d2, d2 + 12);
|
||||
std::vector<double> v3(d3, d3 + 12);
|
||||
resampler.Consume(v1);
|
||||
resampler.Consume(v2);
|
||||
resampler.Consume(v3);
|
||||
ASSERT_EQ(1, image.NumRows());
|
||||
EXPECT_EQ(0.5, image[0][0]);
|
||||
EXPECT_EQ(5.5, image[0][1]);
|
||||
}
|
||||
|
||||
TEST(ChromaResampler, Test2) {
|
||||
Image image(12);
|
||||
ImageBuilder builder(&image);
|
||||
ChromaResampler resampler(2, &builder);
|
||||
double d1[] = { 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d2[] = { 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d3[] = { 2.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
double d4[] = { 3.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
std::vector<double> v1(d1, d1 + 12);
|
||||
std::vector<double> v2(d2, d2 + 12);
|
||||
std::vector<double> v3(d3, d3 + 12);
|
||||
std::vector<double> v4(d4, d4 + 12);
|
||||
resampler.Consume(v1);
|
||||
resampler.Consume(v2);
|
||||
resampler.Consume(v3);
|
||||
resampler.Consume(v4);
|
||||
ASSERT_EQ(2, image.NumRows());
|
||||
EXPECT_EQ(0.5, image[0][0]);
|
||||
EXPECT_EQ(5.5, image[0][1]);
|
||||
EXPECT_EQ(2.5, image[1][0]);
|
||||
EXPECT_EQ(7.5, image[1][1]);
|
||||
}
|
67
3rdparty/chromaprint/tests/test_chromaprint.cpp
vendored
67
3rdparty/chromaprint/tests/test_chromaprint.cpp
vendored
@ -1,67 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "audio_processor.h"
|
||||
#include "test_utils.h"
|
||||
#include "audio_processor.h"
|
||||
#include "chroma.h"
|
||||
#include "chroma_normalizer.h"
|
||||
#include "chroma_resampler.h"
|
||||
#include "fft.h"
|
||||
#include "audio_processor.h"
|
||||
#include "image.h"
|
||||
#include "image_builder.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
static const int SAMPLE_RATE = 11025;
|
||||
static const int FRAME_SIZE = 4096;
|
||||
static const int OVERLAP = FRAME_SIZE - FRAME_SIZE / 3;// 2720;
|
||||
static const int MIN_FREQ = 28;
|
||||
static const int MAX_FREQ = 3520;
|
||||
static const int MAX_FILTER_WIDTH = 20;
|
||||
|
||||
TEST(Chromaprint, BasicImage)
|
||||
{
|
||||
vector<short> data = LoadAudioFile("data/test_stereo_44100.raw");
|
||||
|
||||
Chromaprint::Image image(12);
|
||||
Chromaprint::ImageBuilder image_builder(&image);
|
||||
Chromaprint::ChromaNormalizer chroma_normalizer(&image_builder);
|
||||
Chromaprint::Chroma chroma(MIN_FREQ, MAX_FREQ, FRAME_SIZE, SAMPLE_RATE, &chroma_normalizer);
|
||||
Chromaprint::FFT fft(FRAME_SIZE, OVERLAP, &chroma);
|
||||
Chromaprint::AudioProcessor processor(SAMPLE_RATE, &fft);
|
||||
|
||||
processor.Reset(44100, 2);
|
||||
processor.Consume(&data[0], data.size());
|
||||
processor.Flush();
|
||||
|
||||
double chromagram[][12] = {
|
||||
{ 0.155444, 0.268618, 0.474445, 0.159887, 0.1761, 0.423511, 0.178933, 0.34433, 0.360958, 0.30421, 0.200217, 0.17072 },
|
||||
{ 0.159809, 0.238675, 0.286526, 0.166119, 0.225144, 0.449236, 0.162444, 0.371875, 0.259626, 0.483961, 0.24491, 0.17034 },
|
||||
{ 0.156518, 0.271503, 0.256073, 0.152689, 0.174664, 0.52585, 0.141517, 0.253695, 0.293199, 0.332114, 0.442906, 0.170459 },
|
||||
{ 0.154183, 0.38592, 0.497451, 0.203884, 0.362608, 0.355691, 0.125349, 0.146766, 0.315143, 0.318133, 0.172547, 0.112769 },
|
||||
{ 0.201289, 0.42033, 0.509467, 0.259247, 0.322772, 0.325837, 0.140072, 0.177756, 0.320356, 0.228176, 0.148994, 0.132588 },
|
||||
{ 0.187921, 0.302804, 0.46976, 0.302809, 0.183035, 0.228691, 0.206216, 0.35174, 0.308208, 0.233234, 0.316017, 0.243563 },
|
||||
{ 0.213539, 0.240346, 0.308664, 0.250704, 0.204879, 0.365022, 0.241966, 0.312579, 0.361886, 0.277293, 0.338944, 0.290351 },
|
||||
{ 0.227784, 0.252841, 0.295752, 0.265796, 0.227973, 0.451155, 0.219418, 0.272508, 0.376082, 0.312717, 0.285395, 0.165745 },
|
||||
{ 0.168662, 0.180795, 0.264397, 0.225101, 0.562332, 0.33243, 0.236684, 0.199847, 0.409727, 0.247569, 0.21153, 0.147286 },
|
||||
{ 0.0491864, 0.0503369, 0.130942, 0.0505802, 0.0694409, 0.0303877, 0.0389852, 0.674067, 0.712933, 0.05762, 0.0245158, 0.0389336 },
|
||||
{ 0.0814379, 0.0312366, 0.240546, 0.134609, 0.063374, 0.0466124, 0.0752175, 0.657041, 0.680085, 0.0720311, 0.0249404, 0.0673359 },
|
||||
{ 0.139331, 0.0173442, 0.49035, 0.287237, 0.0453947, 0.0873279, 0.15423, 0.447475, 0.621502, 0.127166, 0.0355933, 0.141163 },
|
||||
{ 0.115417, 0.0132515, 0.356601, 0.245902, 0.0283943, 0.0588233, 0.117077, 0.499376, 0.715366, 0.100398, 0.0281382, 0.0943482 },
|
||||
{ 0.047297, 0.0065354, 0.181074, 0.121455, 0.0135504, 0.030693, 0.0613105, 0.631705, 0.73548, 0.0550565, 0.0128093, 0.0460393 },
|
||||
};
|
||||
|
||||
ASSERT_EQ(14, image.NumRows()) << "Numbers of rows doesn't match";
|
||||
for (int y = 0; y < 14; y++) {
|
||||
for (int x = 0; x < 12; x++) {
|
||||
EXPECT_NEAR(chromagram[y][x], image[y][x], 1e-5)
|
||||
<< "Image not equal at (" << x << ", " << y << ")";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
#include "combined_buffer.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(CombinedBuffer, Size) {
|
||||
short buffer1[] = { 1, 2, 3, 4, 5 };
|
||||
short buffer2[] = { 6, 7, 8 };
|
||||
CombinedBuffer<short> buffer(buffer1, 5, buffer2, 3);
|
||||
EXPECT_EQ(8, buffer.Size());
|
||||
buffer.Shift(1);
|
||||
EXPECT_EQ(7, buffer.Size());
|
||||
}
|
||||
|
||||
TEST(CombinedBuffer, AccessElements) {
|
||||
short buffer1[] = { 1, 2, 3, 4, 5 };
|
||||
short buffer2[] = { 6, 7, 8 };
|
||||
CombinedBuffer<short> buffer(buffer1, 5, buffer2, 3);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
EXPECT_EQ(1 + i, buffer[i]);
|
||||
}
|
||||
buffer.Shift(1);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
EXPECT_EQ(2 + i, buffer[i]);
|
||||
}
|
||||
buffer.Shift(5);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
EXPECT_EQ(7 + i, buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CombinedBuffer, AccessElementsViaIterator) {
|
||||
short buffer1[] = { 1, 2, 3, 4, 5 };
|
||||
short buffer2[] = { 6, 7, 8 };
|
||||
CombinedBuffer<short> buffer(buffer1, 5, buffer2, 3);
|
||||
CombinedBuffer<short>::Iterator iter = buffer.Begin();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
EXPECT_EQ(1 + i, *iter);
|
||||
++iter;
|
||||
}
|
||||
EXPECT_TRUE(buffer.End() == iter);
|
||||
}
|
||||
|
||||
TEST(CombinedBuffer, AccessElementsViaIteratorAfterShift) {
|
||||
short buffer1[] = { 1, 2, 3, 4, 5 };
|
||||
short buffer2[] = { 6, 7, 8 };
|
||||
CombinedBuffer<short> buffer(buffer1, 5, buffer2, 3);
|
||||
buffer.Shift(6);
|
||||
CombinedBuffer<short>::Iterator iter = buffer.Begin();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
EXPECT_EQ(7 + i, *iter);
|
||||
++iter;
|
||||
}
|
||||
EXPECT_TRUE(buffer.End() == iter);
|
||||
}
|
||||
|
||||
TEST(CombinedBuffer, CopyUsingStlAlgorithms) {
|
||||
short buffer1[] = { 1, 2, 3, 4, 5 };
|
||||
short buffer2[] = { 6, 7, 8 };
|
||||
short tmp[10];
|
||||
CombinedBuffer<short> buffer(buffer1, 5, buffer2, 3);
|
||||
fill(tmp, tmp + 10, 0);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
EXPECT_EQ(0, tmp[i]);
|
||||
}
|
||||
copy(buffer.Begin(), buffer.End(), tmp);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
EXPECT_EQ(1 + i, tmp[i]);
|
||||
}
|
||||
for (int i = 8; i < 10; i++) {
|
||||
EXPECT_EQ(0, tmp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CombinedBuffer, CopyUsingStlAlgorithmsAfterShift) {
|
||||
short buffer1[] = { 1, 2, 3, 4, 5 };
|
||||
short buffer2[] = { 6, 7, 8 };
|
||||
short tmp[10];
|
||||
CombinedBuffer<short> buffer(buffer1, 5, buffer2, 3);
|
||||
buffer.Shift(6);
|
||||
fill(tmp, tmp + 10, 0);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
EXPECT_EQ(0, tmp[i]);
|
||||
}
|
||||
copy(buffer.Begin(), buffer.End(), tmp);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
EXPECT_EQ(7 + i, tmp[i]);
|
||||
}
|
||||
for (int i = 2; i < 10; i++) {
|
||||
EXPECT_EQ(0, tmp[i]);
|
||||
}
|
||||
}
|
||||
|
25
3rdparty/chromaprint/tests/test_filter.cpp
vendored
25
3rdparty/chromaprint/tests/test_filter.cpp
vendored
@ -1,25 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "image.h"
|
||||
#include "filter.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(Filter, Filter0)
|
||||
{
|
||||
Image image(2, 2);
|
||||
image[0][0] = 0.0;
|
||||
image[0][1] = 1.0;
|
||||
image[1][0] = 2.0;
|
||||
image[1][1] = 3.0;
|
||||
|
||||
Filter flt1(0, 0, 1, 1);
|
||||
IntegralImage integral_image(&image);
|
||||
ASSERT_FLOAT_EQ(0.0, flt1.Apply(&integral_image, 0));
|
||||
ASSERT_FLOAT_EQ(1.0986123, flt1.Apply(&integral_image, 1));
|
||||
}
|
||||
|
118
3rdparty/chromaprint/tests/test_filter_utils.cpp
vendored
118
3rdparty/chromaprint/tests/test_filter_utils.cpp
vendored
@ -1,118 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "filter_utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(FilterUtils, CompareSubtract) {
|
||||
double res = Subtract(2.0, 1.0);
|
||||
EXPECT_FLOAT_EQ(1.0, res);
|
||||
}
|
||||
|
||||
TEST(FilterUtils, CompareSubtractLog) {
|
||||
double res = SubtractLog(2.0, 1.0);
|
||||
EXPECT_FLOAT_EQ(0.4054651, res);
|
||||
}
|
||||
|
||||
TEST(FilterUtils, Filter0) {
|
||||
double data[] = {
|
||||
1.0, 2.0, 3.0,
|
||||
4.0, 5.0, 6.0,
|
||||
7.0, 8.0, 9.0,
|
||||
};
|
||||
Image image(3, data, data + 9);
|
||||
IntegralImage integral_image(&image);
|
||||
double res;
|
||||
res = Filter0(&integral_image, 0, 0, 1, 1, Subtract);
|
||||
EXPECT_FLOAT_EQ(1.0, res);
|
||||
res = Filter0(&integral_image, 0, 0, 2, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(12.0, res);
|
||||
res = Filter0(&integral_image, 0, 0, 3, 3, Subtract);
|
||||
EXPECT_FLOAT_EQ(45.0, res);
|
||||
res = Filter0(&integral_image, 1, 1, 2, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(28.0, res);
|
||||
res = Filter0(&integral_image, 2, 2, 1, 1, Subtract);
|
||||
EXPECT_FLOAT_EQ(9.0, res);
|
||||
res = Filter0(&integral_image, 0, 0, 3, 1, Subtract);
|
||||
EXPECT_FLOAT_EQ(12.0, res);
|
||||
res = Filter0(&integral_image, 0, 0, 1, 3, Subtract);
|
||||
EXPECT_FLOAT_EQ(6.0, res);
|
||||
}
|
||||
|
||||
TEST(FilterUtils, Filter1) {
|
||||
double data[] = {
|
||||
1.0, 2.0, 3.0,
|
||||
3.0, 4.0, 5.0,
|
||||
6.0, 7.0, 8.0,
|
||||
};
|
||||
Image image(3, data, data + 9);
|
||||
IntegralImage integral_image(&image);
|
||||
double res;
|
||||
res = Filter1(&integral_image, 0, 0, 1, 1, Subtract);
|
||||
EXPECT_FLOAT_EQ(1.0, res); // 2 - 1
|
||||
res = Filter1(&integral_image, 0, 0, 2, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(2.0, res); // 2+4 - 1+3
|
||||
res = Filter1(&integral_image, 0, 0, 3, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(3.0, res); // 2+4+7 - 1+3+6
|
||||
}
|
||||
|
||||
TEST(FilterUtils, Filter2) {
|
||||
double data[] = {
|
||||
1.0, 2.0, 3.0,
|
||||
3.0, 4.0, 5.0,
|
||||
6.0, 7.0, 8.0,
|
||||
};
|
||||
Image image(3, data, data + 9);
|
||||
IntegralImage integral_image(&image);
|
||||
double res;
|
||||
res = Filter2(&integral_image, 0, 0, 2, 1, Subtract);
|
||||
EXPECT_FLOAT_EQ(2.0, res); // 3 - 1
|
||||
res = Filter2(&integral_image, 0, 0, 2, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(4.0, res); // 3+4 - 1+2
|
||||
res = Filter2(&integral_image, 0, 0, 2, 3, Subtract);
|
||||
EXPECT_FLOAT_EQ(6.0, res); // 3+4+5 - 1+2+3
|
||||
}
|
||||
|
||||
TEST(FilterUtils, Filter3) {
|
||||
double data[] = {
|
||||
1.0, 2.1, 3.4,
|
||||
3.1, 4.1, 5.1,
|
||||
6.0, 7.1, 8.0,
|
||||
};
|
||||
Image image(3, data, data + 9);
|
||||
IntegralImage integral_image(&image);
|
||||
double res;
|
||||
res = Filter3(&integral_image, 0, 0, 2, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(0.1, res); // 2.1+3.1 - 1+4.1
|
||||
res = Filter3(&integral_image, 1, 1, 2, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(0.1, res); // 4+8 - 5+7
|
||||
res = Filter3(&integral_image, 0, 1, 2, 2, Subtract);
|
||||
EXPECT_FLOAT_EQ(0.3, res); // 2.1+5.1 - 3.4+4.1
|
||||
}
|
||||
|
||||
TEST(FilterUtils, Filter4) {
|
||||
double data[] = {
|
||||
1.0, 2.0, 3.0,
|
||||
3.0, 4.0, 5.0,
|
||||
6.0, 7.0, 8.0,
|
||||
};
|
||||
Image image(3, data, data + 9);
|
||||
IntegralImage integral_image(&image);
|
||||
double res;
|
||||
res = Filter4(&integral_image, 0, 0, 3, 3, Subtract);
|
||||
EXPECT_FLOAT_EQ(-13.0, res); // 2+4+7 - (1+3+6) - (3+5+8)
|
||||
}
|
||||
|
||||
TEST(FilterUtils, Filter5) {
|
||||
double data[] = {
|
||||
1.0, 2.0, 3.0,
|
||||
3.0, 4.0, 5.0,
|
||||
6.0, 7.0, 8.0,
|
||||
};
|
||||
Image image(3, data, data + 9);
|
||||
IntegralImage integral_image(&image);
|
||||
double res;
|
||||
res = Filter5(&integral_image, 0, 0, 3, 3, Subtract);
|
||||
EXPECT_FLOAT_EQ(-15.0, res); // 3+4+5 - (1+2+3) - (6+7+8)
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "image.h"
|
||||
#include "classifier.h"
|
||||
#include "fingerprint_calculator.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(FingerprintCalculator, CalculateSubfingerprint)
|
||||
{
|
||||
Image image(2, 2);
|
||||
image[0][0] = 0.0;
|
||||
image[0][1] = 1.0;
|
||||
image[1][0] = 2.0;
|
||||
image[1][1] = 3.0;
|
||||
|
||||
Classifier classifiers[] = {
|
||||
Classifier(Filter(0, 0, 1, 1), Quantizer(0.01, 1.01, 1.5)),
|
||||
};
|
||||
FingerprintCalculator calculator(classifiers, 1);
|
||||
|
||||
IntegralImage integral_image(&image);
|
||||
EXPECT_EQ(GrayCode(0), calculator.CalculateSubfingerprint(&integral_image, 0));
|
||||
EXPECT_EQ(GrayCode(2), calculator.CalculateSubfingerprint(&integral_image, 1));
|
||||
}
|
||||
|
||||
TEST(FingerprintCalculator, Calculate)
|
||||
{
|
||||
Image image(2, 3);
|
||||
image[0][0] = 0.0;
|
||||
image[0][1] = 1.0;
|
||||
image[1][0] = 2.0;
|
||||
image[1][1] = 3.0;
|
||||
image[2][0] = 4.0;
|
||||
image[2][1] = 5.0;
|
||||
|
||||
Classifier classifiers[] = {
|
||||
Classifier(Filter(0, 0, 1, 1), Quantizer(0.01, 1.01, 1.5)),
|
||||
};
|
||||
FingerprintCalculator calculator(classifiers, 1);
|
||||
|
||||
vector<int32_t> fp = calculator.Calculate(&image);
|
||||
ASSERT_EQ(3, fp.size());
|
||||
EXPECT_EQ(GrayCode(0), fp[0]);
|
||||
EXPECT_EQ(GrayCode(2), fp[1]);
|
||||
EXPECT_EQ(GrayCode(3), fp[2]);
|
||||
}
|
||||
|
@ -1,79 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "image.h"
|
||||
#include "classifier.h"
|
||||
#include "fingerprint_compressor.h"
|
||||
#include "utils.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(FingerprintCompressor, OneItemOneBit)
|
||||
{
|
||||
FingerprintCompressor compressor;
|
||||
|
||||
int32_t fingerprint[] = { 1 };
|
||||
string value = compressor.Compress(vector<int32_t>(fingerprint, fingerprint + 1));
|
||||
|
||||
char expected[] = { 0, 0, 0, 1, 1 };
|
||||
CheckString(value, expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
||||
|
||||
TEST(FingerprintCompressor, OneItemThreeBits)
|
||||
{
|
||||
FingerprintCompressor compressor;
|
||||
|
||||
int32_t fingerprint[] = { 7 };
|
||||
string value = compressor.Compress(vector<int32_t>(fingerprint, fingerprint + 1));
|
||||
|
||||
char expected[] = { 0, 0, 0, 1, 73, 0 };
|
||||
CheckString(value, expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
||||
|
||||
TEST(FingerprintCompressor, OneItemOneBitExcept)
|
||||
{
|
||||
FingerprintCompressor compressor;
|
||||
|
||||
int32_t fingerprint[] = { 1<<6 };
|
||||
string value = compressor.Compress(vector<int32_t>(fingerprint, fingerprint + 1));
|
||||
|
||||
char expected[] = { 0, 0, 0, 1, 7, 0 };
|
||||
CheckString(value, expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
||||
|
||||
TEST(FingerprintCompressor, OneItemOneBitExcept2)
|
||||
{
|
||||
FingerprintCompressor compressor;
|
||||
|
||||
int32_t fingerprint[] = { 1<<8 };
|
||||
string value = compressor.Compress(vector<int32_t>(fingerprint, fingerprint + 1));
|
||||
|
||||
char expected[] = { 0, 0, 0, 1, 7, 2 };
|
||||
CheckString(value, expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
||||
|
||||
TEST(FingerprintCompressor, TwoItems)
|
||||
{
|
||||
FingerprintCompressor compressor;
|
||||
|
||||
int32_t fingerprint[] = { 1, 0 };
|
||||
string value = compressor.Compress(vector<int32_t>(fingerprint, fingerprint + 2));
|
||||
|
||||
char expected[] = { 0, 0, 0, 2, 65, 0 };
|
||||
CheckString(value, expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
||||
|
||||
TEST(FingerprintCompressor, TwoItemsNoChange)
|
||||
{
|
||||
FingerprintCompressor compressor;
|
||||
|
||||
int32_t fingerprint[] = { 1, 1 };
|
||||
string value = compressor.Compress(vector<int32_t>(fingerprint, fingerprint + 2));
|
||||
|
||||
char expected[] = { 0, 0, 0, 2, 1, 0 };
|
||||
CheckString(value, expected, sizeof(expected)/sizeof(expected[0]));
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "fingerprint_decompressor.h"
|
||||
#include "utils.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(FingerprintDecompressor, OneItemOneBit)
|
||||
{
|
||||
int32_t expected[] = { 1 };
|
||||
char data[] = { 0, 0, 0, 1, 1 };
|
||||
|
||||
int algorithm = 1;
|
||||
vector<int32_t> value = DecompressFingerprint(string(data, NELEMS(data)), &algorithm);
|
||||
CheckFingerprints(value, expected, NELEMS(expected));
|
||||
ASSERT_EQ(0, algorithm);
|
||||
}
|
||||
|
||||
|
||||
TEST(FingerprintDecompressor, OneItemThreeBits)
|
||||
{
|
||||
int32_t expected[] = { 7 };
|
||||
char data[] = { 0, 0, 0, 1, 73, 0 };
|
||||
|
||||
int algorithm = 1;
|
||||
vector<int32_t> value = DecompressFingerprint(string(data, NELEMS(data)), &algorithm);
|
||||
CheckFingerprints(value, expected, NELEMS(expected));
|
||||
ASSERT_EQ(0, algorithm);
|
||||
}
|
||||
|
||||
TEST(FingerprintDecompressor, OneItemOneBitExcept)
|
||||
{
|
||||
int32_t expected[] = { 1<<6 };
|
||||
char data[] = { 0, 0, 0, 1, 7, 0 };
|
||||
|
||||
int algorithm = 1;
|
||||
vector<int32_t> value = DecompressFingerprint(string(data, NELEMS(data)), &algorithm);
|
||||
CheckFingerprints(value, expected, NELEMS(expected));
|
||||
ASSERT_EQ(0, algorithm);
|
||||
}
|
||||
|
||||
TEST(FingerprintDecompressor, OneItemOneBitExcept2)
|
||||
{
|
||||
int32_t expected[] = { 1<<8 };
|
||||
char data[] = { 0, 0, 0, 1, 7, 2 };
|
||||
|
||||
int algorithm = 1;
|
||||
vector<int32_t> value = DecompressFingerprint(string(data, NELEMS(data)), &algorithm);
|
||||
CheckFingerprints(value, expected, NELEMS(expected));
|
||||
ASSERT_EQ(0, algorithm);
|
||||
}
|
||||
|
||||
TEST(FingerprintDecompressor, TwoItems)
|
||||
{
|
||||
int32_t expected[] = { 1, 0 };
|
||||
char data[] = { 0, 0, 0, 2, 65, 0 };
|
||||
|
||||
int algorithm = 1;
|
||||
vector<int32_t> value = DecompressFingerprint(string(data, NELEMS(data)), &algorithm);
|
||||
CheckFingerprints(value, expected, NELEMS(expected));
|
||||
ASSERT_EQ(0, algorithm);
|
||||
}
|
||||
|
||||
TEST(FingerprintDecompressor, TwoItemsNoChange)
|
||||
{
|
||||
int32_t expected[] = { 1, 1 };
|
||||
char data[] = { 0, 0, 0, 2, 1, 0 };
|
||||
|
||||
int algorithm = 1;
|
||||
vector<int32_t> value = DecompressFingerprint(string(data, NELEMS(data)), &algorithm);
|
||||
CheckFingerprints(value, expected, NELEMS(expected));
|
||||
ASSERT_EQ(0, algorithm);
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "integral_image.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(IntegralImage, Basic2D) {
|
||||
double data[] = {
|
||||
1.0, 2.0,
|
||||
3.0, 4.0,
|
||||
};
|
||||
Image image(2, data, data + 4);
|
||||
IntegralImage integral_image(&image);
|
||||
EXPECT_FLOAT_EQ(1.0, integral_image[0][0]);
|
||||
EXPECT_FLOAT_EQ(3.0, integral_image[0][1]);
|
||||
EXPECT_FLOAT_EQ(4.0, integral_image[1][0]);
|
||||
EXPECT_FLOAT_EQ(10.0, integral_image[1][1]);
|
||||
}
|
||||
|
||||
TEST(IntegralImage, Vertical1D) {
|
||||
double data[] = {
|
||||
1.0, 2.0, 3.0
|
||||
};
|
||||
Image image(1, data, data + 3);
|
||||
IntegralImage integral_image(&image);
|
||||
EXPECT_FLOAT_EQ(1.0, integral_image[0][0]);
|
||||
EXPECT_FLOAT_EQ(3.0, integral_image[1][0]);
|
||||
EXPECT_FLOAT_EQ(6.0, integral_image[2][0]);
|
||||
}
|
||||
|
||||
TEST(IntegralImage, Horizontal1D) {
|
||||
double data[] = {
|
||||
1.0, 2.0, 3.0
|
||||
};
|
||||
Image image(3, data, data + 3);
|
||||
IntegralImage integral_image(&image);
|
||||
EXPECT_FLOAT_EQ(1.0, integral_image[0][0]);
|
||||
EXPECT_FLOAT_EQ(3.0, integral_image[0][1]);
|
||||
EXPECT_FLOAT_EQ(6.0, integral_image[0][2]);
|
||||
}
|
80
3rdparty/chromaprint/tests/test_lloyds.cpp
vendored
80
3rdparty/chromaprint/tests/test_lloyds.cpp
vendored
@ -1,80 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "lloyds.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<class T>
|
||||
ostream &operator<<(ostream &stream, const vector<T> &vec)
|
||||
{
|
||||
for (int i = 0; i < vec.size(); i++) {
|
||||
if (i != 0)
|
||||
stream << ", ";
|
||||
stream << vec[i];
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*TEST(Lloyds, Long) {
|
||||
double signal[] = {
|
||||
-2.23622, -2.2133, -2.08922, -2.02973, -2.01912, -2.00194, -1.94793, -1.92903, -1.90671, -1.90311, -1.86394, -1.82542, -1.82281, -1.77955, -1.77286, -1.77119, -1.76317, -1.74447, -1.74447, -1.71927, -1.71244, -1.70758, -1.69632, -1.69448, -1.68845, -1.68842, -1.65839, -1.64934, -1.63575, -1.61216, -1.56943, -1.56546, -1.5601, -1.5584, -1.53875, -1.52408, -1.51576, -1.47345, -1.44838, -1.44712, -1.43751, -1.43722, -1.43159, -1.41818, -1.41585, -1.36654, -1.36556, -1.36486, -1.3596, -1.35941, -1.35301, -1.35301, -1.35145, -1.34479, -1.34443, -1.3441, -1.3381, -1.3334, -1.31715, -1.31105, -1.31071, -1.30166, -1.29944, -1.29715, -1.29669, -1.29634, -1.28696, -1.28504, -1.27143, -1.26548, -1.26533, -1.26421, -1.26054, -1.25978, -1.25631, -1.24751, -1.23887, -1.23797, -1.23588, -1.22391, -1.21961, -1.21559, -1.21499, -1.19502, -1.19009, -1.18784, -1.18746, -1.18264, -1.17917, -1.17597, -1.17482, -1.1664, -1.15644, -1.15584, -1.15317, -1.14694, -1.14341, -1.14246, -1.14234, -1.14027, -1.13955, -1.13745, -1.13674, -1.12764, -1.12735, -1.12729, -1.12645, -1.12578, -1.12533, -1.12131, -1.11019, -1.10879, -1.10357, -1.09973, -1.09187, -1.09187, -1.06664, -1.06356, -1.0554, -1.0492, -1.04506, -1.04027, -1.03942, -1.03896, -1.034, -1.03285, -1.02334, -1.02084, -1.01993, -1.01447, -1.01447, -1.01447, -1.00864, -1.00689, -1.00471, -1.00125, -0.999809, -0.998627, -0.998156, -0.994751, -0.994212, -0.993412, -0.992572, -0.992572, -0.992548, -0.992472, -0.989607, -0.987201, -0.982932, -0.982652, -0.980823, -0.976318, -0.974594, -0.973334, -0.97326, -0.971969, -0.970954, -0.964969, -0.963816, -0.960578, -0.959536, -0.95708, -0.953791, -0.953782, -0.952128, -0.951757, -0.95172, -0.951264, -0.950896, -0.949007, -0.947225, -0.945958, -0.945852, -0.945044, -0.94482, -0.940381, -0.940254, -0.940084, -0.939844, -0.937978, -0.935127, -0.93345, -0.931299, -0.931147, -0.929513, -0.927091, -0.926682, -0.926458, -0.925325, -0.918487, -0.917891, -0.917015, -0.916352, -0.915526, -0.915489, -0.913747, -0.91204, -0.911457, -0.911281, -0.910753, -0.909806, -0.909361, -0.908686, -0.907, -0.906509, -0.903637, -0.902177, -0.896958, -0.896304, -0.895733, -0.889965, -0.886484, -0.884943, -0.882143, -0.879831, -0.879507, -0.876134, -0.875782, -0.873226, -0.873167, -0.872282, -0.870152, -0.869655, -0.869655, -0.866992, -0.862656, -0.862331, -0.861969, -0.861246, -0.856819, -0.854323, -0.853294, -0.846832, -0.843682, -0.842113, -0.840478, -0.835353, -0.83055, -0.828979, -0.828979, -0.828088, -0.826904, -0.826844, -0.826474, -0.820101, -0.819027, -0.819027, -0.818121, -0.812784, -0.812206, -0.810112, -0.806803, -0.805296, -0.80126, -0.800501, -0.798129, -0.797067, -0.786663, -0.785991, -0.784662, -0.78212, -0.776524, -0.774306, -0.772335, -0.771675, -0.771675, -0.77125, -0.770083, -0.769165, -0.767499, -0.766419, -0.763909, -0.762582, -0.76243, -0.761753, -0.761182, -0.759494, -0.755514, -0.745122, -0.742554, -0.739007, -0.73575, -0.735359, -0.73376, -0.732161, -0.728712, -0.726951, -0.726218, -0.725935, -0.724686, -0.722143, -0.722044, -0.721563, -0.721248, -0.720543, -0.719718, -0.716511, -0.714431, -0.714329, -0.712779, -0.712512, -0.712512, -0.711802, -0.71157, -0.709608, -0.706909, -0.706774, -0.704839, -0.703444, -0.702687, -0.70263, -0.702272, -0.700726, -0.700691, -0.700566, -0.698961, -0.697583, -0.697153, -0.696813, -0.696062, -0.695309, -0.694557, -0.691675, -0.691434, -0.687548, -0.686447, -0.684052, -0.68283, -0.682705, -0.682523, -0.682514, -0.679172, -0.675747, -0.675161, -0.673046, -0.670132, -0.663973, -0.659537, -0.655187, -0.65481, -0.653818, -0.65335, -0.653181, -0.649845, -0.649723, -0.648533, -0.647648, -0.645932, -0.645885, -0.645736, -0.643418, -0.642324, -0.642275, -0.641053, -0.641053, -0.636907, -0.635015, -0.634658, -0.632863, -0.629322, -0.629234, -0.628869, -0.627114, -0.626578, -0.626576, -0.62511, -0.625091, -0.621436, -0.620774, -0.616916, -0.616051, -0.612722, -0.611527, -0.610163, -0.609325, -0.606185, -0.606169, -0.606019, -0.603731, -0.602434, -0.596665, -0.596236, -0.595822, -0.594053, -0.588736, -0.588164, -0.586796, -0.586709, -0.585038, -0.583978, -0.583929, -0.582533, -0.576205, -0.57511
|
||||
};
|
||||
vector<double> r = lloyds(signal, signal + sizeof(signal) / sizeof(signal[0]), 10);
|
||||
EXPECT_EQ(9, r.size());
|
||||
EXPECT_FLOAT_EQ(-2.15126, r[0]);
|
||||
EXPECT_FLOAT_EQ(-1.95019, r[1]);
|
||||
EXPECT_FLOAT_EQ(-1.72034, r[2]);
|
||||
EXPECT_FLOAT_EQ(-1.42570, r[3]);
|
||||
EXPECT_FLOAT_EQ(-1.23976, r[4]);
|
||||
EXPECT_FLOAT_EQ(-1.06092, r[5]);
|
||||
EXPECT_FLOAT_EQ(-0.93395, r[6]);
|
||||
EXPECT_FLOAT_EQ(-0.81530, r[7]);
|
||||
EXPECT_FLOAT_EQ(-0.68837, r[8]);
|
||||
}*/
|
||||
|
||||
TEST(LLoyds, Lloyds1) {
|
||||
double data[] = {
|
||||
1.0, 1.1, 1.2,
|
||||
3.0, 3.1, 3.2,
|
||||
};
|
||||
vector<double> sig(data, data + 6);
|
||||
vector<double> table = lloyds(sig, 2);
|
||||
EXPECT_EQ(1, table.size());
|
||||
EXPECT_FLOAT_EQ(2.1, table[0]);
|
||||
}
|
||||
|
||||
TEST(LLoyds, Lloyds2) {
|
||||
double data[] = {
|
||||
1.0, 1.1, 1.2,
|
||||
};
|
||||
vector<double> sig(data, data + 3);
|
||||
vector<double> table = lloyds(sig, 2);
|
||||
EXPECT_EQ(1, table.size());
|
||||
EXPECT_FLOAT_EQ(1.075, table[0]);
|
||||
}
|
||||
|
||||
TEST(LLoyds, Lloyds3) {
|
||||
double data[] = {
|
||||
1.0, 1.1, 1.2,
|
||||
};
|
||||
vector<double> sig(data, data + 3);
|
||||
vector<double> table = lloyds(sig, 3);
|
||||
EXPECT_EQ(2, table.size());
|
||||
EXPECT_FLOAT_EQ(1.05, table[0]);
|
||||
EXPECT_FLOAT_EQ(1.15, table[1]);
|
||||
}
|
||||
|
||||
TEST(LLoyds, Lloyds4) {
|
||||
double data[] = {
|
||||
435,219,891,906,184,572,301,892,875,121,245,146,640,137,938,25,668,288,848,790,141,890,528,145,289,861,339,769,293,757
|
||||
};
|
||||
vector<double> sig(data, data + 30);
|
||||
vector<double> table = lloyds(sig, 4);
|
||||
EXPECT_EQ(3, table.size());
|
||||
EXPECT_FLOAT_EQ(214.77678, table[0]);
|
||||
EXPECT_FLOAT_EQ(451.5625, table[1]);
|
||||
EXPECT_FLOAT_EQ(729.04547, table[2]);
|
||||
}
|
||||
|
||||
|
17
3rdparty/chromaprint/tests/test_quantizer.cpp
vendored
17
3rdparty/chromaprint/tests/test_quantizer.cpp
vendored
@ -1,17 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "quantizer.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(Quantizer, Quantize) {
|
||||
Quantizer q(0.0, 0.1, 0.3);
|
||||
EXPECT_EQ(0, q.Quantize(-0.1));
|
||||
EXPECT_EQ(1, q.Quantize(0.0));
|
||||
EXPECT_EQ(1, q.Quantize(0.03));
|
||||
EXPECT_EQ(2, q.Quantize(0.1));
|
||||
EXPECT_EQ(2, q.Quantize(0.13));
|
||||
EXPECT_EQ(3, q.Quantize(0.3));
|
||||
EXPECT_EQ(3, q.Quantize(0.33));
|
||||
EXPECT_EQ(3, q.Quantize(1000.0));
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "test_utils.h"
|
||||
#include "silence_remover.h"
|
||||
#include "audio_buffer.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(SilenceRemover, PassThrough)
|
||||
{
|
||||
short samples[] = { 1, 2, 3, 4, 5, 6 };
|
||||
vector<short> data(samples, samples + 6);
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<SilenceRemover> processor(new SilenceRemover(buffer.get()));
|
||||
processor->Reset(44100, 1);
|
||||
processor->Consume(&data[0], data.size());
|
||||
processor->Flush();
|
||||
|
||||
ASSERT_EQ(data.size(), buffer->data().size());
|
||||
for (size_t i = 0; i < data.size(); i++) {
|
||||
ASSERT_EQ(data[i], buffer->data()[i]) << "Signals differ at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SilenceRemover, RemoveLeadingSilence)
|
||||
{
|
||||
short samples1[] = { 0, 0, 1, 2, 0, 4, 5, 0 };
|
||||
vector<short> data1(samples1, samples1 + 8);
|
||||
|
||||
short samples2[] = { 1, 2, 0, 4, 5, 0 };
|
||||
vector<short> data2(samples2, samples2 + 6);
|
||||
|
||||
boost::scoped_ptr<AudioBuffer> buffer(new AudioBuffer());
|
||||
boost::scoped_ptr<SilenceRemover> processor(new SilenceRemover(buffer.get()));
|
||||
processor->Reset(44100, 1);
|
||||
processor->Consume(&data1[0], data1.size());
|
||||
processor->Flush();
|
||||
|
||||
ASSERT_EQ(data2.size(), buffer->data().size());
|
||||
for (size_t i = 0; i < data2.size(); i++) {
|
||||
ASSERT_EQ(data2[i], buffer->data()[i]) << "Signals differ at index " << i;
|
||||
}
|
||||
}
|
91
3rdparty/chromaprint/tests/test_utils.cpp
vendored
91
3rdparty/chromaprint/tests/test_utils.cpp
vendored
@ -1,91 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
|
||||
TEST(Utils, PrepareHammingWindow) {
|
||||
double window_ex[10] = { 0.08, 0.187619556165, 0.460121838273, 0.77, 0.972258605562, 0.972258605562, 0.77, 0.460121838273, 0.187619556165, 0.08};
|
||||
double window[10];
|
||||
PrepareHammingWindow(window, window + 10);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
EXPECT_FLOAT_EQ(window_ex[i], window[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Utils, ApplyWindow1) {
|
||||
double window_ex[10] = { 0.08, 0.187619556165, 0.460121838273, 0.77, 0.972258605562, 0.972258605562, 0.77, 0.460121838273, 0.187619556165, 0.08};
|
||||
double window[10];
|
||||
short input[10];
|
||||
double output[10];
|
||||
PrepareHammingWindow(window, window + 10);
|
||||
fill(input, input + 10, numeric_limits<short>::max());
|
||||
double scale = 1.0 / numeric_limits<short>::max();
|
||||
ApplyWindow(input, window, output, 10, scale);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
EXPECT_FLOAT_EQ(window_ex[i], output[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Utils, ApplyWindow2) {
|
||||
double window[10];
|
||||
short input[10];
|
||||
double output[10];
|
||||
PrepareHammingWindow(window, window + 10);
|
||||
fill(input, input + 10, 0);
|
||||
double scale = 1.0 / numeric_limits<short>::max();
|
||||
ApplyWindow(input, window, output, 10, scale);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
EXPECT_FLOAT_EQ(0.0, output[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Utils, Sum) {
|
||||
double data[] = { 0.1, 0.2, 0.4, 1.0 };
|
||||
EXPECT_FLOAT_EQ(1.7, Sum(data, data + 4));
|
||||
}
|
||||
|
||||
TEST(Utils, EuclideanNorm) {
|
||||
double data[] = { 0.1, 0.2, 0.4, 1.0 };
|
||||
EXPECT_FLOAT_EQ(1.1, EuclideanNorm(data, data + 4));
|
||||
}
|
||||
|
||||
TEST(Utils, NormalizeVector) {
|
||||
double data[] = { 0.1, 0.2, 0.4, 1.0 };
|
||||
double normalized_data[] = { 0.090909, 0.181818, 0.363636, 0.909091 };
|
||||
NormalizeVector(data, data + 4, EuclideanNorm<double *>, 0.01);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EXPECT_NEAR(normalized_data[i], data[i], 1e-5) << "Wrong data at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Utils, NormalizeVectorNearZero) {
|
||||
double data[] = { 0.0, 0.001, 0.002, 0.003 };
|
||||
NormalizeVector(data, data + 4, EuclideanNorm<double *>, 0.01);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EXPECT_FLOAT_EQ(0.0, data[i]) << "Wrong data at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Utils, NormalizeVectorZero) {
|
||||
double data[] = { 0.0, 0.0, 0.0, 0.0 };
|
||||
NormalizeVector(data, data + 4, EuclideanNorm<double *>, 0.01);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EXPECT_FLOAT_EQ(0.0, data[i]) << "Wrong data at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Utils, UnsignedToSigned) {
|
||||
EXPECT_EQ(numeric_limits<int32_t>::max(), UnsignedToSigned(0x7FFFFFFFU));
|
||||
EXPECT_EQ(-1, UnsignedToSigned(0xFFFFFFFFU));
|
||||
EXPECT_EQ(-2, UnsignedToSigned(0xFFFFFFFEU));
|
||||
EXPECT_EQ(numeric_limits<int32_t>::min(), UnsignedToSigned(0x80000000U));
|
||||
EXPECT_EQ(numeric_limits<int32_t>::min() + 1, UnsignedToSigned(0x80000001U));
|
||||
}
|
||||
|
||||
TEST(Utils, IsNaN) {
|
||||
EXPECT_FALSE(IsNaN(0.0));
|
||||
EXPECT_TRUE(IsNaN(sqrt(-1.0)));
|
||||
}
|
42
3rdparty/chromaprint/tests/test_utils.h
vendored
42
3rdparty/chromaprint/tests/test_utils.h
vendored
@ -1,42 +0,0 @@
|
||||
#ifndef CHROMAPRINT_TESTS_UTILS_H_
|
||||
#define CHROMAPRINT_TESTS_UTILS_H_
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
inline void CheckString(std::string actual, char *expected, int expected_size)
|
||||
{
|
||||
ASSERT_EQ(expected_size, actual.size());
|
||||
for (int i = 0; i < expected_size; i++) {
|
||||
EXPECT_EQ(expected[i], actual[i]) << "Different at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CheckFingerprints(std::vector<int32_t> actual, int32_t *expected, int expected_size)
|
||||
{
|
||||
ASSERT_EQ(expected_size, actual.size());
|
||||
for (int i = 0; i < expected_size; i++) {
|
||||
EXPECT_EQ(expected[i], actual[i]) << "Different at index " << i;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::vector<short> LoadAudioFile(const std::string &file_name)
|
||||
{
|
||||
std::string path = TESTS_DIR + file_name;
|
||||
std::ifstream file(path.c_str(), std::ifstream::in);
|
||||
file.seekg(0, std::ios::end);
|
||||
int length = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
std::vector<short> data(length / 2);
|
||||
file.read((char *)&data[0], length);
|
||||
file.close();
|
||||
return data;
|
||||
}
|
||||
|
||||
#endif
|
63
3rdparty/chromaprint/tools/CMakeLists.txt
vendored
63
3rdparty/chromaprint/tools/CMakeLists.txt
vendored
@ -1,63 +0,0 @@
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
|
||||
${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
|
||||
${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${TAGLIB_INCLUDES}
|
||||
)
|
||||
|
||||
if(BUILD_EXTRA_TOOLS)
|
||||
|
||||
add_executable(resample resample.cpp)
|
||||
target_link_libraries(resample chromaprint_p
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES})
|
||||
|
||||
add_executable(decode decode.cpp)
|
||||
target_link_libraries(decode chromaprint_p
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES})
|
||||
|
||||
add_executable(chromagram chromagram.cpp)
|
||||
target_link_libraries(chromagram chromaprint_p
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES}
|
||||
-lpng)
|
||||
|
||||
add_executable(spectrogram spectrogram.cpp)
|
||||
target_link_libraries(spectrogram chromaprint_p
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES}
|
||||
-lpng)
|
||||
|
||||
add_executable(learn_filters learn_filters.cpp)
|
||||
target_link_libraries(learn_filters chromaprint_p
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY})
|
||||
|
||||
add_executable(fpeval fpeval.cpp)
|
||||
target_link_libraries(fpeval chromaprint_p
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY})
|
||||
|
||||
endif(BUILD_EXTRA_TOOLS)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_executable(fpcollect fpcollect.cpp)
|
||||
target_link_libraries(fpcollect chromaprint_p
|
||||
${FFMPEG_LIBAVFORMAT_LIBRARIES}
|
||||
${FFMPEG_LIBAVCODEC_LIBRARIES}
|
||||
${FFMPEG_LIBAVUTIL_LIBRARIES}
|
||||
${TAGLIB_LIBRARIES})
|
||||
endif()
|
65
3rdparty/chromaprint/tools/chromagram.cpp
vendored
65
3rdparty/chromaprint/tools/chromagram.cpp
vendored
@ -1,65 +0,0 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ext/ffmpeg_decoder.h"
|
||||
#include "ext/audio_dumper.h"
|
||||
#include "audio_processor.h"
|
||||
#include "chroma.h"
|
||||
#include "spectral_centroid.h"
|
||||
#include "chroma_normalizer.h"
|
||||
#include "chroma_resampler.h"
|
||||
#include "chroma_filter.h"
|
||||
#include "fft.h"
|
||||
#include "audio_processor.h"
|
||||
#include "image.h"
|
||||
#include "image_builder.h"
|
||||
#include "utils.h"
|
||||
#include "ext/image_utils.h"
|
||||
|
||||
static const int SAMPLE_RATE = 11025;
|
||||
static const int FRAME_SIZE = 4096;
|
||||
static const int OVERLAP = FRAME_SIZE - FRAME_SIZE / 3;// 2720;
|
||||
static const int MIN_FREQ = 28;
|
||||
static const int MAX_FREQ = 3520;
|
||||
static const int MAX_FILTER_WIDTH = 20;
|
||||
|
||||
static const int kChromaFilterSize = 5;
|
||||
static const double kChromaFilterCoefficients[] = { 0.25, 0.75, 1.0, 0.75, 0.25 };
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
cerr << "Usage: " << argv[0] << " AUDIOFILE IMAGEFILE\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
string file_name(argv[1]);
|
||||
cout << "Loading file " << file_name << "\n";
|
||||
|
||||
Decoder decoder(file_name);
|
||||
if (!decoder.Open()) {
|
||||
cerr << "ERROR: " << decoder.LastError() << "\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
Chromaprint::Image image(12);
|
||||
Chromaprint::ImageBuilder image_builder(&image);
|
||||
Chromaprint::ChromaNormalizer chroma_normalizer(&image_builder);
|
||||
Chromaprint::ChromaFilter chroma_filter(kChromaFilterCoefficients, kChromaFilterSize, &chroma_normalizer);
|
||||
//Chromaprint::Chroma chroma(MIN_FREQ, MAX_FREQ, FRAME_SIZE, SAMPLE_RATE, &chroma_normalizer);
|
||||
Chromaprint::Chroma chroma(MIN_FREQ, MAX_FREQ, FRAME_SIZE, SAMPLE_RATE, &chroma_filter);
|
||||
Chromaprint::FFT fft(FRAME_SIZE, OVERLAP, &chroma);
|
||||
Chromaprint::AudioProcessor processor(SAMPLE_RATE, &fft);
|
||||
|
||||
processor.Reset(decoder.SampleRate(), decoder.Channels());
|
||||
decoder.Decode(&processor);
|
||||
processor.Flush();
|
||||
|
||||
//Chromaprint::ExportTextImage(&image, argv[2]);
|
||||
Chromaprint::ExportImage(&image, argv[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
28
3rdparty/chromaprint/tools/decode.cpp
vendored
28
3rdparty/chromaprint/tools/decode.cpp
vendored
@ -1,28 +0,0 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ext/ffmpeg_decoder.h"
|
||||
#include "ext/audio_dumper.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
cerr << "Usage: " << argv[0] << " FILENAME\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
string file_name(argv[1]);
|
||||
Decoder decoder(file_name);
|
||||
if (!decoder.Open()) {
|
||||
cerr << "ERROR: " << decoder.LastError() << "\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
AudioDumper dumper(argv[2]);
|
||||
decoder.Decode(&dumper);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
76
3rdparty/chromaprint/tools/fillpuid.py
vendored
76
3rdparty/chromaprint/tools/fillpuid.py
vendored
@ -1,76 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import time
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
import os.path
|
||||
from xml.etree import ElementTree
|
||||
|
||||
|
||||
usage = "usage: %prog [options] logfile"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-a", "--musicdns-apikey", dest="musicdns_api_key", metavar="KEY",
|
||||
help="MusicDNS API key")
|
||||
parser.add_option("-g", "--genpuid", dest="genpuid_path", metavar="PATH",
|
||||
help="path to the GenPUID binary", default="genpuid")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
parser.error("no log file specified")
|
||||
|
||||
|
||||
def read_log_file(input):
|
||||
group = {}
|
||||
for line in input:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
if group:
|
||||
yield group
|
||||
group = {}
|
||||
continue
|
||||
name, value = line.split('=', 1)
|
||||
group[name] = value
|
||||
if group:
|
||||
yield group
|
||||
|
||||
|
||||
def make_groups(input, size=10):
|
||||
group = []
|
||||
for entry in input:
|
||||
group.append(entry)
|
||||
if len(group) >= size:
|
||||
yield group
|
||||
group = []
|
||||
if group:
|
||||
yield group
|
||||
|
||||
|
||||
|
||||
def write_log_file(entry):
|
||||
for row in entry.iteritems():
|
||||
print '%s=%s' % row
|
||||
print
|
||||
|
||||
|
||||
def call_genpuid(entries):
|
||||
paths = [e['FILENAME'] for e in entries]
|
||||
process = subprocess.Popen([options.genpuid_path, options.musicdns_api_key, '-xml'] + paths, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out, err = process.communicate()
|
||||
tree = ElementTree.fromstring('<?xml version="1.0" encoding="iso-8859-1"?>' + out)
|
||||
puids = {}
|
||||
for track in tree.findall("track"):
|
||||
if 'puid' in track.attrib and 'file' in track.attrib:
|
||||
puids[os.path.normpath(track.attrib['file']).encode('iso-8859-1')] = track.attrib['puid']
|
||||
for entry in entries:
|
||||
path = os.path.normpath(entry['FILENAME'])
|
||||
if path in puids:
|
||||
entry['PUID'] = puids[path]
|
||||
|
||||
|
||||
for entries in make_groups(read_log_file(open(args[0]) if args[0] != '-' else sys.stdin), 20):
|
||||
call_genpuid([e for e in entries if 'MBID' not in e])
|
||||
for entry in entries:
|
||||
print >>sys.stderr, entry['FILENAME']
|
||||
write_log_file(entry)
|
||||
|
323
3rdparty/chromaprint/tools/fpcollect.cpp
vendored
323
3rdparty/chromaprint/tools/fpcollect.cpp
vendored
@ -1,323 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
//#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <fileref.h>
|
||||
#include <tag.h>
|
||||
#include "chromaprint.h"
|
||||
#include "fingerprinter.h"
|
||||
#include "fingerprinter_configuration.h"
|
||||
#include "fingerprint_compressor.h"
|
||||
#include "base64.h"
|
||||
#include "ext/ffmpeg_decoder.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const int kChromaprintAlgorithm = CHROMAPRINT_ALGORITHM_DEFAULT;
|
||||
|
||||
typedef vector<string> string_vector;
|
||||
|
||||
void FindFiles(const string &dirname, string_vector *result, time_t changed_since)
|
||||
{
|
||||
DIR *dirp = opendir(dirname.c_str());
|
||||
if (!dirp) {
|
||||
if (errno == ENOTDIR) {
|
||||
result->push_back(dirname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
while (dirp) {
|
||||
struct dirent *dp;
|
||||
if ((dp = readdir(dirp)) != NULL) {
|
||||
struct stat sp;
|
||||
string filename = dirname + '/' + string(dp->d_name);
|
||||
stat(filename.c_str(), &sp);
|
||||
if (S_ISREG(sp.st_mode)) {
|
||||
//cerr << "file " << filename << " mtime=" << sp.st_mtime << " ch=" << changed_since << "\n";
|
||||
if (!changed_since || sp.st_mtime >= changed_since) {
|
||||
result->push_back(filename);
|
||||
}
|
||||
}
|
||||
if (S_ISDIR(sp.st_mode) && dp->d_name[0] != '.') {
|
||||
FindFiles(filename, result, changed_since);
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
string_vector FindFiles(const string_vector &files, time_t changed_since)
|
||||
{
|
||||
string_vector result;
|
||||
for (size_t i = 0; i < files.size(); i++) {
|
||||
FindFiles(files[i], &result, changed_since);
|
||||
}
|
||||
sort(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DISPATCH_TAGLIB_FILE(type, file) \
|
||||
{ \
|
||||
type *tmp = dynamic_cast<type *>(file); \
|
||||
if (tmp) { \
|
||||
return ExtractMBIDFromFile(tmp); \
|
||||
} \
|
||||
}
|
||||
|
||||
#include <xiphcomment.h>
|
||||
#include <apetag.h>
|
||||
#include <vorbisfile.h>
|
||||
#include <oggflacfile.h>
|
||||
#include <speexfile.h>
|
||||
#include <flacfile.h>
|
||||
#include <mpcfile.h>
|
||||
#include <wavpackfile.h>
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
#include <asffile.h>
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
#include <mp4file.h>
|
||||
#endif
|
||||
#include <mpegfile.h>
|
||||
#include <id3v2tag.h>
|
||||
#include <uniquefileidentifierframe.h>
|
||||
|
||||
string ExtractMBIDFromXiphComment(TagLib::Ogg::XiphComment *tag)
|
||||
{
|
||||
string key = "MUSICBRAINZ_TRACKID";
|
||||
if (tag && tag->fieldListMap().contains(key)) {
|
||||
return tag->fieldListMap()[key].front().to8Bit(true);
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
string ExtractMBIDFromAPETag(TagLib::APE::Tag *tag)
|
||||
{
|
||||
string key = "MUSICBRAINZ_TRACKID";
|
||||
if (tag && tag->itemListMap().contains(key)) {
|
||||
return tag->itemListMap()[key].toString().to8Bit(true);
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
string ExtractMBIDFromFile(TagLib::Ogg::Vorbis::File *file)
|
||||
{
|
||||
return ExtractMBIDFromXiphComment(file->tag());
|
||||
}
|
||||
|
||||
string ExtractMBIDFromFile(TagLib::Ogg::FLAC::File *file)
|
||||
{
|
||||
return ExtractMBIDFromXiphComment(file->tag());
|
||||
}
|
||||
|
||||
string ExtractMBIDFromFile(TagLib::Ogg::Speex::File *file)
|
||||
{
|
||||
return ExtractMBIDFromXiphComment(file->tag());
|
||||
}
|
||||
|
||||
string ExtractMBIDFromFile(TagLib::FLAC::File *file)
|
||||
{
|
||||
return ExtractMBIDFromXiphComment(file->xiphComment());
|
||||
}
|
||||
|
||||
string ExtractMBIDFromFile(TagLib::MPC::File *file)
|
||||
{
|
||||
return ExtractMBIDFromAPETag(file->APETag());
|
||||
}
|
||||
|
||||
string ExtractMBIDFromFile(TagLib::WavPack::File *file)
|
||||
{
|
||||
return ExtractMBIDFromAPETag(file->APETag());
|
||||
}
|
||||
|
||||
/*string ExtractMBIDFromFile(TagLib::APE::File *file)
|
||||
{
|
||||
return ExtractMBIDFromAPETag(file->APETag());
|
||||
}*/
|
||||
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
string ExtractMBIDFromFile(TagLib::ASF::File *file)
|
||||
{
|
||||
string key = "MusicBrainz/Track Id";
|
||||
TagLib::ASF::Tag *tag = file->tag();
|
||||
if (tag && tag->attributeListMap().contains(key)) {
|
||||
return tag->attributeListMap()[key].front().toString().to8Bit(true);
|
||||
}
|
||||
return string();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
string ExtractMBIDFromFile(TagLib::MP4::File *file)
|
||||
{
|
||||
string key = "----:com.apple.iTunes:MusicBrainz Track Id";
|
||||
TagLib::MP4::Tag *tag = file->tag();
|
||||
if (tag && tag->itemListMap().contains(key)) {
|
||||
return tag->itemListMap()[key].toStringList().toString().to8Bit(true);
|
||||
}
|
||||
return string();
|
||||
}
|
||||
#endif
|
||||
|
||||
string ExtractMBIDFromFile(TagLib::MPEG::File *file)
|
||||
{
|
||||
TagLib::ID3v2::Tag *tag = file->ID3v2Tag();
|
||||
if (!tag) {
|
||||
return string();
|
||||
}
|
||||
TagLib::ID3v2::FrameList ufid = tag->frameListMap()["UFID"];
|
||||
if (!ufid.isEmpty()) {
|
||||
for (TagLib::ID3v2::FrameList::Iterator i = ufid.begin(); i != ufid.end(); i++) {
|
||||
TagLib::ID3v2::UniqueFileIdentifierFrame *frame = dynamic_cast<TagLib::ID3v2::UniqueFileIdentifierFrame *>(*i);
|
||||
if (frame && frame->owner() == "http://musicbrainz.org") {
|
||||
TagLib::ByteVector id = frame->identifier();
|
||||
return string(id.data(), id.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
string ExtractMusicBrainzTrackID(TagLib::File *file)
|
||||
{
|
||||
DISPATCH_TAGLIB_FILE(TagLib::FLAC::File, file);
|
||||
DISPATCH_TAGLIB_FILE(TagLib::Ogg::Vorbis::File, file);
|
||||
DISPATCH_TAGLIB_FILE(TagLib::Ogg::FLAC::File, file);
|
||||
DISPATCH_TAGLIB_FILE(TagLib::Ogg::Speex::File, file);
|
||||
DISPATCH_TAGLIB_FILE(TagLib::MPC::File, file);
|
||||
DISPATCH_TAGLIB_FILE(TagLib::WavPack::File, file);
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
DISPATCH_TAGLIB_FILE(TagLib::ASF::File, file);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
DISPATCH_TAGLIB_FILE(TagLib::MP4::File, file);
|
||||
#endif
|
||||
DISPATCH_TAGLIB_FILE(TagLib::MPEG::File, file);
|
||||
return string();
|
||||
}
|
||||
|
||||
bool ReadTags(const string &filename, bool ignore_missing_mbid)
|
||||
{
|
||||
TagLib::FileRef file(filename.c_str(), true);
|
||||
if (file.isNull())
|
||||
return false;
|
||||
TagLib::Tag *tags = file.tag();
|
||||
TagLib::AudioProperties *props = file.audioProperties();
|
||||
if (!tags || !props)
|
||||
return false;
|
||||
//cout << "ARTIST=" << tags->artist().to8Bit(true) << "\n";
|
||||
//cout << "TITLE=" << tags->title().to8Bit(true) << "\n";
|
||||
//cout << "ALBUM=" << tags->album().to8Bit(true) << "\n";
|
||||
int length = props->length();
|
||||
if (!length)
|
||||
return false;
|
||||
string mbid = ExtractMusicBrainzTrackID(file.file());
|
||||
if (mbid.size() != 36 && !ignore_missing_mbid)
|
||||
return false;
|
||||
if (mbid.size() == 36)
|
||||
cout << "MBID=" << mbid << "\n";
|
||||
cout << "LENGTH=" << length << "\n";
|
||||
cout << "BITRATE=" << props->bitrate() << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
string ExtractExtension(const string &filename)
|
||||
{
|
||||
size_t pos = filename.find_last_of('.');
|
||||
if (pos == string::npos) {
|
||||
return string();
|
||||
}
|
||||
return boost::to_upper_copy(filename.substr(pos + 1));
|
||||
}
|
||||
|
||||
string EncodeFingerprint(const vector<uint32_t> &fp)
|
||||
{
|
||||
string res;
|
||||
res.resize(fp.size());
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ProcessFile(Chromaprint::Fingerprinter *fingerprinter, const string &filename, bool ignore_missing_mbid, int audio_length)
|
||||
{
|
||||
if (!ReadTags(filename, ignore_missing_mbid))
|
||||
return false;
|
||||
Decoder decoder(filename);
|
||||
if (!decoder.Open())
|
||||
return false;
|
||||
if (!fingerprinter->Start(decoder.SampleRate(), decoder.Channels()))
|
||||
return false;
|
||||
cerr << filename << "\n";
|
||||
cout << "FILENAME=" << filename << "\n";
|
||||
cout << "FORMAT=" << ExtractExtension(filename) << "\n";
|
||||
decoder.Decode(fingerprinter, audio_length);
|
||||
vector<int32_t> fp = fingerprinter->Finish();
|
||||
/*cout << "FINGERPRINT1=";
|
||||
for (int i = 0; i < fp.size(); i++) {
|
||||
cout << fp[i] << ", ";
|
||||
}
|
||||
cout << "\n";*/
|
||||
cout << "FINGERPRINT=" << Chromaprint::Base64Encode(Chromaprint::CompressFingerprint(fp, kChromaprintAlgorithm)) << "\n\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
cerr << "Usage: " << argv[0] << " [OPTIONS] FILE...\n";
|
||||
cerr << "Options:\n";
|
||||
cerr << " -nombid Do not require a MBID embedded in the file\n";
|
||||
cerr << " -since DATE Process only files modified since the given date\n";
|
||||
cerr << " -length SECONDS Length of the audio data used for fingerprinting (default 120)\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
string_vector files;
|
||||
char *changed_since_str = NULL;
|
||||
int audio_length = 120;
|
||||
bool ignore_missing_mbid = false;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-nombid") == 0) {
|
||||
ignore_missing_mbid = true;
|
||||
}
|
||||
else if (strcmp(argv[i], "-since") == 0 && i + 1 < argc) {
|
||||
changed_since_str = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-length") == 0 && i + 1 < argc) {
|
||||
audio_length = atoi(argv[++i]);
|
||||
}
|
||||
else {
|
||||
files.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
time_t changed_since = 0;
|
||||
if (changed_since_str) {
|
||||
struct tm tm;
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
if (strptime(changed_since_str, "%Y-%m-%d %H:%M", &tm) == NULL) {
|
||||
if (strptime(changed_since_str, "%Y-%m-%d", &tm) == NULL) {
|
||||
cerr << "ERROR: Invalid date, the expected format is 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM'\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
tm.tm_isdst = -1;
|
||||
changed_since = mktime(&tm);
|
||||
//cerr << "Calculating fingerprints for files in " << files << " that were changed since " << changed_since_str << "\n";
|
||||
}
|
||||
else {
|
||||
//cerr << "Calculating fingerprints for all files in " << files << "\n";
|
||||
}
|
||||
|
||||
Chromaprint::Fingerprinter fingerprinter(Chromaprint::CreateFingerprinterConfiguration(kChromaprintAlgorithm));
|
||||
files = FindFiles(files, changed_since);
|
||||
for (string_vector::iterator it = files.begin(); it != files.end(); it++) {
|
||||
ProcessFile(&fingerprinter, *it, ignore_missing_mbid, audio_length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
142
3rdparty/chromaprint/tools/fpeval.cpp
vendored
142
3rdparty/chromaprint/tools/fpeval.cpp
vendored
@ -1,142 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include <boost/multi_array.hpp>
|
||||
#include "ext/ffmpeg_decoder.h"
|
||||
#include "ext/image_utils.h"
|
||||
#include "audio_processor.h"
|
||||
#include "fingerprinter.h"
|
||||
#include "image.h"
|
||||
#include "integral_image.h"
|
||||
#include "image_builder.h"
|
||||
#include "utils.h"
|
||||
#include "filter.h"
|
||||
#include "lloyds.h"
|
||||
#include "classifier.h"
|
||||
#include "match.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
typedef vector<string> string_vector;
|
||||
typedef vector<double> double_vector;
|
||||
|
||||
string_vector FindAudioFiles(const char *dirname)
|
||||
{
|
||||
string_vector result;
|
||||
fs::path path(dirname);
|
||||
fs::directory_iterator end_iter;
|
||||
for (fs::directory_iterator dir_iter(path); dir_iter != end_iter; ++dir_iter) {
|
||||
if (fs::is_regular_file(dir_iter->status())) {
|
||||
string filename = dir_iter->path().string();
|
||||
if (boost::ends_with(filename, ".mp3") || boost::ends_with(filename, ".wav")) {
|
||||
result.push_back(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
sort(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<string_vector> GenerateFilePairs(const vector<string> &files)
|
||||
{
|
||||
string last_name;
|
||||
vector<string_vector> result;
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
string name = fs::basename(files[i]);
|
||||
name = name.substr(0, name.find_first_of('-'));
|
||||
if (last_name != name) {
|
||||
result.push_back(string_vector());
|
||||
last_name = name;
|
||||
}
|
||||
result.back().push_back(files[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<int> MultiMapValues(const multimap<int, int> &data, const int &key)
|
||||
{
|
||||
pair<multimap<int, int>::const_iterator, multimap<int, int>::const_iterator> range = data.equal_range(key);
|
||||
vector<int> result;
|
||||
for (multimap<int, int>::const_iterator i = range.first; i != range.second; ++i) {
|
||||
result.push_back((*i).second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const int SAMPLE_RATE = 11025;
|
||||
static const int FRAME_SIZE = 4096;
|
||||
static const int OVERLAP = FRAME_SIZE - FRAME_SIZE / 3;// 2720;
|
||||
static const int MIN_FREQ = 28;
|
||||
static const int MAX_FREQ = 3520;
|
||||
static const int MAX_FILTER_WIDTH = 16;
|
||||
/*static const int OVERLAP = FRAME_SIZE - FRAME_SIZE / 2;// 2720;
|
||||
static const int MIN_FREQ = 300;
|
||||
static const int MAX_FREQ = 5300;
|
||||
static const int MAX_FILTER_WIDTH = 20;*/
|
||||
|
||||
void PrintRate(const std::string &name, const std::vector<int> &values, int scale)
|
||||
{
|
||||
cout << name << " = [";
|
||||
for (int j = 0; j < 32; j++) {
|
||||
double rate = double(values[j]) / scale;
|
||||
if (j != 0) std::cout << ", ";
|
||||
std::cout << rate;
|
||||
}
|
||||
cout << "]\n";
|
||||
}
|
||||
|
||||
#define FP_TYPE_CHROMA 1
|
||||
#define FP_TYPE_CENTROID 2
|
||||
#define FP_TYPE FP_TYPE_CHROMA
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Chromaprint::Fingerprinter fingerprinter;
|
||||
|
||||
vector<string> files = FindAudioFiles(argv[1]);
|
||||
vector< string > names[2];
|
||||
vector< vector<int32_t> > fingerprints[2];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
cout << " - " << files[i] << "\n";
|
||||
Decoder decoder(files[i]);
|
||||
if (!decoder.Open()) {
|
||||
cerr << "ERROR: " << decoder.LastError() << "\n";
|
||||
return 1;
|
||||
}
|
||||
fingerprinter.Start(decoder.SampleRate(), decoder.Channels());
|
||||
decoder.Decode(&fingerprinter, 60);
|
||||
vector<int32_t> fp = fingerprinter.Finish();
|
||||
int orig = files[i].find("orig") != string::npos ? 1 : 0;
|
||||
fingerprints[orig].push_back(fp);
|
||||
names[orig].push_back(files[i]);
|
||||
}
|
||||
int num_files = files.size() / 2;
|
||||
|
||||
typedef boost::multi_array<float, 2> DoubleArray2D;
|
||||
|
||||
float total = 0.0f, diagonal = 0.0f;
|
||||
DoubleArray2D confmatrix(boost::extents[num_files][num_files]);
|
||||
for (int i = 0; i < num_files; i++) {
|
||||
for (int j = 0; j < num_files; j++) {
|
||||
float score = match_fingerprints(fingerprints[0][i], fingerprints[1][j]);
|
||||
cout << " - " << names[0][i] << " / " << names[1][j] << " = " << score <<"\n";
|
||||
confmatrix[i][j] = score;
|
||||
if (i == j) {
|
||||
diagonal += score;
|
||||
}
|
||||
total += score;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "true positive: " << diagonal / num_files << "\n";
|
||||
cout << "false positive: " << (total - diagonal) / (num_files * num_files - num_files) << "\n";
|
||||
cout << "score: " << diagonal / total << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
121
3rdparty/chromaprint/tools/fpsubmit.py
vendored
121
3rdparty/chromaprint/tools/fpsubmit.py
vendored
@ -1,121 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import time
|
||||
import sys
|
||||
import urllib2
|
||||
import urllib
|
||||
import gzip
|
||||
import socket
|
||||
from cStringIO import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
usage = "usage: %prog [options] logfile"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-a", "--api-key", dest="api_key", metavar="KEY",
|
||||
help="your Acoustid API key (http://acoustid.org/api-key)")
|
||||
parser.add_option("-b", "--batch-size", dest="batch_size", type="int",
|
||||
default=50, metavar="SIZE",
|
||||
help="how many fingerprints to submit in one request [default: %default]")
|
||||
parser.add_option("--app-url", dest="app_url", type="string",
|
||||
default='http://api.acoustid.org/submit',
|
||||
help="how many fingerprints to submit in one request [default: %default]")
|
||||
parser.add_option("--app-api-key", dest="app_api_key", type="string", default='5hOby2eZ',
|
||||
help="application API key (needed only if you submit to a non-default URL)")
|
||||
parser.add_option("-s", "--start", dest="start", type="int",
|
||||
default=1, metavar="SIZE",
|
||||
help="start with the Nth entry from the log file [default: %default]")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if not options.api_key:
|
||||
parser.error("no API key specified")
|
||||
if len(args) != 1:
|
||||
parser.error("no log file specified")
|
||||
|
||||
|
||||
USER_API_KEY = options.api_key
|
||||
CLIENT_API_KEY = options.app_api_key
|
||||
API_URL = options.app_url
|
||||
BATCH_SIZE = options.batch_size
|
||||
|
||||
|
||||
def read_log_file(input):
|
||||
group = {}
|
||||
for line in input:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
if group:
|
||||
yield group
|
||||
group = {}
|
||||
continue
|
||||
name, value = line.split('=', 1)
|
||||
group[name] = value
|
||||
if group:
|
||||
yield group
|
||||
|
||||
|
||||
def encode_params(data):
|
||||
encoded_body = StringIO()
|
||||
encoded_file = gzip.GzipFile(mode='w', fileobj=encoded_body)
|
||||
encoded_file.write(urllib.urlencode(data))
|
||||
encoded_file.close()
|
||||
return encoded_body.getvalue()
|
||||
|
||||
|
||||
def submit_data(i, entries):
|
||||
if not entries:
|
||||
return True
|
||||
params = { 'user': USER_API_KEY, 'client': CLIENT_API_KEY }
|
||||
print 'Submitting... (entries from %d to %d)' % (i, i + len(entries) - 1)
|
||||
i = 0
|
||||
for entry in [e for e in entries if e['LENGTH'] >= 40 and len(e['FINGERPRINT'])>100]:
|
||||
if 'MBID' not in entry and 'PUID' not in entry or int(entry.get('LENGTH', '0')) <= 0:
|
||||
continue
|
||||
if 'MBID' in entry:
|
||||
print ' MBID ', entry['MBID'], entry['FINGERPRINT'][:20] + '...'
|
||||
for mbid in entry['MBID'].split(','):
|
||||
params['mbid.%d' % i] = mbid
|
||||
if 'PUID' in entry:
|
||||
print ' PUID ', entry['PUID'], entry['FINGERPRINT'][:20] + '...'
|
||||
params['puid.%d' % i] = entry['PUID']
|
||||
params['fingerprint.%d' % i] = entry['FINGERPRINT']
|
||||
params['length.%d' % i] = entry['LENGTH']
|
||||
if 'BITRATE' in entry:
|
||||
params['bitrate.%d' % i] = entry['BITRATE']
|
||||
if 'FORMAT' in entry:
|
||||
params['format.%d' % i] = entry['FORMAT']
|
||||
i += 1
|
||||
data = encode_params(params)
|
||||
request = urllib2.Request(API_URL, data, headers={'Content-Encoding': 'gzip'})
|
||||
try:
|
||||
urllib2.urlopen(request)
|
||||
except urllib2.HTTPError, e:
|
||||
print e
|
||||
for line in e.readlines():
|
||||
print line.rstrip()
|
||||
return False
|
||||
except urllib2.URLError, e:
|
||||
print e
|
||||
return False
|
||||
except socket.error, e:
|
||||
print e
|
||||
return False
|
||||
print 'OK'
|
||||
return True
|
||||
|
||||
|
||||
batch = []
|
||||
i = options.start
|
||||
j = 0
|
||||
for entry in read_log_file(open(args[0]) if args[0] != '-' else sys.stdin):
|
||||
j += 1
|
||||
if j < options.start:
|
||||
continue
|
||||
batch.append(entry)
|
||||
if len(batch) >= BATCH_SIZE:
|
||||
submit_data(i, batch)
|
||||
i = j
|
||||
batch = []
|
||||
time.sleep(0.1)
|
||||
submit_data(i, batch)
|
||||
|
396
3rdparty/chromaprint/tools/learn_filters.cpp
vendored
396
3rdparty/chromaprint/tools/learn_filters.cpp
vendored
@ -1,396 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include "ext/ffmpeg_decoder.h"
|
||||
#include "ext/image_utils.h"
|
||||
#include "audio_processor.h"
|
||||
#include "chroma.h"
|
||||
#include "spectral_centroid.h"
|
||||
#include "chroma_normalizer.h"
|
||||
#include "chroma_resampler.h"
|
||||
#include "chroma_filter.h"
|
||||
#include "fft.h"
|
||||
#include "audio_processor.h"
|
||||
#include "image.h"
|
||||
#include "integral_image.h"
|
||||
#include "image_builder.h"
|
||||
#include "utils.h"
|
||||
#include "filter.h"
|
||||
#include "lloyds.h"
|
||||
#include "classifier.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Chromaprint;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
typedef vector<string> string_vector;
|
||||
typedef vector<double> double_vector;
|
||||
|
||||
string_vector FindAudioFiles(const char *dirname)
|
||||
{
|
||||
string_vector result;
|
||||
fs::path path(dirname);
|
||||
fs::directory_iterator end_iter;
|
||||
for (fs::directory_iterator dir_iter(path); dir_iter != end_iter; ++dir_iter) {
|
||||
if (fs::is_regular_file(dir_iter->status())) {
|
||||
string filename = dir_iter->path().string();
|
||||
if (boost::ends_with(filename, ".mp3") || boost::ends_with(filename, ".wma") || boost::ends_with(filename, ".wav")) {
|
||||
result.push_back(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
sort(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<string_vector> GenerateFilePairs(const vector<string> &files)
|
||||
{
|
||||
string last_name;
|
||||
vector<string_vector> result;
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
string name = fs::basename(files[i]);
|
||||
name = name.substr(0, name.find_first_of('-'));
|
||||
if (last_name != name) {
|
||||
result.push_back(string_vector());
|
||||
last_name = name;
|
||||
}
|
||||
result.back().push_back(files[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<int> MultiMapValues(const multimap<int, int> &data, const int &key)
|
||||
{
|
||||
pair<multimap<int, int>::const_iterator, multimap<int, int>::const_iterator> range = data.equal_range(key);
|
||||
vector<int> result;
|
||||
for (multimap<int, int>::const_iterator i = range.first; i != range.second; ++i) {
|
||||
result.push_back((*i).second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const int SAMPLE_RATE = 11025;
|
||||
static const int FRAME_SIZE = 4096;
|
||||
static const int OVERLAP = FRAME_SIZE - FRAME_SIZE / 3;// 2720;
|
||||
static const int MIN_FREQ = 28;
|
||||
static const int MAX_FREQ = 3520;
|
||||
static const int MAX_FILTER_WIDTH = 16;
|
||||
/*static const int OVERLAP = FRAME_SIZE - FRAME_SIZE / 2;// 2720;
|
||||
static const int MIN_FREQ = 300;
|
||||
static const int MAX_FREQ = 5300;
|
||||
static const int MAX_FILTER_WIDTH = 20;*/
|
||||
|
||||
static const int TRAINING_SET_SIZE = 60000;
|
||||
|
||||
void PrintRate(const std::string &name, const std::vector<int> &values, int scale)
|
||||
{
|
||||
cout << name << " = [";
|
||||
for (int j = 0; j < 32; j++) {
|
||||
double rate = double(values[j]) / scale;
|
||||
if (j != 0) std::cout << ", ";
|
||||
std::cout << rate;
|
||||
}
|
||||
cout << "]\n";
|
||||
}
|
||||
|
||||
#define FP_TYPE_CHROMA 1
|
||||
#define FP_TYPE_CENTROID 2
|
||||
#define FP_TYPE FP_TYPE_CHROMA
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Chromaprint::ImageBuilder image_builder;
|
||||
#if FP_TYPE == FP_TYPE_CHROMA
|
||||
Chromaprint::ChromaNormalizer chroma_normalizer(&image_builder);
|
||||
static const double kChromaFilterCoeffs[] = { 0.25, 0.75, 1.0, 0.75, 0.25 };
|
||||
Chromaprint::ChromaFilter chroma_filter(kChromaFilterCoeffs, 5, &chroma_normalizer);
|
||||
Chromaprint::Chroma chroma(MIN_FREQ, MAX_FREQ, FRAME_SIZE, SAMPLE_RATE, &chroma_filter);
|
||||
//chroma.set_interpolate(true);
|
||||
Chromaprint::FFT fft(FRAME_SIZE, OVERLAP, &chroma);
|
||||
#elif FP_TYPE == FP_TYPE_CHROMA
|
||||
Chromaprint::SpectralCentroid centroid(16, MIN_FREQ, MAX_FREQ, FRAME_SIZE, SAMPLE_RATE, &image_builder);
|
||||
Chromaprint::FFT fft(FRAME_SIZE, OVERLAP, ¢roid);
|
||||
#endif
|
||||
Chromaprint::AudioProcessor processor(SAMPLE_RATE, &fft);
|
||||
|
||||
cout << "Loading audio files\n";
|
||||
vector<string_vector> files = GenerateFilePairs(FindAudioFiles(argv[1]));
|
||||
vector<int> groups;
|
||||
multimap<int, int> reverse_groups;
|
||||
vector<Chromaprint::Image *> images;
|
||||
vector<Chromaprint::IntegralImage *> integral_images;
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
//cout << i << ".\n";
|
||||
for (int j = 0; j < files[i].size(); j++) {
|
||||
cout << " - " << files[i][j] << "\n";
|
||||
Decoder decoder(files[i][j]);
|
||||
if (!decoder.Open()) {
|
||||
cerr << "ERROR: " << decoder.LastError() << "\n";
|
||||
return 1;
|
||||
}
|
||||
#if FP_TYPE == FP_TYPE_CHROMA
|
||||
Image *image = new Image(12);
|
||||
#elif FP_TYPE == FP_TYPE_CENTROID
|
||||
Image *image = new Image(16);
|
||||
#endif
|
||||
processor.Reset(decoder.SampleRate(), decoder.Channels());
|
||||
fft.Reset();
|
||||
#if FP_TYPE == FP_TYPE_CHROMA
|
||||
chroma.Reset();
|
||||
chroma_filter.Reset();
|
||||
chroma_normalizer.Reset();
|
||||
#elif FP_TYPE == FP_TYPE_CENTROID
|
||||
centroid.Reset();
|
||||
#endif
|
||||
image_builder.Reset(image);
|
||||
decoder.Decode(&processor);
|
||||
processor.Flush();
|
||||
//ExportTextImage(image, files[i][j] + ".img.txt");
|
||||
//Chromaprint::ExportImage(image_builder.image(), files[i][j] + ".img.png");
|
||||
reverse_groups.insert(make_pair(i, images.size()));
|
||||
groups.push_back(i);
|
||||
images.push_back(image);
|
||||
IntegralImage *int_image = new IntegralImage(image) ;
|
||||
// ExportTextImage(int_image, files[i][j] + ".int_img.txt");
|
||||
integral_images.push_back(int_image);
|
||||
//ExportTextImage(int_image, files[i][j] + ".img.txt");
|
||||
// return 1;
|
||||
}
|
||||
cout << images.size() << "\r";
|
||||
cout.flush();
|
||||
}
|
||||
|
||||
cout << "Training data set:\n";
|
||||
cout << " - File groups: " << files.size() << "\n";
|
||||
cout << " - Files: " << images.size() << "\n";
|
||||
files.clear();
|
||||
|
||||
bool labels[TRAINING_SET_SIZE];
|
||||
int data1[TRAINING_SET_SIZE];
|
||||
int data2[TRAINING_SET_SIZE];
|
||||
int data1_pos[TRAINING_SET_SIZE];
|
||||
int data2_pos[TRAINING_SET_SIZE];
|
||||
|
||||
int i = 0;
|
||||
srand(3);
|
||||
// Find matching pairs
|
||||
for (; i < TRAINING_SET_SIZE / 2; i++) {
|
||||
int x1 = rand() % images.size();
|
||||
vector<int> group = MultiMapValues(reverse_groups, groups[x1]);
|
||||
int x2;
|
||||
do {
|
||||
x2 = group[rand() % group.size()];
|
||||
} while (x1 == x2);
|
||||
size_t min_length = min(images[x1]->NumRows(), images[x2]->NumRows());
|
||||
int pos = rand() % (min_length - 30);
|
||||
//cout << "+ " << x1 << " " << x2 << " - " << pos << "\n";
|
||||
data1[i] = x1;
|
||||
data2[i] = x2;
|
||||
data1_pos[i] = pos;
|
||||
data2_pos[i] = pos;
|
||||
labels[i] = true;
|
||||
}
|
||||
// Find non-matching pairs
|
||||
for (; i < TRAINING_SET_SIZE; i++) {
|
||||
int x2, x1 = rand() % images.size();
|
||||
int pos2, pos1 = rand() % (images[x1]->NumRows() - 30);
|
||||
vector<int> group = MultiMapValues(reverse_groups, groups[x1]);
|
||||
set<int> group_set(group.begin(), group.end());
|
||||
do {
|
||||
x2 = rand() % images.size();
|
||||
pos2 = rand() % (images[x2]->NumRows() - 30);
|
||||
} while (group_set.count(x2) && abs(pos1 - pos2) < 50);
|
||||
//cout << "- " << x1 << " " << x2 << " - " << pos1 << " " << pos2 << "\n";
|
||||
data1[i] = x1;
|
||||
data2[i] = x2;
|
||||
data1_pos[i] = pos1;
|
||||
data2_pos[i] = pos2;
|
||||
labels[i] = false;
|
||||
}
|
||||
|
||||
const float maxWidth = 16.0;
|
||||
const float widthScale = 1.0;
|
||||
const float widthIncrement = 1.0;
|
||||
|
||||
const int numFilters = 6;
|
||||
const int maxHeight = images[0]->NumColumns();
|
||||
const int filterWidthInc[] = { 1, 1, 2, 2, 1, 3 };
|
||||
const int filterHeightInc[] = { 1, 2, 1, 2, 3, 1 };
|
||||
const int kNumCandidateQuantizers = 24;
|
||||
|
||||
double weights[TRAINING_SET_SIZE];
|
||||
for (int i = 0; i < TRAINING_SET_SIZE; i++) {
|
||||
weights[i] = 1.0 / TRAINING_SET_SIZE;
|
||||
}
|
||||
|
||||
cout << "Computing filter responses\n";
|
||||
std::vector<Filter> filters;
|
||||
double *values_buffer = new double[100 * TRAINING_SET_SIZE * 2];
|
||||
|
||||
Filter flt;
|
||||
FILE *f = fopen("filters.tmp", "wb");
|
||||
for (int filter = 0; filter < numFilters; filter++) {
|
||||
flt.set_type(filter);
|
||||
for (int y = 0; y < maxHeight; y++) {
|
||||
flt.set_y(y);
|
||||
for (int h = filterHeightInc[filter]; h < maxHeight - y; h += filterHeightInc[filter]) {
|
||||
flt.set_height(h);
|
||||
int pw = 0;
|
||||
for (int wf = filterWidthInc[filter]; wf <= maxWidth; wf += filterWidthInc[filter]) {
|
||||
int w = wf;
|
||||
if (pw == w)
|
||||
continue;
|
||||
flt.set_width(w);
|
||||
fill(values_buffer, values_buffer + TRAINING_SET_SIZE * 2, 0.0);
|
||||
for (int i = 0; i < TRAINING_SET_SIZE; i++) {
|
||||
double value1 = flt.Apply(integral_images[data1[i]], data1_pos[i]);
|
||||
double value2 = flt.Apply(integral_images[data2[i]], data2_pos[i]);
|
||||
//cout << flt << " " << value1 << " [" << data1[i] << ":" << data1_pos[i] << "] " << value2 << " [" << data2[i] << ":" << data2_pos[i] << "]\n";
|
||||
values_buffer[2*i+0] = value1;
|
||||
values_buffer[2*i+1] = value2;
|
||||
}
|
||||
fwrite(values_buffer, sizeof(double), TRAINING_SET_SIZE * 2, f);
|
||||
filters.push_back(flt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cout << "Filters: " << filters.size() << "\n";
|
||||
|
||||
fclose(f);
|
||||
f = fopen("filters.tmp", "rb");
|
||||
|
||||
cout << "Computing quantizers\n";
|
||||
double *all_candidate_quantizers = new double[filters.size() * kNumCandidateQuantizers];
|
||||
double *quantizer_ptr = all_candidate_quantizers;
|
||||
fseek(f, 0, SEEK_SET);
|
||||
double *values_ptr = values_buffer + 100 * TRAINING_SET_SIZE * 2;
|
||||
for (int filter_i = 0; filter_i < filters.size(); filter_i++) {
|
||||
int num_values = TRAINING_SET_SIZE * 2;
|
||||
if (values_ptr >= values_buffer + 100 * TRAINING_SET_SIZE * 2) {
|
||||
fread(values_buffer, sizeof(double), 100 * num_values, f);
|
||||
values_ptr = values_buffer;
|
||||
}
|
||||
double_vector candidate_quantizers = lloyds(values_ptr, values_ptr + num_values, kNumCandidateQuantizers);
|
||||
copy(candidate_quantizers.begin(), candidate_quantizers.end(), quantizer_ptr);
|
||||
quantizer_ptr += kNumCandidateQuantizers;
|
||||
values_ptr += num_values;
|
||||
cout << filter_i << "\r";
|
||||
cout.flush();
|
||||
}
|
||||
|
||||
cout << "Running AdaBoost\n";
|
||||
vector<Classifier> best_classifiers;
|
||||
vector<double> best_classifiers_alpha;
|
||||
|
||||
int iteration = 0;
|
||||
next_iteration:
|
||||
|
||||
double min_error = 1.0;
|
||||
Classifier best_classifier;
|
||||
boost::dynamic_bitset<> best_results(TRAINING_SET_SIZE);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
quantizer_ptr = all_candidate_quantizers;
|
||||
values_ptr = values_buffer + 100 * TRAINING_SET_SIZE * 2;
|
||||
for (int filter_i = 0; filter_i < filters.size(); filter_i++) {
|
||||
std::size_t num_values = TRAINING_SET_SIZE * 2;
|
||||
if (values_ptr >= values_buffer + 100 * TRAINING_SET_SIZE * 2) {
|
||||
fread(values_buffer, sizeof(double), 100 * num_values, f);
|
||||
values_ptr = values_buffer;
|
||||
}
|
||||
|
||||
Quantizer quantizer(0.0, 0.0, 0.0);
|
||||
for (int ti0 = 0; ti0 < kNumCandidateQuantizers - 3; ti0++) {
|
||||
quantizer.set_t0(quantizer_ptr[ti0]);
|
||||
for (int ti1 = ti0 + 1; ti1 < kNumCandidateQuantizers - 2; ti1++) {
|
||||
quantizer.set_t1(quantizer_ptr[ti1]);
|
||||
for (int ti2 = ti1 + 1; ti2 < kNumCandidateQuantizers - 1; ti2++) {
|
||||
quantizer.set_t2(quantizer_ptr[ti2]);
|
||||
double error = 0.0;
|
||||
for (int i = 0; i < TRAINING_SET_SIZE; i++) {
|
||||
int q1 = quantizer.Quantize(values_ptr[i*2 + 0]);
|
||||
int q2 = quantizer.Quantize(values_ptr[i*2 + 1]);
|
||||
bool match = (q1 == q2) == labels[i];
|
||||
if (!match) {
|
||||
error += weights[i];
|
||||
}
|
||||
}
|
||||
if (error < min_error) {
|
||||
best_classifier = Classifier(filters[filter_i], quantizer);
|
||||
min_error = error;
|
||||
for (int i = 0; i < TRAINING_SET_SIZE; i++) {
|
||||
int q1 = quantizer.Quantize(values_ptr[i*2 + 0]);
|
||||
int q2 = quantizer.Quantize(values_ptr[i*2 + 1]);
|
||||
bool match = (q1 == q2) == labels[i];
|
||||
best_results[i] = match;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
quantizer_ptr += kNumCandidateQuantizers;
|
||||
values_ptr += num_values;
|
||||
cout << filter_i << " [" << min_error << "] \r";
|
||||
cout.flush();
|
||||
}
|
||||
|
||||
double weight_sum = 0.0;
|
||||
double alpha = 0.5 * log((1.0 - min_error) / min_error);
|
||||
for (int i = 0; i < TRAINING_SET_SIZE; i++) {
|
||||
weights[i] *= exp(-alpha * (best_results[i] ? 1.0 : -1.0));
|
||||
weight_sum += weights[i];
|
||||
}
|
||||
for (int i = 0; i < TRAINING_SET_SIZE; i++) {
|
||||
weights[i] /= weight_sum;
|
||||
}
|
||||
|
||||
best_classifiers.push_back(best_classifier);
|
||||
best_classifiers_alpha.push_back(alpha);
|
||||
|
||||
int wrong = 0;
|
||||
int counts[2];
|
||||
counts[0] = 0;
|
||||
counts[1] = 0;
|
||||
std::vector<int> bit_tp(32, 0);
|
||||
std::vector<int> bit_fp(32, 0);
|
||||
for (int i = 0; i < TRAINING_SET_SIZE; i++) {
|
||||
double value = 0.0;
|
||||
int bit_error = 0;
|
||||
for (int j = 0; j < best_classifiers.size(); j++) {
|
||||
int q1 = best_classifiers[j].Classify(integral_images[data1[i]], data1_pos[i]);
|
||||
int q2 = best_classifiers[j].Classify(integral_images[data2[i]], data2_pos[i]);
|
||||
int e = abs(q1 - q2);
|
||||
bit_error += e == 3 ? 1 : e;
|
||||
value += best_classifiers_alpha[j] * (q1 == q2 ? 1.0 : -1.0);
|
||||
}
|
||||
bool match = value > 0.0;
|
||||
counts[labels[i]]++;
|
||||
if (labels[i] != match) {
|
||||
wrong += 1.0;
|
||||
}
|
||||
for (int j = 0; j < 32; j++) {
|
||||
bool bit_match = bit_error <= j;
|
||||
if (labels[i] && bit_match) {
|
||||
bit_tp[j]++;
|
||||
}
|
||||
if (!labels[i] && bit_match) {
|
||||
bit_fp[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++iteration;
|
||||
cout << iteration << ". best classifier is " << best_classifier << " with error " << min_error << " (alpha " << alpha << "), final error is " << double(wrong) / TRAINING_SET_SIZE << "\n";
|
||||
PrintRate("TP", bit_tp, counts[1]);
|
||||
PrintRate("FP", bit_fp, counts[0]);
|
||||
|
||||
if (iteration < 16)
|
||||
goto next_iteration;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
42
3rdparty/chromaprint/tools/match.h
vendored
42
3rdparty/chromaprint/tools/match.h
vendored
@ -1,42 +0,0 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
|
||||
/* fingerprint matcher settings */
|
||||
#define ACOUSTID_MAX_BIT_ERROR 2
|
||||
#define ACOUSTID_MAX_ALIGN_OFFSET 120
|
||||
|
||||
#define BITCOUNT(x) __builtin_popcount(x)
|
||||
|
||||
inline float
|
||||
match_fingerprints(const std::vector<int32_t> &a, const std::vector<int32_t> &b)
|
||||
{
|
||||
int i, j, topcount;
|
||||
int maxsize = std::max(a.size(), b.size());
|
||||
int numcounts = maxsize * 2 + 1;
|
||||
int *counts = (int*)malloc(sizeof(int) * numcounts);
|
||||
|
||||
memset(counts, 0, sizeof(int) * numcounts);
|
||||
for (i = 0; i < a.size(); i++) {
|
||||
int jbegin = std::max(0, i - ACOUSTID_MAX_ALIGN_OFFSET);
|
||||
int jend = std::min(b.size(), size_t(i + ACOUSTID_MAX_ALIGN_OFFSET));
|
||||
for (j = jbegin; j < jend; j++) {
|
||||
int biterror = BITCOUNT(a[i] ^ b[j]);
|
||||
if (biterror <= ACOUSTID_MAX_BIT_ERROR) {
|
||||
int offset = i - j + maxsize;
|
||||
counts[offset]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
topcount = 0;
|
||||
for (i = 0; i < numcounts; i++) {
|
||||
if (counts[i] > topcount) {
|
||||
topcount = counts[i];
|
||||
}
|
||||
}
|
||||
|
||||
free(counts);
|
||||
|
||||
return (float)topcount / std::min(a.size(), b.size());
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for FILE in `ls *-orig.wav`; do
|
||||
TMPNEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-128mp3.mp3/'`
|
||||
NEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-128mp3.wav/'`
|
||||
if [ ! -f $NEWFILE ]; then
|
||||
rm -f $NEWFILE
|
||||
ffmpeg -i $FILE -ab 128000 $TMPNEWFILE
|
||||
ffmpeg -i $TMPNEWFILE $NEWFILE
|
||||
rm -f $TMPNEWFILE
|
||||
fi
|
||||
done
|
||||
|
13
3rdparty/chromaprint/tools/misc/prepare-32mp3.sh
vendored
13
3rdparty/chromaprint/tools/misc/prepare-32mp3.sh
vendored
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for FILE in `ls *-orig.wav`; do
|
||||
TMPNEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-32mp3.mp3/'`
|
||||
NEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-32mp3.wav/'`
|
||||
if [ ! -f $NEWFILE ]; then
|
||||
rm -f $NEWFILE
|
||||
ffmpeg -i $FILE -ab 32000 $TMPNEWFILE
|
||||
ffmpeg -i $TMPNEWFILE $NEWFILE
|
||||
rm -f $TMPNEWFILE
|
||||
fi
|
||||
done
|
||||
|
13
3rdparty/chromaprint/tools/misc/prepare-64mp3.sh
vendored
13
3rdparty/chromaprint/tools/misc/prepare-64mp3.sh
vendored
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for FILE in `ls *-orig.wav`; do
|
||||
TMPNEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-64mp3.mp3/'`
|
||||
NEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-64mp3.wav/'`
|
||||
if [ ! -f $NEWFILE ]; then
|
||||
rm -f $NEWFILE
|
||||
ffmpeg -i $FILE -ab 64000 $TMPNEWFILE
|
||||
ffmpeg -i $TMPNEWFILE $NEWFILE
|
||||
rm -f $TMPNEWFILE
|
||||
fi
|
||||
done
|
||||
|
13
3rdparty/chromaprint/tools/misc/prepare-64wma.sh
vendored
13
3rdparty/chromaprint/tools/misc/prepare-64wma.sh
vendored
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for FILE in `ls *-orig.wav`; do
|
||||
TMPNEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-64wma.wma/'`
|
||||
NEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-64wma.wav/'`
|
||||
if [ ! -f $NEWFILE ]; then
|
||||
rm -f $NEWFILE
|
||||
ffmpeg -i $FILE -ab 64000 -acodec wmav2 $TMPNEWFILE
|
||||
ffmpeg -i $TMPNEWFILE $NEWFILE
|
||||
rm -f $TMPNEWFILE
|
||||
fi
|
||||
done
|
||||
|
17
3rdparty/chromaprint/tools/misc/prepare-gain.sh
vendored
17
3rdparty/chromaprint/tools/misc/prepare-gain.sh
vendored
@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for FILE in `ls *-orig.wav`; do
|
||||
TMP1FILE=`echo $FILE | perl -pe 's/-orig\..*$/-tmp.wav/'`
|
||||
TMP2FILE=`echo $FILE | perl -pe 's/-orig\..*$/-tmp2.wav/'`
|
||||
TMPNEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-gain.wma/'`
|
||||
NEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-gain.wav/'`
|
||||
if [ ! -f $NEWFILE ]; then
|
||||
rm -f $NEWFILE $TMP1FILE $TMP2FILE
|
||||
ffmpeg -i $FILE $TMP1FILE
|
||||
sox $TMP1FILE $TMP2FILE gain -n -10
|
||||
ffmpeg -i $TMP2FILE -ab 128000 -acodec wmav2 $TMPNEWFILE
|
||||
ffmpeg -i $TMPNEWFILE $NEWFILE
|
||||
rm -f $TMP1FILE $TMP2FILE $TMPNEWFILE
|
||||
fi
|
||||
done
|
||||
|
@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for FILE in `ls *-orig.wav`; do
|
||||
TMP1FILE=`echo $FILE | perl -pe 's/-orig\..*$/-tmp.wav/'`
|
||||
TMPNEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-resample.wma/'`
|
||||
NEWFILE=`echo $FILE | perl -pe 's/-orig\..*$/-resample.wav/'`
|
||||
if [ ! -f $NEWFILE ]; then
|
||||
rm -f $NEWFILE $TMP1FILE $TMPNEWFILE
|
||||
sox $FILE $TMP1FILE rate -l 8k
|
||||
ffmpeg -i $TMP1FILE -ab 128000 -acodec wmav2 $TMPNEWFILE
|
||||
ffmpeg -i $TMPNEWFILE $NEWFILE
|
||||
rm -f $TMP1FILE $TMPNEWFILE
|
||||
fi
|
||||
done
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for FILE in `ls *.{mp3,wma,ogg}`; do
|
||||
NEWFILE=`echo $FILE | perl -pe 's/\..*$/.wav/'`
|
||||
rm -f $NEWFILE
|
||||
ffmpeg -i $FILE $NEWFILE
|
||||
rm -f $FILE
|
||||
done
|
||||
|
9
3rdparty/chromaprint/tools/misc/prepare.sh
vendored
9
3rdparty/chromaprint/tools/misc/prepare.sh
vendored
@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
cp orig/*.wav .
|
||||
./prepare-32mp3.sh
|
||||
./prepare-64mp3.sh
|
||||
./prepare-128mp3.sh
|
||||
./prepare-64wma.sh
|
||||
./prepare-gain.sh
|
||||
./prepare-wav.sh
|
35
3rdparty/chromaprint/tools/resample.cpp
vendored
35
3rdparty/chromaprint/tools/resample.cpp
vendored
@ -1,35 +0,0 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ext/ffmpeg_decoder.h"
|
||||
#include "ext/audio_dumper.h"
|
||||
#include "audio_processor.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
cerr << "Usage: " << argv[0] << " FILENAME\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
string file_name(argv[1]);
|
||||
cout << "Loading file " << file_name << "\n";
|
||||
|
||||
Decoder decoder(file_name);
|
||||
if (!decoder.Open()) {
|
||||
cerr << "ERROR: " << decoder.LastError() << "\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
AudioDumper dumper("resampled.raw");
|
||||
Chromaprint::AudioProcessor processor(11025, &dumper);
|
||||
processor.Reset(decoder.SampleRate(), decoder.Channels());
|
||||
|
||||
decoder.Decode(&processor);
|
||||
processor.Flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
63
3rdparty/chromaprint/tools/spectrogram.cpp
vendored
63
3rdparty/chromaprint/tools/spectrogram.cpp
vendored
@ -1,63 +0,0 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ext/ffmpeg_decoder.h"
|
||||
#include "ext/audio_dumper.h"
|
||||
#include "audio_processor.h"
|
||||
#include "chroma.h"
|
||||
#include "spectrum.h"
|
||||
#include "chroma_normalizer.h"
|
||||
#include "chroma_resampler.h"
|
||||
#include "chroma_filter.h"
|
||||
#include "fft.h"
|
||||
#include "audio_processor.h"
|
||||
#include "image.h"
|
||||
#include "image_builder.h"
|
||||
#include "utils.h"
|
||||
#include "ext/image_utils.h"
|
||||
|
||||
static const int SAMPLE_RATE = 11025;
|
||||
static const int FRAME_SIZE = 4096;
|
||||
static const int OVERLAP = FRAME_SIZE - FRAME_SIZE / 3;// 2720;
|
||||
static const int MIN_FREQ = 28;
|
||||
static const int MAX_FREQ = 3520;
|
||||
static const int MAX_FILTER_WIDTH = 20;
|
||||
|
||||
static const int kChromaFilterSize = 5;
|
||||
static const double kChromaFilterCoefficients[] = { 0.25, 0.75, 1.0, 0.75, 0.25 };
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
cerr << "Usage: " << argv[0] << " AUDIOFILE IMAGEFILE\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
string file_name(argv[1]);
|
||||
cout << "Loading file " << file_name << "\n";
|
||||
|
||||
Decoder decoder(file_name);
|
||||
if (!decoder.Open()) {
|
||||
cerr << "ERROR: " << decoder.LastError() << "\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
const int numBands = 72;
|
||||
Chromaprint::Image image(numBands);
|
||||
Chromaprint::ImageBuilder image_builder(&image);
|
||||
Chromaprint::Spectrum chroma(numBands, MIN_FREQ, MAX_FREQ, FRAME_SIZE, SAMPLE_RATE, &image_builder);
|
||||
Chromaprint::FFT fft(FRAME_SIZE, OVERLAP, &chroma);
|
||||
Chromaprint::AudioProcessor processor(SAMPLE_RATE, &fft);
|
||||
|
||||
processor.Reset(decoder.SampleRate(), decoder.Channels());
|
||||
decoder.Decode(&processor);
|
||||
processor.Flush();
|
||||
|
||||
//Chromaprint::ExportTextImage(&image, argv[2]);
|
||||
Chromaprint::ExportImage(&image, argv[2], 0.5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user