annotate MatchFeeder.cpp @ 0:640f92242cc1

* initial import
author cannam
date Wed, 24 Oct 2007 12:13:43 +0000
parents
children ca29b0ef78ce
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
cannam@0 19 MatchFeeder::MatchFeeder(Matcher *m1, Matcher *m2) :
cannam@0 20 pm1(m1), pm2(m2)
cannam@0 21 {
cannam@0 22 fftSize = m1->fftSize;
cannam@0 23 finder = new Finder(m1, m2);
cannam@0 24 reBuffer = new double[fftSize/2+1];
cannam@0 25 imBuffer = new double[fftSize/2+1];
cannam@0 26 }
cannam@0 27
cannam@0 28 MatchFeeder::~MatchFeeder()
cannam@0 29 {
cannam@0 30 delete[] imBuffer;
cannam@0 31 delete[] reBuffer;
cannam@0 32 while (!q1.empty()) {
cannam@0 33 delete[] q1.front();
cannam@0 34 q1.pop();
cannam@0 35 }
cannam@0 36 while (!q2.empty()) {
cannam@0 37 delete[] q2.front();
cannam@0 38 q2.pop();
cannam@0 39 }
cannam@0 40 delete finder;
cannam@0 41 }
cannam@0 42
cannam@0 43 void
cannam@0 44 MatchFeeder::feed(const float *const *input)
cannam@0 45 {
cannam@0 46 // We maintain two FIFO queues of audio data frame block pointers,
cannam@0 47 // one per input stream. When the match-feeder function is
cannam@0 48 // entered, it knows that it has at least one block in each queue.
cannam@0 49 // It loops, processing up to one block per matcher, until a queue
cannam@0 50 // is empty. Then it returns, to be called again with more data.
cannam@0 51
cannam@0 52 float *block = new float[fftSize+2];
cannam@0 53 for (size_t i = 0; i < fftSize+2; ++i) {
cannam@0 54 block[i] = input[0][i];
cannam@0 55 }
cannam@0 56 q1.push(block);
cannam@0 57
cannam@0 58 block = new float[fftSize+2];
cannam@0 59 for (size_t i = 0; i < fftSize+2; ++i) {
cannam@0 60 block[i] = input[1][i];
cannam@0 61 }
cannam@0 62 q2.push(block);
cannam@0 63
cannam@0 64 while (!q1.empty() && !q2.empty()) {
cannam@0 65 // std::cerr << "MatchFeeder::feed: q1 " << q1.size() << " q2 " << q2.size() << std::endl;
cannam@0 66 feedBlock();
cannam@0 67 }
cannam@0 68 }
cannam@0 69
cannam@0 70 void
cannam@0 71 MatchFeeder::feedBlock()
cannam@0 72 {
cannam@0 73 if (pm1->frameCount < pm1->blockSize) { // fill initial block
cannam@0 74 // std::cerr << "feeding initial block" << std::endl;
cannam@0 75 feed1();
cannam@0 76 feed2();
cannam@0 77 }
cannam@0 78 //!!! } else if (pm1->atEnd) {
cannam@0 79 // feed2();
cannam@0 80 //!!! } else if (pm2->atEnd)
cannam@0 81 // feed1();
cannam@0 82 else if (pm1->runCount >= Matcher::MAX_RUN_COUNT) { // slope constraints
cannam@0 83 // std::cerr << "pm1 too slopey" << std::endl;
cannam@0 84 feed2();
cannam@0 85 } else if (pm2->runCount >= Matcher::MAX_RUN_COUNT) {
cannam@0 86 // std::cerr << "pm2 too slopey" << std::endl;
cannam@0 87 feed1();
cannam@0 88 } else {
cannam@0 89 switch (finder->getExpandDirection
cannam@0 90 (pm1->frameCount-1, pm2->frameCount-1)) {
cannam@0 91 case ADVANCE_THIS:
cannam@0 92 // std::cerr << "finder says ADVANCE_THIS" << std::endl;
cannam@0 93 feed1();
cannam@0 94 break;
cannam@0 95 case ADVANCE_OTHER:
cannam@0 96 // std::cerr << "finder says ADVANCE_OTHER" << std::endl;
cannam@0 97 feed2();
cannam@0 98 break;
cannam@0 99 case ADVANCE_BOTH:
cannam@0 100 // std::cerr << "finder says ADVANCE_BOTH" << std::endl;
cannam@0 101 feed1();
cannam@0 102 feed2();
cannam@0 103 break;
cannam@0 104 }
cannam@0 105 }
cannam@0 106 }
cannam@0 107
cannam@0 108 void
cannam@0 109 MatchFeeder::feed1()
cannam@0 110 {
cannam@0 111 // std::cerr << "feed1" << std::endl;
cannam@0 112 float *block = q1.front();
cannam@0 113 q1.pop();
cannam@0 114 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 115 reBuffer[i] = block[i*2];
cannam@0 116 }
cannam@0 117 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 118 imBuffer[i] = block[i*2+1];
cannam@0 119 }
cannam@0 120 delete[] block;
cannam@0 121 pm1->processFrame(reBuffer, imBuffer);
cannam@0 122 }
cannam@0 123
cannam@0 124 void
cannam@0 125 MatchFeeder::feed2()
cannam@0 126 {
cannam@0 127 // std::cerr << "feed2" << std::endl;
cannam@0 128 float *block = q2.front();
cannam@0 129 q2.pop();
cannam@0 130 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 131 reBuffer[i] = block[i*2];
cannam@0 132 }
cannam@0 133 for (size_t i = 0; i <= fftSize/2; ++i) {
cannam@0 134 imBuffer[i] = block[i*2+1];
cannam@0 135 }
cannam@0 136 delete[] block;
cannam@0 137 pm2->processFrame(reBuffer, imBuffer);
cannam@0 138 }
cannam@0 139