annotate FIRFilter.cpp @ 37:44d8e5dc1902

Split out Makefile to separate single-platform versions and an .inc file
author Chris Cannam
date Fri, 12 Sep 2014 14:54:55 +0100
parents c8dd1049b2d3
children 4cf2d163127b
rev   line source
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@13 14 FIRFilter::FIRFilter(const size_t &lengthInput, const size_t &numberOfCoefficients) :
c@8 15 m_lengthInput(lengthInput),
c@8 16 m_numberOfCoefficients(numberOfCoefficients),
c@13 17 m_pFftInput(0),
c@13 18 m_pFftCoefficients(0),
c@13 19 m_pFftReal1(0),
c@13 20 m_pFftImag1(0),
c@13 21 m_pFftReal2(0),
c@13 22 m_pFftImag2(0),
c@13 23 m_pFftFilteredReal(0),
c@13 24 m_pFftFilteredImag(0),
c@13 25 m_pFftOutputReal(0),
c@13 26 m_pFftOutputImag(0)
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@13 43 m_pFftInput = new double[m_lengthFIRFFT];
c@13 44 m_pFftCoefficients = new double[m_lengthFIRFFT];
c@13 45 m_pFftReal1 = new double[m_lengthFIRFFT];
c@13 46 m_pFftImag1 = new double[m_lengthFIRFFT];
c@13 47 m_pFftReal2 = new double[m_lengthFIRFFT];
c@13 48 m_pFftImag2 = new double[m_lengthFIRFFT];
c@13 49 m_pFftFilteredReal = new double[m_lengthFIRFFT];
c@13 50 m_pFftFilteredImag = new double[m_lengthFIRFFT];
c@13 51 m_pFftOutputReal = new double[m_lengthFIRFFT];
c@13 52 m_pFftOutputImag = new double[m_lengthFIRFFT];
c@0 53
c@20 54 for(int i = 0; i < (int)m_lengthFIRFFT; i++){
c@13 55 m_pFftInput[i] = m_pFftCoefficients[i] = m_pFftReal1[i] = m_pFftImag1[i] = m_pFftReal2[i] = m_pFftImag2[i] = m_pFftFilteredReal[i] = m_pFftFilteredImag[i] = m_pFftOutputReal[i] = m_pFftOutputImag[i] = 0.0;
c@0 56 }
c@0 57 }
c@0 58
c@0 59 void
c@15 60 FIRFilter::process(const float* pInput, const float* pCoefficients, float* pOutput, OutputTypeArgument outputType)
c@0 61 {
c@15 62
c@9 63 //Copy to same length FFT buffers
c@20 64 for(int i = 0; i < (int)m_lengthFIRFFT; i++){
c@20 65 m_pFftInput[i] = i < (int)m_lengthInput ? pInput[i] : 0.0;
c@20 66 m_pFftCoefficients[i] = i < (int)m_numberOfCoefficients ? pCoefficients[i] : 0.0;
c@0 67 }
c@0 68
c@13 69 FFT::forward(m_lengthFIRFFT, m_pFftInput, 0, m_pFftReal1, m_pFftImag1);
c@13 70 FFT::forward(m_lengthFIRFFT, m_pFftCoefficients, 0, m_pFftReal2, m_pFftImag2);
c@7 71
c@9 72 //Multiply FFT coefficients. Multiplication in freq domain is convolution in time domain.
c@20 73 for (int i = 0; i < (int)m_lengthFIRFFT; i++){
c@13 74 m_pFftFilteredReal[i] = (m_pFftReal1[i] * m_pFftReal2[i]) - (m_pFftImag1[i] * m_pFftImag2[i]);
c@13 75 m_pFftFilteredImag[i] = (m_pFftReal1[i] * m_pFftImag2[i]) + (m_pFftReal2[i] * m_pFftImag1[i]);
c@0 76 }
c@13 77
c@13 78 FFT::inverse(m_lengthFIRFFT, m_pFftFilteredReal, m_pFftFilteredImag, m_pFftOutputReal, m_pFftOutputImag);
c@0 79
c@9 80 //copy to output
c@15 81 int offset = 0;
c@20 82 int outputLength = m_lengthInput;
c@35 83 if (outputType == all) outputLength = m_lengthInput+m_numberOfCoefficients-1;
c@20 84 else if (outputType == middle) offset = floor(m_numberOfCoefficients/2.0f);
c@15 85 else if (outputType != first) cerr << "FIRFilter::process(params) - " << outputType << " is not a valid argument. outputType is set to first." << endl;
c@15 86
c@20 87 for (int i = 0; i < outputLength; i++){
c@14 88 pOutput[i] = m_pFftOutputReal[i + offset];
c@0 89 }
c@0 90 }
c@0 91
c@9 92 //remove memory allocations
c@0 93 void
c@0 94 FIRFilter::cleanup()
c@0 95 {
c@13 96 delete []m_pFftInput;
c@13 97 delete []m_pFftCoefficients;
c@13 98 delete []m_pFftReal1;
c@13 99 delete []m_pFftImag1;
c@13 100 delete []m_pFftReal2;
c@13 101 delete []m_pFftImag2;
c@13 102 delete []m_pFftFilteredReal;
c@13 103 delete []m_pFftFilteredImag;
c@13 104 delete []m_pFftOutputReal;
c@13 105 delete []m_pFftOutputImag;
c@13 106 m_pFftInput = m_pFftCoefficients = m_pFftReal1 = m_pFftImag1 = m_pFftReal2 = m_pFftImag2 = m_pFftFilteredReal = m_pFftFilteredImag = m_pFftOutputReal = m_pFftOutputImag = 0;
Chris@10 107 }