annotate Spectrogram.cpp @ 7:21147df9cb2d

* Error when deleting Spectrogram object in Tempogram::getRemainingFeatures(). * Moved Spectrogram computation into own class.
author Carl Bussey <c.bussey@se10.qmul.ac.uk>
date Thu, 07 Aug 2014 16:21:21 +0100
parents
children 4e429b9f2b4d
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@7 18 m_numberOfOutputBins(floor(fftLength/2 + 0.5) + 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@7 35 int numberOfBlocks = ceil(m_inputLength/m_hopSize) + m_fftLength/m_hopSize-1;
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 cerr << "Spectrogram" << endl;
c@7 47 }
c@7 48
c@7 49 vector< vector<float> > Spectrogram::audioToMagnitudeSpectrogram(const float * const input, const float * window){
c@7 50
c@7 51 int readPointerBeginIndex = m_hopSize-m_fftLength;
c@7 52 int writeBlockPointer = 0;
c@7 53
c@7 54 while(readPointerBeginIndex < m_inputLength){
c@7 55
c@7 56 int readPointer = readPointerBeginIndex;
c@7 57 for (int n = 0; n < m_fftLength; n++){
c@7 58 if(readPointer < 0 || readPointer >= m_inputLength){
c@7 59 fftInput[n] = 0.0; //pad with zeros
c@7 60 }
c@7 61 else{
c@7 62 fftInput[n] = input[readPointer] * window[n];
c@7 63 }
c@7 64 readPointer++;
c@7 65 }
c@7 66
c@7 67 FFT::forward(m_fftLength, fftInput, NULL, fftOutputReal, fftOutputImag);
c@7 68
c@7 69 //@todo: sample at logarithmic spacing? Leave for host?
c@7 70 for(int k = 0; k < m_numberOfOutputBins; k++){
c@7 71 spectrogramOutput[k][writeBlockPointer] = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power?
c@7 72 }
c@7 73
c@7 74 readPointerBeginIndex += m_hopSize;
c@7 75 writeBlockPointer++;
c@7 76 }
c@7 77
c@7 78 return spectrogramOutput;
c@7 79 }