annotate Spectrogram.cpp @ 13:7680cc4c0073

* Tidying - made length of array variables type size_t and for loops unsigned int, where index > 0. * Window length parameter is now a dropdown box.
author Carl Bussey <c.bussey@se10.qmul.ac.uk>
date Wed, 13 Aug 2014 14:18:00 +0100
parents d58409ecd720
children
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@13 12 #include <iostream>
c@7 13
c@13 14 SpectrogramProcessor::SpectrogramProcessor(const size_t &inputLength, const size_t &windowLength, const size_t &fftLength, const size_t &hopSize) :
c@7 15 m_inputLength(inputLength),
c@9 16 m_windowLength(windowLength),
c@7 17 m_fftLength(fftLength),
c@7 18 m_hopSize(hopSize),
c@8 19 m_numberOfOutputBins(ceil(fftLength/2) + 1),
c@13 20 m_pFftInput(0),
c@13 21 m_pFftOutputReal(0),
c@13 22 m_pFftOutputImag(0)
c@7 23 {
c@7 24 initialise();
c@7 25 }
c@7 26
c@11 27 SpectrogramProcessor::~SpectrogramProcessor(){
c@7 28 cleanup();
c@7 29 }
c@7 30
c@11 31 void SpectrogramProcessor::initialise(){
c@13 32 m_pFftInput = new double [m_fftLength];
c@13 33 m_pFftOutputReal = new double [m_fftLength];
c@13 34 m_pFftOutputImag = new double [m_fftLength];
c@7 35 }
c@7 36
c@11 37 void SpectrogramProcessor::cleanup(){
c@13 38 delete []m_pFftInput;
c@13 39 delete []m_pFftOutputReal;
c@13 40 delete []m_pFftOutputImag;
c@7 41
c@13 42 m_pFftInput = m_pFftOutputReal = m_pFftOutputImag = 0;
c@7 43 }
c@7 44
c@9 45 //process method
c@13 46 Spectrogram SpectrogramProcessor::process(const float * const pInput, const float * pWindow) const
c@13 47 {
c@13 48 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@13 49 Spectrogram spectrogram(m_numberOfOutputBins, vector<float>(numberOfBlocks));
c@7 50
c@9 51 int readPointerBeginIndex = m_hopSize-m_windowLength;
c@13 52 unsigned int writeBlockPointer = 0;
c@7 53
c@13 54 while(readPointerBeginIndex < (int)m_inputLength){
c@7 55
c@7 56 int readPointer = readPointerBeginIndex;
c@13 57 for (unsigned int n = 0; n < m_windowLength; n++){
c@13 58 if(readPointer < 0 || readPointer >= (int)m_inputLength){
c@13 59 m_pFftInput[n] = 0.0; //pad with zeros
c@7 60 }
c@7 61 else{
c@13 62 m_pFftInput[n] = pInput[readPointer] * pWindow[n];
c@7 63 }
c@7 64 readPointer++;
c@7 65 }
c@13 66 for (unsigned int n = m_windowLength; n < m_fftLength; n++){
c@13 67 m_pFftInput[n] = 0.0;
c@9 68 }
c@7 69
c@13 70 FFT::forward(m_fftLength, m_pFftInput, 0, m_pFftOutputReal, m_pFftOutputImag);
c@7 71
c@7 72 //@todo: sample at logarithmic spacing? Leave for host?
c@13 73 for(unsigned int k = 0; k < m_numberOfOutputBins; k++){
c@13 74 spectrogram[k][writeBlockPointer] = (m_pFftOutputReal[k]*m_pFftOutputReal[k] + m_pFftOutputImag[k]*m_pFftOutputImag[k]); //Magnitude or power?
c@13 75 //std::cout << spectrogram[k][writeBlockPointer] << std::endl;
c@7 76 }
c@7 77
c@7 78 readPointerBeginIndex += m_hopSize;
c@7 79 writeBlockPointer++;
c@7 80 }
c@7 81
c@13 82 return spectrogram;
Chris@10 83 }