c@7
|
1 //
|
c@17
|
2 // SpectrogramProcessor.cpp
|
c@7
|
3 // Tempogram
|
c@7
|
4 //
|
c@7
|
5 // Created by Carl Bussey on 07/08/2014.
|
c@7
|
6 // Copyright (c) 2014 Carl Bussey. All rights reserved.
|
c@7
|
7 //
|
c@7
|
8
|
c@14
|
9 #include "SpectrogramProcessor.h"
|
c@7
|
10 using namespace std;
|
c@7
|
11 using Vamp::FFT;
|
c@13
|
12 #include <iostream>
|
c@7
|
13
|
c@14
|
14 SpectrogramProcessor::SpectrogramProcessor(const size_t &windowLength, const size_t &fftLength, const size_t &hopSize) :
|
c@9
|
15 m_windowLength(windowLength),
|
c@7
|
16 m_fftLength(fftLength),
|
c@7
|
17 m_hopSize(hopSize),
|
c@8
|
18 m_numberOfOutputBins(ceil(fftLength/2) + 1),
|
c@13
|
19 m_pFftInput(0),
|
c@13
|
20 m_pFftOutputReal(0),
|
c@13
|
21 m_pFftOutputImag(0)
|
c@7
|
22 {
|
c@7
|
23 initialise();
|
c@7
|
24 }
|
c@7
|
25
|
c@11
|
26 SpectrogramProcessor::~SpectrogramProcessor(){
|
c@7
|
27 cleanup();
|
c@7
|
28 }
|
c@7
|
29
|
c@11
|
30 void SpectrogramProcessor::initialise(){
|
c@13
|
31 m_pFftInput = new double [m_fftLength];
|
c@13
|
32 m_pFftOutputReal = new double [m_fftLength];
|
c@13
|
33 m_pFftOutputImag = new double [m_fftLength];
|
c@7
|
34 }
|
c@7
|
35
|
c@11
|
36 void SpectrogramProcessor::cleanup(){
|
c@13
|
37 delete []m_pFftInput;
|
c@13
|
38 delete []m_pFftOutputReal;
|
c@13
|
39 delete []m_pFftOutputImag;
|
c@7
|
40
|
c@13
|
41 m_pFftInput = m_pFftOutputReal = m_pFftOutputImag = 0;
|
c@7
|
42 }
|
c@7
|
43
|
c@14
|
44 SpectrogramTransposed SpectrogramProcessor::transpose(const Spectrogram &spectrogram){
|
c@14
|
45 int numberOfBlocks = spectrogram.size();
|
c@14
|
46 int numberOfBins = spectrogram[0].size();
|
c@14
|
47
|
c@14
|
48 SpectrogramTransposed spectrogramT(numberOfBins, vector<float>(numberOfBlocks));
|
c@14
|
49
|
c@14
|
50 for (int i = 0; i < numberOfBlocks; i++){
|
c@14
|
51 for (int j = 0; j < numberOfBins; j++){
|
c@14
|
52 spectrogramT[j][i] = spectrogram[i][j];
|
c@14
|
53 }
|
c@14
|
54 }
|
c@14
|
55
|
c@14
|
56 return spectrogramT;
|
c@14
|
57 }
|
c@14
|
58
|
c@25
|
59 //calculate max of spectrogram
|
c@25
|
60 float SpectrogramProcessor::calculateMax(const Spectrogram &spectrogram)
|
c@25
|
61 {
|
c@25
|
62 float max = 0;
|
c@25
|
63
|
c@25
|
64 int length = spectrogram.size();
|
c@25
|
65 int height = length > 0 ? spectrogram[0].size() : 0;
|
c@25
|
66
|
c@25
|
67 for (int i = 0; i < length; i++){
|
c@25
|
68 for (int j = 0; j < height; j++){
|
c@25
|
69 max = max > fabs(spectrogram[i][j]) ? max : fabs(spectrogram[i][j]);
|
c@25
|
70 }
|
c@25
|
71 }
|
c@25
|
72
|
c@25
|
73 return max;
|
c@25
|
74 }
|
c@25
|
75
|
c@9
|
76 //process method
|
c@25
|
77 Spectrogram SpectrogramProcessor::process(const float * const pInput, const size_t &inputLength, const float * pWindow) const
|
c@13
|
78 {
|
c@14
|
79 Spectrogram spectrogram;
|
c@7
|
80
|
c@24
|
81 int readBlockPointerIndex = 0;
|
c@24
|
82 int writeBlockPointer = 0;
|
c@7
|
83
|
c@14
|
84 //cout << m_hopSize << endl;
|
c@24
|
85 while(readBlockPointerIndex <= (int)inputLength) {
|
c@7
|
86
|
c@14
|
87 int readPointer = readBlockPointerIndex - m_windowLength/2;
|
c@20
|
88 for (int n = 0; n < (int)m_windowLength; n++){
|
c@14
|
89 if(readPointer < 0 || readPointer >= (int)inputLength){
|
c@13
|
90 m_pFftInput[n] = 0.0; //pad with zeros
|
c@7
|
91 }
|
c@7
|
92 else{
|
c@13
|
93 m_pFftInput[n] = pInput[readPointer] * pWindow[n];
|
c@7
|
94 }
|
c@7
|
95 readPointer++;
|
c@7
|
96 }
|
c@20
|
97 for (int n = m_windowLength; n < (int)m_fftLength; n++){
|
c@13
|
98 m_pFftInput[n] = 0.0;
|
c@9
|
99 }
|
c@7
|
100
|
c@21
|
101 //cerr << m_fftLength << endl;
|
c@13
|
102 FFT::forward(m_fftLength, m_pFftInput, 0, m_pFftOutputReal, m_pFftOutputImag);
|
c@7
|
103
|
c@14
|
104 vector<float> binValues;
|
c@7
|
105 //@todo: sample at logarithmic spacing? Leave for host?
|
c@20
|
106 for(int k = 0; k < (int)m_numberOfOutputBins; k++){
|
c@14
|
107 binValues.push_back(m_pFftOutputReal[k]*m_pFftOutputReal[k] + m_pFftOutputImag[k]*m_pFftOutputImag[k]); //Magnitude or power?
|
c@13
|
108 //std::cout << spectrogram[k][writeBlockPointer] << std::endl;
|
c@7
|
109 }
|
c@14
|
110 spectrogram.push_back(binValues);
|
c@7
|
111
|
c@14
|
112 readBlockPointerIndex += m_hopSize;
|
c@7
|
113 writeBlockPointer++;
|
c@7
|
114 }
|
c@7
|
115
|
c@25
|
116 return spectrogram;
|
Chris@10
|
117 }
|