annotate dsp/signalconditioning/DFProcess.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 d72fcd34d9a7
children 769da847732b
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 "DFProcess.h"
cannam@16 12 #include "maths/MathUtilities.h"
cannam@0 13
cannam@47 14 #include <cstring>
cannam@47 15
cannam@0 16 //////////////////////////////////////////////////////////////////////
cannam@0 17 // Construction/Destruction
cannam@0 18 //////////////////////////////////////////////////////////////////////
cannam@0 19
cannam@0 20 DFProcess::DFProcess( DFProcConfig Config )
cannam@0 21 {
cannam@0 22 filtSrc = NULL;
cannam@0 23 filtDst = NULL;
cannam@0 24 m_filtScratchIn = NULL;
cannam@0 25 m_filtScratchOut = NULL;
cannam@0 26
cannam@0 27 m_FFOrd = 0;
cannam@0 28
cannam@0 29 initialise( Config );
cannam@0 30 }
cannam@0 31
cannam@0 32 DFProcess::~DFProcess()
cannam@0 33 {
cannam@0 34 deInitialise();
cannam@0 35 }
cannam@0 36
cannam@0 37 void DFProcess::initialise( DFProcConfig Config )
cannam@0 38 {
cannam@0 39 m_length = Config.length;
cannam@0 40 m_winPre = Config.winPre;
cannam@0 41 m_winPost = Config.winPost;
cannam@0 42 m_alphaNormParam = Config.AlphaNormParam;
cannam@0 43
cannam@0 44 m_isMedianPositive = Config.isMedianPositive;
cannam@0 45
cannam@0 46 filtSrc = new double[ m_length ];
cannam@0 47 filtDst = new double[ m_length ];
cannam@0 48
cannam@0 49
cannam@0 50 //Low Pass Smoothing Filter Config
cannam@0 51 m_FilterConfigParams.ord = Config.LPOrd;
cannam@0 52 m_FilterConfigParams.ACoeffs = Config.LPACoeffs;
cannam@0 53 m_FilterConfigParams.BCoeffs = Config.LPBCoeffs;
cannam@0 54
cannam@0 55 m_FiltFilt = new FiltFilt( m_FilterConfigParams );
cannam@0 56 }
cannam@0 57
cannam@0 58 void DFProcess::deInitialise()
cannam@0 59 {
cannam@0 60 delete [] filtSrc;
cannam@0 61
cannam@0 62 delete [] filtDst;
cannam@0 63
cannam@0 64 delete [] m_filtScratchIn;
cannam@0 65
cannam@0 66 delete [] m_filtScratchOut;
cannam@0 67
cannam@0 68 delete m_FiltFilt;
cannam@0 69 }
cannam@0 70
cannam@0 71 void DFProcess::process(double *src, double* dst)
cannam@0 72 {
cannam@58 73 if (m_length == 0) return;
cannam@58 74
cannam@0 75 removeDCNormalize( src, filtSrc );
cannam@0 76
cannam@0 77 m_FiltFilt->process( filtSrc, filtDst, m_length );
cannam@0 78
cannam@0 79 medianFilter( filtDst, dst );
cannam@0 80 }
cannam@0 81
cannam@0 82
cannam@0 83 void DFProcess::medianFilter(double *src, double *dst)
cannam@0 84 {
cannam@0 85 unsigned int i,k,j,l;
cannam@0 86 unsigned int index = 0;
cannam@0 87
cannam@0 88 double val = 0;
cannam@0 89
cannam@0 90 double* y = new double[ m_winPost + m_winPre + 1];
cannam@0 91 memset( y, 0, sizeof( double ) * ( m_winPost + m_winPre + 1) );
cannam@0 92
cannam@0 93 double* scratch = new double[ m_length ];
cannam@0 94
cannam@0 95 for( i = 0; i < m_winPre; i++)
cannam@0 96 {
cannam@0 97 k = i + m_winPost + 1;
cannam@0 98
cannam@0 99 for( j = 0; j < k; j++)
cannam@0 100 {
cannam@0 101 y[ j ] = src[ j ];
cannam@0 102 }
cannam@0 103 scratch[ index ] = MathUtilities::median( y, k );
cannam@0 104 index++;
cannam@0 105 }
cannam@0 106
cannam@0 107 for( i = 0; i < ( m_length - ( m_winPost + m_winPre ) ); i ++)
cannam@0 108 {
cannam@0 109
cannam@0 110 l = 0;
cannam@0 111 for( j = i; j < ( i + m_winPost + m_winPre + 1); j++)
cannam@0 112 {
cannam@0 113 y[ l ] = src[ j ];
cannam@0 114 l++;
cannam@0 115 }
cannam@0 116
cannam@0 117 scratch[ index++ ] = MathUtilities::median( y, (m_winPost + m_winPre + 1 ));
cannam@0 118 }
cannam@0 119
cannam@0 120 for( i = std::max( m_length - m_winPost, (unsigned)1); i < m_length; i++)
cannam@0 121 {
cannam@0 122 k = std::max( i - m_winPre, (unsigned)1);
cannam@0 123
cannam@0 124 l = 0;
cannam@0 125 for( j = k; j < m_length; j++)
cannam@0 126 {
cannam@0 127 y[ l ] = src[ j ];
cannam@0 128
cannam@0 129 l++;
cannam@0 130 }
cannam@0 131
cannam@0 132 scratch[ index++ ] = MathUtilities::median( y, l);
cannam@0 133 }
cannam@0 134
cannam@0 135
cannam@0 136 for( i = 0; i < m_length; i++ )
cannam@0 137 {
cannam@0 138 val = src[ i ] - scratch[ i ];// - 0.033;
cannam@0 139
cannam@0 140 if( m_isMedianPositive )
cannam@0 141 {
cannam@0 142 if( val > 0 )
cannam@0 143 {
cannam@0 144 dst[ i ] = val;
cannam@0 145 }
cannam@0 146 else
cannam@0 147 {
cannam@0 148 dst[ i ] = 0;
cannam@0 149 }
cannam@0 150 }
cannam@0 151 else
cannam@0 152 {
cannam@0 153 dst[ i ] = val;
cannam@0 154 }
cannam@0 155 }
cannam@0 156
cannam@0 157 delete [] y;
cannam@0 158 delete [] scratch;
cannam@0 159 }
cannam@0 160
cannam@0 161
cannam@0 162 void DFProcess::removeDCNormalize( double *src, double*dst )
cannam@0 163 {
cannam@0 164 double DFmax = 0;
cannam@0 165 double DFMin = 0;
cannam@0 166 double DFAlphaNorm = 0;
cannam@0 167
cannam@0 168 MathUtilities::getFrameMinMax( src, m_length, &DFMin, &DFmax );
cannam@0 169
cannam@0 170 MathUtilities::getAlphaNorm( src, m_length, m_alphaNormParam, &DFAlphaNorm );
cannam@0 171
cannam@0 172 for( unsigned int i = 0; i< m_length; i++)
cannam@0 173 {
cannam@0 174 dst[ i ] = ( src[ i ] - DFMin ) / DFAlphaNorm;
cannam@0 175 }
cannam@0 176 }