annotate SpectrogramProcessor.cpp @ 57:252d2b03f4a8

Added tag v1.0 for changeset f1c128d0f78c
author Chris Cannam
date Thu, 16 Oct 2014 14:22:50 +0100
parents 4cf2d163127b
children
rev   line source
Chris@43 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@43 2
Chris@43 3 /*
Chris@43 4 Vamp Tempogram Plugin
Chris@43 5 Carl Bussey, Centre for Digital Music, Queen Mary University of London
Chris@43 6 Copyright 2014 Queen Mary University of London.
Chris@43 7
Chris@43 8 This program is free software; you can redistribute it and/or
Chris@43 9 modify it under the terms of the GNU General Public License as
Chris@43 10 published by the Free Software Foundation; either version 2 of the
Chris@43 11 License, or (at your option) any later version. See the file
Chris@43 12 COPYING included with this distribution for more information.
Chris@43 13 */
c@7 14
c@14 15 #include "SpectrogramProcessor.h"
c@7 16 using namespace std;
c@7 17 using Vamp::FFT;
c@13 18 #include <iostream>
c@7 19
c@14 20 SpectrogramProcessor::SpectrogramProcessor(const size_t &windowLength, const size_t &fftLength, const size_t &hopSize) :
c@9 21 m_windowLength(windowLength),
c@7 22 m_fftLength(fftLength),
c@7 23 m_hopSize(hopSize),
c@8 24 m_numberOfOutputBins(ceil(fftLength/2) + 1),
c@13 25 m_pFftInput(0),
c@13 26 m_pFftOutputReal(0),
c@13 27 m_pFftOutputImag(0)
c@7 28 {
c@7 29 initialise();
c@7 30 }
c@7 31
c@11 32 SpectrogramProcessor::~SpectrogramProcessor(){
c@7 33 cleanup();
c@7 34 }
c@7 35
c@11 36 void SpectrogramProcessor::initialise(){
c@13 37 m_pFftInput = new double [m_fftLength];
c@13 38 m_pFftOutputReal = new double [m_fftLength];
c@13 39 m_pFftOutputImag = new double [m_fftLength];
c@7 40 }
c@7 41
c@11 42 void SpectrogramProcessor::cleanup(){
c@13 43 delete []m_pFftInput;
c@13 44 delete []m_pFftOutputReal;
c@13 45 delete []m_pFftOutputImag;
c@7 46
c@13 47 m_pFftInput = m_pFftOutputReal = m_pFftOutputImag = 0;
c@7 48 }
c@7 49
c@14 50 SpectrogramTransposed SpectrogramProcessor::transpose(const Spectrogram &spectrogram){
c@14 51 int numberOfBlocks = spectrogram.size();
c@14 52 int numberOfBins = spectrogram[0].size();
c@14 53
c@14 54 SpectrogramTransposed spectrogramT(numberOfBins, vector<float>(numberOfBlocks));
c@14 55
c@14 56 for (int i = 0; i < numberOfBlocks; i++){
c@14 57 for (int j = 0; j < numberOfBins; j++){
c@14 58 spectrogramT[j][i] = spectrogram[i][j];
c@14 59 }
c@14 60 }
c@14 61
c@14 62 return spectrogramT;
c@14 63 }
c@14 64
c@25 65 //calculate max of spectrogram
c@25 66 float SpectrogramProcessor::calculateMax(const Spectrogram &spectrogram)
c@25 67 {
c@25 68 float max = 0;
c@25 69
c@25 70 int length = spectrogram.size();
c@25 71 int height = length > 0 ? spectrogram[0].size() : 0;
c@25 72
c@25 73 for (int i = 0; i < length; i++){
c@25 74 for (int j = 0; j < height; j++){
c@25 75 max = max > fabs(spectrogram[i][j]) ? max : fabs(spectrogram[i][j]);
c@25 76 }
c@25 77 }
c@25 78
c@25 79 return max;
c@25 80 }
c@25 81
c@9 82 //process method
c@25 83 Spectrogram SpectrogramProcessor::process(const float * const pInput, const size_t &inputLength, const float * pWindow) const
c@13 84 {
c@14 85 Spectrogram spectrogram;
c@7 86
c@24 87 int readBlockPointerIndex = 0;
c@24 88 int writeBlockPointer = 0;
c@7 89
c@14 90 //cout << m_hopSize << endl;
c@24 91 while(readBlockPointerIndex <= (int)inputLength) {
c@7 92
c@14 93 int readPointer = readBlockPointerIndex - m_windowLength/2;
c@20 94 for (int n = 0; n < (int)m_windowLength; n++){
c@14 95 if(readPointer < 0 || readPointer >= (int)inputLength){
c@13 96 m_pFftInput[n] = 0.0; //pad with zeros
c@7 97 }
c@7 98 else{
c@13 99 m_pFftInput[n] = pInput[readPointer] * pWindow[n];
c@7 100 }
c@7 101 readPointer++;
c@7 102 }
c@20 103 for (int n = m_windowLength; n < (int)m_fftLength; n++){
c@13 104 m_pFftInput[n] = 0.0;
c@9 105 }
c@7 106
c@21 107 //cerr << m_fftLength << endl;
c@13 108 FFT::forward(m_fftLength, m_pFftInput, 0, m_pFftOutputReal, m_pFftOutputImag);
c@7 109
c@14 110 vector<float> binValues;
c@7 111 //@todo: sample at logarithmic spacing? Leave for host?
c@20 112 for(int k = 0; k < (int)m_numberOfOutputBins; k++){
c@14 113 binValues.push_back(m_pFftOutputReal[k]*m_pFftOutputReal[k] + m_pFftOutputImag[k]*m_pFftOutputImag[k]); //Magnitude or power?
c@13 114 //std::cout << spectrogram[k][writeBlockPointer] << std::endl;
c@7 115 }
c@14 116 spectrogram.push_back(binValues);
c@7 117
c@14 118 readBlockPointerIndex += m_hopSize;
c@7 119 writeBlockPointer++;
c@7 120 }
c@7 121
c@25 122 return spectrogram;
Chris@10 123 }