comparison 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
comparison
equal deleted inserted replaced
12:d58409ecd720 13:7680cc4c0073
7 // 7 //
8 8
9 #include "Spectrogram.h" 9 #include "Spectrogram.h"
10 using namespace std; 10 using namespace std;
11 using Vamp::FFT; 11 using Vamp::FFT;
12 #include <iostream>
12 13
13 SpectrogramProcessor::SpectrogramProcessor(unsigned int inputLength, unsigned int windowLength, unsigned int fftLength, unsigned int hopSize) : 14 SpectrogramProcessor::SpectrogramProcessor(const size_t &inputLength, const size_t &windowLength, const size_t &fftLength, const size_t &hopSize) :
14 m_inputLength(inputLength), 15 m_inputLength(inputLength),
15 m_windowLength(windowLength), 16 m_windowLength(windowLength),
16 m_fftLength(fftLength), 17 m_fftLength(fftLength),
17 m_hopSize(hopSize), 18 m_hopSize(hopSize),
18 m_numberOfOutputBins(ceil(fftLength/2) + 1), 19 m_numberOfOutputBins(ceil(fftLength/2) + 1),
19 fftInput(0), 20 m_pFftInput(0),
20 fftOutputReal(0), 21 m_pFftOutputReal(0),
21 fftOutputImag(0) 22 m_pFftOutputImag(0)
22 { 23 {
23 initialise(); 24 initialise();
24 } 25 }
25 26
26 SpectrogramProcessor::~SpectrogramProcessor(){ 27 SpectrogramProcessor::~SpectrogramProcessor(){
27 cleanup(); 28 cleanup();
28 } 29 }
29 30
30 void SpectrogramProcessor::initialise(){ 31 void SpectrogramProcessor::initialise(){
31 fftInput = new double [m_fftLength]; 32 m_pFftInput = new double [m_fftLength];
32 fftOutputReal = new double [m_fftLength]; 33 m_pFftOutputReal = new double [m_fftLength];
33 fftOutputImag = new double [m_fftLength]; 34 m_pFftOutputImag = new double [m_fftLength];
34
35 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...
36 spectrogramOutput = vector< vector<float> >(m_numberOfOutputBins, vector<float>(numberOfBlocks));
37 } 35 }
38 36
39 void SpectrogramProcessor::cleanup(){ 37 void SpectrogramProcessor::cleanup(){
40 delete []fftInput; 38 delete []m_pFftInput;
41 delete []fftOutputReal; 39 delete []m_pFftOutputReal;
42 delete []fftOutputImag; 40 delete []m_pFftOutputImag;
43 41
44 fftInput = fftOutputReal = fftOutputImag = 0; 42 m_pFftInput = m_pFftOutputReal = m_pFftOutputImag = 0;
45 } 43 }
46 44
47 //process method 45 //process method
48 vector< vector<float> > SpectrogramProcessor::process(const float * const input, const float * window){ 46 Spectrogram SpectrogramProcessor::process(const float * const pInput, const float * pWindow) const
47 {
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...
49 Spectrogram spectrogram(m_numberOfOutputBins, vector<float>(numberOfBlocks));
49 50
50 int readPointerBeginIndex = m_hopSize-m_windowLength; 51 int readPointerBeginIndex = m_hopSize-m_windowLength;
51 int writeBlockPointer = 0; 52 unsigned int writeBlockPointer = 0;
52 53
53 while(readPointerBeginIndex < m_inputLength){ 54 while(readPointerBeginIndex < (int)m_inputLength){
54 55
55 int readPointer = readPointerBeginIndex; 56 int readPointer = readPointerBeginIndex;
56 for (int n = 0; n < m_windowLength; n++){ 57 for (unsigned int n = 0; n < m_windowLength; n++){
57 if(readPointer < 0 || readPointer >= m_inputLength){ 58 if(readPointer < 0 || readPointer >= (int)m_inputLength){
58 fftInput[n] = 0.0; //pad with zeros 59 m_pFftInput[n] = 0.0; //pad with zeros
59 } 60 }
60 else{ 61 else{
61 fftInput[n] = input[readPointer] * window[n]; 62 m_pFftInput[n] = pInput[readPointer] * pWindow[n];
62 } 63 }
63 readPointer++; 64 readPointer++;
64 } 65 }
65 for (int n = m_windowLength; n < m_fftLength; n++){ 66 for (unsigned int n = m_windowLength; n < m_fftLength; n++){
66 fftInput[n] = 0.0; 67 m_pFftInput[n] = 0.0;
67 } 68 }
68 69
69 FFT::forward(m_fftLength, fftInput, 0, fftOutputReal, fftOutputImag); 70 FFT::forward(m_fftLength, m_pFftInput, 0, m_pFftOutputReal, m_pFftOutputImag);
70 71
71 //@todo: sample at logarithmic spacing? Leave for host? 72 //@todo: sample at logarithmic spacing? Leave for host?
72 for(int k = 0; k < m_numberOfOutputBins; k++){ 73 for(unsigned int k = 0; k < m_numberOfOutputBins; k++){
73 spectrogramOutput[k][writeBlockPointer] = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power? 74 spectrogram[k][writeBlockPointer] = (m_pFftOutputReal[k]*m_pFftOutputReal[k] + m_pFftOutputImag[k]*m_pFftOutputImag[k]); //Magnitude or power?
75 //std::cout << spectrogram[k][writeBlockPointer] << std::endl;
74 } 76 }
75 77
76 readPointerBeginIndex += m_hopSize; 78 readPointerBeginIndex += m_hopSize;
77 writeBlockPointer++; 79 writeBlockPointer++;
78 } 80 }
79 81
80 return spectrogramOutput; 82 return spectrogram;
81 } 83 }