annotate Spectrogram.cpp @ 8:4e429b9f2b4d

* Fixed memory leak bug. Issue with calculating size of spectrogram array. * Fixed bug in Tempogram::reset() where specData wasn't reinitialised.
author Carl Bussey <c.bussey@se10.qmul.ac.uk>
date Thu, 07 Aug 2014 17:25:24 +0100
parents 21147df9cb2d
children be59b4a73f49
rev   line source
c@7 1 //
c@7 2 // Spectrogram.cpp
c@7 3 // Tempogram
c@7 4 //
c@7 5 // Created by Carl Bussey on 07/08/2014.
c@7 6 // Copyright (c) 2014 Carl Bussey. All rights reserved.
c@7 7 //
c@7 8
c@7 9 #include "Spectrogram.h"
c@7 10 #include <iostream>
c@7 11 using namespace std;
c@7 12 using Vamp::FFT;
c@7 13
c@7 14 Spectrogram::Spectrogram(unsigned int inputLength, unsigned int fftLength, unsigned int hopSize) :
c@7 15 m_inputLength(inputLength),
c@7 16 m_fftLength(fftLength),
c@7 17 m_hopSize(hopSize),
c@8 18 m_numberOfOutputBins(ceil(fftLength/2) + 1),
c@7 19 fftInput(NULL),
c@7 20 fftOutputReal(NULL),
c@7 21 fftOutputImag(NULL)
c@7 22 {
c@7 23 initialise();
c@7 24 }
c@7 25
c@7 26 Spectrogram::~Spectrogram(){
c@7 27 cleanup();
c@7 28 }
c@7 29
c@7 30 void Spectrogram::initialise(){
c@7 31 fftInput = new double [m_fftLength];
c@7 32 fftOutputReal = new double [m_fftLength];
c@7 33 fftOutputImag = new double [m_fftLength];
c@7 34
c@8 35 int numberOfBlocks = ceil(m_inputLength/m_hopSize) + 2*(ceil(m_fftLength/m_hopSize)-1); //The last term corresponds to overlaps at the beginning and end with padded zeros. I.e., if m_hopSize = m_fftLength/2, there'll be 1 overlap at each end. If m_hopSize = m_fftLength/4, there'll be 3 overlaps at each end, etc...
c@7 36 spectrogramOutput = vector< vector<float> >(m_numberOfOutputBins, vector<float>(numberOfBlocks));
c@7 37 }
c@7 38
c@7 39 void Spectrogram::cleanup(){
c@7 40 delete []fftInput;
c@7 41 delete []fftOutputReal;
c@7 42 delete []fftOutputImag;
c@7 43
c@7 44 fftInput = fftOutputReal = fftOutputImag = NULL;
c@7 45 }
c@7 46
c@7 47 vector< vector<float> > Spectrogram::audioToMagnitudeSpectrogram(const float * const input, const float * window){
c@7 48
c@7 49 int readPointerBeginIndex = m_hopSize-m_fftLength;
c@7 50 int writeBlockPointer = 0;
c@7 51
c@7 52 while(readPointerBeginIndex < m_inputLength){
c@7 53
c@7 54 int readPointer = readPointerBeginIndex;
c@7 55 for (int n = 0; n < m_fftLength; n++){
c@7 56 if(readPointer < 0 || readPointer >= m_inputLength){
c@7 57 fftInput[n] = 0.0; //pad with zeros
c@7 58 }
c@7 59 else{
c@7 60 fftInput[n] = input[readPointer] * window[n];
c@7 61 }
c@7 62 readPointer++;
c@7 63 }
c@7 64
c@7 65 FFT::forward(m_fftLength, fftInput, NULL, fftOutputReal, fftOutputImag);
c@7 66
c@7 67 //@todo: sample at logarithmic spacing? Leave for host?
c@7 68 for(int k = 0; k < m_numberOfOutputBins; k++){
c@7 69 spectrogramOutput[k][writeBlockPointer] = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power?
c@8 70 cerr << writeBlockPointer << " : " << spectrogramOutput[k].size() << endl;
c@7 71 }
c@7 72
c@7 73 readPointerBeginIndex += m_hopSize;
c@7 74 writeBlockPointer++;
c@7 75 }
c@7 76
c@7 77 return spectrogramOutput;
c@7 78 }