annotate dsp/rateconversion/DecimatorB.cpp @ 414:7e8d1f26b098

Fix compiler warnings with -Wall -Wextra
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 28 Sep 2015 12:33:17 +0100
parents 1494e18439ae
children fdaa63607c15
rev   line source
c@380 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@380 2
c@380 3 /*
c@380 4 QM DSP Library
c@380 5
c@380 6 Centre for Digital Music, Queen Mary, University of London.
c@380 7
c@380 8 This program is free software; you can redistribute it and/or
c@380 9 modify it under the terms of the GNU General Public License as
c@380 10 published by the Free Software Foundation; either version 2 of the
c@380 11 License, or (at your option) any later version. See the file
c@380 12 COPYING included with this distribution for more information.
c@380 13 */
c@380 14
c@380 15 #include "DecimatorB.h"
c@380 16
c@380 17 #include "maths/MathUtilities.h"
c@380 18
c@380 19 #include <iostream>
c@380 20
c@380 21 using std::vector;
c@380 22
c@380 23 DecimatorB::DecimatorB(int inLength, int decFactor)
c@380 24 {
c@380 25 m_inputLength = 0;
c@380 26 m_outputLength = 0;
c@380 27 m_decFactor = 1;
c@380 28 m_aaBuffer = 0;
c@380 29 m_tmpBuffer = 0;
c@380 30
c@380 31 initialise(inLength, decFactor);
c@380 32 }
c@380 33
c@380 34 DecimatorB::~DecimatorB()
c@380 35 {
c@380 36 deInitialise();
c@380 37 }
c@380 38
c@380 39 void DecimatorB::initialise(int inLength, int decFactor)
c@380 40 {
c@380 41 m_inputLength = inLength;
c@380 42 m_decFactor = decFactor;
c@380 43 m_outputLength = m_inputLength / m_decFactor;
c@380 44
c@380 45 if (m_decFactor < 2 || !MathUtilities::isPowerOfTwo(m_decFactor)) {
c@380 46 std::cerr << "ERROR: DecimatorB::initialise: Decimation factor must be a power of 2 and at least 2 (was: " << m_decFactor << ")" << std::endl;
c@380 47 m_decFactor = 0;
c@380 48 return;
c@380 49 }
c@380 50
c@380 51 if (m_inputLength % m_decFactor != 0) {
c@380 52 std::cerr << "ERROR: DecimatorB::initialise: inLength must be a multiple of decimation factor (was: " << m_inputLength << ", factor is " << m_decFactor << ")" << std::endl;
c@380 53 m_decFactor = 0;
c@380 54 return;
c@380 55 }
c@380 56
c@380 57 m_aaBuffer = new double[m_inputLength];
c@380 58 m_tmpBuffer = new double[m_inputLength];
c@380 59
c@380 60 // Order 6 Butterworth lowpass filter
c@380 61 // Calculated using e.g. MATLAB butter(6, 0.5, 'low')
c@380 62
c@380 63 m_b[0] = 0.029588223638661;
c@380 64 m_b[1] = 0.177529341831965;
c@380 65 m_b[2] = 0.443823354579912;
c@380 66 m_b[3] = 0.591764472773216;
c@380 67 m_b[4] = 0.443823354579912;
c@380 68 m_b[5] = 0.177529341831965;
c@380 69 m_b[6] = 0.029588223638661;
c@380 70
c@380 71 m_a[0] = 1.000000000000000;
c@380 72 m_a[1] = 0.000000000000000;
c@380 73 m_a[2] = 0.777695961855673;
c@380 74 m_a[3] = 0.000000000000000;
c@380 75 m_a[4] = 0.114199425062434;
c@380 76 m_a[5] = 0.000000000000000;
c@380 77 m_a[6] = 0.001750925956183;
c@380 78
c@380 79 for (int factor = m_decFactor; factor > 1; factor /= 2) {
c@380 80 m_o.push_back(vector<double>(6, 0.0));
c@380 81 }
c@380 82 }
c@380 83
c@380 84 void DecimatorB::deInitialise()
c@380 85 {
c@380 86 delete [] m_aaBuffer;
c@380 87 delete [] m_tmpBuffer;
c@380 88 }
c@380 89
c@380 90 void DecimatorB::doAntiAlias(const double *src, double *dst, int length,
c@380 91 int filteridx)
c@380 92 {
c@380 93 vector<double> &o = m_o[filteridx];
c@380 94
c@380 95 for (int i = 0; i < length; i++) {
c@380 96
c@380 97 double input = src[i];
c@380 98 double output = input * m_b[0] + o[0];
c@380 99
c@380 100 o[0] = input * m_b[1] - output * m_a[1] + o[1];
c@380 101 o[1] = input * m_b[2] - output * m_a[2] + o[2];
c@380 102 o[2] = input * m_b[3] - output * m_a[3] + o[3];
c@380 103 o[3] = input * m_b[4] - output * m_a[4] + o[4];
c@380 104 o[4] = input * m_b[5] - output * m_a[5] + o[5];
c@380 105 o[5] = input * m_b[6] - output * m_a[6];
c@380 106
c@380 107 dst[i] = output;
c@380 108 }
c@380 109 }
c@380 110
c@380 111 void DecimatorB::doProcess()
c@380 112 {
c@380 113 int filteridx = 0;
c@380 114 int factorDone = 1;
c@380 115
c@380 116 while (factorDone < m_decFactor) {
c@380 117
c@380 118 doAntiAlias(m_tmpBuffer, m_aaBuffer,
c@380 119 m_inputLength / factorDone,
c@380 120 filteridx);
c@380 121
c@380 122 filteridx ++;
c@380 123 factorDone *= 2;
c@380 124
c@380 125 for (int i = 0; i < m_inputLength / factorDone; ++i) {
c@380 126 m_tmpBuffer[i] = m_aaBuffer[i * 2];
c@380 127 }
c@380 128 }
c@380 129 }
c@380 130
c@380 131 void DecimatorB::process(const double *src, double *dst)
c@380 132 {
c@380 133 if (m_decFactor == 0) return;
c@380 134
c@380 135 for (int i = 0; i < m_inputLength; ++i) {
c@380 136 m_tmpBuffer[i] = src[i];
c@380 137 }
c@380 138
c@380 139 doProcess();
c@380 140
c@380 141 for (int i = 0; i < m_outputLength; ++i) {
c@380 142 dst[i] = m_tmpBuffer[i];
c@380 143 }
c@380 144 }
c@380 145
c@380 146 void DecimatorB::process(const float *src, float *dst)
c@380 147 {
c@380 148 if (m_decFactor == 0) return;
c@380 149
c@380 150 for (int i = 0; i < m_inputLength; ++i) {
c@380 151 m_tmpBuffer[i] = src[i];
c@380 152 }
c@380 153
c@380 154 doProcess();
c@380 155
c@380 156 for (int i = 0; i < m_outputLength; ++i) {
c@380 157 dst[i] = m_tmpBuffer[i];
c@380 158 }
c@380 159 }