# HG changeset patch # User Carl Bussey # Date 1407250619 -3600 # Node ID 597f033fa7a2476f133de9476890e6a1e0c767b1 # Parent 5125d34fda67bc243337028d4252a98670771b18 * Some cleaning and rearranging to prepare for band processing implementation diff -r 5125d34fda67 -r 597f033fa7a2 FIRFilter.cpp --- 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 diff -r 5125d34fda67 -r 597f033fa7a2 Makefile --- 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 diff -r 5125d34fda67 -r 597f033fa7a2 Tempogram.cpp --- 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 #include #include #include + 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 >(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 -Tempogram::spectrogramToNoveltyCurve(vector spectrogram, int numberOfBlocks, int blockSize, float samplingFrequency, FeatureSet * featureSet){ - int numberOfBands = 5; - - for (int block = 0; block < numberOfBlocks; block++){ - vector sum = vector(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 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? diff -r 5125d34fda67 -r 597f033fa7a2 Tempogram.h --- 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 spectrogramToNoveltyCurve(vector 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 specData; + vector< vector > specData; + float ** spectrogram; vector noveltyCurve; float minDB; @@ -72,8 +72,6 @@ double * fftOutputImag; int numberOfBlocks; - int hannN; - float *hannWindow; float *hannWindowtN; vector ncTimestamps;