Mercurial > hg > vamp-tempogram
comparison Spectrogram.cpp @ 9:be59b4a73f49
* Added Spectrogram zero padding functionality
* Made output bins correspond to BPM
* User can now specify a range of output bins to view
* Comments added
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Tue, 12 Aug 2014 14:40:37 +0100 |
parents | 4e429b9f2b4d |
children | 17a260410116 09fb76606b2b |
comparison
equal
deleted
inserted
replaced
8:4e429b9f2b4d | 9:be59b4a73f49 |
---|---|
5 // Created by Carl Bussey on 07/08/2014. | 5 // Created by Carl Bussey on 07/08/2014. |
6 // Copyright (c) 2014 Carl Bussey. All rights reserved. | 6 // Copyright (c) 2014 Carl Bussey. All rights reserved. |
7 // | 7 // |
8 | 8 |
9 #include "Spectrogram.h" | 9 #include "Spectrogram.h" |
10 #include <iostream> | |
11 using namespace std; | 10 using namespace std; |
12 using Vamp::FFT; | 11 using Vamp::FFT; |
13 | 12 |
14 Spectrogram::Spectrogram(unsigned int inputLength, unsigned int fftLength, unsigned int hopSize) : | 13 Spectrogram::Spectrogram(unsigned int inputLength, unsigned int windowLength, unsigned int fftLength, unsigned int hopSize) : |
15 m_inputLength(inputLength), | 14 m_inputLength(inputLength), |
15 m_windowLength(windowLength), | |
16 m_fftLength(fftLength), | 16 m_fftLength(fftLength), |
17 m_hopSize(hopSize), | 17 m_hopSize(hopSize), |
18 m_numberOfOutputBins(ceil(fftLength/2) + 1), | 18 m_numberOfOutputBins(ceil(fftLength/2) + 1), |
19 fftInput(NULL), | 19 fftInput(NULL), |
20 fftOutputReal(NULL), | 20 fftOutputReal(NULL), |
30 void Spectrogram::initialise(){ | 30 void Spectrogram::initialise(){ |
31 fftInput = new double [m_fftLength]; | 31 fftInput = new double [m_fftLength]; |
32 fftOutputReal = new double [m_fftLength]; | 32 fftOutputReal = new double [m_fftLength]; |
33 fftOutputImag = new double [m_fftLength]; | 33 fftOutputImag = new double [m_fftLength]; |
34 | 34 |
35 int numberOfBlocks = ceil(m_inputLength/m_hopSize) + 2*(ceil(m_fftLength/m_hopSize)-1); //The last term corresponds to overlaps at the beginning and end with padded zeros. I.e., if m_hopSize = m_fftLength/2, there'll be 1 overlap at each end. If m_hopSize = m_fftLength/4, there'll be 3 overlaps at each end, etc... | 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)); | 36 spectrogramOutput = vector< vector<float> >(m_numberOfOutputBins, vector<float>(numberOfBlocks)); |
37 } | 37 } |
38 | 38 |
39 void Spectrogram::cleanup(){ | 39 void Spectrogram::cleanup(){ |
40 delete []fftInput; | 40 delete []fftInput; |
42 delete []fftOutputImag; | 42 delete []fftOutputImag; |
43 | 43 |
44 fftInput = fftOutputReal = fftOutputImag = NULL; | 44 fftInput = fftOutputReal = fftOutputImag = NULL; |
45 } | 45 } |
46 | 46 |
47 //process method | |
47 vector< vector<float> > Spectrogram::audioToMagnitudeSpectrogram(const float * const input, const float * window){ | 48 vector< vector<float> > Spectrogram::audioToMagnitudeSpectrogram(const float * const input, const float * window){ |
48 | 49 |
49 int readPointerBeginIndex = m_hopSize-m_fftLength; | 50 int readPointerBeginIndex = m_hopSize-m_windowLength; |
50 int writeBlockPointer = 0; | 51 int writeBlockPointer = 0; |
51 | 52 |
52 while(readPointerBeginIndex < m_inputLength){ | 53 while(readPointerBeginIndex < m_inputLength){ |
53 | 54 |
54 int readPointer = readPointerBeginIndex; | 55 int readPointer = readPointerBeginIndex; |
55 for (int n = 0; n < m_fftLength; n++){ | 56 for (int n = 0; n < m_windowLength; n++){ |
56 if(readPointer < 0 || readPointer >= m_inputLength){ | 57 if(readPointer < 0 || readPointer >= m_inputLength){ |
57 fftInput[n] = 0.0; //pad with zeros | 58 fftInput[n] = 0.0; //pad with zeros |
58 } | 59 } |
59 else{ | 60 else{ |
60 fftInput[n] = input[readPointer] * window[n]; | 61 fftInput[n] = input[readPointer] * window[n]; |
61 } | 62 } |
62 readPointer++; | 63 readPointer++; |
63 } | 64 } |
65 for (int n = m_windowLength; n < m_fftLength; n++){ | |
66 fftInput[n] = 0.0; | |
67 } | |
64 | 68 |
65 FFT::forward(m_fftLength, fftInput, NULL, fftOutputReal, fftOutputImag); | 69 FFT::forward(m_fftLength, fftInput, NULL, fftOutputReal, fftOutputImag); |
66 | 70 |
67 //@todo: sample at logarithmic spacing? Leave for host? | 71 //@todo: sample at logarithmic spacing? Leave for host? |
68 for(int k = 0; k < m_numberOfOutputBins; k++){ | 72 for(int k = 0; k < m_numberOfOutputBins; k++){ |
69 spectrogramOutput[k][writeBlockPointer] = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power? | 73 spectrogramOutput[k][writeBlockPointer] = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power? |
70 cerr << writeBlockPointer << " : " << spectrogramOutput[k].size() << endl; | |
71 } | 74 } |
72 | 75 |
73 readPointerBeginIndex += m_hopSize; | 76 readPointerBeginIndex += m_hopSize; |
74 writeBlockPointer++; | 77 writeBlockPointer++; |
75 } | 78 } |