Merge branch 'master' into appearance

This commit is contained in:
Arnaud Bienner 2012-01-09 20:15:10 +01:00
commit c2d794c014
220 changed files with 9528 additions and 8769 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

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

@ -0,0 +1,110 @@
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(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
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)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
add_subdirectory(src)

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!

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@"

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

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

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

@ -1,3 +0,0 @@
*.o
*.dylib
*.so

View File

@ -1,26 +0,0 @@
See the LICENSE file for important license information.
Whitening, SubbandAnalysis, Fingerprint
Dan Ellis <dpwe@ee.columbia.edu>
Brian Whitman <brian@echonest.com>
AudioBufferInput, AudioStreamInput, Codegen, Common, File, MatrixUtility, Metadata
Tristan Jehan <tristan@echonest.com>
Paul Lamere <paul@echonest.com>
Jason Sundram <jsundram@gmail.com>
Brian Whitman <brian@echonest.com>
Murmurhash2
Austin Appleby
Base64
Rene Nyffenegger
Contributors
Alastair Porter <alastair@porter.net.nz>
efsavage
alsuren
artgillespie
yhorng
divan

View File

@ -1,25 +0,0 @@
set(ECHOPRINT-SOURCES
src/AudioBufferInput.cxx
src/AudioStreamInput.cxx
src/Base64.cxx
src/Codegen.cxx
src/Fingerprint.cxx
src/MatrixUtility.cxx
src/Metadata.cxx
src/SubbandAnalysis.cxx
src/Whitening.cxx
)
include_directories(${Boost_INCLUDE_DIRS})
add_library(echoprint STATIC ${ECHOPRINT-SOURCES})
set_target_properties(echoprint PROPERTIES
COMPILE_DEFINITIONS "BOOST_UBLAS_NDEBUG;NDEBUG")
if(NOT WIN32)
set_target_properties(echoprint PROPERTIES
COMPILE_FLAGS "-O3 -fPIC")
else(NOT WIN32)
set_target_properties(echoprint PROPERTIES
COMPILE_FLAGS "-O3")
endif(NOT WIN32)

View File

@ -1,44 +0,0 @@
echoprint-codegen is open source software licensed under the "MIT License"
More information about the MIT License: http://en.wikipedia.org/wiki/MIT_License
Copyright (c) 2011 The Echo Nest Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
libcodegen makes use of the following pieces of software:
- Murmurhash by Austin Appleby (Public Domain / MIT)
http://sites.google.com/site/murmurhash/
- Boost (Boost Software License)
http://www.boost.org/users/license.html
- Base64.cpp and Base64.h, see source files for license
Copyright (C) 2004-2008 René Nyffenegger
codegen (the example binary that the makefile also builds) makes use of libcodegen and:
- Taglib (LGPL)
http://developer.kde.org/~wheeler/taglib.html
- ffmpeg (via system shell, you must install ffmpeg on your own)
http://www.ffmpeg.org/legal.html

View File

@ -1,93 +0,0 @@
# Codegen for Echoprint
Echoprint is an open source music fingerprint and resolving framework powered by the [The Echo Nest](http://the.echonest.com/ "The Echo Nest"). The [code generator](http://github.com/echonest/echoprint-codegen "echoprint-codegen") (library to convert PCM samples from a microphone or file into Echoprint codes) is open source (MIT licensed) and free for any use. The [server component](http://github.com/echonest/echoprint-server "echoprint-server") that stores and resolves queries is open source (Apache 2 licensed) and free for any use. The [data for resolving to millions of songs](http://echoprint.me/data "Echoprint Data") is free for any use provided any changes or additions are merged back to the community.
[Read more about Echoprint here](http://echoprint.me)
There are two modes of operation of the Echoprint codegen:
1. the codegen library (libcodegen) is meant to be linked into code that passes it a buffer of PCM data and will output a code string.
2. the codegen binary runs standalone, accepts filenames as inputs and runs in a multithreaded worker mode.
## Requirements
### For libcodegen
* Boost >= 1.35
* zlib
### Additional requirements for the codegen binary
* [TagLib](http://developer.kde.org/~wheeler/taglib.html "TagLib")
* ffmpeg - this is called via shell and is not linked into codegen
On Ubuntu or Debian you can install these dependencies with:
sudo apt-get install ffmpeg libboost1.42-dev libtag1-dev zlib1g-dev
On OS-X with homebrew you can use:
brew install ffmpeg boost taglib
## Notes about libcodegen:
Code generation takes a buffer of floating point PCM data sampled at 11025 Hz and mono.
Codegen * pCodegen = new Codegen(const float* pcm, uint numSamples, int start_offset);
pcm: a buffer of floats, mono, 11025 Hz
numSamples: the number of samples
start_offset: creates a hint to the server on where the sample is taken from in the original file if known
string code = pCodegen->getCodeString();
The code string is just a base64 encoding of a zlib compression of the original code string, which is a hex encoded series of ASCII numbers. See API/fp.py in echoprint-server for decoding help.
You only need to query for 20 seconds of audio to get a result.
## Notes about the codegen binary
The makefile builds an example code generator that uses libcodegen, called "codegen." This code generator has more features -- it will output ID3 tag information and uses ffmpeg to decode any type of file. If you don't need to compile libcodegen into your app you can rely on this. Note that you need to have ffmpeg installed and accessible on your path for this to work.
./echoprint-codegen billie_jean.mp3 10 30
Will take 30 seconds of audio from 10 seconds into the file and output JSON suitable for querying:
{"metadata":{"artist":"Michael jackson", "release":"800 chansons des annes 80", "title":"Billie jean", "genre":"", "bitrate":192, "sample_rate":44100, "seconds":294, "filename":"billie_jean.mp3", "samples_decoded":220598, "given_duration":30, "start_offset":10, "version":4.00}, "code_count":846, "code":"JxVlIuNwzAMQ1fxCDL133+xo1rnGqNAEcWy/ERa2aKeZmW...
You can POST this JSON directly to the Echo Nest's [song/identify](http://developer.echonest.com/docs/v4/song.html#identify "song/identify") (who has an Echoprint server booted), for example:
curl -F "query=@post_string" http://developer.echonest.com/api/v4/song/identify?api_key=YOUR_KEY
{"fp_lookup_time_ms": 21, "results": [{"songID": "SOAFVGQ1280ED4E371", "match_type": "fp", "title": "Billie Jean", "artist": "Michael Jackson", "artistID": "ARXPPEY1187FB51DF4", "score": 63, "release": "Thriller"}]
(you can also use GET, see the API description)
Or you can host your own [Echoprint server](http://github.com/echonest/echoprint-server "echoprint-server") and ingest or query to that.
Codegen also runs in a multithreaded mode for bulk resolving:
./echoprint-codegen -s 10 30 < file_list
Will compute codes for every file in file_list for 30 seconds starting at 10 seconds. (It tries to be smart about the number of threads to use.) It will output a JSON list. Note that song/identify can accept lists in the JSON, which will be faster than sending each code one at a time. The "tag" parameter is added to each code dictionary to match the resolving material.
## Statistics
### Speed
Codegen scans audio at roughly 250x real time per processor after decoding and resampling to 11025 Hz. This means a full song can be scanned in less than 0.5s on an average computer, and an amount of audio suitable for querying (30s) can be scanned in less than 0.04s.
Decoding from MP3 will be the bottleneck for most implementations. Decoders like mpg123 or ffmpeg can decode 30s mp3 audio to 11025 PCM in under 0.10s.
clump:echoprint-codegen bwhitman$ time mpg123 -q -s -4 -n 1200 song.mp3 > /dev/null
real 0m0.079s
user 0m0.067s
sys 0m0.007s
### Accuracy
Look at http://echoprint.me for information on the accuracy of the echoprint system.
## FAQ
Q: I get "Couldn't decode any samples with: ffmpeg" when running codegen
A: When running the example code generator (echoprint-codegen) make sure ffmpeg is accessible to your path. Try running ffmpeg filename.mp3 on the file you are testing the code generator with. If it doesn't work, codegen won't work.

View File

@ -1,29 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include <string.h>
#include <limits.h>
#include <assert.h>
#include "AudioBufferInput.h"
AudioBufferInput::AudioBufferInput() { }
void AudioBufferInput::SetBuffer(const float* pBuffer, uint numSamples) {
_NumberSamples = numSamples;
_pSamples = new float[_NumberSamples]; // base-class destructor will clean this up.
memcpy(_pSamples, pBuffer, numSamples*sizeof(float));
}
void AudioBufferInput::SaveBuffer(const char*filename) {
FILE *out = fopen(filename,"wb");
fwrite(&_NumberSamples, sizeof(int), 1, out);
uint mn = 1;
fwrite(&mn, sizeof(int), 1, out);
fwrite(_pSamples, 4, _NumberSamples, out);
fclose(out);
}

View File

@ -1,30 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include "Common.h"
#include <iostream>
#include <string>
#ifndef AUDIOBUFFERINPUT_H
#define AUDIOBUFFERINPUT_H
#include "Params.h"
#include "AudioStreamInput.h"
class AudioBufferInput : public AudioStreamInput {
public:
AudioBufferInput();
std::string GetName() {return "direct buffer";}
void SaveBuffer(const char*filename);
void SetBuffer(const float* pBuffer, uint numSamples);
protected:
std::string GetCommandLine(const char*){return "";}
private:
};
#endif

View File

@ -1,132 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include <stddef.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#ifndef _WIN32
#include <unistd.h>
#define POPEN_MODE "r"
#else
#include "win_unistd.h"
#include <winsock.h>
#define POPEN_MODE "rb"
#endif
#include <string.h>
#include "AudioStreamInput.h"
#include "Common.h"
#include "Params.h"
using std::string;
namespace FFMPEG {
// Do we think FFmpeg will read this as an audio file?
bool IsAudioFile(const char* pFileName) {
static const char* supportedExtensions[] = {".mp3", ".m4a", ".mp4", ".aif", ".aiff", ".flac", ".au", ".wav", ".aac", ".flv"};
// Not an exhaustive list. ogg and rm could be added if tested.
for (uint i = 0; i < NELEM(supportedExtensions); i++) {
if (File::ends_with(pFileName, supportedExtensions[i]))
return true;
}
return false;
}
}
bool AudioStreamInput::IsSupported(const char *path) {
return true; // Take a crack at anything, by default. The worst thing that will happen is that we fail.
}
AudioStreamInput::AudioStreamInput() : _pSamples(NULL), _NumberSamples(0), _Offset_s(0), _Seconds(0) {}
AudioStreamInput::~AudioStreamInput() {
if (_pSamples != NULL)
delete [] _pSamples, _pSamples = NULL;
}
bool AudioStreamInput::ProcessFile(const char* filename, int offset_s/*=0*/, int seconds/*=0*/) {
if (!File::Exists(filename) || !IsSupported(filename))
return false;
_Offset_s = offset_s;
_Seconds = seconds;
std::string message = GetCommandLine(filename);
FILE* fp = popen(message.c_str(), POPEN_MODE);
bool ok = (fp != NULL);
if (ok)
{
bool did_work = ProcessFilePointer(fp);
bool succeeded = !pclose(fp);
ok = did_work && succeeded;
}
else
fprintf(stderr, "AudioStreamInput::ProcessFile can't open %s\n", filename);
return ok;
}
// reads raw signed 16-bit shorts from a file
bool AudioStreamInput::ProcessRawFile(const char* rawFilename) {
FILE* fp = fopen(rawFilename, "r"); // TODO: Windows
bool ok = (fp != NULL);
if (ok)
{
ok = ProcessFilePointer(fp);
fclose(fp);
}
return ok;
}
// reads raw signed 16-bit shorts from stdin, for example:
// ffmpeg -i fille.mp3 -f s16le -ac 1 -ar 11025 - | TestAudioSTreamInput
bool AudioStreamInput::ProcessStandardInput(void) {
// TODO - Windows will explodey at not setting O_BINARY on stdin.
return ProcessFilePointer(stdin);
}
bool AudioStreamInput::ProcessFilePointer(FILE* pFile) {
std::vector<short*> vChunks;
uint nSamplesPerChunk = (uint) Params::AudioStreamInput::SamplingRate * Params::AudioStreamInput::SecondsPerChunk;
uint samplesRead = 0;
do {
short* pChunk = new short[nSamplesPerChunk];
samplesRead = fread(pChunk, sizeof (short), nSamplesPerChunk, pFile);
_NumberSamples += samplesRead;
vChunks.push_back(pChunk);
} while (samplesRead > 0);
// Convert from shorts to 16-bit floats and copy into sample buffer.
uint sampleCounter = 0;
_pSamples = new float[_NumberSamples];
uint samplesLeft = _NumberSamples;
for (uint i = 0; i < vChunks.size(); i++)
{
short* pChunk = vChunks[i];
uint numSamples = samplesLeft < nSamplesPerChunk ? samplesLeft : nSamplesPerChunk;
for (uint j = 0; j < numSamples; j++)
_pSamples[sampleCounter++] = (float) pChunk[j] / 32768.0f;
samplesLeft -= numSamples;
delete [] pChunk, vChunks[i] = NULL;
}
assert(samplesLeft == 0);
int error = ferror(pFile);
bool success = error == 0;
if (!success)
perror("ProcessFilePointer error");
return success;
}

View File

@ -1,97 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#ifndef AUDIOSTREAMINPUT_H
#define AUDIOSTREAMINPUT_H
#include "Common.h"
#include "Params.h"
#include <iostream>
#include <string>
#include <math.h>
#include "File.h"
#if defined(_WIN32) && !defined(__MINGW32__)
#define and &&
#define snprintf _snprintf
#endif
class AudioStreamInput {
public:
AudioStreamInput();
virtual ~AudioStreamInput();
virtual bool ProcessFile(const char* filename, int offset_s=0, int seconds=0);
virtual std::string GetName() = 0;
bool ProcessRawFile(const char* rawFilename);
bool ProcessStandardInput(void);
bool ProcessFilePointer(FILE* pFile);
int getNumSamples() const {return _NumberSamples;}
const float* getSamples() {return _pSamples;}
double getDuration() { return (double)getNumSamples() / Params::AudioStreamInput::SamplingRate; }
virtual bool IsSupported(const char* pFileName); //Everything ffmpeg can do, by default
int GetOffset() const { return _Offset_s;}
int GetSeconds() const { return _Seconds;}
protected:
virtual std::string GetCommandLine(const char* filename) = 0;
static bool ends_with(const char *s, const char *ends_with);
float* _pSamples;
uint _NumberSamples;
int _Offset_s;
int _Seconds;
};
class StdinStreamInput : public AudioStreamInput {
public:
std::string GetName(){return "stdin";};
protected:
bool IsSupported(const char* pFileName){ return (std::string("stdin") == pFileName);};
bool ProcessFile(const char* filename){ return ProcessStandardInput();}
virtual std::string GetCommandLine(const char* filename){return "";} // hack
};
class FfmpegStreamInput : public AudioStreamInput {
public:
std::string GetName(){return "ffmpeg";};
protected:
std::string GetCommandLine(const char* filename) {
// TODO: Windows
char message[4096] = {0};
if (_Offset_s == 0 and _Seconds == 0)
snprintf(message, NELEM(message), "ffmpeg -i \"%s\" -ac %d -ar %d -f s16le - 2>/dev/null",
filename, Params::AudioStreamInput::Channels, (uint) Params::AudioStreamInput::SamplingRate);
else
snprintf(message, NELEM(message), "ffmpeg -i \"%s\" -ac %d -ar %d -f s16le -t %d -ss %d - 2>/dev/null",
filename, Params::AudioStreamInput::Channels, (uint) Params::AudioStreamInput::SamplingRate, _Seconds, _Offset_s);
return std::string(message);
}
};
namespace FFMPEG {
bool IsAudioFile(const char* pFileName);
};
class Mpg123StreamInput : public AudioStreamInput {
public:
std::string GetName(){return "mpg123";};
protected:
#define FRAMES_PER_SECOND 38.2813f
bool IsSupported(const char* pFileName){ return File::ends_with(pFileName, ".mp3");};
std::string GetCommandLine(const char* filename) {
char message[4096] = {0};
if (_Offset_s == 0 and _Seconds == 0)
snprintf(message, NELEM(message), "mpg123 --quiet --singlemix --stdout --rate %d \"%s\"",
(uint) Params::AudioStreamInput::SamplingRate, filename);
else
snprintf(message, NELEM(message), "mpg123 --quiet --singlemix --stdout --rate %d --skip %d --frames %d \"%s\"",
(uint) Params::AudioStreamInput::SamplingRate, (uint)(_Offset_s * FRAMES_PER_SECOND) /* unprecise */, (uint)ceilf(_Seconds * FRAMES_PER_SECOND) /* unprecise */, filename);
return std::string(message);
}
};
#endif

View File

@ -1,141 +0,0 @@
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#include "Base64.h"
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static const std::string base64_chars_url =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789-_";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
static inline bool is_base64_url(unsigned char c) {
return (isalnum(c) || (c == '-') || (c == '_'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len, bool url) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++) {
if (url)
ret += base64_chars_url[char_array_4[i]];
else
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++){
if (url)
ret += base64_chars_url[char_array_4[j]];
else
ret += base64_chars[char_array_4[j]];
}
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}

View File

@ -1,10 +0,0 @@
#ifndef BASE64_H
#define BASE64_H
#include <string>
std::string base64_encode(unsigned char const* , unsigned int len, bool url);
std::string base64_decode(std::string const& s);
#endif

View File

@ -1,96 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include <sstream>
#include <iostream>
#include <iomanip>
#include <memory>
#include "Codegen.h"
#include "AudioBufferInput.h"
#include "Fingerprint.h"
#include "Whitening.h"
#include "SubbandAnalysis.h"
#include "Fingerprint.h"
#include "Common.h"
#include "Base64.h"
#include <zlib.h>
#define VERSION 4.11
using namespace std;
float Codegen::getVersion() {
return VERSION;
}
Codegen::Codegen(const float* pcm, uint numSamples, int start_offset) {
if (Params::AudioStreamInput::MaxSamples < (uint)numSamples)
throw std::runtime_error("File was too big\n");
Whitening *pWhitening = new Whitening(pcm, numSamples);
pWhitening->Compute();
AudioBufferInput *pAudio = new AudioBufferInput();
pAudio->SetBuffer(pWhitening->getWhitenedSamples(), pWhitening->getNumSamples());
SubbandAnalysis *pSubbandAnalysis = new SubbandAnalysis(pAudio);
pSubbandAnalysis->Compute();
Fingerprint *pFingerprint = new Fingerprint(pSubbandAnalysis, start_offset);
pFingerprint->Compute();
_CodeString = createCodeString(pFingerprint->getCodes());
_NumCodes = pFingerprint->getCodes().size();
delete pFingerprint;
delete pSubbandAnalysis;
delete pWhitening;
delete pAudio;
}
string Codegen::createCodeString(vector<FPCode> vCodes) {
if (vCodes.size() < 3) {
return "";
}
std::ostringstream codestream;
codestream << std::setfill('0') << std::hex;
for (uint i = 0; i < vCodes.size(); i++)
codestream << std::setw(5) << vCodes[i].frame;
for (uint i = 0; i < vCodes.size(); i++) {
int hash = vCodes[i].code;
codestream << std::setw(5) << hash;
}
return compress(codestream.str());
}
string Codegen::compress(const string& s) {
long max_compressed_length = s.size()*2;
unsigned char *compressed = new unsigned char[max_compressed_length];
// zlib the code string
z_stream stream;
stream.next_in = (Bytef*)(unsigned char*)s.c_str();
stream.avail_in = (uInt)s.size();
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
deflateInit(&stream, Z_DEFAULT_COMPRESSION);
do {
stream.next_out = compressed;
stream.avail_out = max_compressed_length;
if(deflate(&stream, Z_FINISH) == Z_STREAM_END) break;
} while (stream.avail_out == 0);
uint compressed_length = stream.total_out;
deflateEnd(&stream);
// base64 the zlib'd code string
string encoded = base64_encode(compressed, compressed_length, true);
delete [] compressed;
return encoded;
}

View File

@ -1,48 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#ifndef CODEGEN_H
#define CODEGEN_H
// Entry point for generating codes from PCM data.
#include <string>
#include <vector>
#include <sys/types.h>
#ifdef _MSC_VER
#ifdef CODEGEN_EXPORTS
#define CODEGEN_API __declspec(dllexport)
#pragma message("Exporting codegen.dll")
#else
#define CODEGEN_API __declspec(dllimport)
#pragma message("Importing codegen.dll")
#endif
#else
#define CODEGEN_API
#endif
class Fingerprint;
class SubbandAnalysis;
struct FPCode;
class CODEGEN_API Codegen {
public:
Codegen(const float* pcm, unsigned int numSamples, int start_offset);
std::string getCodeString(){return _CodeString;}
int getNumCodes(){return _NumCodes;}
static float getVersion();
private:
Fingerprint* computeFingerprint(SubbandAnalysis *pSubbandAnalysis, int start_offset);
std::string createCodeString(std::vector<FPCode> vCodes);
std::string compress(const std::string& s);
std::string _CodeString;
int _NumCodes;
};
#endif

View File

@ -1,55 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#ifndef COMMON_H
#define COMMON_H
#include <assert.h>
#ifndef _WIN32
#include <sys/time.h>
#else
#include "win_funcs.h"
#include <sys/types.h>
/* for STL*/
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#include <malloc.h>
#endif
#include <float.h>
#include <stdio.h>
#include <stdarg.h>
#ifndef NULL
#define NULL 0
#endif
// Returns the current date in seconds. The precision is in microseconds.
static inline double now (void) {
struct timeval tv;
double now;
gettimeofday (&tv, NULL);
now = 1e-6 * tv.tv_usec + tv.tv_sec;
return now;
}
typedef unsigned int uint;
#define NELEM(array) (sizeof(array) / sizeof(array[0]))
#ifndef _WIN32
#define EN_ARRAY(type,var,size) type var[size]
#else
#define EN_ARRAY(type,var,size) type* var = (type*) _alloca((size)*sizeof(type))
#endif
#endif

View File

@ -1,50 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#ifndef FILE_H
#define FILE_H
#include <string.h>
#ifdef _WIN32
#include "win_unistd.h"
#endif
/*
This makes file writing a bit easier (makes sure we don't forget to fclose, basically). Use it like this:
bool WriteStuffToFile(const char* filename)
{
File f(filename);
if (f)
fprintf(f, "stuff I want to print: %s", stuff);
return f; // success/failure
}
*/
class File {
public:
File(const char* filename){_f = fopen(filename, "w");};
~File(){fclose(_f); _f = NULL;}
operator bool(){return _f != NULL;}
operator FILE*(){return _f;}
static bool Exists(const char* filename){return (access(filename, F_OK) == 0);}
static bool ends_with(const char* filename, const char* ending) {
int nFilename = strlen(filename);
int nEnding = strlen(ending);
bool same = false;
if (nEnding <= nFilename) {
const char* file_end = filename + strlen(filename) - strlen(ending);
for (int i = 0; i < nEnding; i++)
if (tolower(file_end[i]) != tolower(ending[i])) return false;
same = true;
}
return same;
}
private:
FILE* _f;
};
#endif

View File

@ -1,239 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include "Fingerprint.h"
#include "Params.h"
#include <string.h>
unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed ) {
// MurmurHash2, by Austin Appleby http://sites.google.com/site/murmurhash/
// m and r are constants set by austin
const unsigned int m = 0x5bd1e995;
const int r = 24;
// Initialize the hash to a 'random' value
unsigned int h = seed ^ len;
// Mix 4 bytes at a time into the hash
const unsigned char * data = (const unsigned char *)key;
while(len >= 4) {
unsigned int k = *(unsigned int *)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
// Handle the last few bytes of the input array
switch(len) {
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0];
h *= m;
};
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
Fingerprint::Fingerprint(SubbandAnalysis* pSubbandAnalysis, int offset)
: _pSubbandAnalysis(pSubbandAnalysis), _Offset(offset) { }
uint Fingerprint::adaptiveOnsets(int ttarg, matrix_u&out, uint*&onset_counter_for_band) {
// E is a sgram-like matrix of energies.
const float *pE;
int bands, frames, i, j, k;
int deadtime = 128;
double H[SUBBANDS],taus[SUBBANDS], N[SUBBANDS];
int contact[SUBBANDS], lcontact[SUBBANDS], tsince[SUBBANDS];
double overfact = 1.1; /* threshold rel. to actual peak */
uint onset_counter = 0;
matrix_f E = _pSubbandAnalysis->getMatrix();
// Take successive stretches of 8 subband samples and sum their energy under a hann window, then hop by 4 samples (50% window overlap).
int hop = 4;
int nsm = 8;
float ham[nsm];
for(int i = 0 ; i != nsm ; i++)
ham[i] = .5 - .5*cos( (2.*M_PI/(nsm-1))*i);
int nc = floor((float)E.size2()/(float)hop)-(floor((float)nsm/(float)hop)-1);
matrix_f Eb = matrix_f(nc, 8);
for(uint r=0;r<Eb.size1();r++) for(uint c=0;c<Eb.size2();c++) Eb(r,c) = 0.0;
for(i=0;i<nc;i++) {
for(j=0;j<SUBBANDS;j++) {
for(k=0;k<nsm;k++) Eb(i,j) = Eb(i,j) + ( E(j,(i*hop)+k) * ham[k]);
Eb(i,j) = sqrtf(Eb(i,j));
}
}
frames = Eb.size1();
bands = Eb.size2();
pE = &Eb.data()[0];
out = matrix_u(SUBBANDS, frames);
onset_counter_for_band = new uint[SUBBANDS];
double bn[] = {0.1883, 0.4230, 0.3392}; /* preemph filter */ // new
int nbn = 3;
double a1 = 0.98;
double Y0[SUBBANDS];
for (j = 0; j < bands; ++j) {
onset_counter_for_band[j] = 0;
N[j] = 0.0;
taus[j] = 1.0;
H[j] = pE[j];
contact[j] = 0;
lcontact[j] = 0;
tsince[j] = 0;
Y0[j] = 0;
}
for (i = 0; i < frames; ++i) {
for (j = 0; j < SUBBANDS; ++j) {
double xn = 0;
/* calculate the filter - FIR part */
if (i >= 2*nbn) {
for (int k = 0; k < nbn; ++k) {
xn += bn[k]*(pE[j-SUBBANDS*k] - pE[j-SUBBANDS*(2*nbn-k)]);
}
}
/* IIR part */
xn = xn + a1*Y0[j];
/* remember the last filtered level */
Y0[j] = xn;
contact[j] = (xn > H[j])? 1 : 0;
if (contact[j] == 1 && lcontact[j] == 0) {
/* attach - record the threshold level unless we have one */
if(N[j] == 0) {
N[j] = H[j];
}
}
if (contact[j] == 1) {
/* update with new threshold */
H[j] = xn * overfact;
} else {
/* apply decays */
H[j] = H[j] * exp(-1.0/(double)taus[j]);
}
if (contact[j] == 0 && lcontact[j] == 1) {
/* detach */
if (onset_counter_for_band[j] > 0 && (int)out(j, onset_counter_for_band[j]-1) > i - deadtime) {
// overwrite last-written time
--onset_counter_for_band[j];
--onset_counter;
}
out(j, onset_counter_for_band[j]++) = i;
++onset_counter;
tsince[j] = 0;
}
++tsince[j];
if (tsince[j] > ttarg) {
taus[j] = taus[j] - 1;
if (taus[j] < 1) taus[j] = 1;
} else {
taus[j] = taus[j] + 1;
}
if ( (contact[j] == 0) && (tsince[j] > deadtime)) {
/* forget the threshold where we recently hit */
N[j] = 0;
}
lcontact[j] = contact[j];
}
pE += bands;
}
return onset_counter;
}
// dan is going to beat me if i call this "decimated_time_for_frame" like i want to
uint Fingerprint::quantized_time_for_frame_delta(uint frame_delta) {
double time_for_frame_delta = (double)frame_delta / ((double)Params::AudioStreamInput::SamplingRate / 32.0);
return ((int)floor((time_for_frame_delta * 1000.0) / (float)QUANTIZE_DT_S) * QUANTIZE_DT_S) / floor(QUANTIZE_DT_S*1000.0);
}
uint Fingerprint::quantized_time_for_frame_absolute(uint frame) {
double time_for_frame = _Offset + (double)frame / ((double)Params::AudioStreamInput::SamplingRate / 32.0);
return ((int)rint((time_for_frame * 1000.0) / (float)QUANTIZE_A_S) * QUANTIZE_A_S) / floor(QUANTIZE_A_S*1000.0);
}
void Fingerprint::Compute() {
uint actual_codes = 0;
unsigned char hash_material[5];
for(uint i=0;i<5;i++) hash_material[i] = 0;
uint * onset_counter_for_band;
matrix_u out;
uint onset_count = adaptiveOnsets(345, out, onset_counter_for_band);
_Codes.resize(onset_count*6);
for(unsigned char band=0;band<SUBBANDS;band++) {
if (onset_counter_for_band[band]>2) {
for(uint onset=0;onset<onset_counter_for_band[band]-2;onset++) {
// What time was this onset at?
uint time_for_onset_ms_quantized = quantized_time_for_frame_absolute(out(band,onset));
uint p[2][6];
int nhashes = 6;
if ((int)onset == (int)onset_counter_for_band[band]-4) { nhashes = 3; }
if ((int)onset == (int)onset_counter_for_band[band]-3) { nhashes = 1; }
p[0][0] = (out(band,onset+1) - out(band,onset));
p[1][0] = (out(band,onset+2) - out(band,onset+1));
if(nhashes > 1) {
p[0][1] = (out(band,onset+1) - out(band,onset));
p[1][1] = (out(band,onset+3) - out(band,onset+1));
p[0][2] = (out(band,onset+2) - out(band,onset));
p[1][2] = (out(band,onset+3) - out(band,onset+2));
if(nhashes > 3) {
p[0][3] = (out(band,onset+1) - out(band,onset));
p[1][3] = (out(band,onset+4) - out(band,onset+1));
p[0][4] = (out(band,onset+2) - out(band,onset));
p[1][4] = (out(band,onset+4) - out(band,onset+2));
p[0][5] = (out(band,onset+3) - out(band,onset));
p[1][5] = (out(band,onset+4) - out(band,onset+3));
}
}
// For each pair emit a code
for(uint k=0;k<6;k++) {
// Quantize the time deltas to 23ms
short time_delta0 = (short)quantized_time_for_frame_delta(p[0][k]);
short time_delta1 = (short)quantized_time_for_frame_delta(p[1][k]);
// Create a key from the time deltas and the band index
memcpy(hash_material+0, (const void*)&time_delta0, 2);
memcpy(hash_material+2, (const void*)&time_delta1, 2);
memcpy(hash_material+4, (const void*)&band, 1);
uint hashed_code = MurmurHash2(&hash_material, 5, HASH_SEED) & HASH_BITMASK;
// Set the code alongside the time of onset
_Codes[actual_codes++] = FPCode(time_for_onset_ms_quantized, hashed_code);
//fprintf(stderr, "whee %d,%d: [%d, %d] (%d, %d), %d = %u at %d\n", actual_codes, k, time_delta0, time_delta1, p[0][k], p[1][k], band, hashed_code, time_for_onset_ms_quantized);
}
}
}
}
_Codes.resize(actual_codes);
delete [] onset_counter_for_band;
}

View File

@ -1,45 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#ifndef FINGERPRINT_H
#define FINGERPRINT_H
#include "Common.h"
#include "SubbandAnalysis.h"
#include "MatrixUtility.h"
#include <vector>
#define HASH_SEED 0x9ea5fa36
#define QUANTIZE_DT_S (256.0/11025.0)
#define QUANTIZE_A_S (256.0/11025.0)
#define HASH_BITMASK 0x000fffff
#define SUBBANDS 8
struct FPCode {
FPCode() : frame(0), code(0) {}
FPCode(uint f, int c) : frame(f), code(c) {}
uint frame;
uint code;
};
unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed );
class Fingerprint {
public:
uint quantized_time_for_frame_delta(uint frame_delta);
uint quantized_time_for_frame_absolute(uint frame);
Fingerprint(SubbandAnalysis* pSubbandAnalysis, int offset);
void Compute();
uint adaptiveOnsets(int ttarg, matrix_u&out, uint*&onset_counter_for_band) ;
std::vector<FPCode>& getCodes(){return _Codes;}
protected:
SubbandAnalysis *_pSubbandAnalysis;
int _Offset;
std::vector<FPCode> _Codes;
};
#endif

View File

@ -1,61 +0,0 @@
UNAME := $(shell uname -s)
CXX=g++
CC=gcc
#OPTFLAGS=-g -O0
OPTFLAGS=-O3 -DBOOST_UBLAS_NDEBUG -DNDEBUG
CXXFLAGS=-Wall -I/usr/local/include/boost-1_35 `taglib-config --cflags` -fPIC $(OPTFLAGS)
CFLAGS=-Wall -fPIC $(OPTFLAGS)
LDFLAGS=`taglib-config --libs` -lz -lpthread $(OPTFLAGS)
MODULES_LIB = \
AudioBufferInput.o \
AudioStreamInput.o \
Base64.o \
Codegen.o \
Fingerprint.o \
MatrixUtility.o \
SubbandAnalysis.o \
Whitening.o
MODULES = $(MODULES_LIB) Metadata.o
all: libcodegen echoprint-codegen
libcodegen: $(MODULES_LIB)
$(CXX) -shared -fPIC -o libcodegen.so $(MODULES_LIB) -lz
ifeq ($(UNAME),Darwin)
libtool -dynamic -flat_namespace -install_name libcodegen.4.1.1.dylib -lSystem -compatibility_version 4.1 -macosx_version_min 10.6 \
-current_version 4.1.1 -o libcodegen.4.1.1.dylib -undefined suppress \
$(MODULES_LIB) -framework vecLib -framework Accelerate
endif
echoprint-codegen: $(MODULES) main.o
$(CXX) $(MODULES) $(LDFLAGS) main.o -o ../echoprint-codegen
%.o: %.c %.h
$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.cxx %.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o: %.cxx
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
rm -f *.o ../echoprint-codegen
rm -f *.so
ifeq ($(UNAME),Darwin)
rm -f *.dylib
endif
PREFIX ?= /usr/local
# todo: dylib
install: all
install ../echoprint-codegen $(PREFIX)/bin
install -d $(PREFIX)/include/echoprint
install -m 644 Codegen.h $(PREFIX)/include/echoprint
install -m 644 libcodegen.so $(PREFIX)/lib
.PHONY: clean all libcodegen echoprint-codegen install

View File

@ -1,52 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include "MatrixUtility.h"
// http://www.boost.org/doc/libs/1_35_0/libs/numeric/ublas/doc/matrix.htm
namespace MatrixUtility {
bool TextFileOutput(const matrix_f& A, const char* filename) {
FILE *matrix_file = fopen(filename, "w");
bool success = (matrix_file != NULL);
if (success) {
const float *d = &A.data()[0];
for (uint i = 0; i < A.size1(); i++) {
for (uint j = 0; j < A.size2(); j++)
fprintf(matrix_file, "%2.3f ", d[i*A.size2() + j]);
fprintf(matrix_file, "\n");
}
fclose(matrix_file);
}
return success;
}
bool FileOutput(const matrix_f& A, const char* filename) {
FILE *matrix_file = fopen(filename, "wb");
bool success = (matrix_file != NULL);
if (success) {
uint mm = A.size1();
uint mn = A.size2();
fwrite(&mm, sizeof(int), 1, matrix_file);
fwrite(&mn, sizeof(int), 1, matrix_file);
for (uint i = 0; i< A.size1(); i++) {
for(uint j=0;j<A.size2(); j++) {
const float d = A(i, j);
fwrite(&d, sizeof(float), 1, matrix_file);
}
}
fclose(matrix_file);
}
return success;
}
} // namespace

View File

@ -1,31 +0,0 @@
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#ifndef MATRIXUTILITY_H
#define MATRIXUTILITY_H
#include "Common.h"
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
namespace ublas = boost::numeric::ublas;
typedef ublas::matrix<float> matrix_f;
typedef ublas::matrix<uint> matrix_u;
typedef ublas::matrix_row<matrix_f> matrix_row_f;
typedef ublas::matrix_row<const ublas::matrix<float> > const_matrix_row_f;
typedef ublas::matrix_column<matrix_f> matrix_column_f;
typedef ublas::matrix_range<matrix_f> matrix_range_f;
namespace MatrixUtility {
inline uint rows(matrix_f A){ return A.size1();}
inline uint cols(matrix_f A){ return A.size2();}
bool FileOutput(const matrix_f& A, const char* filename);
bool TextFileOutput(const matrix_f& A, const char* filename);
}
#endif

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