c@0
|
1 //
|
c@0
|
2 // FIRFilter.cpp
|
c@0
|
3 // Tempogram
|
c@0
|
4 //
|
c@0
|
5 // Created by Carl Bussey on 25/06/2014.
|
c@0
|
6 // Copyright (c) 2014 Carl Bussey. All rights reserved.
|
c@0
|
7 //
|
c@0
|
8
|
c@0
|
9 #include "FIRFilter.h"
|
c@7
|
10
|
c@0
|
11 using namespace std;
|
c@0
|
12 using Vamp::FFT;
|
c@0
|
13
|
c@0
|
14 FIRFilter::FIRFilter(const unsigned int lengthInput, const unsigned int numberOfCoefficients) :
|
c@8
|
15 m_lengthInput(lengthInput),
|
c@8
|
16 m_numberOfCoefficients(numberOfCoefficients),
|
c@0
|
17 fftInput(NULL),
|
c@0
|
18 fftCoefficients(NULL),
|
c@0
|
19 fftReal1(NULL),
|
c@0
|
20 fftImag1(NULL),
|
c@0
|
21 fftReal2(NULL),
|
c@0
|
22 fftImag2(NULL),
|
c@0
|
23 fftFilteredReal(NULL),
|
c@0
|
24 fftFilteredImag(NULL),
|
c@0
|
25 fftOutputReal(NULL),
|
c@0
|
26 fftOutputImag(NULL)
|
c@0
|
27 {
|
c@0
|
28 initialise();
|
c@0
|
29 }
|
c@0
|
30
|
c@0
|
31 FIRFilter::~FIRFilter()
|
c@0
|
32 {
|
c@0
|
33 cleanup();
|
c@0
|
34 }
|
c@0
|
35
|
c@9
|
36 //allocate memory
|
c@0
|
37 void
|
c@0
|
38 FIRFilter::initialise()
|
c@0
|
39 {
|
c@9
|
40 //next power of 2
|
c@8
|
41 m_lengthFIRFFT = pow(2,(ceil(log2(m_lengthInput+m_numberOfCoefficients-1))));
|
c@0
|
42
|
c@8
|
43 fftInput = new double[m_lengthFIRFFT];
|
c@8
|
44 fftCoefficients = new double[m_lengthFIRFFT];
|
c@8
|
45 fftReal1 = new double[m_lengthFIRFFT];
|
c@8
|
46 fftImag1 = new double[m_lengthFIRFFT];
|
c@8
|
47 fftReal2 = new double[m_lengthFIRFFT];
|
c@8
|
48 fftImag2 = new double[m_lengthFIRFFT];
|
c@8
|
49 fftFilteredReal = new double[m_lengthFIRFFT];
|
c@8
|
50 fftFilteredImag = new double[m_lengthFIRFFT];
|
c@8
|
51 fftOutputReal = new double[m_lengthFIRFFT];
|
c@8
|
52 fftOutputImag = new double[m_lengthFIRFFT];
|
c@0
|
53
|
c@8
|
54 for(int i = 0; i < m_lengthFIRFFT; i++){
|
c@0
|
55 fftInput[i] = fftCoefficients[i] = fftReal1[i] = fftImag1[i] = fftReal2[i] = fftImag2[i] = fftFilteredReal[i] = fftFilteredImag[i] = fftOutputReal[i] = fftOutputImag[i] = 0.0;
|
c@0
|
56 }
|
c@0
|
57 }
|
c@0
|
58
|
c@0
|
59 void
|
c@0
|
60 FIRFilter::process(const float* input, const float* coefficients, float* output)
|
c@0
|
61 {
|
c@9
|
62 //Copy to same length FFT buffers
|
c@8
|
63 for(int i = 0; i < m_lengthFIRFFT; i++){
|
c@8
|
64 fftInput[i] = i < m_lengthInput ? input[i] : 0.0;
|
c@8
|
65 fftCoefficients[i] = i < m_numberOfCoefficients ? coefficients[i] : 0.0;
|
c@0
|
66 }
|
c@0
|
67
|
c@8
|
68 FFT::forward(m_lengthFIRFFT, fftInput, NULL, fftReal1, fftImag1);
|
c@8
|
69 FFT::forward(m_lengthFIRFFT, fftCoefficients, NULL, fftReal2, fftImag2);
|
c@7
|
70
|
c@9
|
71 //Multiply FFT coefficients. Multiplication in freq domain is convolution in time domain.
|
c@8
|
72 for (int i = 0; i < m_lengthFIRFFT; i++){
|
c@0
|
73 fftFilteredReal[i] = (fftReal1[i] * fftReal2[i]) - (fftImag1[i] * fftImag2[i]);
|
c@0
|
74 fftFilteredImag[i] = (fftReal1[i] * fftImag2[i]) + (fftReal2[i] * fftImag1[i]);
|
c@0
|
75 }
|
c@8
|
76 FFT::inverse(m_lengthFIRFFT, fftFilteredReal, fftFilteredImag, fftOutputReal, fftOutputImag);
|
c@0
|
77
|
c@9
|
78 //copy to output
|
c@8
|
79 for (int i = 0; i < m_lengthInput; i++){
|
c@0
|
80 output[i] = fftOutputReal[i];
|
c@0
|
81 }
|
c@0
|
82 }
|
c@0
|
83
|
c@9
|
84 //remove memory allocations
|
c@0
|
85 void
|
c@0
|
86 FIRFilter::cleanup()
|
c@0
|
87 {
|
c@0
|
88 delete []fftInput;
|
c@0
|
89 delete []fftCoefficients;
|
c@0
|
90 delete []fftReal1;
|
c@0
|
91 delete []fftImag1;
|
c@0
|
92 delete []fftReal2;
|
c@0
|
93 delete []fftImag2;
|
c@0
|
94 delete []fftFilteredReal;
|
c@0
|
95 delete []fftFilteredImag;
|
c@0
|
96 delete []fftOutputReal;
|
c@0
|
97 delete []fftOutputImag;
|
c@7
|
98 fftInput = fftCoefficients = fftReal1 = fftImag1 = fftReal2 = fftImag2 = fftFilteredReal = fftFilteredImag = fftOutputReal = fftOutputImag = NULL;
|
c@0
|
99 } |