Add Chromaprint to 3rdparty.

This commit is contained in:
John Maguire 2012-01-06 15:55:50 +00:00
parent 74c4720054
commit 1bcbc2ed3e
135 changed files with 10664 additions and 0 deletions

38
3rdparty/chromaprint/.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
CMakeFiles
CMakeCache.txt
Makefile
cmake_install.cmake
config.h
tests/all_tests
tools/fpgen
tools/fpcollect
*.exe
*.dll
*.so
*.a
tools/fpeval
tools/learn_filters
tools/decode
tools/chromagram
tools/resample
libchromaprint.pc
install_manifest.txt
tools/spectrogram
src/libchromaprint.so.*
*.vcxproj
*.vcxproj.*
*.dir
*.sln
*.suo
Debug
src/Debug
*.dll
*.lib
*.pdb
*.dll.manifest
*.exp
*.dylib
*.vcproj
*.user
*.ncb
src/Release

5
3rdparty/chromaprint/CHANGES.txt vendored Normal file
View File

@ -0,0 +1,5 @@
Version 0.1 (2010-10-30)
========================
- Initial release.

158
3rdparty/chromaprint/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,158 @@
cmake_minimum_required(VERSION 2.6)
project(chromaprint)
set(PROJECT_VERSION 0.6.0)
# 1. If the library source code has changed at all since the last update, then increment revision.
# 2. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
# 3. If any interfaces have been added since the last public release, then increment age.
# 4. If any interfaces have been removed since the last public release, then set age to 0.
set(chromaprint_SOVERSION_CURRENT 1)
set(chromaprint_SOVERSION_REVISION 4)
set(chromaprint_SOVERSION_AGE 1)
math(EXPR chromaprint_SOVERSION_MAJOR "${chromaprint_SOVERSION_CURRENT} - ${chromaprint_SOVERSION_AGE}")
math(EXPR chromaprint_SOVERSION_MINOR "${chromaprint_SOVERSION_AGE}")
math(EXPR chromaprint_SOVERSION_PATCH "${chromaprint_SOVERSION_REVISION}")
set(chromaprint_VERSION ${chromaprint_SOVERSION_MAJOR}.${chromaprint_SOVERSION_MINOR}.${chromaprint_SOVERSION_PATCH})
set(chromaprint_SOVERSION ${chromaprint_SOVERSION_MAJOR})
include(CheckFunctionExists)
set(CMAKE_REQUIRED_LIBRARIES -lm)
check_function_exists(lrintf HAVE_LRINTF)
check_function_exists(round HAVE_ROUND)
add_definitions(
-DHAVE_CONFIG_H
-D_SCL_SECURE_NO_WARNINGS
-D_USE_MATH_DEFINES
-D__STDC_LIMIT_MACROS
-D__STDC_CONSTANT_MACROS
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)")
set(EXEC_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Installation prefix for executables and object code libraries" FORCE)
set(BIN_INSTALL_DIR ${EXEC_INSTALL_PREFIX}/bin CACHE PATH "Installation prefix for user executables" FORCE)
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)
option(WITH_VDSP "Use vDSP for FFT calculations" OFF)
set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests/)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
find_package(FFmpeg)
find_package(FFTW3)
if(APPLE)
find_library(ACCELERATE_LIBRARIES Accelerate)
endif()
set(FFT_OPTION_COUNT 0)
if(WITH_AVFFT)
math(EXPR FFT_OPTION_COUNT "${FFT_OPTION_COUNT} + 1")
endif()
if(WITH_FFTW3)
math(EXPR FFT_OPTION_COUNT "${FFT_OPTION_COUNT} + 1")
endif()
if(WITH_VDSP)
math(EXPR FFT_OPTION_COUNT "${FFT_OPTION_COUNT} + 1")
endif()
if(FFT_OPTION_COUNT GREATER "1")
message(FATAL_ERROR "Only one of WITH_AVFFT, WITH_FFTW3 AND WITH_VDSP can be selected")
endif()
if(WITH_AVFFT AND NOT FFMPEG_LIBAVCODEC_FFT_FOUND)
message(FATAL_ERROR "FFmpeg with avfft.h not found")
endif()
if(WITH_FFTW3 AND NOT FFTW3_FOUND)
message(FATAL_ERROR "FFTW3 not found")
endif()
if(APPLE AND WITH_VDSP AND NOT ACCELERATE_LIBRARIES)
message(FATAL_ERROR "vDSP (Accelerate) not found")
endif()
if(NOT WITH_AVFFT AND NOT WITH_FFTW3)
if(APPLE AND ACCELERATE_LIBRARIES)
set(WITH_VDSP ON)
elseif(FFMPEG_LIBAVCODEC_FFT_FOUND)
set(WITH_AVFFT ON)
elseif(FFTW3_FOUND)
set(WITH_FFTW3 ON)
else()
message(FATAL_ERROR "Neither FFmpeg with avfft.h nor FFTW3 found")
endif()
endif()
if(WITH_AVFFT)
message(STATUS "Using FFmpeg for FFT calculations")
endif(WITH_AVFFT)
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)

502
3rdparty/chromaprint/COPYING.txt vendored Normal file
View File

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library 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.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

44
3rdparty/chromaprint/NEWS.txt vendored Normal file
View File

@ -0,0 +1,44 @@
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 Normal file
View File

@ -0,0 +1,96 @@
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

View File

@ -0,0 +1,133 @@
#
# Try to find FFTW3 library
# (see www.fftw.org)
# Once run this will define:
#
# FFTW3_FOUND
# FFTW3_INCLUDE_DIR
# FFTW3_LIBRARIES
# FFTW3_LINK_DIRECTORIES
#
# You may set one of these options before including this file:
# FFTW3_USE_SSE2
#
# TODO: _F_ versions.
#
# Jan Woetzel 05/2004
# www.mip.informatik.uni-kiel.de
# --------------------------------
FIND_PATH(FFTW3_INCLUDE_DIR fftw3.h
${FFTW3_DIR}/include
${FFTW3_HOME}/include
${FFTW3_DIR}
${FFTW3_HOME}
$ENV{FFTW3_DIR}/include
$ENV{FFTW3_HOME}/include
$ENV{FFTW3_DIR}
$ENV{FFTW3_HOME}
/usr/include
/usr/local/include
$ENV{SOURCE_DIR}/fftw3
$ENV{SOURCE_DIR}/fftw3/include
$ENV{SOURCE_DIR}/fftw
$ENV{SOURCE_DIR}/fftw/include
)
#MESSAGE("DBG FFTW3_INCLUDE_DIR=${FFTW3_INCLUDE_DIR}")
SET(FFTW3_POSSIBLE_LIBRARY_PATH
${FFTW3_DIR}/lib
${FFTW3_HOME}/lib
${FFTW3_DIR}
${FFTW3_HOME}
$ENV{FFTW3_DIR}/lib
$ENV{FFTW3_HOME}/lib
$ENV{FFTW3_DIR}
$ENV{FFTW3_HOME}
/usr/lib
/usr/local/lib
$ENV{SOURCE_DIR}/fftw3
$ENV{SOURCE_DIR}/fftw3/lib
$ENV{SOURCE_DIR}/fftw
$ENV{SOURCE_DIR}/fftw/lib
)
# the lib prefix is containe din filename onf W32, unfortuantely. JW
# teh "general" lib:
FIND_LIBRARY(FFTW3_FFTW_LIBRARY
NAMES fftw3 libfftw libfftw3 libfftw3-3
PATHS
${FFTW3_POSSIBLE_LIBRARY_PATH}
)
#MESSAGE("DBG FFTW3_FFTW_LIBRARY=${FFTW3_FFTW_LIBRARY}")
FIND_LIBRARY(FFTW3_FFTWF_LIBRARY
NAMES fftwf3 fftwf libfftwf libfftwf3 libfftw3f-3
PATHS
${FFTW3_POSSIBLE_LIBRARY_PATH}
)
#MESSAGE("DBG FFTW3_FFTWF_LIBRARY=${FFTW3_FFTWF_LIBRARY}")
FIND_LIBRARY(FFTW3_FFTWL_LIBRARY
NAMES fftwl3 fftwl libfftwl libfftwl3 libfftw3l-3
PATHS
${FFTW3_POSSIBLE_LIBRARY_PATH}
)
#MESSAGE("DBG FFTW3_FFTWF_LIBRARY=${FFTW3_FFTWL_LIBRARY}")
FIND_LIBRARY(FFTW3_FFTW_SSE2_LIBRARY
NAMES fftw_sse2 fftw3_sse2 libfftw_sse2 libfftw3_sse2
PATHS
${FFTW3_POSSIBLE_LIBRARY_PATH}
)
#MESSAGE("DBG FFTW3_FFTW_SSE2_LIBRARY=${FFTW3_FFTW_SSE2_LIBRARY}")
FIND_LIBRARY(FFTW3_FFTWF_SSE_LIBRARY
NAMES fftwf_sse fftwf3_sse libfftwf_sse libfftwf3_sse
PATHS
${FFTW3_POSSIBLE_LIBRARY_PATH}
)
#MESSAGE("DBG FFTW3_FFTWF_SSE_LIBRARY=${FFTW3_FFTWF_SSE_LIBRARY}")
# --------------------------------
# select one of the above
# default:
IF (FFTW3_FFTW_LIBRARY)
SET(FFTW3_LIBRARIES ${FFTW3_FFTW_LIBRARY})
ENDIF (FFTW3_FFTW_LIBRARY)
# specialized:
IF (FFTW3_USE_SSE2 AND FFTW3_FFTW_SSE2_LIBRARY)
SET(FFTW3_LIBRARIES ${FFTW3_FFTW_SSE2_LIBRARY})
ENDIF (FFTW3_USE_SSE2 AND FFTW3_FFTW_SSE2_LIBRARY)
# --------------------------------
IF(FFTW3_LIBRARIES)
IF (FFTW3_INCLUDE_DIR)
# OK, found all we need
SET(FFTW3_FOUND TRUE)
GET_FILENAME_COMPONENT(FFTW3_LINK_DIRECTORIES ${FFTW3_LIBRARIES} PATH)
ELSE (FFTW3_INCLUDE_DIR)
MESSAGE("FFTW3 include dir not found. Set FFTW3_DIR to find it.")
ENDIF(FFTW3_INCLUDE_DIR)
ELSE(FFTW3_LIBRARIES)
MESSAGE("FFTW3 lib not found. Set FFTW3_DIR to find it.")
ENDIF(FFTW3_LIBRARIES)
MARK_AS_ADVANCED(
FFTW3_INCLUDE_DIR
FFTW3_LIBRARIES
FFTW3_FFTW_LIBRARY
FFTW3_FFTW_SSE2_LIBRARY
FFTW3_FFTWF_LIBRARY
FFTW3_FFTWF_SSE_LIBRARY
FFTW3_FFTWL_LIBRARY
FFTW3_LINK_DIRECTORIES
)

View File

@ -0,0 +1,128 @@
# Locate ffmpeg
# This module defines
# FFMPEG_LIBRARIES
# FFMPEG_FOUND, if false, do not try to link to ffmpeg
# FFMPEG_INCLUDE_DIR, where to find the headers
#
# $FFMPEG_DIR is an environment variable that would
# correspond to the ./configure --prefix=$FFMPEG_DIR
#
# Created by Robert Osfield.
# Modified by Lukas Lalinsky.
#In ffmpeg code, old version use "#include <header.h>" and newer use "#include <libname/header.h>"
#In OSG ffmpeg plugin, we use "#include <header.h>" for compatibility with old version of ffmpeg
#We have to search the path which contain the header.h (usefull for old version)
#and search the path which contain the libname/header.h (usefull for new version)
#Then we need to include ${FFMPEG_libname_INCLUDE_DIRS} (in old version case, use by ffmpeg header and osg plugin code)
# (in new version case, use by ffmpeg header)
#and ${FFMPEG_libname_INCLUDE_DIRS/libname} (in new version case, use by osg plugin code)
# Macro to find header and lib directories
# example: FFMPEG_FIND(AVFORMAT avformat avformat.h)
MACRO(FFMPEG_FIND varname shortname headername)
FIND_PATH(FFMPEG_${varname}_INCLUDE_DIRS lib${shortname}/${headername}
PATHS
${FFMPEG_ROOT}/include
$ENV{FFMPEG_DIR}/include
~/Library/Frameworks
/Library/Frameworks
/usr/local/include
/usr/include/
/sw/include # Fink
/opt/local/include # DarwinPorts
/opt/csw/include # Blastwave
/opt/include
/usr/freeware/include
NO_DEFAULT_PATH
PATH_SUFFIXES ffmpeg
DOC "Location of FFMPEG Headers"
)
FIND_PATH(FFMPEG_${varname}_INCLUDE_DIRS lib${shortname}/${headername}
PATH_SUFFIXES ffmpeg
DOC "Location of FFMPEG Headers"
)
FIND_LIBRARY(FFMPEG_${varname}_LIBRARIES
NAMES ${shortname}
PATHS
${FFMPEG_ROOT}/lib
$ENV{FFMPEG_DIR}/lib
~/Library/Frameworks
/Library/Frameworks
/usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
/sw/lib
/opt/local/lib
/opt/csw/lib
/opt/lib
/usr/freeware/lib64
NO_DEFAULT_PATH
DOC "Location of FFMPEG Libraries"
)
FIND_LIBRARY(FFMPEG_${varname}_LIBRARIES
NAMES ${shortname}
DOC "Location of FFMPEG Libraries"
)
IF (FFMPEG_${varname}_LIBRARIES AND FFMPEG_${varname}_INCLUDE_DIRS)
SET(FFMPEG_${varname}_FOUND 1)
ENDIF(FFMPEG_${varname}_LIBRARIES AND FFMPEG_${varname}_INCLUDE_DIRS)
ENDMACRO(FFMPEG_FIND)
SET(FFMPEG_ROOT "$ENV{FFMPEG_DIR}" CACHE PATH "Location of FFMPEG")
# find stdint.h
FIND_PATH(FFMPEG_STDINT_INCLUDE_DIR stdint.h
PATHS
${FFMPEG_ROOT}/include
$ENV{FFMPEG_DIR}/include
~/Library/Frameworks
/Library/Frameworks
/usr/local/include
/usr/include
/sw/include # Fink
/opt/local/include # DarwinPorts
/opt/csw/include # Blastwave
/opt/include
/usr/freeware/include
PATH_SUFFIXES ffmpeg
DOC "Location of FFMPEG stdint.h Header"
)
FFMPEG_FIND(LIBAVFORMAT avformat avformat.h)
FFMPEG_FIND(LIBAVDEVICE avdevice avdevice.h)
FFMPEG_FIND(LIBAVCODEC avcodec avcodec.h)
FFMPEG_FIND(LIBAVCODEC_FFT avcodec avfft.h)
FFMPEG_FIND(LIBAVUTIL avutil avutil.h)
FFMPEG_FIND(LIBSWSCALE swscale swscale.h) # not sure about the header to look for here.
SET(FFMPEG_FOUND "NO")
# Note we don't check FFMPEG_LIBSWSCALE_FOUND here, it's optional.
IF (FFMPEG_LIBAVFORMAT_FOUND AND FFMPEG_LIBAVDEVICE_FOUND AND FFMPEG_LIBAVCODEC_FOUND AND FFMPEG_LIBAVUTIL_FOUND AND FFMPEG_STDINT_INCLUDE_DIR)
SET(FFMPEG_FOUND "YES")
SET(FFMPEG_INCLUDE_DIRS ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS})
SET(FFMPEG_LIBRARY_DIRS ${FFMPEG_LIBAVFORMAT_LIBRARY_DIRS})
# Note we don't add FFMPEG_LIBSWSCALE_LIBRARIES here, it will be added if found later.
SET(FFMPEG_LIBRARIES
${FFMPEG_LIBAVFORMAT_LIBRARIES}
${FFMPEG_LIBAVDEVICE_LIBRARIES}
${FFMPEG_LIBAVCODEC_LIBRARIES}
${FFMPEG_LIBAVUTIL_LIBRARIES})
ELSE ()
# MESSAGE(STATUS "Could not find FFMPEG")
ENDIF()

View File

@ -0,0 +1,175 @@
# Locate the Google C++ Testing Framework.
#
# Defines the following variables:
#
# GTEST_FOUND - Found the Google Testing framework
# GTEST_INCLUDE_DIRS - Include directories
#
# Also defines the library variables below as normal
# variables. These contain debug/optimized keywords when
# a debugging library is found.
#
# GTEST_BOTH_LIBRARIES - Both libgtest & libgtest-main
# GTEST_LIBRARIES - libgtest
# GTEST_MAIN_LIBRARIES - libgtest-main
#
# Accepts the following variables as input:
#
# GTEST_ROOT - (as CMake or env. variable)
# The root directory of the gtest install prefix
#
# GTEST_MSVC_SEARCH - If on MSVC, enables searching the build tree of
# GTest if set to MD or MT (defaults: MD)
#
#-----------------------
# Example Usage:
#
# enable_testing(true)
# find_package(GTest REQUIRED)
# include_directories(${GTEST_INCLUDE_DIRS})
#
# add_executable(foo foo.cc)
# target_link_libraries(foo ${GTEST_BOTH_LIBRARIES})
#
# add_test(AllTestsInFoo foo)
#
#-----------------------
#
# If you would like each Google test to show up in CTest as
# a test you may use the following macro. NOTE: It WILL slow
# down your tests, so be warned.
#
# GTEST_ADD_TESTS(executable extra_args ARGN)
# executable = The path to the test executable
# extra_args = Pass a list of extra arguments to be passed to
# executable enclosed in quotes (or "" for none)
# ARGN = A list of source files to search for tests & test
# fixtures.
#
# Example:
# set(FooTestArgs --foo 1 --bar 2)
# add_executable(FooTest FooUnitTest.cc)
# GTEST_ADD_TESTS(FooTest "${FooTestArgs}" FooUnitTest.cc)
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009 Philip Lowman <philip@yhbt.com>
# Copyright 2009 Daniel Blezek <blezek@gmail.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#=============================================================================
#
# Thanks to Daniel Blezek <blezek@gmail.com> for the GTEST_ADD_TESTS code
function(GTEST_ADD_TESTS executable extra_args)
if(NOT ARGN)
message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
endif()
foreach(source ${ARGN})
file(READ "${source}" contents)
string(REGEX MATCHALL "TEST_?F?\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
foreach(hit ${found_tests})
string(REGEX REPLACE ".*\\(([A-Za-z_0-9]+)[, ]*([A-Za-z_0-9]+)\\).*" "\\1.\\2" test_name ${hit})
add_test(${test_name} ${executable} --gtest_filter=${test_name} ${extra_args})
endforeach()
endforeach()
endfunction()
function(_gtest_append_debugs _endvar _library)
if(${_library} AND ${_library}_DEBUG)
set(_output optimized ${${_library}} debug ${${_library}_DEBUG})
else()
set(_output ${${_library}})
endif()
set(${_endvar} ${_output} PARENT_SCOPE)
endfunction()
function(_gtest_find_library _name)
find_library(${_name}
NAMES ${ARGN}
HINTS
$ENV{GTEST_ROOT}
${GTEST_ROOT}
PATH_SUFFIXES ${_gtest_libpath_suffixes}
)
mark_as_advanced(${_name})
endfunction()
#
if(NOT DEFINED GTEST_MSVC_SEARCH)
set(GTEST_MSVC_SEARCH MD)
endif()
set(_gtest_libpath_suffixes lib)
if(MSVC)
if(GTEST_MSVC_SEARCH STREQUAL "MD")
list(APPEND _gtest_libpath_suffixes
msvc/gtest-md/Debug
msvc/gtest-md/Release)
elseif(GTEST_MSVC_SEARCH STREQUAL "MT")
list(APPEND _gtest_libpath_suffixes
msvc/gtest/Debug
msvc/gtest/Release)
endif()
endif()
find_path(GTEST_INCLUDE_DIR gtest/gtest.h
HINTS
$ENV{GTEST_ROOT}/include
${GTEST_ROOT}/include
)
mark_as_advanced(GTEST_INCLUDE_DIR)
if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
# The provided /MD project files for Google Test add -md suffixes to the
# library names.
_gtest_find_library(GTEST_LIBRARY gtest-md gtest)
_gtest_find_library(GTEST_LIBRARY_DEBUG gtest-mdd gtestd)
_gtest_find_library(GTEST_MAIN_LIBRARY gtest_main-md gtest_main)
_gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
else()
_gtest_find_library(GTEST_LIBRARY gtest)
_gtest_find_library(GTEST_LIBRARY_DEBUG gtestd)
_gtest_find_library(GTEST_MAIN_LIBRARY gtest_main)
_gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTest DEFAULT_MSG GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
if(GTEST_FOUND)
set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR})
_gtest_append_debugs(GTEST_LIBRARIES GTEST_LIBRARY)
_gtest_append_debugs(GTEST_MAIN_LIBRARIES GTEST_MAIN_LIBRARY)
set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
endif()

View File

@ -0,0 +1,135 @@
# - Try to find the Taglib library
# Once done this will define
#
# TAGLIB_FOUND - system has the taglib library
# TAGLIB_CFLAGS - the taglib cflags
# TAGLIB_LIBRARIES - The libraries needed to use taglib
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if(NOT TAGLIB_MIN_VERSION)
set(TAGLIB_MIN_VERSION "1.6")
endif(NOT TAGLIB_MIN_VERSION)
if(NOT WIN32)
find_program(TAGLIBCONFIG_EXECUTABLE NAMES taglib-config PATHS
${BIN_INSTALL_DIR}
)
endif(NOT WIN32)
#reset vars
set(TAGLIB_LIBRARIES)
set(TAGLIB_CFLAGS)
# if taglib-config has been found
if(TAGLIBCONFIG_EXECUTABLE)
exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --version RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_VERSION)
if(TAGLIB_VERSION STRLESS "${TAGLIB_MIN_VERSION}")
message(STATUS "TagLib version too old: version searched :${TAGLIB_MIN_VERSION}, found ${TAGLIB_VERSION}")
set(TAGLIB_FOUND FALSE)
else(TAGLIB_VERSION STRLESS "${TAGLIB_MIN_VERSION}")
exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_LIBRARIES)
exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_CFLAGS)
if(TAGLIB_LIBRARIES AND TAGLIB_CFLAGS)
set(TAGLIB_FOUND TRUE)
endif(TAGLIB_LIBRARIES AND TAGLIB_CFLAGS)
string(REGEX REPLACE " *-I" ";" TAGLIB_INCLUDES "${TAGLIB_CFLAGS}")
endif(TAGLIB_VERSION STRLESS "${TAGLIB_MIN_VERSION}")
mark_as_advanced(TAGLIB_CFLAGS TAGLIB_LIBRARIES TAGLIB_INCLUDES)
else(TAGLIBCONFIG_EXECUTABLE)
find_path(TAGLIB_INCLUDES
NAMES
tag.h
PATH_SUFFIXES taglib
PATHS
${KDE4_INCLUDE_DIR}
${INCLUDE_INSTALL_DIR}
)
IF(NOT WIN32)
# on non-win32 we don't need to take care about WIN32_DEBUG_POSTFIX
FIND_LIBRARY(TAGLIB_LIBRARIES tag PATHS ${KDE4_LIB_DIR} ${LIB_INSTALL_DIR})
ELSE(NOT WIN32)
# 1. get all possible libnames
SET(args PATHS ${KDE4_LIB_DIR} ${LIB_INSTALL_DIR})
SET(newargs "")
SET(libnames_release "")
SET(libnames_debug "")
LIST(LENGTH args listCount)
# just one name
LIST(APPEND libnames_release "tag")
LIST(APPEND libnames_debug "tagd")
SET(newargs ${args})
# search the release lib
FIND_LIBRARY(TAGLIB_LIBRARIES_RELEASE
NAMES ${libnames_release}
${newargs}
)
# search the debug lib
FIND_LIBRARY(TAGLIB_LIBRARIES_DEBUG
NAMES ${libnames_debug}
${newargs}
)
IF(TAGLIB_LIBRARIES_RELEASE AND TAGLIB_LIBRARIES_DEBUG)
# both libs found
SET(TAGLIB_LIBRARIES optimized ${TAGLIB_LIBRARIES_RELEASE}
debug ${TAGLIB_LIBRARIES_DEBUG})
ELSE(TAGLIB_LIBRARIES_RELEASE AND TAGLIB_LIBRARIES_DEBUG)
IF(TAGLIB_LIBRARIES_RELEASE)
# only release found
SET(TAGLIB_LIBRARIES ${TAGLIB_LIBRARIES_RELEASE})
ELSE(TAGLIB_LIBRARIES_RELEASE)
# only debug (or nothing) found
SET(TAGLIB_LIBRARIES ${TAGLIB_LIBRARIES_DEBUG})
ENDIF(TAGLIB_LIBRARIES_RELEASE)
ENDIF(TAGLIB_LIBRARIES_RELEASE AND TAGLIB_LIBRARIES_DEBUG)
MARK_AS_ADVANCED(TAGLIB_LIBRARIES_RELEASE)
MARK_AS_ADVANCED(TAGLIB_LIBRARIES_DEBUG)
ENDIF(NOT WIN32)
INCLUDE(FindPackageMessage)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Taglib DEFAULT_MSG TAGLIB_INCLUDES TAGLIB_LIBRARIES)
endif(TAGLIBCONFIG_EXECUTABLE)
if(TAGLIB_FOUND)
if(NOT Taglib_FIND_QUIETLY AND TAGLIBCONFIG_EXECUTABLE)
message(STATUS "Taglib found: ${TAGLIB_LIBRARIES}")
endif(NOT Taglib_FIND_QUIETLY AND TAGLIBCONFIG_EXECUTABLE)
else(TAGLIB_FOUND)
if(Taglib_FIND_REQUIRED)
message(FATAL_ERROR "Could not find Taglib")
endif(Taglib_FIND_REQUIRED)
endif(TAGLIB_FOUND)

7
3rdparty/chromaprint/config.h.in vendored Normal file
View File

@ -0,0 +1,7 @@
#cmakedefine HAVE_ROUND 1
#cmakedefine HAVE_LRINTF 1
#cmakedefine WITH_AVFFT 1
#cmakedefine WITH_FFTW3 1
#cmakedefine WITH_VDSP 1
#cmakedefine TESTS_DIR "@TESTS_DIR@"

View File

@ -0,0 +1,39 @@
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}
)

View File

@ -0,0 +1,118 @@
/*
* 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 */

View File

@ -0,0 +1,156 @@
/*
* 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 Normal file
View File

@ -0,0 +1,303 @@
#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

View File

@ -0,0 +1,12 @@
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}

74
3rdparty/chromaprint/src/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,74 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(chromaprint_SRCS
chromaprint.cpp
audio_processor.cpp
chroma.cpp
chroma_resampler.cpp
chroma_filter.cpp
integral_image.cpp
spectrum.cpp
spectral_centroid.cpp
filter.cpp
fft.cpp
fingerprinter.cpp
image_builder.cpp
lloyds.cpp
silence_remover.cpp
fingerprint_calculator.cpp
fingerprint_compressor.cpp
fingerprint_decompressor.cpp
fingerprinter_configuration.cpp
base64.cpp
avresample/resample2.c
)
if(WITH_AVFFT)
set(chromaprint_SRCS fft_lib_avfft.cpp ${chromaprint_SRCS})
set(chromaprint_LINK_LIBS
${FFMPEG_LIBAVCODEC_LIBRARIES}
${FFMPEG_LIBAVUTIL_LIBRARIES}
)
include_directories(
${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
)
endif(WITH_AVFFT)
if(WITH_FFTW3)
set(chromaprint_SRCS fft_lib_fftw3.cpp ${chromaprint_SRCS})
set(chromaprint_LINK_LIBS ${FFTW3_LIBRARIES})
include_directories(${FFTW3_INCLUDE_DIR})
endif(WITH_FFTW3)
if(WITH_VDSP)
set(chromaprint_SRCS fft_lib_vdsp.cpp ${chromaprint_SRCS})
set(chromaprint_LINK_LIBS ${ACCELERATE_LIBRARIES})
endif()
add_library(chromaprint_p STATIC ${chromaprint_SRCS})
target_link_libraries(chromaprint_p ${chromaprint_LINK_LIBS})
set(chromaprint_HDRS chromaprint.h)
add_library(chromaprint ${chromaprint_SRCS} ${chromaprint_SRCS} ${chromaprint_HDRS})
set_target_properties(chromaprint PROPERTIES
VERSION ${chromaprint_VERSION}
SOVERSION ${chromaprint_SOVERSION}
PUBLIC_HEADER ${chromaprint_HDRS}
DEFINE_SYMBOL CHROMAPRINT_API_EXPORTS
)
if(BUILD_FRAMEWORK)
set_target_properties(chromaprint PROPERTIES FRAMEWORK TRUE)
endif()
target_link_libraries(chromaprint ${chromaprint_LINK_LIBS})
install(TARGETS chromaprint
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}
)

View File

@ -0,0 +1,38 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_AUDIO_CONSUMER_H_
#define CHROMAPRINT_AUDIO_CONSUMER_H_
namespace Chromaprint
{
class AudioConsumer
{
public:
virtual ~AudioConsumer() {}
virtual void Consume(short *input, int length) = 0;
};
};
#endif

View File

@ -0,0 +1,191 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <assert.h>
#include <algorithm>
#include <stdio.h>
extern "C" {
#include "avresample/avcodec.h"
}
#include "debug.h"
#include "audio_processor.h"
using namespace std;
using namespace Chromaprint;
static const int kMinSampleRate = 1000;
static const int kMaxBufferSize = 1024 * 16;
// Resampler configuration
static const int kResampleFilterLength = 16;
static const int kResamplePhaseCount = 10;
static const int kResampleLinear = 0;
static const double kResampleCutoff = 0.8;
AudioProcessor::AudioProcessor(int sample_rate, AudioConsumer *consumer)
: m_buffer_size(kMaxBufferSize),
m_target_sample_rate(sample_rate),
m_consumer(consumer),
m_resample_ctx(0)
{
m_buffer = new short[kMaxBufferSize];
m_buffer_offset = 0;
m_resample_buffer = new short[kMaxBufferSize];
}
AudioProcessor::~AudioProcessor()
{
if (m_resample_ctx) {
av_resample_close(m_resample_ctx);
}
delete[] m_resample_buffer;
delete[] m_buffer;
}
void AudioProcessor::LoadMono(short *input, int length)
{
short *output = m_buffer + m_buffer_offset;
while (length--) {
*output++ = input[0];
input++;
}
}
void AudioProcessor::LoadStereo(short *input, int length)
{
short *output = m_buffer + m_buffer_offset;
while (length--) {
*output++ = (input[0] + input[1]) / 2;
input += 2;
}
}
void AudioProcessor::LoadMultiChannel(short *input, int length)
{
short *output = m_buffer + m_buffer_offset;
while (length--) {
long sum = 0;
for (int i = 0; i < m_num_channels; i++) {
sum += *input++;
}
*output++ = (short)(sum / m_num_channels);
}
}
int AudioProcessor::Load(short *input, int length)
{
assert(length >= 0);
assert(m_buffer_offset <= m_buffer_size);
length = min(length, m_buffer_size - m_buffer_offset);
switch (m_num_channels) {
case 1:
LoadMono(input, length);
break;
case 2:
LoadStereo(input, length);
break;
default:
LoadMultiChannel(input, length);
break;
}
m_buffer_offset += length;
return length;
}
void AudioProcessor::Resample()
{
if (!m_resample_ctx) {
m_consumer->Consume(m_buffer, m_buffer_offset);
m_buffer_offset = 0;
return;
}
int consumed = 0;
int length = av_resample(m_resample_ctx, m_resample_buffer, m_buffer, &consumed, m_buffer_offset, kMaxBufferSize, 1);
if (length > kMaxBufferSize) {
DEBUG() << "Chromaprint::AudioProcessor::Resample() -- Resampling overwrote output buffer.\n";
length = kMaxBufferSize;
}
m_consumer->Consume(m_resample_buffer, length);
int remaining = m_buffer_offset - consumed;
if (remaining > 0) {
copy(m_buffer + consumed, m_buffer + m_buffer_offset, m_buffer);
}
else if (remaining < 0) {
DEBUG() << "Chromaprint::AudioProcessor::Resample() -- Resampling overread input buffer.\n";
remaining = 0;
}
m_buffer_offset = remaining;
}
bool AudioProcessor::Reset(int sample_rate, int num_channels)
{
if (num_channels <= 0) {
DEBUG() << "Chromaprint::AudioProcessor::Reset() -- No audio channels.\n";
return false;
}
if (sample_rate <= kMinSampleRate) {
DEBUG() << "Chromaprint::AudioProcessor::Reset() -- Sample rate less "
<< "than " << kMinSampleRate << " (" << sample_rate << ").\n";
return false;
}
m_buffer_offset = 0;
if (m_resample_ctx) {
av_resample_close(m_resample_ctx);
m_resample_ctx = 0;
}
if (sample_rate != m_target_sample_rate) {
m_resample_ctx = av_resample_init(
m_target_sample_rate, sample_rate,
kResampleFilterLength,
kResamplePhaseCount,
kResampleLinear,
kResampleCutoff);
}
m_num_channels = num_channels;
return true;
}
void AudioProcessor::Consume(short *input, int length)
{
assert(length >= 0);
assert(length % m_num_channels == 0);
length /= m_num_channels;
while (length > 0) {
int consumed = Load(input, length);
input += consumed * m_num_channels;
length -= consumed;
if (m_buffer_size == m_buffer_offset) {
Resample();
if (m_buffer_size == m_buffer_offset) {
DEBUG() << "Chromaprint::AudioProcessor::Consume() -- Resampling failed?\n";
return;
}
}
}
}
void AudioProcessor::Flush()
{
if (m_buffer_offset) {
Resample();
}
}

View File

@ -0,0 +1,87 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_AUDIO_PROCESSOR_H_
#define CHROMAPRINT_AUDIO_PROCESSOR_H_
#include "utils.h"
#include "audio_consumer.h"
struct AVResampleContext;
namespace Chromaprint
{
class AudioProcessor : public AudioConsumer
{
public:
AudioProcessor(int sample_rate, AudioConsumer *consumer);
virtual ~AudioProcessor();
int target_sample_rate() const
{
return m_target_sample_rate;
}
void set_target_sample_rate(int sample_rate)
{
m_target_sample_rate = sample_rate;
}
AudioConsumer *consumer() const
{
return m_consumer;
}
void set_consumer(AudioConsumer *consumer)
{
m_consumer = consumer;
}
//! Prepare for a new audio stream
bool Reset(int sample_rate, int num_channels);
//! Process a chunk of data from the audio stream
void Consume(short *input, int length);
//! Process any buffered input that was not processed before and clear buffers
void Flush();
private:
CHROMAPRINT_DISABLE_COPY(AudioProcessor);
int Load(short *input, int length);
void LoadMono(short *input, int length);
void LoadStereo(short *input, int length);
void LoadMultiChannel(short *input, int length);
void Resample();
short *m_buffer;
short *m_resample_buffer;
int m_buffer_offset;
int m_buffer_size;
int m_target_sample_rate;
int m_num_channels;
AudioConsumer *m_consumer;
struct AVResampleContext *m_resample_ctx;
};
};
#endif

View File

@ -0,0 +1,101 @@
/*
* copyright (c) 2001 Fabrice Bellard
*
* 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_H
#define AVCODEC_H
/* Just a heavily bastardized version of the original file from
* ffmpeg, just enough to get resample2.c to compile without
* modification -- Lennart */
#if defined(HAVE_CONFIG_H)
#include <config.h>
#endif
#include <sys/types.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
typedef void *AVClass;
#define av_mallocz(l) calloc(1, (l))
#define av_malloc(l) malloc(l)
#define av_realloc(p,l) realloc((p),(l))
#define av_free(p) free(p)
#ifdef _MSC_VER
#define CHROMAPRINT_C_INLINE __inline
#else
#define CHROMAPRINT_C_INLINE inline
#endif
static CHROMAPRINT_C_INLINE void av_freep(void *k) {
void **p = (void **)k;
if (p) {
free(*p);
*p = NULL;
}
}
static CHROMAPRINT_C_INLINE int av_clip(int a, int amin, int amax)
{
if (a < amin) return amin;
else if (a > amax) return amax;
else return a;
}
#define av_log(a,b,c)
#define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
#define FFSIGN(a) ((a) > 0 ? 1 : -1)
#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
struct AVResampleContext;
struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff);
int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx);
void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
void av_resample_close(struct AVResampleContext *c);
void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type);
/* error handling */
#if EDOM > 0
#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions.
#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value.
#else
/* Some platforms have E* and errno already negated. */
#define AVERROR(e) (e)
#define AVUNERROR(e) (e)
#endif
/*
* crude lrintf for non-C99 systems.
*/
#ifndef HAVE_LRINTF
#define lrintf(x) ((long int)floor(x + 0.5))
#endif
#endif /* AVCODEC_H */

View File

@ -0,0 +1 @@
/* empty file, just here to allow us to compile an unmodified resampler2.c */

View File

@ -0,0 +1,320 @@
/*
* audio resampling
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* 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
*/
/**
* @file
* audio resampling
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "avcodec.h"
#include "dsputil.h"
#ifndef CONFIG_RESAMPLE_HP
#define FILTER_SHIFT 15
#define FELEM int16_t
#define FELEM2 int32_t
#define FELEML int64_t
#define FELEM_MAX INT16_MAX
#define FELEM_MIN INT16_MIN
#define WINDOW_TYPE 9
#elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE)
#define FILTER_SHIFT 30
#define FELEM int32_t
#define FELEM2 int64_t
#define FELEML int64_t
#define FELEM_MAX INT32_MAX
#define FELEM_MIN INT32_MIN
#define WINDOW_TYPE 12
#else
#define FILTER_SHIFT 0
#define FELEM double
#define FELEM2 double
#define FELEML double
#define WINDOW_TYPE 24
#endif
typedef struct AVResampleContext{
const AVClass *av_class;
FELEM *filter_bank;
int filter_length;
int ideal_dst_incr;
int dst_incr;
int index;
int frac;
int src_incr;
int compensation_distance;
int phase_shift;
int phase_mask;
int linear;
}AVResampleContext;
/**
* 0th order modified bessel function of the first kind.
*/
static double bessel(double x){
double v=1;
double lastv=0;
double t=1;
int i;
x= x*x/4;
for(i=1; v != lastv; i++){
lastv=v;
t *= x/(i*i);
v += t;
}
return v;
}
/**
* builds a polyphase filterbank.
* @param factor resampling factor
* @param scale wanted sum of coefficients for each filter
* @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16
* @return 0 on success, negative on error
*/
static int build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){
int ph, i;
double x, y, w;
double *tab = av_malloc(tap_count * sizeof(*tab));
const int center= (tap_count-1)/2;
if (!tab)
return AVERROR(ENOMEM);
/* if upsampling, only need to interpolate, no filter */
if (factor > 1.0)
factor = 1.0;
for(ph=0;ph<phase_count;ph++) {
double norm = 0;
for(i=0;i<tap_count;i++) {
x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
if (x == 0) y = 1.0;
else y = sin(x) / x;
switch(type){
case 0:{
const float d= -0.5; //first order derivative = -0.5
x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x);
else y= d*(-4 + 8*x - 5*x*x + x*x*x);
break;}
case 1:
w = 2.0*x / (factor*tap_count) + M_PI;
y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w);
break;
default:
w = 2.0*x / (factor*tap_count*M_PI);
y *= bessel(type*sqrt(FFMAX(1-w*w, 0)));
break;
}
tab[i] = y;
norm += y;
}
/* normalize so that an uniform color remains the same */
for(i=0;i<tap_count;i++) {
#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
filter[ph * tap_count + i] = tab[i] / norm;
#else
filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm), FELEM_MIN, FELEM_MAX);
#endif
}
}
#if 0
{
#define LEN 1024
int j,k;
double sine[LEN + tap_count];
double filtered[LEN];
double maxff=-2, minff=2, maxsf=-2, minsf=2;
for(i=0; i<LEN; i++){
double ss=0, sf=0, ff=0;
for(j=0; j<LEN+tap_count; j++)
sine[j]= cos(i*j*M_PI/LEN);
for(j=0; j<LEN; j++){
double sum=0;
ph=0;
for(k=0; k<tap_count; k++)
sum += filter[ph * tap_count + k] * sine[k+j];
filtered[j]= sum / (1<<FILTER_SHIFT);
ss+= sine[j + center] * sine[j + center];
ff+= filtered[j] * filtered[j];
sf+= sine[j + center] * filtered[j];
}
ss= sqrt(2*ss/LEN);
ff= sqrt(2*ff/LEN);
sf= 2*sf/LEN;
maxff= FFMAX(maxff, ff);
minff= FFMIN(minff, ff);
maxsf= FFMAX(maxsf, sf);
minsf= FFMIN(minsf, sf);
if(i%11==0){
av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
minff=minsf= 2;
maxff=maxsf= -2;
}
}
}
#endif
av_free(tab);
return 0;
}
AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){
AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));
double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
int phase_count= 1<<phase_shift;
if (!c)
return NULL;
c->phase_shift= phase_shift;
c->phase_mask= phase_count-1;
c->linear= linear;
c->filter_length= FFMAX((int)ceil(filter_size/factor), 1);
c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM));
if (!c->filter_bank)
goto error;
if (build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<<FILTER_SHIFT, WINDOW_TYPE))
goto error;
memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM));
c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1];
c->src_incr= out_rate;
c->ideal_dst_incr= c->dst_incr= in_rate * phase_count;
c->index= -phase_count*((c->filter_length-1)/2);
return c;
error:
av_free(c->filter_bank);
av_free(c);
return NULL;
}
void av_resample_close(AVResampleContext *c){
av_freep(&c->filter_bank);
av_freep(&c);
}
void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){
// sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr;
c->compensation_distance= compensation_distance;
c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
}
int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){
int dst_index, i;
int index= c->index;
int frac= c->frac;
int dst_incr_frac= c->dst_incr % c->src_incr;
int dst_incr= c->dst_incr / c->src_incr;
int compensation_distance= c->compensation_distance;
if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){
int64_t index2= ((int64_t)index)<<32;
int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);
for(dst_index=0; dst_index < dst_size; dst_index++){
dst[dst_index] = src[index2>>32];
index2 += incr;
}
frac += dst_index * dst_incr_frac;
index += dst_index * dst_incr;
index += frac / c->src_incr;
frac %= c->src_incr;
}else{
for(dst_index=0; dst_index < dst_size; dst_index++){
FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask);
int sample_index= index >> c->phase_shift;
FELEM2 val=0;
if(sample_index < 0){
for(i=0; i<c->filter_length; i++)
val += src[FFABS(sample_index + i) % src_size] * filter[i];
}else if(sample_index + c->filter_length > src_size){
break;
}else if(c->linear){
FELEM2 v2=0;
for(i=0; i<c->filter_length; i++){
val += src[sample_index + i] * (FELEM2)filter[i];
v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length];
}
val+=(v2-val)*(FELEML)frac / c->src_incr;
}else{
for(i=0; i<c->filter_length; i++){
val += src[sample_index + i] * (FELEM2)filter[i];
}
}
#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
dst[dst_index] = av_clip_int16(lrintf(val));
#else
val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;
dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val;
#endif
frac += dst_incr_frac;
index += dst_incr;
if(frac >= c->src_incr){
frac -= c->src_incr;
index++;
}
if(dst_index + 1 == compensation_distance){
compensation_distance= 0;
dst_incr_frac= c->ideal_dst_incr % c->src_incr;
dst_incr= c->ideal_dst_incr / c->src_incr;
}
}
}
*consumed= FFMAX(index, 0) >> c->phase_shift;
if(index>=0) index &= c->phase_mask;
if(compensation_distance){
compensation_distance -= dst_index;
assert(compensation_distance > 0);
}
if(update_ctx){
c->frac= frac;
c->index= index;
c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
c->compensation_distance= compensation_distance;
}
#if 0
if(update_ctx && !c->compensation_distance){
#undef rand
av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2);
av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance);
}
#endif
return dst_index;
}

92
3rdparty/chromaprint/src/base64.cpp vendored Normal file
View File

@ -0,0 +1,92 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <algorithm>
#include <assert.h>
#include "base64.h"
#include "bit_string_writer.h"
#include "debug.h"
using namespace std;
using namespace Chromaprint;
static const char kBase64Chars[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
static const char kBase64CharsReversed[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
string Chromaprint::Base64Encode(const string &orig)
{
int size = orig.size();
int encoded_size = (size * 4 + 2) / 3;
string encoded(encoded_size, '\x00');
const unsigned char *src = (unsigned char *)orig.data();
string::iterator dest = encoded.begin();
while (size > 0) {
*dest++ = kBase64Chars[(src[0] >> 2)];
*dest++ = kBase64Chars[((src[0] << 4) | (--size ? (src[1] >> 4) : 0)) & 63];
if (size) {
*dest++ = kBase64Chars[((src[1] << 2) | (--size ? (src[2] >> 6) : 0)) & 63];
if (size) {
*dest++ = kBase64Chars[src[2] & 63];
--size;
}
}
src += 3;
}
return encoded;
}
string Chromaprint::Base64Decode(const string &encoded)
{
string str((3 * encoded.size()) / 4, '\x00');
const unsigned char *src = (const unsigned char *)encoded.data();
int size = encoded.size();
string::iterator dest = str.begin();
while (size > 0) {
int b0 = kBase64CharsReversed[*src++];
if (--size) {
int b1 = kBase64CharsReversed[*src++];
int r = (b0 << 2) | (b1 >> 4);
assert(dest != str.end());
*dest++ = r;
if (--size) {
int b2 = kBase64CharsReversed[*src++];
r = ((b1 << 4) & 255) | (b2 >> 2);
assert(dest != str.end());
*dest++ = r;
if (--size) {
int b3 = kBase64CharsReversed[*src++];
r = ((b2 << 6) & 255) | b3;
assert(dest != str.end());
*dest++ = r;
--size;
}
}
}
}
return str;
}

35
3rdparty/chromaprint/src/base64.h vendored Normal file
View File

@ -0,0 +1,35 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_BASE64_H_
#define CHROMAPRINT_BASE64_H_
#include <string>
namespace Chromaprint
{
std::string Base64Encode(const std::string &str);
std::string Base64Decode(const std::string &encoded);
};
#endif

View File

@ -0,0 +1,69 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_BIT_STRING_READER_H_
#define CHROMAPRINT_BIT_STRING_READER_H_
#include <stdint.h>
#include <string>
#include "debug.h"
namespace Chromaprint
{
class BitStringReader
{
public:
BitStringReader(const std::string &input) : m_value(input), m_buffer(0), m_buffer_size(0)
{
m_value_iter = m_value.begin();
}
uint32_t Read(int bits)
{
if (m_buffer_size < bits) {
if (m_value_iter != m_value.end()) {
m_buffer |= (unsigned char)(*m_value_iter++) << m_buffer_size;
m_buffer_size += 8;
}
}
uint32_t result = m_buffer & ((1 << bits) - 1);
m_buffer >>= bits;
m_buffer_size -= bits;
return result;
}
void Reset()
{
m_buffer = 0;
m_buffer_size = 0;
}
private:
std::string m_value;
std::string::iterator m_value_iter;
uint32_t m_buffer;
int m_buffer_size;
};
};
#endif

View File

@ -0,0 +1,77 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_BIT_STRING_WRITER_H_
#define CHROMAPRINT_BIT_STRING_WRITER_H_
#include <stdint.h>
#include <vector>
#include <string>
namespace Chromaprint
{
class Classifier;
class Image;
class IntegralImage;
class BitStringWriter
{
public:
BitStringWriter() : m_buffer(0), m_buffer_size(0)
{
}
void Write(uint32_t x, int bits)
{
m_buffer |= (x << m_buffer_size);
m_buffer_size += bits;
while (m_buffer_size >= 8) {
m_value.push_back(m_buffer & 255);
m_buffer >>= 8;
m_buffer_size -= 8;
}
}
void Flush()
{
while (m_buffer_size > 0) {
m_value.push_back(m_buffer & 255);
m_buffer >>= 8;
m_buffer_size -= 8;
}
m_buffer_size = 0;
}
std::string value() const
{
return m_value;
}
private:
std::string m_value;
uint32_t m_buffer;
int m_buffer_size;
};
};
#endif

95
3rdparty/chromaprint/src/chroma.cpp vendored Normal file
View File

@ -0,0 +1,95 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <limits>
#include <math.h>
#include "fft_frame.h"
#include "utils.h"
#include "chroma.h"
#include "debug.h"
using namespace std;
using namespace Chromaprint;
static const int NUM_BANDS = 12;
inline double FreqToOctave(double freq, double base = 440.0 / 16.0)
{
return log(freq / base) / log(2.0);
}
Chroma::Chroma(int min_freq, int max_freq, int frame_size, int sample_rate, FeatureVectorConsumer *consumer)
: m_interpolate(false),
m_notes(frame_size),
m_notes_frac(frame_size),
m_features(NUM_BANDS),
m_consumer(consumer)
{
PrepareNotes(min_freq, max_freq, frame_size, sample_rate);
}
Chroma::~Chroma()
{
}
void Chroma::PrepareNotes(int min_freq, int max_freq, int frame_size, int sample_rate)
{
m_min_index = max(1, FreqToIndex(min_freq, frame_size, sample_rate));
m_max_index = min(frame_size / 2, FreqToIndex(max_freq, frame_size, sample_rate));
for (int i = m_min_index; i < m_max_index; i++) {
double freq = IndexToFreq(i, frame_size, sample_rate);
double octave = FreqToOctave(freq);
double note = NUM_BANDS * (octave - floor(octave));
m_notes[i] = (char)note;
m_notes_frac[i] = note - m_notes[i];
}
}
void Chroma::Reset()
{
}
void Chroma::Consume(const FFTFrame &frame)
{
fill(m_features.begin(), m_features.end(), 0.0);
for (int i = m_min_index; i < m_max_index; i++) {
int note = m_notes[i];
double energy = frame.Energy(i);
if (m_interpolate) {
int note2 = note;
double a = 1.0;
if (m_notes_frac[i] < 0.5) {
note2 = (note + NUM_BANDS - 1) % NUM_BANDS;
a = 0.5 + m_notes_frac[i];
}
if (m_notes_frac[i] > 0.5) {
note2 = (note + 1) % NUM_BANDS;
a = 1.5 - m_notes_frac[i];
}
m_features[note] += energy * a;
m_features[note2] += energy * (1.0 - a);
}
else {
m_features[note] += energy;
}
}
m_consumer->Consume(m_features);
}

68
3rdparty/chromaprint/src/chroma.h vendored Normal file
View File

@ -0,0 +1,68 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_CHROMA_H_
#define CHROMAPRINT_CHROMA_H_
#include <math.h>
#include <vector>
#include "utils.h"
#include "fft_frame_consumer.h"
#include "feature_vector_consumer.h"
namespace Chromaprint
{
class Chroma : public FFTFrameConsumer
{
public:
Chroma(int min_freq, int max_freq, int frame_size, int sample_rate, FeatureVectorConsumer *consumer);
~Chroma();
bool interpolate() const
{
return m_interpolate;
}
void set_interpolate(bool interpolate)
{
m_interpolate = interpolate;
}
void Reset();
void Consume(const FFTFrame &frame);
private:
CHROMAPRINT_DISABLE_COPY(Chroma);
void PrepareNotes(int min_freq, int max_freq, int frame_size, int sample_rate);
bool m_interpolate;
std::vector<char> m_notes;
std::vector<double> m_notes_frac;
int m_min_index;
int m_max_index;
std::vector<double> m_features;
FeatureVectorConsumer *m_consumer;
};
};
#endif

View File

@ -0,0 +1,69 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <limits>
#include <assert.h>
#include <math.h>
#include "chroma_filter.h"
#include "utils.h"
using namespace std;
using namespace Chromaprint;
ChromaFilter::ChromaFilter(const double *coefficients, int length, FeatureVectorConsumer *consumer)
: m_coefficients(coefficients),
m_length(length),
m_buffer(8),
m_result(12),
m_buffer_offset(0),
m_buffer_size(1),
m_consumer(consumer)
{
}
ChromaFilter::~ChromaFilter()
{
}
void ChromaFilter::Reset()
{
m_buffer_size = 1;
m_buffer_offset = 0;
}
void ChromaFilter::Consume(std::vector<double> &features)
{
m_buffer[m_buffer_offset] = features;
m_buffer_offset = (m_buffer_offset + 1) % 8;
if (m_buffer_size >= m_length) {
int offset = (m_buffer_offset + 8 - m_length) % 8;
fill(m_result.begin(), m_result.end(), 0.0);
for (int i = 0; i < 12; i++) {
for (int j = 0; j < m_length; j++) {
m_result[i] += m_buffer[(offset + j) % 8][i] * m_coefficients[j];
}
}
m_consumer->Consume(m_result);
}
else {
m_buffer_size++;
}
}

View File

@ -0,0 +1,54 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_CHROMA_FILTER_H_
#define CHROMAPRINT_CHROMA_FILTER_H_
#include <vector>
#include "feature_vector_consumer.h"
namespace Chromaprint
{
class ChromaFilter : public FeatureVectorConsumer
{
public:
ChromaFilter(const double *coefficients, int length, FeatureVectorConsumer *consumer);
~ChromaFilter();
void Reset();
void Consume(std::vector<double> &features);
FeatureVectorConsumer *consumer() { return m_consumer; }
void set_consumer(FeatureVectorConsumer *consumer) { m_consumer = consumer; }
private:
const double *m_coefficients;
int m_length;
std::vector< std::vector<double> > m_buffer;
std::vector<double> m_result;
int m_buffer_offset;
int m_buffer_size;
FeatureVectorConsumer *m_consumer;
};
};
#endif

View File

@ -0,0 +1,55 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_CHROMA_NORMALIZER_H_
#define CHROMAPRINT_CHROMA_NORMALIZER_H_
#include <vector>
#include <algorithm>
#include "feature_vector_consumer.h"
#include "utils.h"
namespace Chromaprint
{
class ChromaNormalizer : public FeatureVectorConsumer
{
public:
ChromaNormalizer(FeatureVectorConsumer *consumer) : m_consumer(consumer) {}
~ChromaNormalizer() {}
void Reset() {}
void Consume(std::vector<double> &features)
{
NormalizeVector(features.begin(), features.end(),
Chromaprint::EuclideanNorm<std::vector<double>::iterator>,
0.01);
m_consumer->Consume(features);
}
private:
CHROMAPRINT_DISABLE_COPY(ChromaNormalizer);
FeatureVectorConsumer *m_consumer;
};
};
#endif

View File

@ -0,0 +1,62 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <limits>
#include <assert.h>
#include <math.h>
#include "chroma_resampler.h"
#include "utils.h"
using namespace std;
using namespace Chromaprint;
ChromaResampler::ChromaResampler(int factor, FeatureVectorConsumer *consumer)
: m_result(12, 0.0),
m_iteration(0),
m_factor(factor),
m_consumer(consumer)
{
}
ChromaResampler::~ChromaResampler()
{
}
void ChromaResampler::Reset()
{
m_iteration = 0;
fill(m_result.begin(), m_result.end(), 0.0);
}
void ChromaResampler::Consume(std::vector<double> &features)
{
for (int i = 0; i < 12; i++) {
m_result[i] += features[i];
}
m_iteration += 1;
if (m_iteration == m_factor) {
for (int i = 0; i < 12; i++) {
m_result[i] /= m_factor;
}
m_consumer->Consume(m_result);
Reset();
}
}

View File

@ -0,0 +1,52 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_CHROMA_RESAMPLER_H_
#define CHROMAPRINT_CHROMA_RESAMPLER_H_
#include <vector>
#include "image.h"
#include "feature_vector_consumer.h"
namespace Chromaprint
{
class ChromaResampler : public FeatureVectorConsumer
{
public:
ChromaResampler(int factor, FeatureVectorConsumer *consumer);
~ChromaResampler();
void Reset();
void Consume(std::vector<double> &features);
FeatureVectorConsumer *consumer() { return m_consumer; }
void set_consumer(FeatureVectorConsumer *consumer) { m_consumer = consumer; }
private:
std::vector<double> m_result;
int m_iteration;
int m_factor;
FeatureVectorConsumer *m_consumer;
};
};
#endif

150
3rdparty/chromaprint/src/chromaprint.cpp vendored Normal file
View File

@ -0,0 +1,150 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <vector>
#include <string>
#include <algorithm>
#include <chromaprint.h>
#include "fingerprinter.h"
#include "fingerprint_compressor.h"
#include "fingerprint_decompressor.h"
#include "fingerprinter_configuration.h"
#include "base64.h"
using namespace std;
using namespace Chromaprint;
extern "C" {
struct ChromaprintContextPrivate {
int algorithm;
Fingerprinter *fingerprinter;
vector<int32_t> fingerprint;
};
#define STR(x) #x
#define VERSION_STR(minor, major, patch) \
STR(major) "." STR(minor) "." STR(patch)
static const char *version_str = VERSION_STR(
CHROMAPRINT_VERSION_MAJOR,
CHROMAPRINT_VERSION_MINOR,
CHROMAPRINT_VERSION_PATCH);
const char *chromaprint_get_version(void)
{
return version_str;
}
ChromaprintContext *chromaprint_new(int algorithm)
{
ChromaprintContextPrivate *ctx = new ChromaprintContextPrivate();
ctx->algorithm = algorithm;
ctx->fingerprinter = new Fingerprinter(CreateFingerprinterConfiguration(algorithm));
return (ChromaprintContext *)ctx;
}
void chromaprint_free(ChromaprintContext *c)
{
ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
delete ctx->fingerprinter;
delete ctx;
}
int chromaprint_start(ChromaprintContext *c, int sample_rate, int num_channels)
{
ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
return ctx->fingerprinter->Start(sample_rate, num_channels) ? 1 : 0;
}
int chromaprint_feed(ChromaprintContext *c, void *data, int length)
{
ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
ctx->fingerprinter->Consume((short *)data, length);
return 1;
}
int chromaprint_finish(ChromaprintContext *c)
{
ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
ctx->fingerprint = ctx->fingerprinter->Finish();
return 1;
}
int chromaprint_get_fingerprint(ChromaprintContext *c, char **data)
{
ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
string fp = Chromaprint::Base64Encode(Chromaprint::CompressFingerprint(ctx->fingerprint, ctx->algorithm));
*data = (char *)malloc(fp.size() + 1);
if (!*data) {
return 0;
}
copy(fp.begin(), fp.end(), *data);
(*data)[fp.size()] = 0;
return 1;
}
int chromaprint_get_raw_fingerprint(ChromaprintContext *c, void **data, int *size)
{
ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
*data = malloc(sizeof(int32_t) * ctx->fingerprint.size());
if (!*data) {
return 0;
}
*size = ctx->fingerprint.size();
copy(ctx->fingerprint.begin(), ctx->fingerprint.end(), *((int32_t **)data));
return 1;
}
int chromaprint_encode_fingerprint(void *fp, int size, int algorithm, void **encoded_fp, int *encoded_size, int base64)
{
vector<int32_t> uncompressed = vector<int32_t>((int32_t *)fp, (int32_t *)fp + size);
string compressed = Chromaprint::CompressFingerprint(uncompressed, algorithm);
if (!base64) {
*encoded_fp = malloc(compressed.size());
*encoded_size = compressed.size();
copy(compressed.begin(), compressed.end(), (char *)*encoded_fp);
return 1;
}
string encoded = Chromaprint::Base64Encode(compressed);
*encoded_fp = malloc(encoded.size() + 1);
*encoded_size = encoded.size();
copy(encoded.begin(), encoded.end(), (char *)*encoded_fp);
((char *)*encoded_fp)[encoded.size()] = 0;
return 1;
}
int chromaprint_decode_fingerprint(void *encoded_fp, int encoded_size, void **fp, int *size, int *algorithm, int base64)
{
string encoded = string((char *)encoded_fp, encoded_size);
string compressed = base64 ? Chromaprint::Base64Decode(encoded) : encoded;
vector<int32_t> uncompressed = Chromaprint::DecompressFingerprint(compressed, algorithm);
*fp = malloc(sizeof(int32_t) * uncompressed.size());
*size = uncompressed.size();
copy(uncompressed.begin(), uncompressed.end(), (int32_t *)*fp);
return 0;
}
void chromaprint_dealloc(void *ptr)
{
free(ptr);
}
}

222
3rdparty/chromaprint/src/chromaprint.h vendored Normal file
View File

@ -0,0 +1,222 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_CHROMAPRINT_H_
#define CHROMAPRINT_CHROMAPRINT_H_
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(_WIN32) || defined(_WIN64))
# ifdef CHROMAPRINT_NODLL
# define CHROMAPRINT_API
# else
# ifdef CHROMAPRINT_API_EXPORTS
# define CHROMAPRINT_API __declspec(dllexport)
# else
# define CHROMAPRINT_API __declspec(dllimport)
# endif
# endif
#else
# if __GNUC__ >= 4
# define CHROMAPRINT_API __attribute__ ((visibility("default")))
# else
# define CHROMAPRINT_API
# endif
#endif
typedef void *ChromaprintContext;
#define CHROMAPRINT_VERSION_MAJOR 0
#define CHROMAPRINT_VERSION_MINOR 6
#define CHROMAPRINT_VERSION_PATCH 0
enum ChromaprintAlgorithm {
CHROMAPRINT_ALGORITHM_TEST1 = 0,
CHROMAPRINT_ALGORITHM_TEST2,
CHROMAPRINT_ALGORITHM_TEST3
};
#define CHROMAPRINT_ALGORITHM_DEFAULT CHROMAPRINT_ALGORITHM_TEST2
/**
* Return the version number of Chromaprint.
*/
CHROMAPRINT_API const char *chromaprint_get_version(void);
/**
* Allocate and initialize the Chromaprint context.
*
* Parameters:
* - version: Version of the fingerprint algorithm, use
* CHROMAPRINT_ALGORITHM_DEFAULT for the default
* algorithm
*
* Returns:
* - Chromaprint context pointer
*/
CHROMAPRINT_API ChromaprintContext *chromaprint_new(int algorithm);
/**
* Deallocate the Chromaprint context.
*
* Parameters:
* - ctx: Chromaprint context pointer
*/
CHROMAPRINT_API void chromaprint_free(ChromaprintContext *ctx);
/**
* Return the fingerprint algorithm this context is configured to use.
*/
CHROMAPRINT_API int chromaprint_get_algorithm(ChromaprintContext *ctx);
/**
* Restart the computation of a fingerprint with a new audio stream.
*
* Parameters:
* - ctx: Chromaprint context pointer
* - sample_rate: sample rate of the audio stream (in Hz)
* - num_channels: numbers of channels in the audio stream (1 or 2)
*
* Returns:
* - 0 on error, 1 on success
*/
CHROMAPRINT_API int chromaprint_start(ChromaprintContext *ctx, int sample_rate, int num_channels);
/**
* Send audio data to the fingerprint calculator.
*
* Parameters:
* - ctx: Chromaprint context pointer
* - data: raw audio data, should point to an array of 16-bit signed
* integers in native byte-order
* - size: size of the data buffer (in samples)
*
* Returns:
* - 0 on error, 1 on success
*/
CHROMAPRINT_API int chromaprint_feed(ChromaprintContext *ctx, void *data, int size);
/**
* Process any remaining buffered audio data and calculate the fingerprint.
*
* Parameters:
* - ctx: Chromaprint context pointer
*
* Returns:
* - 0 on error, 1 on success
*/
CHROMAPRINT_API int chromaprint_finish(ChromaprintContext *ctx);
/**
* Return the calculated fingerprint as a compressed string.
*
* The caller is responsible for freeing the returned pointer using
* chromaprint_dealloc().
*
* Parameters:
* - ctx: Chromaprint context pointer
* - fingerprint: pointer to a pointer, where a pointer to the allocated array
* will be stored
*
* Returns:
* - 0 on error, 1 on success
*/
CHROMAPRINT_API int chromaprint_get_fingerprint(ChromaprintContext *ctx, char **fingerprint);
/**
* Return the calculated fingerprint as an array of 32-bit integers.
*
* The caller is responsible for freeing the returned pointer using
* chromaprint_dealloc().
*
* Parameters:
* - ctx: Chromaprint context pointer
* - fingerprint: pointer to a pointer, where a pointer to the allocated array
* will be stored
* - size: number of items in the returned raw fingerprint
*
* Returns:
* - 0 on error, 1 on success
*/
CHROMAPRINT_API int chromaprint_get_raw_fingerprint(ChromaprintContext *ctx, void **fingerprint, int *size);
/**
* Compress and optionally base64-encode a raw fingerprint
*
* The caller is responsible for freeing the returned pointer using
* chromaprint_dealloc().
*
* Parameters:
* - fp: pointer to an array of 32-bit integers representing the raw
* fingerprint to be encoded
* - size: number of items in the raw fingerprint
* - algorithm: Chromaprint algorithm version which was used to generate the
* raw fingerprint
* - encoded_fp: pointer to a pointer, where the encoded fingerprint will be
* stored
* - encoded_size: size of the encoded fingerprint in bytes
* - base64: Whether to return binary data or base64-encoded ASCII data. The
* compressed fingerprint will be encoded using base64 with the
* URL-safe scheme if you set this parameter to 1. It will return
* binary data if it's 0.
*
* Returns:
* - 0 on error, 1 on success
*/
CHROMAPRINT_API int chromaprint_encode_fingerprint(void *fp, int size, int algorithm, void **encoded_fp, int *encoded_size, int base64);
/**
* Uncompress and optionally base64-decode an encoded fingerprint
*
* The caller is responsible for freeing the returned pointer using
* chromaprint_dealloc().
*
* Parameters:
* - encoded_fp: Pointer to an encoded fingerprint
* - encoded_size: Size of the encoded fingerprint in bytes
* - fp: Pointer to a pointer, where the decoded raw fingerprint (array
* of 32-bit integers) will be stored
* - size: Number of items in the returned raw fingerprint
* - algorithm: Chromaprint algorithm version which was used to generate the
* raw fingerprint
* - base64: Whether the encoded_fp parameter contains binary data or
* base64-encoded ASCII data. If 1, it will base64-decode the data
* before uncompressing the fingerprint.
*
* Returns:
* - 0 on error, 1 on success
*/
CHROMAPRINT_API int chromaprint_decode_fingerprint(void *encoded_fp, int encoded_size, void **fp, int *size, int *algorithm, int base64);
/**
* Free memory allocated by any function from the Chromaprint API.
*
* Parameters:
* - ptr: Pointer to be deallocated
*/
CHROMAPRINT_API void chromaprint_dealloc(void *ptr);
#ifdef __cplusplus
}
#endif
#endif

61
3rdparty/chromaprint/src/classifier.h vendored Normal file
View File

@ -0,0 +1,61 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_CLASSIFIER_H_
#define CHROMAPRINT_CLASSIFIER_H_
#include <ostream>
#include "quantizer.h"
#include "filter.h"
#include "integral_image.h"
namespace Chromaprint
{
class Classifier
{
public:
Classifier(const Filter &filter = Filter(), const Quantizer &quantizer = Quantizer())
: m_filter(filter), m_quantizer(quantizer)
{
}
int Classify(IntegralImage *image, int offset) const
{
double value = m_filter.Apply(image, offset);
return m_quantizer.Quantize(value);
}
const Filter &filter() const { return m_filter; }
const Quantizer &quantizer() const { return m_quantizer; }
private:
Filter m_filter;
Quantizer m_quantizer;
};
inline std::ostream &operator<<(std::ostream &stream, const Classifier &q)
{
stream << "Classifier(" << q.filter() << ", " << q.quantizer() << ")";
return stream;
}
};
#endif

View File

@ -0,0 +1,176 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_COMBINED_BUFFER_H_
#define CHROMAPRINT_COMBINED_BUFFER_H_
#include <math.h>
#include <assert.h>
#include <algorithm>
namespace Chromaprint
{
template<class T>
class CombinedBuffer;
template<class T>
class _CombinedBufferIterator
{
public:
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef int difference_type;
typedef T* pointer;
typedef T& reference;
_CombinedBufferIterator(CombinedBuffer<T> *buffer = 0, int pos = 0)
: m_buffer(buffer)
{
pos += buffer->Offset();
if (pos < buffer->BufferSize(0)) {
m_ptr = buffer->Buffer(0) + pos;
m_ptr_end = buffer->Buffer(0) + buffer->BufferSize(0);
}
else {
pos -= buffer->BufferSize(0);
m_ptr = buffer->Buffer(1) + pos;
m_ptr_end = buffer->Buffer(1) + buffer->BufferSize(1);
}
}
_CombinedBufferIterator<T> &operator=(const _CombinedBufferIterator<T> &rhs)
{
m_buffer = rhs.m_buffer;
m_ptr = rhs.m_ptr;
m_ptr_end = rhs.m_pre_end;
return *this;
}
bool operator==(const _CombinedBufferIterator<T> &rhs) const
{
return (m_ptr == rhs.m_ptr) && (m_buffer == rhs.m_buffer);
}
bool operator!=(const _CombinedBufferIterator<T> &rhs) const
{
return !(operator==(rhs));
}
void operator++()
{
++m_ptr;
if (m_ptr >= m_ptr_end) {
if (m_ptr_end == m_buffer->Buffer(0) + m_buffer->BufferSize(0)) {
m_ptr = m_buffer->Buffer(1);
m_ptr_end = m_buffer->Buffer(1) + m_buffer->BufferSize(1);
}
}
}
void operator++(int)
{
++(*this);
}
short &operator*()
{
assert(m_ptr);
return *m_ptr;
}
private:
CombinedBuffer<T> *m_buffer;
T *m_ptr_end;
T *m_ptr;
};
template<class T>
class CombinedBuffer
{
public:
typedef _CombinedBufferIterator<T> Iterator;
CombinedBuffer(T *buffer1, int size1, T *buffer2, int size2)
: m_offset(0)
{
m_buffer[0] = buffer1;
m_buffer[1] = buffer2;
m_buffer[2] = 0;
m_size[0] = size1;
m_size[1] = size2;
m_size[2] = -1;
}
int Size()
{
return m_size[0] + m_size[1] - m_offset;
}
int Shift(int shift)
{
m_offset += shift;
return m_offset;
}
int Offset() const
{
return m_offset;
}
Iterator Begin()
{
return Iterator(this, 0);
}
Iterator End()
{
return Iterator(this, Size());
}
T &operator[](int i)
{
i += m_offset;
if (i < m_size[0]) {
return m_buffer[0][i];
}
i -= m_size[0];
return m_buffer[1][i];
}
T *Buffer(int i)
{
return m_buffer[i];
}
int BufferSize(int i)
{
return m_size[i];
}
private:
T *m_buffer[3];
int m_size[3];
int m_offset;
};
};
#endif

42
3rdparty/chromaprint/src/debug.h vendored Normal file
View File

@ -0,0 +1,42 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_DEBUG_H_
#define CHROMAPRINT_DEBUG_H_
#ifdef NDEBUG
#include <ostream>
#else
#include <iostream>
#endif
namespace Chromaprint
{
#ifdef NDEBUG
extern std::ostream noop_ostream;
#define DEBUG() if (true) {} else noop_ostream
#else
#define DEBUG() std::cerr
#endif
};
#endif

15
3rdparty/chromaprint/src/decoder.h vendored Normal file
View File

@ -0,0 +1,15 @@
#ifndef CHROMAPRINT_DECODER_H_
#define CHROMAPRINT_DECODER_H_
namespace Chromaprint
{
class Decoder
{
public:
};
};
#endif

View File

@ -0,0 +1,30 @@
#ifndef CHROMAPRINT_EXT_AUDIO_DUMPER_H_
#define CHROMAPRINT_EXT_AUDIO_DUMPER_H_
#include <stdio.h>
#include <string>
#include "audio_consumer.h"
class AudioDumper : public Chromaprint::AudioConsumer
{
public:
AudioDumper(const std::string &file_name)
{
m_file = fopen(file_name.c_str(), "wb");
}
~AudioDumper()
{
fclose(m_file);
}
void Consume(short *input, int length)
{
fwrite(input, sizeof(short), length, m_file);
}
private:
FILE *m_file;
};
#endif

View File

@ -0,0 +1,230 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef FFMPEG_DECODER_H_
#define FFMPEG_DECODER_H_
#include <algorithm>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}
#include "audio_consumer.h"
class Decoder
{
public:
Decoder(const std::string &file_name);
~Decoder();
bool Open();
void Decode(Chromaprint::AudioConsumer *consumer, int max_length = 0);
int Channels()
{
return m_codec_ctx->channels;
}
int SampleRate()
{
return m_codec_ctx->sample_rate;
}
std::string LastError()
{
return m_error;
}
private:
static const int BUFFER_SIZE = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
uint8_t *m_buffer1;
uint8_t *m_buffer2;
std::string m_file_name;
std::string m_error;
AVFormatContext *m_format_ctx;
AVCodecContext *m_codec_ctx;
AVStream *m_stream;
//AVAudioConvert *m_convert_ctx;
};
inline Decoder::Decoder(const std::string &file_name)
: m_file_name(file_name), m_format_ctx(0), m_codec_ctx(0), m_stream(0)
/*, m_convert_ctx(0)*/
{
av_register_all();
av_log_set_level(AV_LOG_ERROR);
m_buffer1 = (uint8_t *)av_malloc(BUFFER_SIZE);
m_buffer2 = (uint8_t *)av_malloc(BUFFER_SIZE);
}
inline Decoder::~Decoder()
{
if (m_codec_ctx) {
avcodec_close(m_codec_ctx);
}
if (m_format_ctx) {
av_close_input_file(m_format_ctx);
}
//av_audio_convert_free(m_convert_ctx);
av_free(m_buffer2);
av_free(m_buffer1);
}
inline bool Decoder::Open()
{
if (av_open_input_file(&m_format_ctx, m_file_name.c_str(), NULL, 0, NULL) != 0) {
m_error = "Couldn't open the file." + m_file_name;
return false;
}
if (av_find_stream_info(m_format_ctx) < 0) {
m_error = "Couldn't find stream information in the file.";
return false;
}
//dump_format(m_format_ctx, 0, m_file_name.c_str(), 0);
for (size_t i = 0; i < m_format_ctx->nb_streams; i++) {
AVCodecContext *avctx = m_format_ctx->streams[i]->codec;
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(52, 20, 0)
if (avctx && avctx->codec_type == CODEC_TYPE_AUDIO) {
#else
if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
#endif
m_stream = m_format_ctx->streams[i];
m_codec_ctx = avctx;
break;
}
}
if (!m_codec_ctx) {
m_error = "Couldn't find any audio stream in the file.";
return false;
}
AVCodec *codec = avcodec_find_decoder(m_codec_ctx->codec_id);
if (!codec) {
m_error = "Unknown codec.";
return false;
}
if (avcodec_open(m_codec_ctx, codec) < 0) {
m_error = "Couldn't open the codec.";
return false;
}
if (m_codec_ctx->sample_fmt != SAMPLE_FMT_S16) {
m_error = "Unsupported sample format.\n";
return false;
}
/*m_convert_ctx = av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
m_codec_ctx->sample_fmt, 1,
NULL, 0);
if (!m_convert_ctx) {
m_error = "Cannot create sample format converter.";
return false;
}*/
if (Channels() <= 0) {
m_error = "Invalid audio stream (no channels).\n";
return false;
}
return true;
}
#include <stdio.h>
inline void Decoder::Decode(Chromaprint::AudioConsumer *consumer, int max_length)
{
AVPacket packet, packet_temp;
int remaining = max_length * SampleRate() * Channels();
int stop = 0;
av_init_packet(&packet);
av_init_packet(&packet_temp);
while (!stop) {
if (av_read_frame(m_format_ctx, &packet) < 0) {
// consumer->Flush();
break;
}
packet_temp.data = packet.data;
packet_temp.size = packet.size;
while (packet_temp.size > 0) {
int buffer_size = BUFFER_SIZE;
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(52, 20, 0)
int consumed = avcodec_decode_audio2(
m_codec_ctx, (int16_t *)m_buffer1, &buffer_size,
packet_temp.data, packet_temp.size);
#else
int consumed = avcodec_decode_audio3(
m_codec_ctx, (int16_t *)m_buffer1, &buffer_size,
&packet_temp);
#endif
if (consumed < 0) {
break;
}
packet_temp.data += consumed;
packet_temp.size -= consumed;
if (buffer_size <= 0) {
continue;
}
int length = buffer_size / 2;
int16_t *audio_buffer = (int16_t *)m_buffer1;
/*if (m_convert_ctx) {
const void *ibuf[6] = { m_buffer1 };
void *obuf[6] = { m_buffer2 };
int istride[6] = { av_get_bits_per_sample_format(m_codec_ctx->sample_fmt) / 8 };
int ostride[6] = { 2 };
if (av_audio_convert(m_convert_ctx, obuf, ostride, ibuf, istride, len) < 0) {
break;
}
length = buffer_size / istride[0];
audio_buffer = (int16_t *)m_buffer2;
}*/
if (max_length) {
length = std::min(remaining, length);
}
consumer->Consume(audio_buffer, length);
if (max_length) {
remaining -= length;
if (remaining <= 0) {
stop = 1;
break;
}
}
}
if (packet.data) {
av_free_packet(&packet);
}
}
}
#endif

View File

@ -0,0 +1,27 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <algorithm>
#include "image_utils.h"
using namespace std;
using namespace Chromaprint;

View File

@ -0,0 +1,108 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_EXT_IMAGE_UTILS_H_
#define CHROMAPRINT_EXT_IMAGE_UTILS_H_
#include <string>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <png++/png.hpp>
#include "image.h"
namespace Chromaprint
{
//! Export image to a PNG file
inline void ExportImage(Image *data, const std::string &file_name, double power = 1.0)
{
static const int kNumColors = 6;
static int colors[][3] = {
{ 0, 0, 0 },
{ 218, 38, 0 },
{ 221, 99, 0 },
{ 255, 253, 0 },
{ 255, 254, 83 },
{ 255, 255, 200 },
{ 255, 255, 255 },
};
png::image<png::rgb_pixel> image(data->NumRows(), data->NumColumns());
double min_value = (*data)[0][0], max_value = (*data)[0][0];
for (size_t y = 0; y < data->NumRows(); y++) {
for (size_t x = 0; x < data->NumColumns(); x++) {
double value = (*data)[y][x];
min_value = std::min(min_value, value);
max_value = std::max(max_value, value);
}
}
//std::cout << "min_value=" << min_value << "\n";
//std::cout << "max_value=" << max_value << "\n";
for (size_t y = 0; y < data->NumRows(); y++) {
for (size_t x = 0; x < data->NumColumns(); x++) {
double value = ((*data)[y][x] - min_value) / (max_value - min_value);
value = pow(value, power);
double color_value = kNumColors * value;
int color_index = int(color_value);
double color_alpha = color_value - color_index;
if (color_index < 0) {
color_index = 0;
color_alpha = 0;
}
else if (color_index > kNumColors) {
color_index = kNumColors;
color_alpha = 0;
}
//std::cout << "value=" << color_value << "\n";
//std::cout << "alpha=" << color_alpha << "\n";
int r = colors[color_index][0] + (colors[color_index+1][0] - colors[color_index][0]) * color_alpha;
int g = colors[color_index][1] + (colors[color_index+1][1] - colors[color_index][1]) * color_alpha;
int b = colors[color_index][2] + (colors[color_index+1][2] - colors[color_index][2]) * color_alpha;
//int color = 255 * vlue + 0.5;
image[data->NumColumns()-x-1][y] = png::rgb_pixel(r, g, b);
}
}
image.write(file_name);
}
//! Export image in a text format (floating point numbers) to any stream
template <class ImageType>
void ExportTextImage(ImageType *image, std::ostream &stream)
{
for (int i = 0; i < image->NumRows(); i++) {
for (int j = 0; j < image->NumColumns(); j++) {
stream << image->Row(i)[j] << " ";
}
stream << "\n";
}
}
//! Export image in a text format (floating point numbers) to a file
template <class ImageType>
void ExportTextImage(ImageType *image, const std::string &file_name)
{
std::fstream out(file_name.c_str(), std::ios::out);
ExportTextImage(image, out);
}
};
#endif

View File

@ -0,0 +1,101 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef FFMPEG_DECODER_H_
#define FFMPEG_DECODER_H_
#include <algorithm>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}
#include "sox_audio_source.h"
#include "audio_consumer.h"
class Decoder
{
public:
Decoder(const std::string &file_name);
~Decoder();
bool Open();
void Decode(Chromaprint::AudioConsumer *consumer, int max_length = 0);
int Channels()
{
return m_source->Channels();
}
int SampleRate()
{
return m_source->SampleRate();
}
std::string LastError()
{
return "";
// return m_error;
}
private:
SoxAudioSource *m_source;
short m_buffer[1024];
};
inline Decoder::Decoder(const std::string &file_name)
{
m_source = new SoxAudioSource(file_name);
m_source->Open();
}
inline Decoder::~Decoder()
{
delete m_source;
}
inline bool Decoder::Open()
{
return true;
}
#include <stdio.h>
inline void Decoder::Decode(Chromaprint::AudioConsumer *consumer, int max_length)
{
int remaining = SampleRate() * Channels() * max_length;
while (true) {
int res = m_source->Read(m_buffer, size_t(1024));
if (res <= 0) {
break;
}
if (max_length) {
res = std::min(res, remaining);
}
consumer->Consume(m_buffer, res);
if (max_length) {
remaining -= res;
if (res <= 0) {
break;
}
}
}
}
#endif

View File

@ -0,0 +1,39 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FEATURE_VECTOR_CONSUMER_H_
#define CHROMAPRINT_FEATURE_VECTOR_CONSUMER_H_
#include <vector>
namespace Chromaprint
{
class FeatureVectorConsumer
{
public:
virtual ~FeatureVectorConsumer() {}
virtual void Consume(std::vector<double> &features) = 0;
};
};
#endif

77
3rdparty/chromaprint/src/fft.cpp vendored Normal file
View File

@ -0,0 +1,77 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <limits>
#include "utils.h"
#include "fft_lib.h"
#include "fft.h"
#include "debug.h"
using namespace std;
using namespace Chromaprint;
FFT::FFT(int frame_size, int overlap, FFTFrameConsumer *consumer)
: m_window(new double[frame_size]),
m_buffer_offset(0),
m_buffer(new short[frame_size]),
m_frame(frame_size),
m_frame_size(frame_size),
m_increment(frame_size - overlap),
m_consumer(consumer)
{
PrepareHammingWindow(m_window, m_window + frame_size);
for (int i = 0; i < frame_size; i++) {
m_window[i] /= numeric_limits<short>::max();
}
m_lib = new FFTLib(frame_size, m_window);
}
FFT::~FFT()
{
delete m_lib;
delete[] m_buffer;
delete[] m_window;
}
void FFT::Reset()
{
m_buffer_offset = 0;
}
void FFT::Consume(short *input, int length)
{
// Special case, just pre-filling the buffer
if (m_buffer_offset + length < m_frame_size) {
copy(input, input + length, m_buffer + m_buffer_offset);
m_buffer_offset += length;
return;
}
// Apply FFT on the available data
CombinedBuffer<short> combined_buffer(m_buffer, m_buffer_offset, input, length);
while (combined_buffer.Size() >= m_frame_size) {
m_lib->ComputeFrame(combined_buffer.Begin(), m_frame.data());
m_consumer->Consume(m_frame);
combined_buffer.Shift(m_increment);
}
// Copy the remaining input data to the internal buffer
copy(combined_buffer.Begin(), combined_buffer.End(), m_buffer);
m_buffer_offset = combined_buffer.Size();
}

62
3rdparty/chromaprint/src/fft.h vendored Normal file
View File

@ -0,0 +1,62 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FFT_H_
#define CHROMAPRINT_FFT_H_
#include <math.h>
#include "utils.h"
#include "fft_frame.h"
#include "fft_frame_consumer.h"
#include "audio_consumer.h"
#include "combined_buffer.h"
namespace Chromaprint
{
class FFTLib;
class FFT : public AudioConsumer
{
public:
FFT(int frame_size, int overlap, FFTFrameConsumer *consumer);
~FFT();
int FrameSize() const { return m_frame_size; }
int Overlap() const { return m_frame_size - m_increment; }
void Reset();
void Consume(short *input, int length);
private:
CHROMAPRINT_DISABLE_COPY(FFT);
double *m_window;
int m_buffer_offset;
short *m_buffer;
FFTFrame m_frame;
int m_frame_size;
int m_increment;
FFTLib *m_lib;
FFTFrameConsumer *m_consumer;
};
};
#endif

69
3rdparty/chromaprint/src/fft_frame.h vendored Normal file
View File

@ -0,0 +1,69 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FFT_FRAME_H_
#define CHROMAPRINT_FFT_FRAME_H_
#include <math.h>
namespace Chromaprint
{
class FFTFrame
{
public:
FFTFrame(int size) : m_size(size)
{
m_data = new double[size];
}
~FFTFrame()
{
delete[] m_data;
}
double Magnitude(int i) const
{
return sqrt(Energy(i));
}
double Energy(int i) const
{
return m_data[i];
}
int size() const
{
return m_size;
}
double *data()
{
return m_data;
}
private:
double *m_data;
int m_size;
};
};
#endif

View File

@ -0,0 +1,38 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FFT_FRAME_CONSUMER_H_
#define CHROMAPRINT_FFT_FRAME_CONSUMER_H_
namespace Chromaprint
{
class FFTFrame;
class FFTFrameConsumer
{
public:
virtual ~FFTFrameConsumer() {}
virtual void Consume(const FFTFrame &frame) = 0;
};
};
#endif

40
3rdparty/chromaprint/src/fft_lib.h vendored Normal file
View File

@ -0,0 +1,40 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FFT_LIB_H_
#define CHROMAPRINT_FFT_LIB_H_
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WITH_AVFFT
#include "fft_lib_avfft.h"
#endif
#ifdef WITH_FFTW3
#include "fft_lib_fftw3.h"
#endif
#ifdef WITH_VDSP
#include "fft_lib_vdsp.h"
#endif
#endif

View File

@ -0,0 +1,60 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "utils.h"
#include "fft_lib_avfft.h"
using namespace std;
using namespace Chromaprint;
FFTLib::FFTLib(int frame_size, double *window)
: m_window(window),
m_frame_size(frame_size)
{
m_input = (float *)av_mallocz(sizeof(float) * frame_size);
int bits = -1;
while (frame_size) {
bits++;
frame_size >>= 1;
}
m_rdft_ctx = av_rdft_init(bits, DFT_R2C);
}
FFTLib::~FFTLib()
{
av_rdft_end(m_rdft_ctx);
av_free(m_input);
}
void FFTLib::ComputeFrame(CombinedBuffer<short>::Iterator input, double *output)
{
ApplyWindow(input, m_window, m_input, m_frame_size, 1.0);
av_rdft_calc(m_rdft_ctx, m_input);
float *in_ptr = m_input;
output[0] = in_ptr[0] * in_ptr[0];
output[m_frame_size / 2] = in_ptr[1] * in_ptr[1];
output += 1;
in_ptr += 2;
for (int i = 1; i < m_frame_size / 2; i++) {
*output++ = in_ptr[0] * in_ptr[0] + in_ptr[1] * in_ptr[1];
in_ptr += 2;
}
}

View File

@ -0,0 +1,53 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FFT_LIB_AVFFT_H_
#define CHROMAPRINT_FFT_LIB_AVFFT_H_
#include <math.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavcodec/avfft.h>
}
#include "combined_buffer.h"
namespace Chromaprint
{
class FFTLib
{
public:
FFTLib(int frame_size, double *window);
~FFTLib();
void ComputeFrame(CombinedBuffer<short>::Iterator input, double *output);
private:
CHROMAPRINT_DISABLE_COPY(FFTLib);
double *m_window;
int m_frame_size;
float *m_input;
RDFTContext *m_rdft_ctx;
};
};
#endif

View File

@ -0,0 +1,58 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "utils.h"
#include "fft_lib_fftw3.h"
using namespace std;
using namespace Chromaprint;
FFTLib::FFTLib(int frame_size, double *window)
: m_frame_size(frame_size),
m_window(window)
{
m_input = (double *)fftw_malloc(sizeof(double) * frame_size);
m_output = (double *)fftw_malloc(sizeof(double) * frame_size);
m_plan = fftw_plan_r2r_1d(frame_size, m_input, m_output, FFTW_R2HC, FFTW_ESTIMATE);
}
FFTLib::~FFTLib()
{
fftw_destroy_plan(m_plan);
fftw_free(m_input);
fftw_free(m_output);
}
void FFTLib::ComputeFrame(CombinedBuffer<short>::Iterator input, double *output)
{
ApplyWindow(input, m_window, m_input, m_frame_size, 1.0);
fftw_execute(m_plan);
double *in_ptr = m_output;
double *rev_in_ptr = m_output + m_frame_size - 1;
output[0] = in_ptr[0] * in_ptr[0];
output[m_frame_size / 2] = in_ptr[m_frame_size / 2] * in_ptr[m_frame_size / 2];
in_ptr += 1;
output += 1;
for (int i = 1; i < m_frame_size / 2; i++) {
*output++ = in_ptr[0] * in_ptr[0] + rev_in_ptr[0] * rev_in_ptr[0];
in_ptr++;
rev_in_ptr--;
}
}

View File

@ -0,0 +1,51 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FFT_LIB_FFTW3_H_
#define CHROMAPRINT_FFT_LIB_FFTW3_H_
#include <math.h>
#include <fftw3.h>
#include "combined_buffer.h"
namespace Chromaprint
{
class FFTLib
{
public:
FFTLib(int frame_size, double *window);
~FFTLib();
void ComputeFrame(CombinedBuffer<short>::Iterator input, double *output);
private:
CHROMAPRINT_DISABLE_COPY(FFTLib);
double *m_window;
int m_frame_size;
double *m_input;
double *m_output;
fftw_plan m_plan;
};
};
#endif

View File

@ -0,0 +1,61 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2011 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "utils.h"
#include "fft_lib_vdsp.h"
using namespace std;
using namespace Chromaprint;
FFTLib::FFTLib(int frame_size, double *window)
: m_window(window),
m_frame_size(frame_size)
{
double log2n = log2(frame_size);
assert(log2n == int(log2n));
m_log2n = int(log2n);
m_input = new float[frame_size];
m_a.realp = new float[frame_size / 2];
m_a.imagp = new float[frame_size / 2];
m_setup = vDSP_create_fftsetup(m_log2n, 0);
}
FFTLib::~FFTLib()
{
vDSP_destroy_fftsetup(m_setup);
delete[] m_a.realp;
delete[] m_a.imagp;
delete[] m_input;
}
void FFTLib::ComputeFrame(CombinedBuffer<short>::Iterator input, double *output)
{
ApplyWindow(input, m_window, m_input, m_frame_size, 1.0);
// XXX we can avoid this ctoz call by changing ApplyWindow, is it worth it?
vDSP_ctoz((DSPComplex *)m_input, 2, &m_a, 1, m_frame_size / 2);
vDSP_fft_zrip(m_setup, &m_a, 1, m_log2n, FFT_FORWARD);
output[0] = m_a.realp[0] * m_a.realp[0];
output[m_frame_size / 2] = m_a.imagp[0] * m_a.imagp[0];
output += 1;
for (int i = 1; i < m_frame_size / 2; i++) {
*output++ = m_a.realp[i] * m_a.realp[i] + m_a.imagp[i] * m_a.imagp[i];
}
}

52
3rdparty/chromaprint/src/fft_lib_vdsp.h vendored Normal file
View File

@ -0,0 +1,52 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2011 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FFT_LIB_VDSP_H_
#define CHROMAPRINT_FFT_LIB_VDSP_H_
#include <math.h>
#include <Accelerate/Accelerate.h>
#include "combined_buffer.h"
namespace Chromaprint
{
class FFTLib
{
public:
FFTLib(int frame_size, double *window);
~FFTLib();
void ComputeFrame(CombinedBuffer<short>::Iterator input, double *output);
private:
CHROMAPRINT_DISABLE_COPY(FFTLib);
double *m_window;
float *m_input;
int m_frame_size;
int m_log2n;
FFTSetup m_setup;
DSPSplitComplex m_a;
};
};
#endif

47
3rdparty/chromaprint/src/filter.cpp vendored Normal file
View File

@ -0,0 +1,47 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <math.h>
#include "filter.h"
#include "filter_utils.h"
using namespace std;
using namespace Chromaprint;
#define COMPARE_FUNC SubtractLog
double Filter::Apply(IntegralImage *image, int x) const
{
switch (m_type) {
case 0:
return Filter0(image, x, m_y, m_width, m_height, COMPARE_FUNC);
case 1:
return Filter1(image, x, m_y, m_width, m_height, COMPARE_FUNC);
case 2:
return Filter2(image, x, m_y, m_width, m_height, COMPARE_FUNC);
case 3:
return Filter3(image, x, m_y, m_width, m_height, COMPARE_FUNC);
case 4:
return Filter4(image, x, m_y, m_width, m_height, COMPARE_FUNC);
case 5:
return Filter5(image, x, m_y, m_width, m_height, COMPARE_FUNC);
}
return 0.0;
}

67
3rdparty/chromaprint/src/filter.h vendored Normal file
View File

@ -0,0 +1,67 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FILTER_H_
#define CHROMAPRINT_FILTER_H_
#include <ostream>
#include "integral_image.h"
namespace Chromaprint
{
class Filter
{
public:
Filter(int type = 0, int y = 0, int height = 0, int width = 0)
: m_type(type), m_y(y), m_height(height), m_width(width)
{}
double Apply(IntegralImage *image, int offset) const;
int type() const { return m_type; }
void set_type(int type) { m_type = type; }
int y() const { return m_y; }
void set_y(int y) { m_y = y; }
int height() const { return m_height; }
void set_height(int height) { m_height = height; }
int width() const { return m_width; }
void set_width(int width) { m_width = width; }
private:
int m_type;
int m_y;
int m_height;
int m_width;
};
inline std::ostream &operator<<(std::ostream &stream, const Filter &f)
{
stream << "Filter(" << f.type() << ", " << f.y() << ", "
<< f.height() << ", " << f.width() << ")";
return stream;
}
};
#endif

136
3rdparty/chromaprint/src/filter_utils.h vendored Normal file
View File

@ -0,0 +1,136 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FILTER_UTILS_H_
#define CHROMAPRINT_FILTER_UTILS_H_
#include <math.h>
#include "integral_image.h"
#include "utils.h"
namespace Chromaprint
{
inline double Subtract(double a, double b)
{
return a - b;
}
inline double SubtractLog(double a, double b)
{
double r = log(1.0 + a) - log(1.0 + b);
assert(!IsNaN(r));
return r;
}
// oooooooooooooooo
// oooooooooooooooo
// oooooooooooooooo
// oooooooooooooooo
template<class Comparator>
double Filter0(IntegralImage *image, int x, int y, int w, int h, Comparator cmp)
{
double a = image->Area(x, y, x + w - 1, y + h - 1);
double b = 0;
return cmp(a, b);
}
// ................
// ................
// oooooooooooooooo
// oooooooooooooooo
template<class Comparator>
double Filter1(IntegralImage *image, int x, int y, int w, int h, Comparator cmp)
{
int h_2 = h / 2;
double a = image->Area(x, y + h_2, x + w - 1, y + h - 1);
double b = image->Area(x, y, x + w - 1, y + h_2 - 1);
return cmp(a, b);
}
// .......ooooooooo
// .......ooooooooo
// .......ooooooooo
// .......ooooooooo
template<class Comparator>
double Filter2(IntegralImage *image, int x, int y, int w, int h, Comparator cmp)
{
int w_2 = w / 2;
double a = image->Area(x + w_2, y, x + w - 1, y + h - 1);
double b = image->Area(x, y, x + w_2 - 1, y + h - 1);
return cmp(a, b);
}
// .......ooooooooo
// .......ooooooooo
// ooooooo.........
// ooooooo.........
template<class Comparator>
double Filter3(IntegralImage *image, int x, int y, int w, int h, Comparator cmp)
{
int w_2 = w / 2;
int h_2 = h / 2;
double a = image->Area(x, y + h_2, x + w_2 - 1, y + h - 1) +
image->Area(x + w_2, y, x + w - 1, y + h_2 - 1);
double b = image->Area(x, y, x + w_2 -1, y + h_2 - 1) +
image->Area(x + w_2, y + h_2, x + w - 1, y + h - 1);
return cmp(a, b);
}
// ................
// oooooooooooooooo
// ................
template<class Comparator>
double Filter4(IntegralImage *image, int x, int y, int w, int h, Comparator cmp)
{
int h_3 = h / 3;
double a = image->Area(x, y + h_3, x + w - 1, y + 2 * h_3 - 1);
double b = image->Area(x, y, x + w - 1, y + h_3 - 1) +
image->Area(x, y + 2 * h_3, x + w - 1, y + h - 1);
return cmp(a, b);
}
// .....oooooo.....
// .....oooooo.....
// .....oooooo.....
// .....oooooo.....
template<class Comparator>
double Filter5(IntegralImage *image, int x, int y, int w, int h, Comparator cmp)
{
int w_3 = w / 3;
double a = image->Area(x + w_3, y, x + 2 * w_3 - 1, y + h - 1);
double b = image->Area(x, y, x + w_3 - 1, y + h - 1) +
image->Area(x + 2 * w_3, y, x + w - 1, y + h - 1);
return cmp(a, b);
}
};
#endif

View File

@ -0,0 +1,67 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "fingerprint_calculator.h"
#include "classifier.h"
#include "debug.h"
#include "utils.h"
using namespace std;
using namespace Chromaprint;
FingerprintCalculator::FingerprintCalculator(const Classifier *classifiers, int num_classifiers)
: m_classifiers(classifiers), m_num_classifiers(num_classifiers)
{
m_max_filter_width = 0;
for (int i = 0; i < num_classifiers; i++) {
m_max_filter_width = max(m_max_filter_width, classifiers[i].filter().width());
}
assert(m_max_filter_width > 0);
}
vector<int32_t> FingerprintCalculator::Calculate(Image *image)
{
int length = image->NumRows() - m_max_filter_width + 1;
if (length <= 0) {
DEBUG() << "Chromaprint::FingerprintCalculator::Calculate() -- Not "
<< "enough data. Image has " << image->NumRows() << " rows, "
<< "needs at least " << m_max_filter_width << " rows.\n";
return vector<int32_t>();
}
IntegralImage integral_image(image);
vector<int32_t> fingerprint(length);
for (int i = 0; i < length; i++) {
fingerprint[i] = CalculateSubfingerprint(&integral_image, i);
}
return fingerprint;
}
int32_t FingerprintCalculator::CalculateSubfingerprint(IntegralImage *image, int offset)
{
uint32_t bits = 0;
for (int i = 0; i < m_num_classifiers; i++) {
//for (int i = m_num_classifiers - 1; i >= 0; i--) {
bits = (bits << 2) | GrayCode(m_classifiers[i].Classify(image, offset));
//bits = (bits << 2) | m_classifiers[i].Classify(image, offset);
}
return UnsignedToSigned(bits);
}

View File

@ -0,0 +1,51 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FINGERPRINT_CALCULATOR_H_
#define CHROMAPRINT_FINGERPRINT_CALCULATOR_H_
#include <stdint.h>
#include <vector>
namespace Chromaprint
{
class Classifier;
class Image;
class IntegralImage;
class FingerprintCalculator
{
public:
FingerprintCalculator(const Classifier *classifiers, int num_classifiers);
std::vector<int32_t> Calculate(Image *image);
int32_t CalculateSubfingerprint(IntegralImage *image, int offset);
private:
const Classifier *m_classifiers;
int m_num_classifiers;
int m_max_filter_width;
};
};
#endif

View File

@ -0,0 +1,92 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <algorithm>
#include "fingerprint_compressor.h"
#include "bit_string_writer.h"
#include "debug.h"
#include "utils.h"
using namespace std;
using namespace Chromaprint;
static const int kMaxNormalValue = 7;
static const int kNormalBits = 3;
static const int kExceptionBits = 5;
FingerprintCompressor::FingerprintCompressor()
{
}
void FingerprintCompressor::ProcessSubfingerprint(uint32_t x)
{
int bit = 1, last_bit = 0;
while (x != 0) {
if ((x & 1) != 0) {
m_bits.push_back(bit - last_bit);
last_bit = bit;
}
x >>= 1;
bit++;
}
m_bits.push_back(0);
}
void FingerprintCompressor::WriteNormalBits()
{
BitStringWriter writer;
for (size_t i = 0; i < m_bits.size(); i++) {
writer.Write(min(int(m_bits[i]), kMaxNormalValue), kNormalBits);
}
writer.Flush();
m_result += writer.value();
}
void FingerprintCompressor::WriteExceptionBits()
{
BitStringWriter writer;
for (size_t i = 0; i < m_bits.size(); i++) {
if (m_bits[i] >= kMaxNormalValue) {
writer.Write(int(m_bits[i]) - kMaxNormalValue, kExceptionBits);
}
}
writer.Flush();
m_result += writer.value();
}
std::string FingerprintCompressor::Compress(const vector<int32_t> &data, int algorithm)
{
if (data.size() > 0) {
ProcessSubfingerprint(data[0]);
for (size_t i = 1; i < data.size(); i++) {
ProcessSubfingerprint(data[i] ^ data[i - 1]);
}
}
int length = data.size();
m_result.resize(4);
m_result[0] = algorithm & 255;
m_result[1] = (length >> 16) & 255;
m_result[2] = (length >> 8) & 255;
m_result[3] = (length ) & 255;
WriteNormalBits();
WriteExceptionBits();
return m_result;
}

View File

@ -0,0 +1,59 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FINGERPRINT_COMPRESSOR_H_
#define CHROMAPRINT_FINGERPRINT_COMPRESSOR_H_
#include <stdint.h>
#include <vector>
#include <string>
namespace Chromaprint
{
class Classifier;
class Image;
class IntegralImage;
class FingerprintCompressor
{
public:
FingerprintCompressor();
std::string Compress(const std::vector<int32_t> &fingerprint, int algorithm = 0);
private:
void WriteNormalBits();
void WriteExceptionBits();
void ProcessSubfingerprint(uint32_t);
std::string m_result;
std::vector<char> m_bits;
};
inline std::string CompressFingerprint(const std::vector<int32_t> &data, int algorithm = 0)
{
FingerprintCompressor compressor;
return compressor.Compress(data, algorithm);
}
};
#endif

View File

@ -0,0 +1,99 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "fingerprint_decompressor.h"
#include "debug.h"
#include "utils.h"
using namespace std;
using namespace Chromaprint;
static const int kMaxNormalValue = 7;
static const int kNormalBits = 3;
static const int kExceptionBits = 5;
FingerprintDecompressor::FingerprintDecompressor()
{
}
void FingerprintDecompressor::UnpackBits()
{
int i = 0, last_bit = 0, value = 0;
for (size_t j = 0; j < m_bits.size(); j++) {
int bit = m_bits[j];
if (bit == 0) {
m_result[i] = (i > 0) ? value ^ m_result[i - 1] : value;
value = 0;
last_bit = 0;
i++;
continue;
}
bit += last_bit;
last_bit = bit;
value |= 1 << (bit - 1);
}
}
void FingerprintDecompressor::ReadNormalBits(BitStringReader *reader)
{
size_t i = 0;
while (i < m_result.size()) {
int bit = reader->Read(kNormalBits);
if (bit == 0) {
i++;
}
m_bits.push_back(bit);
}
}
void FingerprintDecompressor::ReadExceptionBits(BitStringReader *reader)
{
for (size_t i = 0; i < m_bits.size(); i++) {
if (m_bits[i] == kMaxNormalValue) {
m_bits[i] += reader->Read(kExceptionBits);
}
}
}
std::vector<int32_t> FingerprintDecompressor::Decompress(const string &data, int *algorithm)
{
if (algorithm) {
*algorithm = data[0];
}
int length =
((unsigned char)(data[1]) << 16) |
((unsigned char)(data[2]) << 8) |
((unsigned char)(data[3]) );
BitStringReader reader(data);
reader.Read(8);
reader.Read(8);
reader.Read(8);
reader.Read(8);
m_result = vector<int32_t>(length, -1);
reader.Reset();
ReadNormalBits(&reader);
reader.Reset();
ReadExceptionBits(&reader);
UnpackBits();
return m_result;
}

View File

@ -0,0 +1,56 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FINGERPRINT_DECOMPRESSOR_H_
#define CHROMAPRINT_FINGERPRINT_DECOMPRESSOR_H_
#include <stdint.h>
#include <vector>
#include <string>
#include "bit_string_reader.h"
namespace Chromaprint
{
class FingerprintDecompressor
{
public:
FingerprintDecompressor();
std::vector<int32_t> Decompress(const std::string &fingerprint, int *algorithm = 0);
private:
void ReadNormalBits(BitStringReader *reader);
void ReadExceptionBits(BitStringReader *reader);
void UnpackBits();
std::vector<int32_t> m_result;
std::vector<char> m_bits;
};
inline std::vector<int32_t> DecompressFingerprint(const std::string &data, int *algorithm = 0)
{
FingerprintDecompressor decompressor;
return decompressor.Decompress(data, algorithm);
}
};
#endif

View File

@ -0,0 +1,97 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "fingerprinter.h"
#include "chroma.h"
#include "chroma_normalizer.h"
#include "chroma_filter.h"
#include "fft.h"
#include "audio_processor.h"
#include "image_builder.h"
#include "fingerprint_calculator.h"
#include "fingerprinter_configuration.h"
#include "classifier.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;
static const int MIN_FREQ = 28;
static const int MAX_FREQ = 3520;
Fingerprinter::Fingerprinter(FingerprinterConfiguration *config)
: m_image(12)
{
if (!config) {
config = new FingerprinterConfigurationTest1();
}
m_image_builder = new ImageBuilder(&m_image);
m_chroma_normalizer = new ChromaNormalizer(m_image_builder);
m_chroma_filter = new ChromaFilter(config->filter_coefficients(), config->num_filter_coefficients(), m_chroma_normalizer);
m_chroma = new Chroma(MIN_FREQ, MAX_FREQ, FRAME_SIZE, SAMPLE_RATE, m_chroma_filter);
//m_chroma->set_interpolate(true);
m_fft = new FFT(FRAME_SIZE, OVERLAP, m_chroma);
m_audio_processor = new AudioProcessor(SAMPLE_RATE, m_fft);
m_fingerprint_calculator = new FingerprintCalculator(config->classifiers(), config->num_classifiers());
m_config = config;
}
Fingerprinter::~Fingerprinter()
{
delete m_fingerprint_calculator;
delete m_audio_processor;
delete m_fft;
delete m_chroma;
delete m_chroma_filter;
delete m_chroma_normalizer;
delete m_image_builder;
delete m_config;
}
bool Fingerprinter::Start(int sample_rate, int num_channels)
{
if (!m_audio_processor->Reset(sample_rate, num_channels)) {
// FIXME save error message somewhere
return false;
}
m_fft->Reset();
m_chroma->Reset();
m_chroma_filter->Reset();
m_chroma_normalizer->Reset();
m_image = Image(12); // XXX
m_image_builder->Reset(&m_image);
return true;
}
void Fingerprinter::Consume(short *samples, int length)
{
assert(length >= 0);
m_audio_processor->Consume(samples, length);
}
vector<int32_t> Fingerprinter::Finish()
{
m_audio_processor->Flush();
return m_fingerprint_calculator->Calculate(&m_image);
}

View File

@ -0,0 +1,78 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FINGERPRINTER_H_
#define CHROMAPRINT_FINGERPRINTER_H_
#include <stdint.h>
#include <vector>
#include "image.h"
#include "audio_consumer.h"
namespace Chromaprint
{
class ImageBuilder;
class IntegralImage;
class FFT;
class Chroma;
class ChromaNormalizer;
class ChromaFilter;
class AudioProcessor;
class FingerprintCalculator;
class FingerprinterConfiguration;
class Fingerprinter : public AudioConsumer
{
public:
Fingerprinter(FingerprinterConfiguration *config = 0);
~Fingerprinter();
/**
* Initialize the fingerprinting process.
*/
bool Start(int sample_rate, int num_channels);
/**
* Process a block of raw audio data. Call this method as many times
* as you need.
*/
void Consume(short *input, int length);
/**
* Calculate the fingerprint based on the provided audio data.
*/
std::vector<int32_t> Finish();
private:
Image m_image;
ImageBuilder *m_image_builder;
Chroma *m_chroma;
ChromaNormalizer *m_chroma_normalizer;
ChromaFilter *m_chroma_filter;
FFT *m_fft;
AudioProcessor *m_audio_processor;
FingerprintCalculator *m_fingerprint_calculator;
FingerprinterConfiguration *m_config;
};
};
#endif

View File

@ -0,0 +1,107 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "fingerprinter_configuration.h"
#include "utils.h"
using namespace std;
using namespace Chromaprint;
static const int kChromaFilterSize = 5;
static const double kChromaFilterCoefficients[] = { 0.25, 0.75, 1.0, 0.75, 0.25 };
static const Classifier kClassifiersTest1[16] = {
Classifier(Filter(0, 0, 3, 15), Quantizer(2.10543, 2.45354, 2.69414)),
Classifier(Filter(1, 0, 4, 14), Quantizer(-0.345922, 0.0463746, 0.446251)),
Classifier(Filter(1, 4, 4, 11), Quantizer(-0.392132, 0.0291077, 0.443391)),
Classifier(Filter(3, 0, 4, 14), Quantizer(-0.192851, 0.00583535, 0.204053)),
Classifier(Filter(2, 8, 2, 4), Quantizer(-0.0771619, -0.00991999, 0.0575406)),
Classifier(Filter(5, 6, 2, 15), Quantizer(-0.710437, -0.518954, -0.330402)),
Classifier(Filter(1, 9, 2, 16), Quantizer(-0.353724, -0.0189719, 0.289768)),
Classifier(Filter(3, 4, 2, 10), Quantizer(-0.128418, -0.0285697, 0.0591791)),
Classifier(Filter(3, 9, 2, 16), Quantizer(-0.139052, -0.0228468, 0.0879723)),
Classifier(Filter(2, 1, 3, 6), Quantizer(-0.133562, 0.00669205, 0.155012)),
Classifier(Filter(3, 3, 6, 2), Quantizer(-0.0267, 0.00804829, 0.0459773)),
Classifier(Filter(2, 8, 1, 10), Quantizer(-0.0972417, 0.0152227, 0.129003)),
Classifier(Filter(3, 4, 4, 14), Quantizer(-0.141434, 0.00374515, 0.149935)),
Classifier(Filter(5, 4, 2, 15), Quantizer(-0.64035, -0.466999, -0.285493)),
Classifier(Filter(5, 9, 2, 3), Quantizer(-0.322792, -0.254258, -0.174278)),
Classifier(Filter(2, 1, 8, 4), Quantizer(-0.0741375, -0.00590933, 0.0600357))
};
FingerprinterConfigurationTest1::FingerprinterConfigurationTest1()
{
set_classifiers(kClassifiersTest1, 16);
set_filter_coefficients(kChromaFilterCoefficients, kChromaFilterSize);
set_interpolate(false);
}
static const Classifier kClassifiersTest2[16] = {
Classifier(Filter(0, 4, 3, 15), Quantizer(1.98215, 2.35817, 2.63523)),
Classifier(Filter(4, 4, 6, 15), Quantizer(-1.03809, -0.651211, -0.282167)),
Classifier(Filter(1, 0, 4, 16), Quantizer(-0.298702, 0.119262, 0.558497)),
Classifier(Filter(3, 8, 2, 12), Quantizer(-0.105439, 0.0153946, 0.135898)),
Classifier(Filter(3, 4, 4, 8), Quantizer(-0.142891, 0.0258736, 0.200632)),
Classifier(Filter(4, 0, 3, 5), Quantizer(-0.826319, -0.590612, -0.368214)),
Classifier(Filter(1, 2, 2, 9), Quantizer(-0.557409, -0.233035, 0.0534525)),
Classifier(Filter(2, 7, 3, 4), Quantizer(-0.0646826, 0.00620476, 0.0784847)),
Classifier(Filter(2, 6, 2, 16), Quantizer(-0.192387, -0.029699, 0.215855)),
Classifier(Filter(2, 1, 3, 2), Quantizer(-0.0397818, -0.00568076, 0.0292026)),
Classifier(Filter(5, 10, 1, 15), Quantizer(-0.53823, -0.369934, -0.190235)),
Classifier(Filter(3, 6, 2, 10), Quantizer(-0.124877, 0.0296483, 0.139239)),
Classifier(Filter(2, 1, 1, 14), Quantizer(-0.101475, 0.0225617, 0.231971)),
Classifier(Filter(3, 5, 6, 4), Quantizer(-0.0799915, -0.00729616, 0.063262)),
Classifier(Filter(1, 9, 2, 12), Quantizer(-0.272556, 0.019424, 0.302559)),
Classifier(Filter(3, 4, 2, 14), Quantizer(-0.164292, -0.0321188, 0.0846339)),
};
FingerprinterConfigurationTest2::FingerprinterConfigurationTest2()
{
set_classifiers(kClassifiersTest2, 16);
set_filter_coefficients(kChromaFilterCoefficients, kChromaFilterSize);
set_interpolate(false);
}
static const Classifier kClassifiersTest3[16] = {
Classifier(Filter(0, 4, 3, 15), Quantizer(1.98215, 2.35817, 2.63523)),
Classifier(Filter(4, 4, 6, 15), Quantizer(-1.03809, -0.651211, -0.282167)),
Classifier(Filter(1, 0, 4, 16), Quantizer(-0.298702, 0.119262, 0.558497)),
Classifier(Filter(3, 8, 2, 12), Quantizer(-0.105439, 0.0153946, 0.135898)),
Classifier(Filter(3, 4, 4, 8), Quantizer(-0.142891, 0.0258736, 0.200632)),
Classifier(Filter(4, 0, 3, 5), Quantizer(-0.826319, -0.590612, -0.368214)),
Classifier(Filter(1, 2, 2, 9), Quantizer(-0.557409, -0.233035, 0.0534525)),
Classifier(Filter(2, 7, 3, 4), Quantizer(-0.0646826, 0.00620476, 0.0784847)),
Classifier(Filter(2, 6, 2, 16), Quantizer(-0.192387, -0.029699, 0.215855)),
Classifier(Filter(2, 1, 3, 2), Quantizer(-0.0397818, -0.00568076, 0.0292026)),
Classifier(Filter(5, 10, 1, 15), Quantizer(-0.53823, -0.369934, -0.190235)),
Classifier(Filter(3, 6, 2, 10), Quantizer(-0.124877, 0.0296483, 0.139239)),
Classifier(Filter(2, 1, 1, 14), Quantizer(-0.101475, 0.0225617, 0.231971)),
Classifier(Filter(3, 5, 6, 4), Quantizer(-0.0799915, -0.00729616, 0.063262)),
Classifier(Filter(1, 9, 2, 12), Quantizer(-0.272556, 0.019424, 0.302559)),
Classifier(Filter(3, 4, 2, 14), Quantizer(-0.164292, -0.0321188, 0.0846339)),
};
FingerprinterConfigurationTest3::FingerprinterConfigurationTest3()
{
set_classifiers(kClassifiersTest3, 16);
set_filter_coefficients(kChromaFilterCoefficients, kChromaFilterSize);
set_interpolate(true);
}

View File

@ -0,0 +1,126 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_FINGERPRINTER_CONFIGURATION_H_
#define CHROMAPRINT_FINGERPRINTER_CONFIGURATION_H_
#include "classifier.h"
#include "chromaprint.h"
namespace Chromaprint
{
class FingerprinterConfiguration
{
public:
FingerprinterConfiguration()
: m_num_classifiers(0), m_classifiers(0)
{
}
int num_filter_coefficients() const
{
return m_num_filter_coefficients;
}
const double *filter_coefficients() const
{
return m_filter_coefficients;
}
void set_filter_coefficients(const double *filter_coefficients, int size)
{
m_filter_coefficients = filter_coefficients;
m_num_filter_coefficients = size;
}
int num_classifiers() const
{
return m_num_classifiers;
}
const Classifier *classifiers() const
{
return m_classifiers;
}
void set_classifiers(const Classifier *classifiers, int size)
{
m_classifiers = classifiers;
m_num_classifiers = size;
}
bool interpolate() const
{
return m_interpolate;
}
void set_interpolate(bool value)
{
m_interpolate = value;
}
private:
int m_num_classifiers;
const Classifier *m_classifiers;
int m_num_filter_coefficients;
const double *m_filter_coefficients;
bool m_interpolate;
};
// Used for http://oxygene.sk/lukas/2010/07/introducing-chromaprint/
// Trained on a randomly selected test data
class FingerprinterConfigurationTest1 : public FingerprinterConfiguration
{
public:
FingerprinterConfigurationTest1();
};
// Trained on 60k pairs based on eMusic samples (mp3)
class FingerprinterConfigurationTest2 : public FingerprinterConfiguration
{
public:
FingerprinterConfigurationTest2();
};
// Trained on 60k pairs based on eMusic samples with interpolation enabled (mp3)
class FingerprinterConfigurationTest3 : public FingerprinterConfiguration
{
public:
FingerprinterConfigurationTest3();
};
inline FingerprinterConfiguration *CreateFingerprinterConfiguration(int algorithm)
{
switch (algorithm) {
case CHROMAPRINT_ALGORITHM_TEST1:
return new FingerprinterConfigurationTest1();
case CHROMAPRINT_ALGORITHM_TEST2:
return new FingerprinterConfigurationTest2();
case CHROMAPRINT_ALGORITHM_TEST3:
return new FingerprinterConfigurationTest3();
}
return 0;
}
};
#endif

0
3rdparty/chromaprint/src/foo.cpp vendored Normal file
View File

74
3rdparty/chromaprint/src/image.h vendored Normal file
View File

@ -0,0 +1,74 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_IMAGE_H_
#define CHROMAPRINT_IMAGE_H_
#include <vector>
#include <algorithm>
#include <assert.h>
namespace Chromaprint
{
class Image
{
public:
explicit Image(int columns) : m_columns(columns)
{
}
Image(int columns, int rows) : m_columns(columns), m_data(columns * rows)
{
}
template<class Iterator>
Image(int columns, Iterator first, Iterator last) : m_columns(columns), m_data(first, last)
{
}
int NumColumns() const { return m_columns; }
int NumRows() const { return m_data.size() / m_columns; }
void AddRow(const std::vector<double> &row)
{
m_data.resize(m_data.size() + m_columns);
std::copy(row.begin(), row.end(), m_data.end() - m_columns);
}
double *Row(int i)
{
assert(0 <= i && i < NumRows());
return &m_data[m_columns * i];
}
double *operator[](int i)
{
return Row(i);
}
private:
int m_columns;
std::vector<double> m_data;
};
};
#endif

View File

@ -0,0 +1,43 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <limits>
#include <assert.h>
#include <math.h>
#include "image_builder.h"
using namespace std;
using namespace Chromaprint;
ImageBuilder::ImageBuilder(Image *image)
: m_image(image)
{
}
ImageBuilder::~ImageBuilder()
{
}
void ImageBuilder::Consume(std::vector<double> &features)
{
assert(features.size() == (size_t)m_image->NumColumns());
m_image->AddRow(features);
}

View File

@ -0,0 +1,66 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_IMAGE_BUILDER_H_
#define CHROMAPRINT_IMAGE_BUILDER_H_
#include <vector>
#include "utils.h"
#include "image.h"
#include "feature_vector_consumer.h"
namespace Chromaprint
{
/**
* Accepts feature vectors and builds a 2D image out of them.
*/
class ImageBuilder : public FeatureVectorConsumer
{
public:
ImageBuilder(Image *image = 0);
~ImageBuilder();
void Reset(Image *image)
{
set_image(image);
}
void Consume(std::vector<double> &features);
Image *image() const
{
return m_image;
}
void set_image(Image *image)
{
m_image = image;
}
private:
CHROMAPRINT_DISABLE_COPY(ImageBuilder);
Image *m_image;
};
};
#endif

View File

@ -0,0 +1,49 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "integral_image.h"
using namespace std;
using namespace Chromaprint;
void IntegralImage::Transform()
{
int num_rows = m_image->NumRows();
int num_columns = m_image->NumColumns();
double *current = m_image->Row(0) + 1;
double *last = m_image->Row(0);
for (int m = 1; m < num_columns; m++) {
// First column - add value on top
*current = current[0] + current[-1];
++current;
}
for (int n = 1; n < num_rows; n++) {
// First row - add value on left
*current = current[0] + last[0];
++current;
++last;
// Add values on left, up and up-left
for (int m = 1; m < num_columns; m++) {
*current = current[0] + current[-1] + last[0] - last[-1];
++current;
++last;
}
}
}

View File

@ -0,0 +1,87 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_INTEGRAL_IMAGE_H_
#define CHROMAPRINT_INTEGRAL_IMAGE_H_
#include "image.h"
namespace Chromaprint
{
/**
* Image transformation that allows us to quickly calculate the sum of
* values in a rectangular area.
*
* http://en.wikipedia.org/wiki/Summed_area_table
*/
class IntegralImage
{
public:
/**
* Construct the integral image. Note that will modify the original
* image in-place, so it will not be usable afterwards.
*/
IntegralImage(Image *image) : m_image(image)
{
Transform();
}
//! Number of columns in the image
int NumColumns() const { return m_image->NumColumns(); }
//! Number of rows in the image
int NumRows() const { return m_image->NumRows(); }
double *Row(int i)
{
return m_image->Row(i);
}
double *operator[](int i)
{
return m_image->Row(i);
}
double Area(int x1, int y1, int x2, int y2)
{
double area = (*m_image)[x2][y2];
if (x1 > 0) {
area -= (*m_image)[x1-1][y2];
if (y1 > 0) {
area += (*m_image)[x1-1][y1-1];
}
}
if (y1 > 0) {
area -= (*m_image)[x2][y1-1];
}
//std::cout << "Area("<<x1<<","<<y1<<","<<x2<<","<<y2<<") = "<<area<<"\n";
return area;
}
private:
void Transform();
Image *m_image;
};
};
#endif

111
3rdparty/chromaprint/src/lloyds.cpp vendored Normal file
View File

@ -0,0 +1,111 @@
#include <math.h>
#include <assert.h>
#include <algorithm>
//#include <iostream>
#include "lloyds.h"
#include <limits>
using namespace std;
template <typename T>
T min(const vector<T> &array)
{
T m = array.size() ? array[0] : 0;
for (int i = 1; i < array.size(); i++) {
if (array[i] < m) {
m = array[i];
}
}
return m;
}
template <typename T>
T max(const vector<T> &array)
{
T m = array.size() ? array[0] : 0;
for (int i = 1; i < array.size(); i++) {
if (array[i] > m) {
m = array[i];
}
}
return m;
}
inline double sqr(double a)
{
return a * a;
}
/*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;
}*/
vector<double> lloyds(vector<double> &sig, int len)
{
vector<double> x(len-1);
vector<double> q(len);
sort(sig.begin(), sig.end());
// Set initial endpoints
double sig_min = sig[0];
double sig_max = sig[sig.size()-1];
// Initial parameters
for (int i = 0; i < len; i++) {
q[i] = i * (sig_max - sig_min) / (len - 1) + sig_min;
}
for (int i = 0; i < len - 1; i++) {
x[i] = (q[i] + q[i+1]) / 2;
}
double reldist = 1.0, dist = 1.0;
double stop_criteria = max(numeric_limits<double>::epsilon() * fabs(sig_max), 1e-7);
double iteration = 0;
while (reldist > stop_criteria) {
iteration++;
reldist = dist;
dist = 0.0;
size_t sig_it = 0;
for (int i = 0; i < len; i++) {
double sum = 0.0;
int cnt = 0;
while (sig_it < sig.size() && (i == len - 1 || sig[sig_it] < x[i])) {
sum += sig[sig_it];
dist += sqr(sig[sig_it] - q[i]);
++cnt;
++sig_it;
}
if (cnt) {
q[i] = sum / cnt;
}
else if (i == 0) {
q[i] = (sig_min + x[i]) / 2.0;
}
else if (i == len - 1) {
q[i] = (x[i-1] + sig_max) / 2.0;
}
else {
q[i] = (x[i-1] + x[i]) / 2.0;
}
}
dist /= sig.size();
reldist = fabs(reldist - dist);
// Set the endpoints in between the updated quanta
for (int i = 0; i < len - 1; i++) {
x[i] = (q[i] + q[i+1]) / 2.0;
}
}
return x;
}

15
3rdparty/chromaprint/src/lloyds.h vendored Normal file
View File

@ -0,0 +1,15 @@
#ifndef CHROMAPRINT_EXT_LLOYDS_H_
#define CHROMAPRINT_EXT_LLOYDS_H_
#include <vector>
std::vector<double> lloyds(std::vector<double> &sig, int len);
template<class Iterator>
std::vector<double> lloyds(Iterator first, Iterator last, int len)
{
std::vector<double> sig(first, last);
return lloyds(sig, len);
}
#endif

76
3rdparty/chromaprint/src/quantizer.h vendored Normal file
View File

@ -0,0 +1,76 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_QUANTIZER_H_
#define CHROMAPRINT_QUANTIZER_H_
#include <assert.h>
#include <ostream>
namespace Chromaprint
{
class Quantizer
{
public:
Quantizer(double t0 = 0.0, double t1 = 0.0, double t2 = 0.0)
: m_t0(t0), m_t1(t1), m_t2(t2)
{
assert(t0 <= t1 && t1 <= t2);
}
int Quantize(double value) const
{
if (value < m_t1) {
if (value < m_t0) {
return 0;
}
return 1;
}
else {
if (value < m_t2) {
return 2;
}
return 3;
}
}
double t0() const { return m_t0; }
void set_t0(double t) { m_t0 = t; }
double t1() const { return m_t1; }
void set_t1(double t) { m_t1 = t; }
double t2() const { return m_t2; }
void set_t2(double t) { m_t2 = t; }
private:
double m_t0, m_t1, m_t2;
};
inline std::ostream &operator<<(std::ostream &stream, const Quantizer &q)
{
stream << "Quantizer(" << q.t0() << ", " << q.t1() << ", " << q.t2() << ")";
return stream;
}
};
#endif

View File

@ -0,0 +1,65 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <assert.h>
#include <algorithm>
#include "debug.h"
#include "silence_remover.h"
using namespace std;
using namespace Chromaprint;
SilenceRemover::SilenceRemover(AudioConsumer *consumer)
: m_start(true),
m_consumer(consumer)
{
}
bool SilenceRemover::Reset(int sample_rate, int num_channels)
{
if (num_channels != 1) {
DEBUG() << "Chromaprint::SilenceRemover::Reset() -- Expecting mono audio signal.\n";
return false;
}
m_start = true;
return true;
}
void SilenceRemover::Consume(short *input, int length)
{
if (m_start) {
while (length) {
if (*input != 0) {
m_start = false;
break;
}
input++;
length--;
}
}
if (length) {
m_consumer->Consume(input, length);
}
}
void SilenceRemover::Flush()
{
}

View File

@ -0,0 +1,59 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_SILENCE_REMOVER_H_
#define CHROMAPRINT_SILENCE_REMOVER_H_
#include "utils.h"
#include "audio_consumer.h"
namespace Chromaprint
{
class SilenceRemover : public AudioConsumer
{
public:
SilenceRemover(AudioConsumer *consumer);
AudioConsumer *consumer() const
{
return m_consumer;
}
void set_consumer(AudioConsumer *consumer)
{
m_consumer = consumer;
}
bool Reset(int sample_rate, int num_channels);
void Consume(short *input, int length);
void Flush();
private:
CHROMAPRINT_DISABLE_COPY(SilenceRemover);
bool m_start;
AudioConsumer *m_consumer;
};
};
#endif

View File

@ -0,0 +1,71 @@
#include <algorithm>
#include <limits>
#include "sox_audio_source.h"
using namespace std;
static const size_t kBufferSize = 2 * 4096;
bool SoxAudioSource::initialized_ = false;
SoxAudioSource::SoxAudioSource(const string &file_name)
: format_(0), file_name_(file_name)
{
if (!initialized_) {
sox_init();
initialized_ = true;
}
buffer_ = new sox_sample_t[kBufferSize];
}
SoxAudioSource::~SoxAudioSource()
{
Close();
delete[] buffer_;
}
bool SoxAudioSource::Open()
{
Close();
format_ = sox_open_read(file_name_.c_str(), NULL, NULL, NULL);
return format_ != 0;
}
void SoxAudioSource::Close()
{
if (format_) {
sox_close(format_);
format_ = 0;
}
}
int SoxAudioSource::SampleRate()
{
return static_cast<int>(format_->signal.rate);
}
int SoxAudioSource::Channels()
{
return format_->signal.channels;
}
std::size_t SoxAudioSource::Read(short *buffer, std::size_t size)
{
size_t remaining = size;
short *ptr = buffer;
while (remaining > 0) {
size_t res = sox_read(format_, buffer_, std::min(remaining, kBufferSize));
if (res == SOX_EOF || res == 0) {
break;
}
int clips = 0;
for (size_t i = 0; i < res; i++) {
// XXX assumes that short is 16-bit
SOX_SAMPLE_LOCALS;
*ptr++ = SOX_SAMPLE_TO_SIGNED_16BIT(buffer_[i], clips);
}
remaining -= res;
}
//cout << "read " << size - remaining << "\n";
return size - remaining;
}

View File

@ -0,0 +1,29 @@
#ifndef FP_SOX_AUDIO_SOURCE_H_
#define FP_SOX_AUDIO_SOURCE_H_
extern "C" {
#include <sox.h>
}
#include <string>
class SoxAudioSource {
public:
SoxAudioSource(const std::string &file_name);
virtual ~SoxAudioSource();
bool Open();
void Close();
virtual int SampleRate();
virtual int Channels();
virtual std::size_t Length() { return format_->signal.length; }
virtual std::size_t Read(short *buffer, std::size_t size);
private:
static bool initialized_;
std::string file_name_;
sox_format_t *format_;
sox_sample_t *buffer_;
};
#endif

View File

@ -0,0 +1,91 @@
/*
* SpectralCentroidprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <limits>
#include <math.h>
#include "fft_frame.h"
#include "utils.h"
#include "spectral_centroid.h"
using namespace std;
using namespace Chromaprint;
SpectralCentroid::SpectralCentroid(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate, FeatureVectorConsumer *consumer)
: m_bands(num_bands + 1),
m_features(num_bands),
m_consumer(consumer)
{
PrepareBands(num_bands, min_freq, max_freq, frame_size, sample_rate);
}
SpectralCentroid::~SpectralCentroid()
{
}
void SpectralCentroid::PrepareBands(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate)
{
double min_bark = FreqToBark(min_freq);
double max_bark = FreqToBark(max_freq);
double band_size = (max_bark - min_bark) / num_bands;
int min_index = FreqToIndex(min_freq, frame_size, sample_rate);
//int max_index = FreqToIndex(max_freq, frame_size, sample_rate);
m_bands[0] = min_index;
double prev_bark = min_bark;
for (int i = min_index, b = 0; i < frame_size / 2; i++) {
double freq = IndexToFreq(i, frame_size, sample_rate);
double bark = FreqToBark(freq);
if (bark - prev_bark > band_size) {
b += 1;
prev_bark = bark;
m_bands[b] = i;
if (b >= num_bands) {
break;
}
}
}
}
void SpectralCentroid::Reset()
{
}
void SpectralCentroid::Consume(const FFTFrame &frame)
{
for (int i = 0; i < NumBands(); i++) {
int first = FirstIndex(i);
int last = LastIndex(i);
double numerator = 0.0;
double denominator = 0.0;
for (int j = first; j < last; j++) {
double s = frame.Energy(j);
numerator += j * s;
denominator += s;
}
double centroid = numerator / denominator;
if (centroid != centroid)
centroid = (first + last) / 2.0; // handle NaN
m_features[i] = (centroid - first) / (last - first);
}
m_consumer->Consume(m_features);
}

View File

@ -0,0 +1,59 @@
/*
* SpectralCentroidprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_SPECTRAL_CENTROID_H_
#define CHROMAPRINT_SPECTRAL_CENTROID_H_
#include <math.h>
#include <vector>
#include "utils.h"
#include "fft_frame_consumer.h"
#include "feature_vector_consumer.h"
namespace Chromaprint
{
class SpectralCentroid : public FFTFrameConsumer
{
public:
SpectralCentroid(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate, FeatureVectorConsumer *consumer);
~SpectralCentroid();
void Reset();
void Consume(const FFTFrame &frame);
protected:
int NumBands() const { return m_bands.size() - 1; }
int FirstIndex(int band) const { return m_bands[band]; }
int LastIndex(int band) const { return m_bands[band + 1]; }
private:
CHROMAPRINT_DISABLE_COPY(SpectralCentroid);
void PrepareBands(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate);
std::vector<int> m_bands;
std::vector<double> m_features;
FeatureVectorConsumer *m_consumer;
};
};
#endif

88
3rdparty/chromaprint/src/spectrum.cpp vendored Normal file
View File

@ -0,0 +1,88 @@
/*
* Spectrumprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <limits>
#include <math.h>
#include "fft_frame.h"
#include "utils.h"
#include "spectrum.h"
using namespace std;
using namespace Chromaprint;
Spectrum::Spectrum(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate, FeatureVectorConsumer *consumer)
: m_bands(num_bands + 1),
m_features(num_bands),
m_consumer(consumer)
{
PrepareBands(num_bands, min_freq, max_freq, frame_size, sample_rate);
}
Spectrum::~Spectrum()
{
}
void Spectrum::PrepareBands(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate)
{
double min_bark = FreqToBark(min_freq);
double max_bark = FreqToBark(max_freq);
double band_size = (max_bark - min_bark) / num_bands;
int min_index = FreqToIndex(min_freq, frame_size, sample_rate);
//int max_index = FreqToIndex(max_freq, frame_size, sample_rate);
m_bands[0] = min_index;
double prev_bark = min_bark;
for (int i = min_index, b = 0; i < frame_size / 2; i++) {
double freq = IndexToFreq(i, frame_size, sample_rate);
double bark = FreqToBark(freq);
if (bark - prev_bark > band_size) {
b += 1;
prev_bark = bark;
m_bands[b] = i;
if (b >= num_bands) {
break;
}
}
}
}
void Spectrum::Reset()
{
}
void Spectrum::Consume(const FFTFrame &frame)
{
for (int i = 0; i < NumBands(); i++) {
int first = FirstIndex(i);
int last = LastIndex(i);
double numerator = 0.0;
double denominator = 0.0;
for (int j = first; j < last; j++) {
double s = frame.Energy(j);
numerator += j * s;
denominator += s;
}
m_features[i] = denominator / (last - first);
}
m_consumer->Consume(m_features);
}

59
3rdparty/chromaprint/src/spectrum.h vendored Normal file
View File

@ -0,0 +1,59 @@
/*
* SpectralCentroidprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_SPECTRUM_H_
#define CHROMAPRINT_SPECTRUM_H_
#include <math.h>
#include <vector>
#include "utils.h"
#include "fft_frame_consumer.h"
#include "feature_vector_consumer.h"
namespace Chromaprint
{
class Spectrum : public FFTFrameConsumer
{
public:
Spectrum(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate, FeatureVectorConsumer *consumer);
~Spectrum();
void Reset();
void Consume(const FFTFrame &frame);
protected:
int NumBands() const { return m_bands.size() - 1; }
int FirstIndex(int band) const { return m_bands[band]; }
int LastIndex(int band) const { return m_bands[band + 1]; }
private:
CHROMAPRINT_DISABLE_COPY(Spectrum);
void PrepareBands(int num_bands, int min_freq, int max_freq, int frame_size, int sample_rate);
std::vector<int> m_bands;
std::vector<double> m_features;
FeatureVectorConsumer *m_consumer;
};
};
#endif

154
3rdparty/chromaprint/src/utils.h vendored Normal file
View File

@ -0,0 +1,154 @@
/*
* Chromaprint -- Audio fingerprinting toolkit
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef CHROMAPRINT_UTILS_H_
#define CHROMAPRINT_UTILS_H_
#if defined(HAVE_CONFIG_H)
#include <config.h>
#endif
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <limits>
#include <iterator>
#ifndef HAVE_ROUND
static inline double round(double x)
{
if (x >= 0.0)
return floor(x + 0.5);
else
return ceil(x - 0.5);
}
#endif
#define CHROMAPRINT_DISABLE_COPY(ClassName) \
ClassName(const ClassName &); \
void operator=(const ClassName &);
//#include <iostream>
namespace Chromaprint
{
template<class RandomAccessIterator>
void PrepareHammingWindow(RandomAccessIterator first, RandomAccessIterator last)
{
size_t i = 0, max_i = last - first - 1;
double scale = 2. * M_PI / max_i;
while (first != last) {
*first++ = 0.54 - 0.46 * cos(scale * i++);
}
}
template<class InputIterator1, class InputIterator2, class OutputIterator>
void ApplyWindow(InputIterator1 input, InputIterator2 window, OutputIterator output, int size, double scale)
{
while (size--) {
*output = *input * *window * scale;
++input;
++window;
++output;
}
}
template<class Iterator>
typename std::iterator_traits<Iterator>::value_type Sum(Iterator first, Iterator last)
{
typename std::iterator_traits<Iterator>::value_type sum = 0;
while (first != last) {
sum += *first;
++first;
}
return sum;
}
template<class Iterator>
typename std::iterator_traits<Iterator>::value_type EuclideanNorm(Iterator first, Iterator last)
{
typename std::iterator_traits<Iterator>::value_type squares = 0;
while (first != last) {
squares += *first * *first;
++first;
}
return (squares > 0) ? sqrt(squares) : 0;
}
template<class Iterator, class Func>
void NormalizeVector(Iterator first, Iterator last, Func func, double threshold = 0.01)
{
double norm = func(first, last);
if (norm < threshold) {
std::fill(first, last, 0.0);
}
else {
while (first != last) {
*first /= norm;
++first;
}
}
}
inline int GrayCode(int i)
{
static const unsigned char CODES[] = { 0, 1, 3, 2 };
return CODES[i];
}
inline double IndexToFreq(int i, int frame_size, int sample_rate)
{
return double(i) * sample_rate / frame_size;
}
inline int FreqToIndex(double freq, int frame_size, int sample_rate)
{
return (int)round(frame_size * freq / sample_rate);
}
inline int32_t UnsignedToSigned(uint32_t x)
{
return *((int32_t *)&x);
//return x & 0x80000000 ? x & 0x7FFFFFFF - 0x80000000 : x;
}
template<class T>
inline bool IsNaN(T value)
{
return value != value;
}
inline double FreqToBark(double f)
{
double z = (26.81 * f) / (1960.0 + f) - 0.53;
if (z < 2.0) {
z = z + 0.15 * (2.0 - z);
} else if (z > 20.1) {
z = z + 0.22 * (z - 20.1);
}
return z;
}
};
#endif

View File

@ -0,0 +1,41 @@
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
)

View File

@ -0,0 +1,21 @@
#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;
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

8
3rdparty/chromaprint/tests/main.cpp vendored Normal file
View File

@ -0,0 +1,8 @@
#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 Normal file
View File

@ -0,0 +1,99 @@
#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]);
}

View File

@ -0,0 +1,114 @@
#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;
}
}

View File

@ -0,0 +1,56 @@
#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)));
}

View File

@ -0,0 +1,47 @@
#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));
}

View File

@ -0,0 +1,53 @@
#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]));
}

Some files were not shown because too many files have changed in this diff Show More