annotate dsp/signalconditioning/Filter.cpp @ 483:fdaa63607c15

Untabify, indent, tidy
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 31 May 2019 11:54:32 +0100
parents 7461bf03194e
children
rev   line source
c@225 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@225 2
c@225 3 /*
c@225 4 QM DSP Library
c@225 5
c@225 6 Centre for Digital Music, Queen Mary, University of London.
c@309 7
c@309 8 This program is free software; you can redistribute it and/or
c@309 9 modify it under the terms of the GNU General Public License as
c@309 10 published by the Free Software Foundation; either version 2 of the
c@309 11 License, or (at your option) any later version. See the file
c@309 12 COPYING included with this distribution for more information.
c@225 13 */
c@225 14
c@225 15 #include "Filter.h"
c@225 16
c@417 17 #include <stdexcept>
c@225 18
c@417 19 using namespace std;
c@417 20
c@417 21 Filter::Filter(Parameters params)
c@225 22 {
c@417 23 if (params.a.empty()) {
c@417 24 m_fir = true;
c@417 25 if (params.b.empty()) {
c@417 26 throw logic_error("Filter must have at least one pair of coefficients");
c@417 27 }
c@417 28 } else {
c@417 29 m_fir = false;
c@417 30 if (params.a.size() != params.b.size()) {
c@417 31 throw logic_error("Inconsistent numbers of filter coefficients");
c@417 32 }
c@417 33 }
c@417 34
c@417 35 m_sz = int(params.b.size());
c@417 36 m_order = m_sz - 1;
c@225 37
c@417 38 m_a = params.a;
c@417 39 m_b = params.b;
c@417 40
c@417 41 // We keep some empty space at the start of the buffer, and
c@417 42 // encroach gradually into it as we add individual sample
c@417 43 // calculations at the start. Then when we run out of space, we
c@417 44 // move the buffer back to the end and begin again. This is
c@417 45 // significantly faster than moving the whole buffer along in
c@417 46 // 1-sample steps every time.
c@417 47
c@417 48 m_offmax = 20;
c@417 49 m_offa = m_offmax;
c@417 50 m_offb = m_offmax;
c@417 51
c@417 52 if (!m_fir) {
c@417 53 m_bufa.resize(m_order + m_offmax);
c@417 54 }
c@417 55
c@417 56 m_bufb.resize(m_sz + m_offmax);
c@225 57 }
c@225 58
c@225 59 Filter::~Filter()
c@225 60 {
c@225 61 }
c@225 62
c@417 63 void
c@417 64 Filter::reset()
c@225 65 {
c@417 66 m_offb = m_offmax;
c@417 67 m_offa = m_offmax;
c@225 68
c@417 69 if (!m_fir) {
c@417 70 m_bufa.assign(m_bufa.size(), 0.0);
c@417 71 }
c@225 72
c@417 73 m_bufb.assign(m_bufb.size(), 0.0);
c@225 74 }
c@225 75
c@417 76 void
c@434 77 Filter::process(const double *const QM_R__ in,
cannam@483 78 double *const QM_R__ out,
cannam@483 79 const int n)
c@225 80 {
c@417 81 for (int s = 0; s < n; ++s) {
c@417 82
cannam@483 83 if (m_offb > 0) {
cannam@483 84 --m_offb;
cannam@483 85 } else {
c@417 86 for (int i = m_sz - 2; i >= 0; --i) {
c@417 87 m_bufb[i + m_offmax + 1] = m_bufb[i];
c@417 88 }
c@417 89 m_offb = m_offmax;
c@417 90 }
c@417 91 m_bufb[m_offb] = in[s];
c@417 92
c@417 93 double b_sum = 0.0;
c@417 94 for (int i = 0; i < m_sz; ++i) {
c@417 95 b_sum += m_b[i] * m_bufb[i + m_offb];
c@417 96 }
c@417 97
c@417 98 double outval;
c@417 99
c@417 100 if (m_fir) {
c@417 101
c@417 102 outval = b_sum;
c@417 103
c@417 104 } else {
c@417 105
c@417 106 double a_sum = 0.0;
c@417 107 for (int i = 0; i < m_order; ++i) {
c@417 108 a_sum += m_a[i + 1] * m_bufa[i + m_offa];
c@417 109 }
c@417 110
c@417 111 outval = b_sum - a_sum;
c@417 112
cannam@483 113 if (m_offa > 0) {
cannam@483 114 --m_offa;
cannam@483 115 } else {
c@417 116 for (int i = m_order - 2; i >= 0; --i) {
c@417 117 m_bufa[i + m_offmax + 1] = m_bufa[i];
c@417 118 }
c@417 119 m_offa = m_offmax;
c@417 120 }
c@417 121 m_bufa[m_offa] = outval;
c@417 122 }
c@417 123
cannam@483 124 out[s] = outval;
c@417 125 }
c@225 126 }
c@225 127