annotate MatchFeeder.cpp @ 14:cdead4a52755

Make feeder/matcher able to return feature vectors
author Chris Cannam
date Fri, 10 Oct 2014 12:04:54 +0100
parents a02321c31884
children a82276091bbd
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 Vamp feature extraction plugin using the MATCH audio alignment
cannam@0 5 algorithm.
cannam@0 6
cannam@0 7 Centre for Digital Music, Queen Mary, University of London.
cannam@0 8 This file copyright 2007 Simon Dixon, Chris Cannam and QMUL.
cannam@0 9
cannam@0 10 This program is free software; you can redistribute it and/or
cannam@0 11 modify it under the terms of the GNU General Public License as
cannam@0 12 published by the Free Software Foundation; either version 2 of the
cannam@0 13 License, or (at your option) any later version. See the file
cannam@0 14 COPYING included with this distribution for more information.
cannam@0 15 */
cannam@0 16
cannam@0 17 #include "MatchFeeder.h"
cannam@0 18
Chris@14 19 using std::vector;
Chris@14 20
cannam@0 21 MatchFeeder::MatchFeeder(Matcher *m1, Matcher *m2) :
cannam@0 22 pm1(m1), pm2(m2)
cannam@0 23 {
cannam@0 24 fftSize = m1->fftSize;
cannam@0 25 finder = new Finder(m1, m2);
cannam@0 26 reBuffer = new double[fftSize/2+1];
cannam@0 27 imBuffer = new double[fftSize/2+1];
cannam@0 28 }
cannam@0 29
cannam@0 30 MatchFeeder::~MatchFeeder()
cannam@0 31 {
cannam@0 32 delete[] imBuffer;
cannam@0 33 delete[] reBuffer;
cannam@0 34 while (!q1.empty()) {
cannam@0 35 delete[] q1.front();
cannam@0 36 q1.pop();
cannam@0 37 }
cannam@0 38 while (!q2.empty()) {
cannam@0 39 delete[] q2.front();
cannam@0 40 q2.pop();
cannam@0 41 }
cannam@0 42 delete finder;
cannam@0 43 }
cannam@0 44
cannam@0 45 void
cannam@0 46 MatchFeeder::feed(const float *const *input)
cannam@0 47 {
cannam@0 48 // We maintain two FIFO queues of audio data frame block pointers,
cannam@0 49 // one per input stream. When the match-feeder function is
cannam@0 50 // entered, it knows that it has at least one block in each queue.
cannam@0 51 // It loops, processing up to one block per matcher, until a queue
cannam@0 52 // is empty. Then it returns, to be called again with more data.
cannam@0 53
Chris@14 54 prepare(input);
Chris@14 55
Chris@14 56 while (!q1.empty() && !q2.empty()) {
Chris@14 57 // std::cerr << "MatchFeeder::feed: q1 " << q1.size() << " q2 " << q2.size() << std::endl;
Chris@14 58 (void)feedBlock();
Chris@14 59 }
Chris@14 60 }
Chris@14 61
Chris@14 62 MatchFeeder::Features
Chris@14 63 MatchFeeder::feedAndGetFeatures(const float *const *input)
Chris@14 64 {
Chris@14 65 prepare(input);
Chris@14 66
Chris@14 67 Features all;
Chris@14 68
Chris@14 69 while (!q1.empty() && !q2.empty()) {
Chris@14 70 Features ff = feedBlock();
Chris@14 71 all.f1.insert(all.f1.end(), ff.f1.begin(), ff.f1.end());
Chris@14 72 all.f2.insert(all.f2.end(), ff.f2.begin(), ff.f2.end());
Chris@14 73 }
Chris@14 74
Chris@14 75 return all;
Chris@14 76 }
Chris@14 77
Chris@14 78 void
Chris@14 79 MatchFeeder::prepare(const float *const *input)
Chris@14 80 {
cannam@0 81 float *block = new float[fftSize+2];
cannam@0 82 for (size_t i = 0; i < fftSize+2; ++i) {
cannam@0 83 block[i] = input[0][i];
cannam@0 84 }
cannam@0 85 q1.push(block);
cannam@0 86
cannam@0 87 block = new float[fftSize+2];
cannam@0 88 for (size_t i = 0; i < fftSize+2; ++i) {
cannam@0 89 block[i] = input[1][i];
cannam@0 90 }
cannam@0 91 q2.push(block);
cannam@0 92 }
cannam@0 93
Chris@14 94 MatchFeeder::Features
cannam@0 95 MatchFeeder::feedBlock()
cannam@0 96 {
Chris@14 97 Features ff;
Chris@14 98 vector<double> f1, f2;
Chris@14 99
cannam@0 100 if (pm1->frameCount < pm1->blockSize) { // fill initial block
cannam@0 101 // std::cerr << "feeding initial block" << std::endl;
Chris@14 102 f1 = feed1();
Chris@14 103 f2 = feed2();
cannam@0 104 }
cannam@0 105 //!!! } else if (pm1->atEnd) {
cannam@0 106 // feed2();
cannam@0 107 //!!! } else if (pm2->atEnd)
cannam@0 108 // feed1();
cannam@0 109 else if (pm1->runCount >= Matcher::MAX_RUN_COUNT) { // slope constraints
cannam@0 110 // std::cerr << "pm1 too slopey" << std::endl;
Chris@14 111 f2 = feed2();
cannam@0 112 } else if (pm2->runCount >= Matcher::MAX_RUN_COUNT) {
cannam@0 113 // std::cerr << "pm2 too slopey" << std::endl;
Chris@14 114 f1 = feed1();
cannam@0 115 } else {
cannam@0 116 switch (finder->getExpandDirection
cannam@0 117 (pm1->frameCount-1, pm2->frameCount-1)) {
cannam@0 118 case ADVANCE_THIS:
cannam@0 119 // std::cerr << "finder says ADVANCE_THIS" << std::endl;
Chris@14 120 f1 = feed1();
cannam@0 121 break;
cannam@0 122 case ADVANCE_OTHER:
cannam@0 123 // std::cerr << "finder says ADVANCE_OTHER" << std::endl;
Chris@14 124 f2 = feed2();
cannam@0 125 break;
cannam@0 126 case ADVANCE_BOTH:
cannam@0 127 // std::cerr << "finder says ADVANCE_BOTH" << std::endl;
Chris@14 128 f1 = feed1();
Chris@14 129 f2 = feed2();
cannam@0 130 break;
cannam@0 131 }
cannam@0 132 }
Chris@14 133
Chris@14 134 if (!f1.empty()) ff.f1.push_back(f1);
Chris@14 135 if (!f2.empty()) ff.f2.push_back(f2);
Chris@14 136 return ff;
cannam@0 137 }
cannam@0 138
Chris@14 139 vector<double>
cannam@0 140 MatchFeeder::feed1()
cannam@0 141 {
cannam@0 142 // std::cerr << "feed1" << std::endl;
cannam@0 143 float *block = q1.front();
cannam@0 144 q1.pop();
cannam@0 145 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 146 reBuffer[i] = block[i*2];
cannam@0 147 }
cannam@0 148 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 149 imBuffer[i] = block[i*2+1];
cannam@0 150 }
cannam@0 151 delete[] block;
Chris@14 152 return pm1->processFrame(reBuffer, imBuffer);
cannam@0 153 }
cannam@0 154
Chris@14 155 vector<double>
cannam@0 156 MatchFeeder::feed2()
cannam@0 157 {
cannam@0 158 // std::cerr << "feed2" << std::endl;
cannam@0 159 float *block = q2.front();
cannam@0 160 q2.pop();
cannam@0 161 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 162 reBuffer[i] = block[i*2];
cannam@0 163 }
cannam@0 164 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 165 imBuffer[i] = block[i*2+1];
cannam@0 166 }
cannam@0 167 delete[] block;
Chris@14 168 return pm2->processFrame(reBuffer, imBuffer);
cannam@0 169 }
cannam@0 170