Mercurial > hg > vamp-tempogram
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 } |