Mercurial > hg > vamp-tempogram
diff SpectrogramProcessor.cpp @ 14:c11367df624d
* Renamed NoveltyCurve.* and Spectrogram.* to $(Name)Processor.*
* Aligned novelty curve with audio - when performing FIRFilter::process(params), take inputLength after group delay.
* Removed trail of Spectrogram.
* General tidying!
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Thu, 14 Aug 2014 10:31:49 +0100 (2014-08-14) |
parents | Spectrogram.cpp@7680cc4c0073 |
children | 1e4c02ca8b81 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SpectrogramProcessor.cpp Thu Aug 14 10:31:49 2014 +0100 @@ -0,0 +1,100 @@ +// +// Spectrogram.cpp +// Tempogram +// +// Created by Carl Bussey on 07/08/2014. +// Copyright (c) 2014 Carl Bussey. All rights reserved. +// + +#include "SpectrogramProcessor.h" +using namespace std; +using Vamp::FFT; +#include <iostream> + +SpectrogramProcessor::SpectrogramProcessor(const size_t &windowLength, const size_t &fftLength, const size_t &hopSize) : + m_windowLength(windowLength), + m_fftLength(fftLength), + m_hopSize(hopSize), + m_numberOfOutputBins(ceil(fftLength/2) + 1), + m_pFftInput(0), + m_pFftOutputReal(0), + m_pFftOutputImag(0) +{ + initialise(); +} + +SpectrogramProcessor::~SpectrogramProcessor(){ + cleanup(); +} + +void SpectrogramProcessor::initialise(){ + m_pFftInput = new double [m_fftLength]; + m_pFftOutputReal = new double [m_fftLength]; + m_pFftOutputImag = new double [m_fftLength]; +} + +void SpectrogramProcessor::cleanup(){ + delete []m_pFftInput; + delete []m_pFftOutputReal; + delete []m_pFftOutputImag; + + m_pFftInput = m_pFftOutputReal = m_pFftOutputImag = 0; +} + +SpectrogramTransposed SpectrogramProcessor::transpose(const Spectrogram &spectrogram){ + int numberOfBlocks = spectrogram.size(); + int numberOfBins = spectrogram[0].size(); + + SpectrogramTransposed spectrogramT(numberOfBins, vector<float>(numberOfBlocks)); + + for (int i = 0; i < numberOfBlocks; i++){ + for (int j = 0; j < numberOfBins; j++){ + spectrogramT[j][i] = spectrogram[i][j]; + } + } + + return spectrogramT; +} + +//process method +Spectrogram SpectrogramProcessor::process(const float * const pInput, const size_t &inputLength, const float * pWindow, const bool &transposeOutput) const +{ + Spectrogram spectrogram; + + unsigned int readBlockPointerIndex = 0; + unsigned int writeBlockPointer = 0; + + //cout << m_hopSize << endl; + while(readBlockPointerIndex <= inputLength) { + + int readPointer = readBlockPointerIndex - m_windowLength/2; + for (unsigned int n = 0; n < m_windowLength; n++){ + if(readPointer < 0 || readPointer >= (int)inputLength){ + m_pFftInput[n] = 0.0; //pad with zeros + } + else{ + m_pFftInput[n] = pInput[readPointer] * pWindow[n]; + } + readPointer++; + } + for (unsigned int n = m_windowLength; n < m_fftLength; n++){ + m_pFftInput[n] = 0.0; + } + + FFT::forward(m_fftLength, m_pFftInput, 0, m_pFftOutputReal, m_pFftOutputImag); + + vector<float> binValues; + //@todo: sample at logarithmic spacing? Leave for host? + for(unsigned int k = 0; k < m_numberOfOutputBins; k++){ + binValues.push_back(m_pFftOutputReal[k]*m_pFftOutputReal[k] + m_pFftOutputImag[k]*m_pFftOutputImag[k]); //Magnitude or power? + //std::cout << spectrogram[k][writeBlockPointer] << std::endl; + } + spectrogram.push_back(binValues); + + readBlockPointerIndex += m_hopSize; + writeBlockPointer++; + } + + if(transposeOutput) return transpose(spectrogram); + else return spectrogram; +}