annotate dsp/rateconversion/Decimator.cpp @ 129:6ec45e85ed81 kissfft

Drop in kissfft to replace the "old" fft, and add tests for newly-supported sizes
author Chris Cannam
date Tue, 15 Oct 2013 11:38:18 +0100
parents e5907ae6de17
children 4f092806782b
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 This file 2005-2006 Christian Landone.
Chris@84 8
Chris@84 9 This program is free software; you can redistribute it and/or
Chris@84 10 modify it under the terms of the GNU General Public License as
Chris@84 11 published by the Free Software Foundation; either version 2 of the
Chris@84 12 License, or (at your option) any later version. See the file
Chris@84 13 COPYING included with this distribution for more information.
cannam@0 14 */
cannam@0 15
cannam@0 16 #include "Decimator.h"
cannam@0 17
cannam@22 18 #include <iostream>
cannam@22 19
cannam@0 20 //////////////////////////////////////////////////////////////////////
cannam@0 21 // Construction/Destruction
cannam@0 22 //////////////////////////////////////////////////////////////////////
cannam@0 23
cannam@0 24 Decimator::Decimator( unsigned int inLength, unsigned int decFactor )
cannam@0 25 {
cannam@0 26
cannam@0 27 m_inputLength = 0;
cannam@0 28 m_outputLength = 0;
cannam@0 29 m_decFactor = 1;
cannam@0 30
cannam@0 31 initialise( inLength, decFactor );
cannam@0 32 }
cannam@0 33
cannam@0 34 Decimator::~Decimator()
cannam@0 35 {
cannam@0 36 deInitialise();
cannam@0 37 }
cannam@0 38
cannam@0 39 void Decimator::initialise( unsigned int inLength, unsigned 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
cannam@0 45 decBuffer = new double[ m_inputLength ];
cannam@0 46
cannam@22 47 // If adding new factors here, add them to
cannam@22 48 // getHighestSupportedFactor in the header as well
cannam@22 49
cannam@22 50 if(m_decFactor == 8)
cannam@22 51 {
cannam@22 52 //////////////////////////////////////////////////
cannam@22 53 b[0] = 0.060111378492136;
cannam@22 54 b[1] = -0.257323420830598;
cannam@22 55 b[2] = 0.420583503165928;
cannam@22 56 b[3] = -0.222750785197418;
cannam@22 57 b[4] = -0.222750785197418;
cannam@22 58 b[5] = 0.420583503165928;
cannam@22 59 b[6] = -0.257323420830598;
cannam@22 60 b[7] = 0.060111378492136;
cannam@22 61
cannam@22 62 a[0] = 1;
cannam@22 63 a[1] = -5.667654878577432;
cannam@22 64 a[2] = 14.062452278088417;
cannam@22 65 a[3] = -19.737303840697738;
cannam@22 66 a[4] = 16.889698874608641;
cannam@22 67 a[5] = -8.796600612325928;
cannam@22 68 a[6] = 2.577553446979888;
cannam@22 69 a[7] = -0.326903916815751;
cannam@22 70 //////////////////////////////////////////////////
cannam@22 71 }
cannam@22 72 else if( m_decFactor == 4 )
cannam@0 73 {
cannam@0 74 //////////////////////////////////////////////////
cannam@0 75 b[ 0 ] = 0.10133306904918619;
cannam@0 76 b[ 1 ] = -0.2447523353702363;
cannam@0 77 b[ 2 ] = 0.33622528590120965;
cannam@0 78 b[ 3 ] = -0.13936581560633518;
cannam@0 79 b[ 4 ] = -0.13936581560633382;
cannam@0 80 b[ 5 ] = 0.3362252859012087;
cannam@0 81 b[ 6 ] = -0.2447523353702358;
cannam@0 82 b[ 7 ] = 0.10133306904918594;
cannam@0 83
cannam@0 84 a[ 0 ] = 1;
cannam@0 85 a[ 1 ] = -3.9035590278139427;
cannam@0 86 a[ 2 ] = 7.5299379980621133;
cannam@0 87 a[ 3 ] = -8.6890803793177511;
cannam@0 88 a[ 4 ] = 6.4578667096099176;
cannam@0 89 a[ 5 ] = -3.0242979431223631;
cannam@0 90 a[ 6 ] = 0.83043385136748382;
cannam@0 91 a[ 7 ] = -0.094420800837809335;
cannam@0 92 //////////////////////////////////////////////////
cannam@0 93 }
cannam@0 94 else if( m_decFactor == 2 )
cannam@0 95 {
cannam@0 96 //////////////////////////////////////////////////
cannam@0 97 b[ 0 ] = 0.20898944260075727;
cannam@0 98 b[ 1 ] = 0.40011234879814367;
cannam@0 99 b[ 2 ] = 0.819741973072733;
cannam@0 100 b[ 3 ] = 1.0087419911682323;
cannam@0 101 b[ 4 ] = 1.0087419911682325;
cannam@0 102 b[ 5 ] = 0.81974197307273156;
cannam@0 103 b[ 6 ] = 0.40011234879814295;
cannam@0 104 b[ 7 ] = 0.20898944260075661;
cannam@0 105
cannam@0 106 a[ 0 ] = 1;
cannam@0 107 a[ 1 ] = 0.0077331184208358217;
cannam@0 108 a[ 2 ] = 1.9853971155964376;
cannam@0 109 a[ 3 ] = 0.19296739275341004;
cannam@0 110 a[ 4 ] = 1.2330748872852182;
cannam@0 111 a[ 5 ] = 0.18705341389316466;
cannam@0 112 a[ 6 ] = 0.23659265908013868;
cannam@0 113 a[ 7 ] = 0.032352924250533946;
cannam@0 114 }
cannam@0 115 else
cannam@0 116 {
cannam@22 117 if ( m_decFactor != 1 ) {
cannam@22 118 std::cerr << "WARNING: Decimator::initialise: unsupported decimation factor " << m_decFactor << ", no antialiasing filter will be used" << std::endl;
cannam@22 119 }
cannam@22 120
cannam@0 121 //////////////////////////////////////////////////
cannam@0 122 b[ 0 ] = 1;
cannam@0 123 b[ 1 ] = 0;
cannam@0 124 b[ 2 ] = 0;
cannam@0 125 b[ 3 ] = 0;
cannam@0 126 b[ 4 ] = 0;
cannam@0 127 b[ 5 ] = 0;
cannam@0 128 b[ 6 ] = 0;
cannam@0 129 b[ 7 ] = 0;
cannam@0 130
cannam@0 131 a[ 0 ] = 1;
cannam@0 132 a[ 1 ] = 0;
cannam@0 133 a[ 2 ] = 0;
cannam@0 134 a[ 3 ] = 0;
cannam@0 135 a[ 4 ] = 0;
cannam@0 136 a[ 5 ] = 0;
cannam@0 137 a[ 6 ] = 0;
cannam@0 138 a[ 7 ] = 0;
cannam@0 139 }
cannam@0 140
cannam@0 141 resetFilter();
cannam@0 142 }
cannam@0 143
cannam@0 144 void Decimator::deInitialise()
cannam@0 145 {
cannam@0 146 delete [] decBuffer;
cannam@0 147 }
cannam@0 148
cannam@0 149 void Decimator::resetFilter()
cannam@0 150 {
cannam@0 151 Input = Output = 0;
cannam@0 152
cannam@0 153 o1=o2=o3=o4=o5=o6=o7=0;
cannam@0 154 }
cannam@0 155
cannam@22 156 void Decimator::doAntiAlias(const double *src, double *dst, unsigned int length)
cannam@0 157 {
cannam@0 158
cannam@0 159 for( unsigned int i = 0; i < length; i++ )
cannam@0 160 {
cannam@0 161 Input = (double)src[ i ];
cannam@0 162
cannam@0 163 Output = Input * b[ 0 ] + o1;
cannam@0 164
cannam@0 165 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2;
cannam@0 166 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3;
cannam@0 167 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4;
cannam@0 168 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5;
cannam@0 169 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6;
cannam@0 170 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7;
cannam@0 171 o7 = Input * b[ 7 ] - Output * a[ 7 ] ;
cannam@0 172
cannam@0 173 dst[ i ] = Output;
cannam@0 174 }
cannam@0 175
cannam@0 176 }
cannam@0 177
cannam@55 178 void Decimator::doAntiAlias(const float *src, double *dst, unsigned int length)
cannam@55 179 {
cannam@55 180
cannam@55 181 for( unsigned int i = 0; i < length; i++ )
cannam@55 182 {
cannam@55 183 Input = (double)src[ i ];
cannam@55 184
cannam@55 185 Output = Input * b[ 0 ] + o1;
cannam@55 186
cannam@55 187 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2;
cannam@55 188 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3;
cannam@55 189 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4;
cannam@55 190 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5;
cannam@55 191 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6;
cannam@55 192 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7;
cannam@55 193 o7 = Input * b[ 7 ] - Output * a[ 7 ] ;
cannam@55 194
cannam@55 195 dst[ i ] = Output;
cannam@55 196 }
cannam@55 197
cannam@55 198 }
cannam@55 199
cannam@22 200 void Decimator::process(const double *src, double *dst)
cannam@0 201 {
cannam@0 202 if( m_decFactor != 1 )
cannam@0 203 {
cannam@0 204 doAntiAlias( src, decBuffer, m_inputLength );
cannam@0 205 }
cannam@0 206 unsigned idx = 0;
cannam@0 207
cannam@0 208 for( unsigned int i = 0; i < m_outputLength; i++ )
cannam@0 209 {
cannam@0 210 dst[ idx++ ] = decBuffer[ m_decFactor * i ];
cannam@0 211 }
cannam@0 212 }
cannam@55 213
cannam@55 214 void Decimator::process(const float *src, float *dst)
cannam@55 215 {
cannam@55 216 if( m_decFactor != 1 )
cannam@55 217 {
cannam@55 218 doAntiAlias( src, decBuffer, m_inputLength );
cannam@55 219 }
cannam@55 220 unsigned idx = 0;
cannam@55 221
cannam@55 222 for( unsigned int i = 0; i < m_outputLength; i++ )
cannam@55 223 {
cannam@55 224 dst[ idx++ ] = decBuffer[ m_decFactor * i ];
cannam@55 225 }
cannam@55 226 }