Chromaprint
NAME
Audio::Fingerprint::Chromaprint - Get audio fingerprint using the chromaprint / AcoustID library
SYNOPSIS
use Audio::Fingerprint::Chromaprint;
use Audio::Sndfile;
my $fp = Audio::Fingerprint::Chromaprint.new;
my $wav = Audio::Sndfile.new(filename => 'some.wav', :r);
$fp.start($wav.samplerate, $wav.channels);
# Read the whole file at once
my ( $data, $frames ) = $wav.read-short($wav.frames, :raw);
# You can feed multiple times
$fp.feed($data, $frames);
# call finish to indicate done feeding
$fp.finish;
say $fp.fingerprint;
DESCRIPTION
This provides a mechanism for obtaining a fingerprint of some audio data using the Chromaprint library, you can use this to identify recorded audio or determine whether two audio files are the same for instance.
You need several seconds worth of data in order to be able to get a usable fingerprint, and for comparison of two files you will need to ensure that you have the same number of samples, ideally you should fingerprint the entire audio file, but this may be slow if you have a large file.
The library only can handle integer PCM audio data, if you need to deal with encoded data such as MP3 or Ogg/Vorbis you will need to use another library to decode it to raw samples.
Depending on how the Chromaprint library was built, it may or may not be safe to have multiple instances created at the same time, so it is probably safest to take care you only have a single instance in your application.
METHODS
method new
method new(Int :$silence-threshold, Algorithm :$algorithm = Test2) returns Audio::Fingerprint::Chromaprint
This is the contructor for the class. If the chromaprint library
was built with the faster fftw
library rather than ffmpeq
then the initialisation of the library is not thread-safe, so
it may be best to avoid having more than one instance at a time
in your application.
If the named parameter silence-threshold
is supplied then it should be
in the range of 0 - 32768 and will be used to modify the way in which the
analysis is done. It's probably best not to use this if the fingerprints
are to be shared with other systems, and if it is used it should be the
same for every calculation if the fingerprint is to be compared.
algorithm
is a value of the enum
Audio::Fingerprint::Chromaprint::Algorithm
, the default is Test2
(the values are Test1
to Test4
,) they aren't very well documented
so I would suggest sticking to the default. Obviously for
comparison purposes the algorithm used to generate the fingerprints
should be the same.
method version
method version() returns Str
This returns a Str representing the version of the library being used.
method start
method start(Int $samplerate, Int $channels) returns Bool
This prepares the chromaprint library to begin receiving the
samples for an audio file. This must be called before feed
.
The $samplerate
and $channels
should be an accurate
reflection of the data that is going to be fed.
method feed
multi method feed(CArray $data, Int $frames) returns Bool
multi method feed(@frames) returns Bool
This adds the audio data that is to be analysed, the data should be interleaved 16 bit signed integers. You will need several seconds worth of data (which can be fed in pieces,) to be able to get a usable fingerprint, so, depending on the samplerate of the audio data, you may need to feed at minimum somewhere in the region of 100,000 frames.
The CArray candidate is more efficient as no conversion
needs to be done to the data before passing to the
underlying library function - $frames
should be the
number of items in $data
divided by the number of
channels, if you are getting the data with Audio::Sndfile
for example then these values will be those returned
by read-short
with the :raw
adverb.
If you provide @frames
as an array, it should contain
a number of indivual samples that is divisible by the
number of channels in the data, this value will be used
to calculate $frames
.
If start
hasn't been called (or if finish
has
already been called without a subsequent start
then
an exception will be thrown.
method finish
method finish() returns Bool
This indicates to the library that the user has done feeding
data and that the remaining buffered data can be used to
calculate the fingerprint, if there is insufficient data
to calculate the fingerprint then the libchromaprint
may
rudely print a warning to STDERR
.
After finish
has been called then start
must be called
to allow the feeding of further data as the state of the
engine will be reset.
method fingerprint
method fingerprint() returns Str
This returns the calculated fingerprint as a string, if there was unsufficient data provided then the fingerprint may only comprise 4 or 5 characters, rather than 23 or so that it should be.