diff MatchFeeder.cpp @ 0:640f92242cc1

* initial import
author cannam
date Wed, 24 Oct 2007 12:13:43 +0000
parents
children ca29b0ef78ce
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MatchFeeder.cpp	Wed Oct 24 12:13:43 2007 +0000
@@ -0,0 +1,139 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp feature extraction plugin using the MATCH audio alignment
+    algorithm.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2007 Simon Dixon, Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "MatchFeeder.h"
+
+MatchFeeder::MatchFeeder(Matcher *m1, Matcher *m2) :
+    pm1(m1), pm2(m2)
+{
+    fftSize = m1->fftSize;
+    finder = new Finder(m1, m2);
+    reBuffer = new double[fftSize/2+1];
+    imBuffer = new double[fftSize/2+1];
+}
+
+MatchFeeder::~MatchFeeder()
+{
+    delete[] imBuffer;
+    delete[] reBuffer;
+    while (!q1.empty()) {
+        delete[] q1.front();
+        q1.pop();
+    }
+    while (!q2.empty()) {
+        delete[] q2.front();
+        q2.pop();
+    }
+    delete finder;
+}
+
+void
+MatchFeeder::feed(const float *const *input)
+{
+    // We maintain two FIFO queues of audio data frame block pointers,
+    // one per input stream.  When the match-feeder function is
+    // entered, it knows that it has at least one block in each queue.
+    // It loops, processing up to one block per matcher, until a queue
+    // is empty.  Then it returns, to be called again with more data.
+
+    float *block = new float[fftSize+2];
+    for (size_t i = 0; i < fftSize+2; ++i) {
+        block[i] = input[0][i];
+    }
+    q1.push(block);
+
+    block = new float[fftSize+2];
+    for (size_t i = 0; i < fftSize+2; ++i) {
+        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::feedBlock()
+{
+    if (pm1->frameCount < pm1->blockSize) {		// fill initial block
+//        std::cerr << "feeding initial block" << std::endl;
+        feed1();
+        feed2();
+    }
+//!!!    } else if (pm1->atEnd) {
+//        feed2();
+//!!!    } else if (pm2->atEnd)
+//        feed1();
+    else if (pm1->runCount >= Matcher::MAX_RUN_COUNT) {  // slope constraints
+//        std::cerr << "pm1 too slopey" << std::endl;
+        feed2();
+    } else if (pm2->runCount >= Matcher::MAX_RUN_COUNT) {
+//        std::cerr << "pm2 too slopey" << std::endl;
+        feed1();
+    } else {
+        switch (finder->getExpandDirection
+                (pm1->frameCount-1, pm2->frameCount-1)) {
+        case ADVANCE_THIS:
+//            std::cerr << "finder says ADVANCE_THIS" << std::endl;
+            feed1();
+            break;
+        case ADVANCE_OTHER:
+//            std::cerr << "finder says ADVANCE_OTHER" << std::endl;
+            feed2();
+            break;
+        case ADVANCE_BOTH:
+//            std::cerr << "finder says ADVANCE_BOTH" << std::endl;
+            feed1();
+            feed2();
+            break;
+        }
+    }
+}
+
+void
+MatchFeeder::feed1()
+{
+//    std::cerr << "feed1" << std::endl;
+    float *block = q1.front();
+    q1.pop();
+    for (size_t i = 0; i <= fftSize/2; ++i) {
+        reBuffer[i] = block[i*2];
+    }
+    for (size_t i = 0; i <= fftSize/2; ++i) {
+        imBuffer[i] = block[i*2+1];
+    }
+    delete[] block;
+    pm1->processFrame(reBuffer, imBuffer);
+}
+
+void
+MatchFeeder::feed2()
+{
+//    std::cerr << "feed2" << std::endl;
+    float *block = q2.front();
+    q2.pop();
+    for (size_t i = 0; i <= fftSize/2; ++i) {
+        reBuffer[i] = block[i*2];
+    }
+    for (size_t i = 0; i <= fftSize/2; ++i) {
+        imBuffer[i] = block[i*2+1];
+    }
+    delete[] block;
+    pm2->processFrame(reBuffer, imBuffer);
+}
+