annotate dsp/rateconversion/DecimatorB.cpp @ 209:ccd2019190bf msvc

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