Mercurial > hg > vamp-tempogram
changeset 3:5125d34fda67
* Implemented normalisation
* Implemented threshold
* Strated implementing bandpass processing
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Wed, 09 Jul 2014 20:14:20 +0100 |
parents | 1d0b7dcea27f |
children | 597f033fa7a2 |
files | Makefile Tempogram.cpp Tempogram.h |
diffstat | 3 files changed, 82 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Wed Jul 09 14:32:32 2014 +0100 +++ b/Makefile Wed Jul 09 20:14:20 2014 +0100 @@ -38,7 +38,8 @@ ## Xcode 4 command-line tools. CXX := g++ -CXXFLAGS := -mmacosx-version-min=10.6 -arch x86_64 -I$(VAMP_SDK_DIR) -Wall -fPIC +#-mmacosx-version-min=10.6 +CXXFLAGS := -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 14:32:32 2014 +0100 +++ b/Tempogram.cpp Wed Jul 09 20:14:20 2014 +0100 @@ -19,14 +19,17 @@ m_blockSize(0), m_stepSize(0), compressionConstant(1000), //make param + specMax(0), previousY(NULL), currentY(NULL), + minDB(0), tN(1024), //make param thopSize(512), //make param fftInput(NULL), fftOutputReal(NULL), fftOutputImag(NULL), - ncLength(0) + numberOfBlocks(0), + hannN(0) // Also be sure to set your plugin parameters (presumably stored // in member variables) to their default values here -- the host @@ -266,6 +269,7 @@ m_stepSize = stepSize; currentY = new float[m_blockSize]; previousY = new float[m_blockSize]; + minDB = pow((float)10,(float)-74/20); return true; } @@ -285,24 +289,17 @@ Feature feature; const float *in = inputBuffers[0]; - - float sum = 0; + 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); feature.values.push_back(magnitude); - currentY[i] = log(1+compressionConstant*magnitude); - if(currentY[i] >= previousY[i]){ - sum += (currentY[i] - previousY[i]); - } + + specMax = specMax > magnitude ? specMax : magnitude; } - noveltyCurve.push_back(sum); - - float *tmpY = currentY; - currentY = previousY; - previousY = tmpY; - tmpY = NULL; - + numberOfBlocks++; ncTimestamps.push_back(timestamp); featureSet[2].push_back(feature); @@ -317,7 +314,6 @@ fftInput = new double[tN]; fftOutputReal = new double[tN]; fftOutputImag = new double[tN]; - ncLength = noveltyCurve.size(); WindowFunction::hanning(hannWindow, hannN, true); } @@ -336,6 +332,64 @@ 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() { @@ -343,45 +397,30 @@ initialiseForGRF(); FeatureSet featureSet; - vector<float> noveltyCurveLocalAverage(ncLength); - - FIRFilter *filter = new FIRFilter(ncLength, hannN); - filter->process(&noveltyCurve[0], hannWindow, &noveltyCurveLocalAverage[0]); - delete filter; - - for(int i = 0; i < ncLength; i++){ - noveltyCurve[i] -= noveltyCurveLocalAverage[i]; - noveltyCurve[i] = noveltyCurve[i] >= 0 ? noveltyCurve[i] : 0; - Feature ncFeature; - ncFeature.hasTimestamp = true; - ncFeature.timestamp = ncTimestamps[i]; - ncFeature.values.push_back(noveltyCurve[i]); - featureSet[1].push_back(ncFeature); - } - + noveltyCurve = spectrogramToNoveltyCurve(specData, numberOfBlocks, m_blockSize, m_inputSampleRate, &featureSet); WindowFunction::hanning(hannWindowtN, tN); int timestampInc = floor((((float)ncTimestamps[1].nsec - ncTimestamps[0].nsec)/1e9)*(thopSize) + 0.5); - int i=0; + int i = 0; int index; int frameBeginOffset = floor(tN/2 + 0.5); - while(i < ncLength){ + while(i < numberOfBlocks){ Feature feature; for (int n = frameBeginOffset; n < tN; n++){ index = i + n - tN/2; assert (index >= 0); - if(index < ncLength){ + if(index < numberOfBlocks){ fftInput[n] = noveltyCurve[i + n] * hannWindowtN[n]; } - else if(index >= ncLength){ + else if(index >= numberOfBlocks){ fftInput[n] = 0.0; //pad the end with zeros } //cout << fftInput[n] << endl; } - if (i+tN/2 > ncLength){ + if (i+tN/2 > numberOfBlocks){ feature.timestamp = Vamp::RealTime::fromSeconds(ncTimestamps[i].sec + timestampInc); } else{
--- a/Tempogram.h Wed Jul 09 14:32:32 2014 +0100 +++ b/Tempogram.h Wed Jul 09 20:14:20 2014 +0100 @@ -45,6 +45,7 @@ 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, @@ -57,9 +58,12 @@ size_t m_blockSize; size_t m_stepSize; float compressionConstant; + float specMax; float *previousY; float *currentY; + vector<float> specData; vector<float> noveltyCurve; + float minDB; unsigned int tN; unsigned int thopSize; @@ -67,7 +71,7 @@ double * fftOutputReal; double * fftOutputImag; - int ncLength; + int numberOfBlocks; int hannN; float *hannWindow; float *hannWindowtN;