| c@7 | 1 // | 
| c@17 | 2 //  SpectrogramProcessor.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@14 | 9 #include "SpectrogramProcessor.h" | 
| c@7 | 10 using namespace std; | 
| c@7 | 11 using Vamp::FFT; | 
| c@13 | 12 #include <iostream> | 
| c@7 | 13 | 
| c@14 | 14 SpectrogramProcessor::SpectrogramProcessor(const size_t &windowLength, const size_t &fftLength, const size_t &hopSize) : | 
| 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), | 
| c@13 | 19     m_pFftInput(0), | 
| c@13 | 20     m_pFftOutputReal(0), | 
| c@13 | 21     m_pFftOutputImag(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@13 | 31     m_pFftInput = new double [m_fftLength]; | 
| c@13 | 32     m_pFftOutputReal = new double [m_fftLength]; | 
| c@13 | 33     m_pFftOutputImag = new double [m_fftLength]; | 
| c@7 | 34 } | 
| c@7 | 35 | 
| c@11 | 36 void SpectrogramProcessor::cleanup(){ | 
| c@13 | 37     delete []m_pFftInput; | 
| c@13 | 38     delete []m_pFftOutputReal; | 
| c@13 | 39     delete []m_pFftOutputImag; | 
| c@7 | 40 | 
| c@13 | 41     m_pFftInput = m_pFftOutputReal = m_pFftOutputImag = 0; | 
| c@7 | 42 } | 
| c@7 | 43 | 
| c@14 | 44 SpectrogramTransposed SpectrogramProcessor::transpose(const Spectrogram &spectrogram){ | 
| c@14 | 45     int numberOfBlocks = spectrogram.size(); | 
| c@14 | 46     int numberOfBins = spectrogram[0].size(); | 
| c@14 | 47 | 
| c@14 | 48     SpectrogramTransposed spectrogramT(numberOfBins, vector<float>(numberOfBlocks)); | 
| c@14 | 49 | 
| c@14 | 50     for (int i = 0; i < numberOfBlocks; i++){ | 
| c@14 | 51         for (int j = 0; j < numberOfBins; j++){ | 
| c@14 | 52             spectrogramT[j][i] = spectrogram[i][j]; | 
| c@14 | 53         } | 
| c@14 | 54     } | 
| c@14 | 55 | 
| c@14 | 56     return spectrogramT; | 
| c@14 | 57 } | 
| c@14 | 58 | 
| c@9 | 59 //process method | 
| c@14 | 60 Spectrogram SpectrogramProcessor::process(const float * const pInput, const size_t &inputLength, const float * pWindow, const bool &transposeOutput) const | 
| c@13 | 61 { | 
| c@14 | 62     Spectrogram spectrogram; | 
| c@7 | 63 | 
| c@24 | 64     int readBlockPointerIndex = 0; | 
| c@24 | 65     int writeBlockPointer = 0; | 
| c@7 | 66 | 
| c@14 | 67     //cout << m_hopSize << endl; | 
| c@24 | 68     while(readBlockPointerIndex <= (int)inputLength) { | 
| c@7 | 69 | 
| c@14 | 70         int readPointer = readBlockPointerIndex - m_windowLength/2; | 
| c@20 | 71         for (int n = 0; n < (int)m_windowLength; n++){ | 
| c@14 | 72             if(readPointer < 0 || readPointer >= (int)inputLength){ | 
| c@13 | 73                 m_pFftInput[n] = 0.0; //pad with zeros | 
| c@7 | 74             } | 
| c@7 | 75             else{ | 
| c@13 | 76                 m_pFftInput[n] = pInput[readPointer] * pWindow[n]; | 
| c@7 | 77             } | 
| c@7 | 78             readPointer++; | 
| c@7 | 79         } | 
| c@20 | 80         for (int n = m_windowLength; n < (int)m_fftLength; n++){ | 
| c@13 | 81             m_pFftInput[n] = 0.0; | 
| c@9 | 82         } | 
| c@7 | 83 | 
| c@21 | 84         //cerr << m_fftLength << endl; | 
| c@13 | 85         FFT::forward(m_fftLength, m_pFftInput, 0, m_pFftOutputReal, m_pFftOutputImag); | 
| c@7 | 86 | 
| c@14 | 87         vector<float> binValues; | 
| c@7 | 88         //@todo: sample at logarithmic spacing? Leave for host? | 
| c@20 | 89         for(int k = 0; k < (int)m_numberOfOutputBins; k++){ | 
| c@14 | 90             binValues.push_back(m_pFftOutputReal[k]*m_pFftOutputReal[k] + m_pFftOutputImag[k]*m_pFftOutputImag[k]); //Magnitude or power? | 
| c@13 | 91             //std::cout << spectrogram[k][writeBlockPointer] << std::endl; | 
| c@7 | 92         } | 
| c@14 | 93         spectrogram.push_back(binValues); | 
| c@7 | 94 | 
| c@14 | 95         readBlockPointerIndex += m_hopSize; | 
| c@7 | 96         writeBlockPointer++; | 
| c@7 | 97     } | 
| c@7 | 98 | 
| c@14 | 99     if(transposeOutput) return transpose(spectrogram); | 
| c@14 | 100     else return spectrogram; | 
| Chris@10 | 101 } |