c@7: // c@17: // SpectrogramProcessor.cpp c@7: // Tempogram c@7: // c@7: // Created by Carl Bussey on 07/08/2014. c@7: // Copyright (c) 2014 Carl Bussey. All rights reserved. c@7: // c@7: c@14: #include "SpectrogramProcessor.h" c@7: using namespace std; c@7: using Vamp::FFT; c@13: #include c@7: c@14: SpectrogramProcessor::SpectrogramProcessor(const size_t &windowLength, const size_t &fftLength, const size_t &hopSize) : c@9: m_windowLength(windowLength), c@7: m_fftLength(fftLength), c@7: m_hopSize(hopSize), c@8: m_numberOfOutputBins(ceil(fftLength/2) + 1), c@13: m_pFftInput(0), c@13: m_pFftOutputReal(0), c@13: m_pFftOutputImag(0) c@7: { c@7: initialise(); c@7: } c@7: c@11: SpectrogramProcessor::~SpectrogramProcessor(){ c@7: cleanup(); c@7: } c@7: c@11: void SpectrogramProcessor::initialise(){ c@13: m_pFftInput = new double [m_fftLength]; c@13: m_pFftOutputReal = new double [m_fftLength]; c@13: m_pFftOutputImag = new double [m_fftLength]; c@7: } c@7: c@11: void SpectrogramProcessor::cleanup(){ c@13: delete []m_pFftInput; c@13: delete []m_pFftOutputReal; c@13: delete []m_pFftOutputImag; c@7: c@13: m_pFftInput = m_pFftOutputReal = m_pFftOutputImag = 0; c@7: } c@7: c@14: SpectrogramTransposed SpectrogramProcessor::transpose(const Spectrogram &spectrogram){ c@14: int numberOfBlocks = spectrogram.size(); c@14: int numberOfBins = spectrogram[0].size(); c@14: c@14: SpectrogramTransposed spectrogramT(numberOfBins, vector(numberOfBlocks)); c@14: c@14: for (int i = 0; i < numberOfBlocks; i++){ c@14: for (int j = 0; j < numberOfBins; j++){ c@14: spectrogramT[j][i] = spectrogram[i][j]; c@14: } c@14: } c@14: c@14: return spectrogramT; c@14: } c@14: c@25: //calculate max of spectrogram c@25: float SpectrogramProcessor::calculateMax(const Spectrogram &spectrogram) c@25: { c@25: float max = 0; c@25: c@25: int length = spectrogram.size(); c@25: int height = length > 0 ? spectrogram[0].size() : 0; c@25: c@25: for (int i = 0; i < length; i++){ c@25: for (int j = 0; j < height; j++){ c@25: max = max > fabs(spectrogram[i][j]) ? max : fabs(spectrogram[i][j]); c@25: } c@25: } c@25: c@25: return max; c@25: } c@25: c@9: //process method c@25: Spectrogram SpectrogramProcessor::process(const float * const pInput, const size_t &inputLength, const float * pWindow) const c@13: { c@14: Spectrogram spectrogram; c@7: c@24: int readBlockPointerIndex = 0; c@24: int writeBlockPointer = 0; c@7: c@14: //cout << m_hopSize << endl; c@24: while(readBlockPointerIndex <= (int)inputLength) { c@7: c@14: int readPointer = readBlockPointerIndex - m_windowLength/2; c@20: for (int n = 0; n < (int)m_windowLength; n++){ c@14: if(readPointer < 0 || readPointer >= (int)inputLength){ c@13: m_pFftInput[n] = 0.0; //pad with zeros c@7: } c@7: else{ c@13: m_pFftInput[n] = pInput[readPointer] * pWindow[n]; c@7: } c@7: readPointer++; c@7: } c@20: for (int n = m_windowLength; n < (int)m_fftLength; n++){ c@13: m_pFftInput[n] = 0.0; c@9: } c@7: c@21: //cerr << m_fftLength << endl; c@13: FFT::forward(m_fftLength, m_pFftInput, 0, m_pFftOutputReal, m_pFftOutputImag); c@7: c@14: vector binValues; c@7: //@todo: sample at logarithmic spacing? Leave for host? c@20: for(int k = 0; k < (int)m_numberOfOutputBins; k++){ c@14: binValues.push_back(m_pFftOutputReal[k]*m_pFftOutputReal[k] + m_pFftOutputImag[k]*m_pFftOutputImag[k]); //Magnitude or power? c@13: //std::cout << spectrogram[k][writeBlockPointer] << std::endl; c@7: } c@14: spectrogram.push_back(binValues); c@7: c@14: readBlockPointerIndex += m_hopSize; c@7: writeBlockPointer++; c@7: } c@7: c@25: return spectrogram; Chris@10: }