Mercurial > hg > match-vamp
changeset 23:64c4c0cf80c9
Add alternate Matcher API calls to provide external feature data
author | Chris Cannam |
---|---|
date | Fri, 10 Oct 2014 16:27:45 +0100 |
parents | ac39717fc88d |
children | 89929e9e54fb |
files | MatchVampPlugin.cpp Matcher.cpp Matcher.h |
diffstat | 3 files changed, 113 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/MatchVampPlugin.cpp Fri Oct 10 16:27:29 2014 +0100 +++ b/MatchVampPlugin.cpp Fri Oct 10 16:27:45 2014 +0100 @@ -394,7 +394,7 @@ desc.description = "Spectral features extracted from performance A"; desc.unit = ""; desc.hasFixedBinCount = true; - desc.binCount = Matcher::getFeatureSize(m_params); + desc.binCount = Matcher::getFeatureSizeFor(m_params); desc.hasKnownExtents = false; desc.isQuantized = false; desc.sampleType = OutputDescriptor::FixedSampleRate; @@ -407,7 +407,7 @@ desc.description = "Spectral features extracted from performance B"; desc.unit = ""; desc.hasFixedBinCount = true; - desc.binCount = Matcher::getFeatureSize(m_params); + desc.binCount = Matcher::getFeatureSizeFor(m_params); desc.hasKnownExtents = false; desc.isQuantized = false; desc.sampleType = OutputDescriptor::FixedSampleRate;
--- a/Matcher.cpp Fri Oct 10 16:27:29 2014 +0100 +++ b/Matcher.cpp Fri Oct 10 16:27:45 2014 +0100 @@ -37,6 +37,40 @@ ltAverage = 0; frameCount = 0; runCount = 0; + freqMapSize = 0; + externalFeatureSize = 0; + featureSize = 0; + blockSize = 0; + scale = 90; + + blockSize = lrint(params.blockTime / params.hopTime); +#ifdef DEBUG_MATCHER + cerr << "Matcher: blockSize = " << blockSize << endl; +#endif + + distance = 0; + bestPathCost = 0; + distYSizes = 0; + distXSize = 0; + + initialised = false; +} + +Matcher::Matcher(Parameters parameters, Matcher *p, int featureSize) : + params(parameters), + externalFeatureSize(featureSize) +{ +#ifdef DEBUG_MATCHER + cerr << "Matcher::Matcher(" << params.sampleRate << ", " << p << ", " << featureSize << ")" << endl; +#endif + + otherMatcher = p; // the first matcher will need this to be set later + firstPM = (!p); + ltAverage = 0; + frameCount = 0; + runCount = 0; + freqMapSize = 0; + featureSize = 0; blockSize = 0; scale = 90; @@ -52,7 +86,7 @@ initialised = false; -} // default constructor +} Matcher::~Matcher() { @@ -85,13 +119,17 @@ initialised = true; - freqMapSize = getFeatureSize(params); + if (externalFeatureSize == 0) { + freqMapSize = getFeatureSizeFor(params); + featureSize = freqMapSize; + makeFreqMap(); + } else { + featureSize = externalFeatureSize; + } - makeFreqMap(); - - initVector<double>(prevFrame, freqMapSize); - initVector<double>(newFrame, freqMapSize); - initMatrix<double>(frames, blockSize, freqMapSize); + initVector<double>(prevFrame, featureSize); + initVector<double>(newFrame, featureSize); + initMatrix<double>(frames, blockSize, featureSize); initVector<double>(totalEnergies, blockSize); int distSize = (params.maxRunCount + 1) * blockSize; @@ -124,6 +162,7 @@ Matcher::makeFreqMap() { initVector<int>(freqMap, params.fftSize/2 + 1); + if (params.useChromaFrequencyMap) { #ifdef DEBUG_MATCHER cerr << "makeFreqMap: calling makeChromaFrequencyMap" << endl; @@ -138,7 +177,7 @@ } // makeFreqMap() int -Matcher::getFeatureSize(Parameters params) +Matcher::getFeatureSizeFor(Parameters params) { if (params.useChromaFrequencyMap) { return 13; @@ -205,13 +244,16 @@ calcAdvance(); - if ((frameCount % 100) == 0) { - if (!silent) { - cerr << "Progress:" << frameCount << " " << ltAverage << endl; - } - } + return processedFrame; +} - return processedFrame; +void +Matcher::consumeFeatureVector(std::vector<double> feature) +{ + if (!initialised) init(); + int frameIndex = frameCount % blockSize; + frames[frameIndex] = feature; + calcAdvance(); } vector<double> @@ -275,6 +317,12 @@ frames[frameIndex] = processedFrame; + if ((frameCount % 100) == 0) { + if (!silent) { + cerr << "Progress:" << frameCount << " " << ltAverage << endl; + } + } + return processedFrame; } @@ -417,7 +465,7 @@ { double d = 0; double sum = 0; - for (int i = 0; i < freqMapSize; i++) { + for (int i = 0; i < featureSize; i++) { d += fabs(f1[i] - f2[i]); sum += f1[i] + f2[i]; }
--- a/Matcher.h Fri Oct 10 16:27:29 2014 +0100 +++ b/Matcher.h Fri Oct 10 16:27:45 2014 +0100 @@ -186,11 +186,23 @@ * bin. */ vector<int> freqMap; - /** The number of entries in <code>freqMap</code>. Note that the - * length of the array is greater, because its size is not known - * at creation time. */ + /** The number of entries in <code>freqMap</code>. */ int freqMapSize; + /** The number of values in an externally-supplied feature vector, + * used in preference to freqMap/freqMapSize if constructed with + * the external feature version of the Matcher constructor. If + * this is zero, the internal feature extractor will be used as + * normal. + */ + int externalFeatureSize; + + /** The number of values in the feature vectors actually in + * use. This will be externalFeatureSize if greater than zero, or + * freqMapSize otherwise. + */ + int featureSize; + /** The most recent frame; used for calculating the frame to frame * spectral difference. These are therefore frequency warped but * not yet normalised. */ @@ -240,6 +252,21 @@ */ Matcher(Parameters parameters, Matcher *p); + /** Constructor for Matcher using externally supplied features. + * A Matcher made using this constructor will not carry out its + * own feature extraction from frequency-domain audio data, but + * instead will accept arbitrary feature frames calculated by + * some external code. + * + * @param p The Matcher representing the performance with which + * this one is going to be matched. Some information is shared + * between the two matchers (currently one possesses the distance + * matrix and optimal path matrix). + * + * @param featureSize Number of values in each feature vector. + */ + Matcher(Parameters parameters, Matcher *p, int featureSize); + ~Matcher(); /** For debugging, outputs information about the Matcher to @@ -264,7 +291,7 @@ * Return the feature vector size that will be used for the given * parameters. */ - static int getFeatureSize(Parameters params); + static int getFeatureSizeFor(Parameters params); protected: template <typename T> @@ -315,9 +342,26 @@ * * Return value is the frame (post-processed, with warping, * rectification, and normalisation as appropriate). + * + * The Matcher must have been constructed using the constructor + * without an external featureSize parameter in order to use this + * function. (Otherwise it will be expecting you to call + * consumeFeatureVector.) */ std::vector<double> consumeFrame(double *reBuffer, double *imBuffer); + /** Processes a feature vector frame (presumably calculated from + * audio data by some external code). As consumeFrame, except + * that it does not calculate a feature from audio data but + * instead uses the supplied feature directly. + * + * The Matcher must have been constructed using the constructor + * that accepts an external featureSize parameter in order to + * use this function. The supplied feature must be of the size + * that was passed to the constructor. + */ + void consumeFeatureVector(std::vector<double> feature); + /** Calculates the Manhattan distance between two vectors, with an * optional normalisation by the combined values in the * vectors. Since the vectors contain energy, this could be