changeset 4:597f033fa7a2

* Some cleaning and rearranging to prepare for band processing implementation
author Carl Bussey <c.bussey@se10.qmul.ac.uk>
date Tue, 05 Aug 2014 15:56:59 +0100
parents 5125d34fda67
children 8d7e336b41e9
files FIRFilter.cpp Makefile Tempogram.cpp Tempogram.h
diffstat 4 files changed, 37 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/FIRFilter.cpp	Wed Jul 09 20:14:20 2014 +0100
+++ b/FIRFilter.cpp	Tue Aug 05 15:56:59 2014 +0100
@@ -86,7 +86,6 @@
         output[i] = fftOutputReal[i];
         max = max > output[i] ? max : output[i];
     }
-    //cout << max << endl;
 }
 
 void
--- a/Makefile	Wed Jul 09 20:14:20 2014 +0100
+++ b/Makefile	Tue Aug 05 15:56:59 2014 +0100
@@ -21,11 +21,11 @@
 
 # Edit this to list the .cpp or .c files in your plugin project
 #
-PLUGIN_SOURCES := Tempogram.cpp FIRFilter.cpp WindowFunction.cpp plugins.cpp
+PLUGIN_SOURCES := Tempogram.cpp FIRFilter.cpp WindowFunction.cpp plugins.cpp NoveltyCurve.cpp
 
 # Edit this to list the .h files in your plugin project
 #
-PLUGIN_HEADERS := Tempogram.h FIRFilter.h WindowFunction.h
+PLUGIN_HEADERS := Tempogram.h FIRFilter.h WindowFunction.h NoveltyCurve.h
 
 # Edit this to the location of the Vamp plugin SDK, relative to your
 # project directory
@@ -39,7 +39,7 @@
 
 CXX := g++
 #-mmacosx-version-min=10.6
-CXXFLAGS := -arch x86_64 -I$(VAMP_SDK_DIR) -Wall -fPIC
+CXXFLAGS := -mmacosx-version-min=10.6 -arch x86_64 -I$(VAMP_SDK_DIR) -Wall -fPIC
 PLUGIN_EXT := .dylib
 LDFLAGS := $(CXXFLAGS) -dynamiclib -install_name $(PLUGIN_LIBRARY_NAME)$(PLUGIN_EXT) /usr/local/lib/libvamp-sdk.a -exported_symbols_list vamp-plugin.list
 
--- a/Tempogram.cpp	Wed Jul 09 20:14:20 2014 +0100
+++ b/Tempogram.cpp	Tue Aug 05 15:56:59 2014 +0100
@@ -7,10 +7,12 @@
 #include "Tempogram.h"
 #include "FIRFilter.h"
 #include "WindowFunction.h"
+#include "NoveltyCurve.h"
 #include <vamp-sdk/FFT.h>
 #include <cmath>
 #include <fstream>
 #include <assert.h>
+
 using Vamp::FFT;
 using namespace std;
 
@@ -22,14 +24,14 @@
     specMax(0),
     previousY(NULL),
     currentY(NULL),
+    spectrogram(NULL),
     minDB(0),
-    tN(1024), //make param
-    thopSize(512), //make param
+    tN(256), //make param
+    thopSize(128), //make param
     fftInput(NULL),
     fftOutputReal(NULL),
     fftOutputImag(NULL),
-    numberOfBlocks(0),
-    hannN(0)
+    numberOfBlocks(0)
 
     // Also be sure to set your plugin parameters (presumably stored
     // in member variables) to their default values here -- the host
@@ -271,6 +273,9 @@
     previousY = new float[m_blockSize];
     minDB = pow((float)10,(float)-74/20);
     
+    specData = vector< vector<float> >(m_blockSize/2 + 1);
+    spectrogram = new float * [m_blockSize/2 + 1];
+    
     return true;
 }
 
@@ -283,6 +288,7 @@
 Tempogram::FeatureSet
 Tempogram::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
 {
+    
     size_t n = m_blockSize/2 + 1;
     
     FeatureSet featureSet;
@@ -293,10 +299,8 @@
     for (int i = 0; i < n; i++){
         float magnitude = sqrt(in[2*i] * in[2*i] + in[2*i + 1] * in[2*i + 1]);
         magnitude = magnitude > minDB ? magnitude : minDB;
-        specData.push_back(magnitude);
+        specData[i].push_back(magnitude);
         feature.values.push_back(magnitude);
-        
-        specMax = specMax > magnitude ? specMax : magnitude;
     }
     
     numberOfBlocks++;
@@ -308,20 +312,18 @@
 
 void
 Tempogram::initialiseForGRF(){
-    hannN = 129;
-    hannWindow = new float[hannN];
     hannWindowtN = new float[tN];
     fftInput = new double[tN];
     fftOutputReal = new double[tN];
     fftOutputImag = new double[tN];
     
-    WindowFunction::hanning(hannWindow, hannN, true);
+    for (int i = 0; i < (m_blockSize/2 + 1); i ++){
+        spectrogram[i] = &specData[i][0];
+    }
 }
 
 void
 Tempogram::cleanupForGRF(){
-    delete []hannWindow;
-    hannWindow = NULL;
     delete []hannWindowtN;
     hannWindowtN = NULL;
     delete []fftInput;
@@ -332,64 +334,6 @@
     fftOutputImag = NULL;
 }
 
-vector<float>
-Tempogram::spectrogramToNoveltyCurve(vector<float> spectrogram, int numberOfBlocks, int blockSize, float samplingFrequency, FeatureSet * featureSet){
-    int numberOfBands = 5;
-    
-    for (int block = 0; block < numberOfBlocks; block++){
-        vector<float> sum = vector<float>(numberOfBands);
-        
-        int band = 0;
-        for (int k = 0; k < blockSize; k++){
-            int index = block*blockSize + k;
-            
-            if(index > 500*pow(2.5, band))
-                if(band < numberOfBands)
-                    band++;
-            
-            specData[index] = log(1+compressionConstant*(specData[index]/specMax));
-            
-            float currentY = specData[index];
-            float prevI = index - m_blockSize;
-            float previousY = prevI >= 0 ? specData[prevI] : 0;
-            
-            if(currentY >= previousY){
-                sum[band] += (currentY - previousY);
-            }
-        }
-        
-        float total = 0;
-        for(int band = 0; band < numberOfBands; band++){
-            total += sum[band];
-        }
-        float average = total/numberOfBands;
-        
-        noveltyCurve.push_back(average);
-    }
-    
-    vector<float> noveltyCurveLocalAverage(numberOfBlocks);
-    
-    FIRFilter *filter = new FIRFilter(numberOfBlocks, hannN);
-    filter->process(&noveltyCurve[0], hannWindow, &noveltyCurveLocalAverage[0]);
-    delete filter;
-    
-    for (int i = 0; i < numberOfBlocks; i++){
-        
-        noveltyCurve[i] -= noveltyCurveLocalAverage[i];
-        noveltyCurve[i] = noveltyCurve[i] >= 0 ? noveltyCurve[i] : 0;
-        
-        if(featureSet != NULL){
-            Feature ncFeature;
-            ncFeature.hasTimestamp = true;
-            ncFeature.timestamp = ncTimestamps[i];
-            ncFeature.values.push_back(noveltyCurve[i]);
-            (*featureSet)[1].push_back(ncFeature);
-        }
-    }
-    
-    return noveltyCurve;
-}
-
 Tempogram::FeatureSet
 Tempogram::getRemainingFeatures()
 {
@@ -397,19 +341,30 @@
     initialiseForGRF();
     FeatureSet featureSet;
     
-    noveltyCurve = spectrogramToNoveltyCurve(specData, numberOfBlocks, m_blockSize, m_inputSampleRate, &featureSet);
+    NoveltyCurve nc(m_inputSampleRate, m_blockSize, numberOfBlocks, compressionConstant);
+    noveltyCurve = nc.spectrogramToNoveltyCurve(spectrogram);
+    
+    for (int i = 0; i < numberOfBlocks; i++){
+        Feature featureNC;
+        cout << "nc:" << noveltyCurve[i] << endl;
+        featureNC.values.push_back(noveltyCurve[i]);
+        featureNC.hasTimestamp = true;
+        featureNC.timestamp = ncTimestamps[i];
+        featureSet[1].push_back(featureNC);
+    }
+    
     WindowFunction::hanning(hannWindowtN, tN);
     
     int timestampInc = floor((((float)ncTimestamps[1].nsec - ncTimestamps[0].nsec)/1e9)*(thopSize) + 0.5);
     int i = 0;
     int index;
-    int frameBeginOffset = floor(tN/2 + 0.5);
+    int frameBeginOffset = thopSize;
     
     while(i < numberOfBlocks){
         Feature feature;
         
         for (int n = frameBeginOffset; n < tN; n++){
-            index = i + n - tN/2;
+            index = i + n - thopSize;
             assert (index >= 0);
             
             if(index < numberOfBlocks){
@@ -418,18 +373,18 @@
             else if(index >= numberOfBlocks){
                 fftInput[n] = 0.0; //pad the end with zeros
             }
-            //cout << fftInput[n] << endl;
         }
-        if (i+tN/2 > numberOfBlocks){
+        
+        if (i+thopSize > numberOfBlocks){
             feature.timestamp = Vamp::RealTime::fromSeconds(ncTimestamps[i].sec + timestampInc);
         }
         else{
-            feature.timestamp = ncTimestamps[i + tN/2];
+            feature.timestamp = ncTimestamps[i + thopSize];
         }
         
         FFT::forward(tN, fftInput, NULL, fftOutputReal, fftOutputImag);
         
-        //TODO: sample at logarithmic spacing
+        //@todo: sample at logarithmic spacing? Leave for host?
         for(int k = 0; k < tN; k++){
             float fftOutputPower = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power?
             
--- a/Tempogram.h	Wed Jul 09 20:14:20 2014 +0100
+++ b/Tempogram.h	Tue Aug 05 15:56:59 2014 +0100
@@ -45,7 +45,6 @@
     bool initialise(size_t channels, size_t stepSize, size_t blockSize);
     void initialiseForGRF();
     void cleanupForGRF();
-    vector<float> spectrogramToNoveltyCurve(vector<float> spectrogramData, int numberOfBlocks, int blockSize, float samplingFrequency, FeatureSet * featureSet = NULL);
     void reset();
 
     FeatureSet process(const float *const *inputBuffers,
@@ -61,7 +60,8 @@
     float specMax;
     float *previousY;
     float *currentY;
-    vector<float> specData;
+    vector< vector<float> > specData;
+    float ** spectrogram;
     vector<float> noveltyCurve;
     float minDB;
     
@@ -72,8 +72,6 @@
     double * fftOutputImag;
     
     int numberOfBlocks;
-    int hannN;
-    float *hannWindow;
     float *hannWindowtN;
     
     vector<Vamp::RealTime> ncTimestamps;