annotate dsp/rateconversion/Decimator.cpp @ 73:dcb555b90924

* Key detector: when returning key strengths, use the peak value of the three underlying chromagram correlations (from 36-bin chromagram) corresponding to each key, instead of the mean. Rationale: This is the same method as used when returning the key value, and it's nice to have the same results in both returned value and plot. The peak performed better than the sum with a simple test set of triads, so it seems reasonable to change the plot to match the key output rather than the other way around. * FFT: kiss_fftr returns only the non-conjugate bins, synthesise the rest rather than leaving them (perhaps dangerously) undefined. Fixes an uninitialised data error in chromagram that could cause garbage results from key detector. * Constant Q: remove precalculated values again, I reckon they're not proving such a good tradeoff.
author cannam
date Fri, 05 Jun 2009 15:12:39 +0000
parents 7fe29d8a7eaf
children e5907ae6de17
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.
cannam@0 7 This file copyright 2005-2006 Christian Landone.
cannam@0 8 All rights reserved.
cannam@0 9 */
cannam@0 10
cannam@0 11 #include "Decimator.h"
cannam@0 12
cannam@22 13 #include <iostream>
cannam@22 14
cannam@0 15 //////////////////////////////////////////////////////////////////////
cannam@0 16 // Construction/Destruction
cannam@0 17 //////////////////////////////////////////////////////////////////////
cannam@0 18
cannam@0 19 Decimator::Decimator( unsigned int inLength, unsigned int decFactor )
cannam@0 20 {
cannam@0 21
cannam@0 22 m_inputLength = 0;
cannam@0 23 m_outputLength = 0;
cannam@0 24 m_decFactor = 1;
cannam@0 25
cannam@0 26 initialise( inLength, decFactor );
cannam@0 27 }
cannam@0 28
cannam@0 29 Decimator::~Decimator()
cannam@0 30 {
cannam@0 31 deInitialise();
cannam@0 32 }
cannam@0 33
cannam@0 34 void Decimator::initialise( unsigned int inLength, unsigned int decFactor)
cannam@0 35 {
cannam@0 36 m_inputLength = inLength;
cannam@0 37 m_decFactor = decFactor;
cannam@0 38 m_outputLength = m_inputLength / m_decFactor;
cannam@0 39
cannam@0 40 decBuffer = new double[ m_inputLength ];
cannam@0 41
cannam@22 42 // If adding new factors here, add them to
cannam@22 43 // getHighestSupportedFactor in the header as well
cannam@22 44
cannam@22 45 if(m_decFactor == 8)
cannam@22 46 {
cannam@22 47 //////////////////////////////////////////////////
cannam@22 48 b[0] = 0.060111378492136;
cannam@22 49 b[1] = -0.257323420830598;
cannam@22 50 b[2] = 0.420583503165928;
cannam@22 51 b[3] = -0.222750785197418;
cannam@22 52 b[4] = -0.222750785197418;
cannam@22 53 b[5] = 0.420583503165928;
cannam@22 54 b[6] = -0.257323420830598;
cannam@22 55 b[7] = 0.060111378492136;
cannam@22 56
cannam@22 57 a[0] = 1;
cannam@22 58 a[1] = -5.667654878577432;
cannam@22 59 a[2] = 14.062452278088417;
cannam@22 60 a[3] = -19.737303840697738;
cannam@22 61 a[4] = 16.889698874608641;
cannam@22 62 a[5] = -8.796600612325928;
cannam@22 63 a[6] = 2.577553446979888;
cannam@22 64 a[7] = -0.326903916815751;
cannam@22 65 //////////////////////////////////////////////////
cannam@22 66 }
cannam@22 67 else if( m_decFactor == 4 )
cannam@0 68 {
cannam@0 69 //////////////////////////////////////////////////
cannam@0 70 b[ 0 ] = 0.10133306904918619;
cannam@0 71 b[ 1 ] = -0.2447523353702363;
cannam@0 72 b[ 2 ] = 0.33622528590120965;
cannam@0 73 b[ 3 ] = -0.13936581560633518;
cannam@0 74 b[ 4 ] = -0.13936581560633382;
cannam@0 75 b[ 5 ] = 0.3362252859012087;
cannam@0 76 b[ 6 ] = -0.2447523353702358;
cannam@0 77 b[ 7 ] = 0.10133306904918594;
cannam@0 78
cannam@0 79 a[ 0 ] = 1;
cannam@0 80 a[ 1 ] = -3.9035590278139427;
cannam@0 81 a[ 2 ] = 7.5299379980621133;
cannam@0 82 a[ 3 ] = -8.6890803793177511;
cannam@0 83 a[ 4 ] = 6.4578667096099176;
cannam@0 84 a[ 5 ] = -3.0242979431223631;
cannam@0 85 a[ 6 ] = 0.83043385136748382;
cannam@0 86 a[ 7 ] = -0.094420800837809335;
cannam@0 87 //////////////////////////////////////////////////
cannam@0 88 }
cannam@0 89 else if( m_decFactor == 2 )
cannam@0 90 {
cannam@0 91 //////////////////////////////////////////////////
cannam@0 92 b[ 0 ] = 0.20898944260075727;
cannam@0 93 b[ 1 ] = 0.40011234879814367;
cannam@0 94 b[ 2 ] = 0.819741973072733;
cannam@0 95 b[ 3 ] = 1.0087419911682323;
cannam@0 96 b[ 4 ] = 1.0087419911682325;
cannam@0 97 b[ 5 ] = 0.81974197307273156;
cannam@0 98 b[ 6 ] = 0.40011234879814295;
cannam@0 99 b[ 7 ] = 0.20898944260075661;
cannam@0 100
cannam@0 101 a[ 0 ] = 1;
cannam@0 102 a[ 1 ] = 0.0077331184208358217;
cannam@0 103 a[ 2 ] = 1.9853971155964376;
cannam@0 104 a[ 3 ] = 0.19296739275341004;
cannam@0 105 a[ 4 ] = 1.2330748872852182;
cannam@0 106 a[ 5 ] = 0.18705341389316466;
cannam@0 107 a[ 6 ] = 0.23659265908013868;
cannam@0 108 a[ 7 ] = 0.032352924250533946;
cannam@0 109 }
cannam@0 110 else
cannam@0 111 {
cannam@22 112 if ( m_decFactor != 1 ) {
cannam@22 113 std::cerr << "WARNING: Decimator::initialise: unsupported decimation factor " << m_decFactor << ", no antialiasing filter will be used" << std::endl;
cannam@22 114 }
cannam@22 115
cannam@0 116 //////////////////////////////////////////////////
cannam@0 117 b[ 0 ] = 1;
cannam@0 118 b[ 1 ] = 0;
cannam@0 119 b[ 2 ] = 0;
cannam@0 120 b[ 3 ] = 0;
cannam@0 121 b[ 4 ] = 0;
cannam@0 122 b[ 5 ] = 0;
cannam@0 123 b[ 6 ] = 0;
cannam@0 124 b[ 7 ] = 0;
cannam@0 125
cannam@0 126 a[ 0 ] = 1;
cannam@0 127 a[ 1 ] = 0;
cannam@0 128 a[ 2 ] = 0;
cannam@0 129 a[ 3 ] = 0;
cannam@0 130 a[ 4 ] = 0;
cannam@0 131 a[ 5 ] = 0;
cannam@0 132 a[ 6 ] = 0;
cannam@0 133 a[ 7 ] = 0;
cannam@0 134 }
cannam@0 135
cannam@0 136 resetFilter();
cannam@0 137 }
cannam@0 138
cannam@0 139 void Decimator::deInitialise()
cannam@0 140 {
cannam@0 141 delete [] decBuffer;
cannam@0 142 }
cannam@0 143
cannam@0 144 void Decimator::resetFilter()
cannam@0 145 {
cannam@0 146 Input = Output = 0;
cannam@0 147
cannam@0 148 o1=o2=o3=o4=o5=o6=o7=0;
cannam@0 149 }
cannam@0 150
cannam@22 151 void Decimator::doAntiAlias(const double *src, double *dst, unsigned int length)
cannam@0 152 {
cannam@0 153
cannam@0 154 for( unsigned int i = 0; i < length; i++ )
cannam@0 155 {
cannam@0 156 Input = (double)src[ i ];
cannam@0 157
cannam@0 158 Output = Input * b[ 0 ] + o1;
cannam@0 159
cannam@0 160 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2;
cannam@0 161 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3;
cannam@0 162 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4;
cannam@0 163 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5;
cannam@0 164 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6;
cannam@0 165 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7;
cannam@0 166 o7 = Input * b[ 7 ] - Output * a[ 7 ] ;
cannam@0 167
cannam@0 168 dst[ i ] = Output;
cannam@0 169 }
cannam@0 170
cannam@0 171 }
cannam@0 172
cannam@55 173 void Decimator::doAntiAlias(const float *src, double *dst, unsigned int length)
cannam@55 174 {
cannam@55 175
cannam@55 176 for( unsigned int i = 0; i < length; i++ )
cannam@55 177 {
cannam@55 178 Input = (double)src[ i ];
cannam@55 179
cannam@55 180 Output = Input * b[ 0 ] + o1;
cannam@55 181
cannam@55 182 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2;
cannam@55 183 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3;
cannam@55 184 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4;
cannam@55 185 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5;
cannam@55 186 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6;
cannam@55 187 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7;
cannam@55 188 o7 = Input * b[ 7 ] - Output * a[ 7 ] ;
cannam@55 189
cannam@55 190 dst[ i ] = Output;
cannam@55 191 }
cannam@55 192
cannam@55 193 }
cannam@55 194
cannam@22 195 void Decimator::process(const double *src, double *dst)
cannam@0 196 {
cannam@0 197 if( m_decFactor != 1 )
cannam@0 198 {
cannam@0 199 doAntiAlias( src, decBuffer, m_inputLength );
cannam@0 200 }
cannam@0 201 unsigned idx = 0;
cannam@0 202
cannam@0 203 for( unsigned int i = 0; i < m_outputLength; i++ )
cannam@0 204 {
cannam@0 205 dst[ idx++ ] = decBuffer[ m_decFactor * i ];
cannam@0 206 }
cannam@0 207 }
cannam@55 208
cannam@55 209 void Decimator::process(const float *src, float *dst)
cannam@55 210 {
cannam@55 211 if( m_decFactor != 1 )
cannam@55 212 {
cannam@55 213 doAntiAlias( src, decBuffer, m_inputLength );
cannam@55 214 }
cannam@55 215 unsigned idx = 0;
cannam@55 216
cannam@55 217 for( unsigned int i = 0; i < m_outputLength; i++ )
cannam@55 218 {
cannam@55 219 dst[ idx++ ] = decBuffer[ m_decFactor * i ];
cannam@55 220 }
cannam@55 221 }