# HG changeset patch # User Chris Cannam # Date 1412939094 -3600 # Node ID cdead4a52755d50de05e7067fef8f2db79ef3b11 # Parent 66082cc488c3269cbbae0d0cf4436043be024502 Make feeder/matcher able to return feature vectors diff -r 66082cc488c3 -r cdead4a52755 Makefile.linux --- a/Makefile.linux Fri Oct 10 10:52:07 2014 +0100 +++ b/Makefile.linux Fri Oct 10 12:04:54 2014 +0100 @@ -1,5 +1,5 @@ -CXXFLAGS += -fPIC -ffast-math -O3 -Wall +CXXFLAGS += -fPIC -ffast-math -O3 -Wall -Werror LDFLAGS += -shared -Wl,-Bstatic -lvamp-sdk -Wl,-Bdynamic -lpthread -Wl,--version-script=vamp-plugin.map include Makefile.inc diff -r 66082cc488c3 -r cdead4a52755 MatchFeeder.cpp --- a/MatchFeeder.cpp Fri Oct 10 10:52:07 2014 +0100 +++ b/MatchFeeder.cpp Fri Oct 10 12:04:54 2014 +0100 @@ -16,6 +16,8 @@ #include "MatchFeeder.h" +using std::vector; + MatchFeeder::MatchFeeder(Matcher *m1, Matcher *m2) : pm1(m1), pm2(m2) { @@ -49,6 +51,33 @@ // It loops, processing up to one block per matcher, until a queue // is empty. Then it returns, to be called again with more data. + prepare(input); + + while (!q1.empty() && !q2.empty()) { +// std::cerr << "MatchFeeder::feed: q1 " << q1.size() << " q2 " << q2.size() << std::endl; + (void)feedBlock(); + } +} + +MatchFeeder::Features +MatchFeeder::feedAndGetFeatures(const float *const *input) +{ + prepare(input); + + Features all; + + while (!q1.empty() && !q2.empty()) { + Features ff = feedBlock(); + all.f1.insert(all.f1.end(), ff.f1.begin(), ff.f1.end()); + all.f2.insert(all.f2.end(), ff.f2.begin(), ff.f2.end()); + } + + return all; +} + +void +MatchFeeder::prepare(const float *const *input) +{ float *block = new float[fftSize+2]; for (size_t i = 0; i < fftSize+2; ++i) { block[i] = input[0][i]; @@ -60,20 +89,18 @@ block[i] = input[1][i]; } q2.push(block); - - while (!q1.empty() && !q2.empty()) { -// std::cerr << "MatchFeeder::feed: q1 " << q1.size() << " q2 " << q2.size() << std::endl; - feedBlock(); - } } -void +MatchFeeder::Features MatchFeeder::feedBlock() { + Features ff; + vector f1, f2; + if (pm1->frameCount < pm1->blockSize) { // fill initial block // std::cerr << "feeding initial block" << std::endl; - feed1(); - feed2(); + f1 = feed1(); + f2 = feed2(); } //!!! } else if (pm1->atEnd) { // feed2(); @@ -81,31 +108,35 @@ // feed1(); else if (pm1->runCount >= Matcher::MAX_RUN_COUNT) { // slope constraints // std::cerr << "pm1 too slopey" << std::endl; - feed2(); + f2 = feed2(); } else if (pm2->runCount >= Matcher::MAX_RUN_COUNT) { // std::cerr << "pm2 too slopey" << std::endl; - feed1(); + f1 = feed1(); } else { switch (finder->getExpandDirection (pm1->frameCount-1, pm2->frameCount-1)) { case ADVANCE_THIS: // std::cerr << "finder says ADVANCE_THIS" << std::endl; - feed1(); + f1 = feed1(); break; case ADVANCE_OTHER: // std::cerr << "finder says ADVANCE_OTHER" << std::endl; - feed2(); + f2 = feed2(); break; case ADVANCE_BOTH: // std::cerr << "finder says ADVANCE_BOTH" << std::endl; - feed1(); - feed2(); + f1 = feed1(); + f2 = feed2(); break; } } + + if (!f1.empty()) ff.f1.push_back(f1); + if (!f2.empty()) ff.f2.push_back(f2); + return ff; } -void +vector MatchFeeder::feed1() { // std::cerr << "feed1" << std::endl; @@ -118,10 +149,10 @@ imBuffer[i] = block[i*2+1]; } delete[] block; - pm1->processFrame(reBuffer, imBuffer); + return pm1->processFrame(reBuffer, imBuffer); } -void +vector MatchFeeder::feed2() { // std::cerr << "feed2" << std::endl; @@ -134,6 +165,6 @@ imBuffer[i] = block[i*2+1]; } delete[] block; - pm2->processFrame(reBuffer, imBuffer); + return pm2->processFrame(reBuffer, imBuffer); } diff -r 66082cc488c3 -r cdead4a52755 MatchFeeder.h --- a/MatchFeeder.h Fri Oct 10 10:52:07 2014 +0100 +++ b/MatchFeeder.h Fri Oct 10 12:04:54 2014 +0100 @@ -20,6 +20,7 @@ #include "Finder.h" #include +#include class MatchFeeder { @@ -27,14 +28,33 @@ MatchFeeder(Matcher *m1, Matcher *m2); ~MatchFeeder(); + /** + * Feed the two supplied channels of frequency-domain input data + * to feeders 1 and 2 respectively, as appropriate (depending on + * their advance status). + */ void feed(const float *const *input); + struct Features { + std::vector > f1; + std::vector > f2; + }; + + /** + * Feed the two supplied channels of frequency-domain input data + * to feeders 1 and 2 respectively, as appropriate (depending on + * their advance status) and return any new feature vectors + * calculated by the two feeders. + */ + Features feedAndGetFeatures(const float *const *input); + Finder *getFinder() { return finder; } protected: - void feedBlock(); - void feed1(); - void feed2(); + void prepare(const float *const *input); + Features feedBlock(); + std::vector feed1(); + std::vector feed2(); Finder *finder; Matcher *pm1; diff -r 66082cc488c3 -r cdead4a52755 Matcher.cpp --- a/Matcher.cpp Fri Oct 10 10:52:07 2014 +0100 +++ b/Matcher.cpp Fri Oct 10 12:04:54 2014 +0100 @@ -230,7 +230,7 @@ } } // makeChromaFrequencyMap() -void +vector Matcher::processFrame(double *reBuffer, double *imBuffer) { if (!initialised) init(); @@ -341,6 +341,8 @@ for (int i = 0; i < freqMapSize; i++) frames[frameIndex][i] /= ltAverage; + vector processedFrame = frames[frameIndex]; + int stop = otherMatcher->frameCount; int index = stop - blockSize; if (index < 0) @@ -426,12 +428,10 @@ if ((frameCount % 100) == 0) { if (!silent) { cerr << "Progress:" << frameCount << " " << ltAverage << endl; -// Profile.report(); } } -//!!! if (frameCount == maxFrames) -// closeStreams(); -// } + + return processedFrame; } // processFrame() int diff -r 66082cc488c3 -r cdead4a52755 Matcher.h --- a/Matcher.h Fri Oct 10 10:52:07 2014 +0100 +++ b/Matcher.h Fri Oct 10 12:04:54 2014 +0100 @@ -303,8 +303,11 @@ * otherMatcher and storing them in the distance matrix, and * finally updating the optimal path matrix using the dynamic * time warping algorithm. + * + * Return value is the frame (post-processed, with warping, + * rectification, and normalisation as appropriate). */ - void processFrame(double *reBuffer, double *imBuffer); + std::vector processFrame(double *reBuffer, double *imBuffer); /** Calculates the Manhattan distance between two vectors, with an * optional normalisation by the combined values in the diff -r 66082cc488c3 -r cdead4a52755 Path.cpp --- a/Path.cpp Fri Oct 10 10:52:07 2014 +0100 +++ b/Path.cpp Fri Oct 10 12:04:54 2014 +0100 @@ -21,7 +21,7 @@ { if (length == 0) return 0; - while (val.size() < length) { + while ((int)val.size() < length) { val.push_back(0); len.push_back(0); }