annotate FIRFilter.cpp @ 60:ac1a75151fc9 tip

isnan(int) is meaningless, and msvc refuses it as ambiguous
author Chris Cannam
date Wed, 18 Dec 2019 16:47:10 +0000
parents 4cf2d163127b
children
rev   line source
Chris@43 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@43 2
Chris@43 3 /*
Chris@43 4 Vamp Tempogram Plugin
Chris@43 5 Carl Bussey, Centre for Digital Music, Queen Mary University of London
Chris@43 6 Copyright 2014 Queen Mary University of London.
Chris@43 7
Chris@43 8 This program is free software; you can redistribute it and/or
Chris@43 9 modify it under the terms of the GNU General Public License as
Chris@43 10 published by the Free Software Foundation; either version 2 of the
Chris@43 11 License, or (at your option) any later version. See the file
Chris@43 12 COPYING included with this distribution for more information.
Chris@43 13 */
c@0 14
c@0 15 #include "FIRFilter.h"
c@7 16
c@0 17 using namespace std;
c@0 18 using Vamp::FFT;
c@0 19
c@13 20 FIRFilter::FIRFilter(const size_t &lengthInput, const size_t &numberOfCoefficients) :
c@8 21 m_lengthInput(lengthInput),
c@8 22 m_numberOfCoefficients(numberOfCoefficients),
c@13 23 m_pFftInput(0),
c@13 24 m_pFftCoefficients(0),
c@13 25 m_pFftReal1(0),
c@13 26 m_pFftImag1(0),
c@13 27 m_pFftReal2(0),
c@13 28 m_pFftImag2(0),
c@13 29 m_pFftFilteredReal(0),
c@13 30 m_pFftFilteredImag(0),
c@13 31 m_pFftOutputReal(0),
c@13 32 m_pFftOutputImag(0)
c@0 33 {
c@0 34 initialise();
c@0 35 }
c@0 36
c@0 37 FIRFilter::~FIRFilter()
c@0 38 {
c@0 39 cleanup();
c@0 40 }
c@0 41
c@9 42 //allocate memory
c@0 43 void
c@0 44 FIRFilter::initialise()
c@0 45 {
c@9 46 //next power of 2
c@8 47 m_lengthFIRFFT = pow(2,(ceil(log2(m_lengthInput+m_numberOfCoefficients-1))));
c@0 48
c@13 49 m_pFftInput = new double[m_lengthFIRFFT];
c@13 50 m_pFftCoefficients = new double[m_lengthFIRFFT];
c@13 51 m_pFftReal1 = new double[m_lengthFIRFFT];
c@13 52 m_pFftImag1 = new double[m_lengthFIRFFT];
c@13 53 m_pFftReal2 = new double[m_lengthFIRFFT];
c@13 54 m_pFftImag2 = new double[m_lengthFIRFFT];
c@13 55 m_pFftFilteredReal = new double[m_lengthFIRFFT];
c@13 56 m_pFftFilteredImag = new double[m_lengthFIRFFT];
c@13 57 m_pFftOutputReal = new double[m_lengthFIRFFT];
c@13 58 m_pFftOutputImag = new double[m_lengthFIRFFT];
c@0 59
c@20 60 for(int i = 0; i < (int)m_lengthFIRFFT; i++){
c@13 61 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 62 }
c@0 63 }
c@0 64
c@0 65 void
c@15 66 FIRFilter::process(const float* pInput, const float* pCoefficients, float* pOutput, OutputTypeArgument outputType)
c@0 67 {
c@15 68
c@9 69 //Copy to same length FFT buffers
c@20 70 for(int i = 0; i < (int)m_lengthFIRFFT; i++){
c@20 71 m_pFftInput[i] = i < (int)m_lengthInput ? pInput[i] : 0.0;
c@20 72 m_pFftCoefficients[i] = i < (int)m_numberOfCoefficients ? pCoefficients[i] : 0.0;
c@0 73 }
c@0 74
c@13 75 FFT::forward(m_lengthFIRFFT, m_pFftInput, 0, m_pFftReal1, m_pFftImag1);
c@13 76 FFT::forward(m_lengthFIRFFT, m_pFftCoefficients, 0, m_pFftReal2, m_pFftImag2);
c@7 77
c@9 78 //Multiply FFT coefficients. Multiplication in freq domain is convolution in time domain.
c@20 79 for (int i = 0; i < (int)m_lengthFIRFFT; i++){
c@13 80 m_pFftFilteredReal[i] = (m_pFftReal1[i] * m_pFftReal2[i]) - (m_pFftImag1[i] * m_pFftImag2[i]);
c@13 81 m_pFftFilteredImag[i] = (m_pFftReal1[i] * m_pFftImag2[i]) + (m_pFftReal2[i] * m_pFftImag1[i]);
c@0 82 }
c@13 83
c@13 84 FFT::inverse(m_lengthFIRFFT, m_pFftFilteredReal, m_pFftFilteredImag, m_pFftOutputReal, m_pFftOutputImag);
c@0 85
c@9 86 //copy to output
c@15 87 int offset = 0;
c@20 88 int outputLength = m_lengthInput;
c@35 89 if (outputType == all) outputLength = m_lengthInput+m_numberOfCoefficients-1;
c@20 90 else if (outputType == middle) offset = floor(m_numberOfCoefficients/2.0f);
c@15 91 else if (outputType != first) cerr << "FIRFilter::process(params) - " << outputType << " is not a valid argument. outputType is set to first." << endl;
c@15 92
c@20 93 for (int i = 0; i < outputLength; i++){
c@14 94 pOutput[i] = m_pFftOutputReal[i + offset];
c@0 95 }
c@0 96 }
c@0 97
c@9 98 //remove memory allocations
c@0 99 void
c@0 100 FIRFilter::cleanup()
c@0 101 {
c@13 102 delete []m_pFftInput;
c@13 103 delete []m_pFftCoefficients;
c@13 104 delete []m_pFftReal1;
c@13 105 delete []m_pFftImag1;
c@13 106 delete []m_pFftReal2;
c@13 107 delete []m_pFftImag2;
c@13 108 delete []m_pFftFilteredReal;
c@13 109 delete []m_pFftFilteredImag;
c@13 110 delete []m_pFftOutputReal;
c@13 111 delete []m_pFftOutputImag;
c@13 112 m_pFftInput = m_pFftCoefficients = m_pFftReal1 = m_pFftImag1 = m_pFftReal2 = m_pFftImag2 = m_pFftFilteredReal = m_pFftFilteredImag = m_pFftOutputReal = m_pFftOutputImag = 0;
Chris@10 113 }