# HG changeset patch # User Carl Bussey # Date 1407250755 -3600 # Node ID 8d7e336b41e94c43d1013077757f17246178c112 # Parent 597f033fa7a2476f133de9476890e6a1e0c767b1 Adding NoveltyCurve.* diff -r 597f033fa7a2 -r 8d7e336b41e9 NoveltyCurve.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NoveltyCurve.cpp Tue Aug 05 15:59:15 2014 +0100 @@ -0,0 +1,139 @@ +// +// NoveltyCurve.cpp +// Tempogram +// +// Created by Carl Bussey on 10/07/2014. +// Copyright (c) 2014 Carl Bussey. All rights reserved. +// + +#include +#include +#include +#include "FIRFilter.h" +#include "WindowFunction.h" +using namespace std; +#include "NoveltyCurve.h" + +NoveltyCurve::NoveltyCurve(float samplingFrequency, int blockSize, int numberOfBlocks, int compressionConstant) : + m_samplingFrequency(samplingFrequency), + m_blockSize(blockSize), + m_numberOfBlocks(numberOfBlocks), + m_compressionConstant(compressionConstant), + m_numberOfBands(5), + m_bandBoundaries(NULL), + m_hannLength(65), + m_hannWindow(NULL), + m_bandSum(NULL) +{ + initialise(); +} + +NoveltyCurve::~NoveltyCurve(){ + cleanup(); +} + +void +NoveltyCurve::initialise(){ + data = vector(m_numberOfBlocks); + + m_hannWindow = new float[m_hannLength]; + WindowFunction::hanning(m_hannWindow, m_hannLength, true); + + m_bandBoundaries = new int[m_numberOfBands+1]; //make index variable + + m_bandBoundaries[0] = 0; + for (int band = 1; band < m_numberOfBands; band++){ + float lowFreq = 500*pow(2.5, band-1); + m_bandBoundaries[band] = m_blockSize*lowFreq/m_samplingFrequency; + } + m_bandBoundaries[m_numberOfBands] = m_blockSize/2 + 1; + + m_bandSum = new float * [m_numberOfBands]; + for (int i = 0; i < m_numberOfBands; i++){ + m_bandSum[i] = new float[m_numberOfBlocks]; + } +} + +void +NoveltyCurve::cleanup(){ + delete []m_hannWindow; + m_hannWindow = NULL; + delete []m_bandBoundaries; + m_bandBoundaries = NULL; + + for(int i = 0; i < m_numberOfBands; i++){ + delete []m_bandSum[i]; + m_bandSum[i] = NULL; + } + delete []m_bandSum; + m_bandSum = NULL; +} + +float NoveltyCurve::calculateMax(float ** spectrogram){ + int specLength = (m_blockSize/2 + 1); + float max = 0; + + for (int j = 0; j < m_numberOfBlocks; j++){ + for (int i = 0; i < specLength; i++){ + max = max > spectrogram[i][j] ? max : spectrogram[i][j]; + } + } + + return max; +} + +void NoveltyCurve::subtractLocalAverage(float * noveltyCurve){ + vector localAverage(m_numberOfBlocks); + + FIRFilter *filter = new FIRFilter(m_numberOfBlocks, m_hannLength); + filter->process(&noveltyCurve[0], m_hannWindow, &localAverage[0]); + delete filter; + + for (int i = 0; i < m_numberOfBlocks; i++){ + noveltyCurve[i] -= localAverage[i]; + noveltyCurve[i] = noveltyCurve[i] >= 0 ? noveltyCurve[i] : 0; + } +} + +vector +NoveltyCurve::spectrogramToNoveltyCurve(float ** spectrogram){ + + float normaliseScale = calculateMax(spectrogram); + + for (int block = 0; block < m_numberOfBlocks; block++){ + + for (int band = 0; band < m_numberOfBands; band++){ + + int specIndex = m_bandBoundaries[band]; + int bandEnd = m_bandBoundaries[band+1]; + + while(specIndex < bandEnd){ + + spectrogram[specIndex][block] /= normaliseScale; //normalise + spectrogram[specIndex][block] = log(1+m_compressionConstant*spectrogram[specIndex][block]); + + int currentY = spectrogram[specIndex][block]; + int prevBlock = block-1; + int previousY = prevBlock >= 0 ? spectrogram[specIndex][prevBlock] : 0; + + if(currentY > previousY){ + m_bandSum[band][block] += (currentY - previousY); + } + + //cout << specIndex << endl; + specIndex++; + } + } + + float total = 0; + for(int band = 0; band < m_numberOfBands; band++){ + total += m_bandSum[band][block]; + } + float average = total/m_numberOfBands; + data[block] = average; + } + + subtractLocalAverage(&data[0]); + + return data; +} \ No newline at end of file diff -r 597f033fa7a2 -r 8d7e336b41e9 NoveltyCurve.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NoveltyCurve.h Tue Aug 05 15:59:15 2014 +0100 @@ -0,0 +1,38 @@ +// +// NoveltyCurve.h +// Tempogram +// +// Created by Carl Bussey on 10/07/2014. +// Copyright (c) 2014 Carl Bussey. All rights reserved. +// + +#ifndef __Tempogram__NoveltyCurve__ +#define __Tempogram__NoveltyCurve__ + +#include + +class NoveltyCurve{ + float m_samplingFrequency; + int m_blockSize; + int m_numberOfBlocks; + int m_compressionConstant; + int m_numberOfBands; + int * m_bandBoundaries; + int m_hannLength; + float * m_hannWindow; + float ** m_bandSum; + + void initialise(); + void cleanup(); + float calculateMax(float ** spectrogram); + void subtractLocalAverage(float * noveltyCurve); + +public: + vector data; + + NoveltyCurve(float samplingFrequency, int blockSize, int numberOfBlocks, int compressionConstant); + ~NoveltyCurve(); + vector spectrogramToNoveltyCurve(float ** spectrogram); +}; + +#endif /* defined(__Tempogram__NoveltyCurve__) */ diff -r 597f033fa7a2 -r 8d7e336b41e9 NoveltyCurve.o Binary file NoveltyCurve.o has changed