annotate Spectrogram.cpp @ 12:d58409ecd720

* Merging Chris' changes
author Carl Bussey <c.bussey@se10.qmul.ac.uk>
date Wed, 13 Aug 2014 10:47:39 +0100
parents 09fb76606b2b 17a260410116
children 7680cc4c0073
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 using namespace std;
c@7 11 using Vamp::FFT;
c@7 12
c@11 13 SpectrogramProcessor::SpectrogramProcessor(unsigned int inputLength, unsigned int windowLength, unsigned int fftLength, unsigned int hopSize) :
c@7 14 m_inputLength(inputLength),
c@9 15 m_windowLength(windowLength),
c@7 16 m_fftLength(fftLength),
c@7 17 m_hopSize(hopSize),
c@8 18 m_numberOfOutputBins(ceil(fftLength/2) + 1),
Chris@10 19 fftInput(0),
Chris@10 20 fftOutputReal(0),
Chris@10 21 fftOutputImag(0)
c@7 22 {
c@7 23 initialise();
c@7 24 }
c@7 25
c@11 26 SpectrogramProcessor::~SpectrogramProcessor(){
c@7 27 cleanup();
c@7 28 }
c@7 29
c@11 30 void SpectrogramProcessor::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@9 35 int numberOfBlocks = ceil(m_inputLength/m_hopSize) + 2*(ceil(m_windowLength/m_hopSize)-1); //The last term corresponds to overlaps at the beginning and end with padded zeros. I.e., if m_hopSize = m_windowLength/2, there'll be 1 overlap at each end. If m_hopSize = m_windowLength/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@11 39 void SpectrogramProcessor::cleanup(){
c@7 40 delete []fftInput;
c@7 41 delete []fftOutputReal;
c@7 42 delete []fftOutputImag;
c@7 43
Chris@10 44 fftInput = fftOutputReal = fftOutputImag = 0;
c@7 45 }
c@7 46
c@9 47 //process method
c@11 48 vector< vector<float> > SpectrogramProcessor::process(const float * const input, const float * window){
c@7 49
c@9 50 int readPointerBeginIndex = m_hopSize-m_windowLength;
c@7 51 int writeBlockPointer = 0;
c@7 52
c@7 53 while(readPointerBeginIndex < m_inputLength){
c@7 54
c@7 55 int readPointer = readPointerBeginIndex;
c@9 56 for (int n = 0; n < m_windowLength; n++){
c@7 57 if(readPointer < 0 || readPointer >= m_inputLength){
c@7 58 fftInput[n] = 0.0; //pad with zeros
c@7 59 }
c@7 60 else{
c@7 61 fftInput[n] = input[readPointer] * window[n];
c@7 62 }
c@7 63 readPointer++;
c@7 64 }
c@9 65 for (int n = m_windowLength; n < m_fftLength; n++){
c@9 66 fftInput[n] = 0.0;
c@9 67 }
c@7 68
Chris@10 69 FFT::forward(m_fftLength, fftInput, 0, fftOutputReal, fftOutputImag);
c@7 70
c@7 71 //@todo: sample at logarithmic spacing? Leave for host?
c@7 72 for(int k = 0; k < m_numberOfOutputBins; k++){
c@7 73 spectrogramOutput[k][writeBlockPointer] = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power?
c@7 74 }
c@7 75
c@7 76 readPointerBeginIndex += m_hopSize;
c@7 77 writeBlockPointer++;
c@7 78 }
c@7 79
c@7 80 return spectrogramOutput;
Chris@10 81 }