comparison dsp/onsets/DetectionFunction.cpp @ 14:68801ecbab6a

* add adaptive whitening and simple power metric
author cannam
date Thu, 09 Aug 2007 16:30:26 +0000
parents f2b5c4251bf3
children 2e3f5d2d62c1
comparison
equal deleted inserted replaced
13:f2b5c4251bf3 14:68801ecbab6a
18 m_window(0) 18 m_window(0)
19 { 19 {
20 m_magHistory = NULL; 20 m_magHistory = NULL;
21 m_phaseHistory = NULL; 21 m_phaseHistory = NULL;
22 m_phaseHistoryOld = NULL; 22 m_phaseHistoryOld = NULL;
23 m_magPeaks = NULL;
23 24
24 initialise( Config ); 25 initialise( Config );
25 } 26 }
26 27
27 DetectionFunction::~DetectionFunction() 28 DetectionFunction::~DetectionFunction()
32 33
33 void DetectionFunction::initialise( DFConfig Config ) 34 void DetectionFunction::initialise( DFConfig Config )
34 { 35 {
35 m_dataLength = Config.frameLength; 36 m_dataLength = Config.frameLength;
36 m_halfLength = m_dataLength/2; 37 m_halfLength = m_dataLength/2;
38
37 m_DFType = Config.DFType; 39 m_DFType = Config.DFType;
38 m_stepSecs = Config.stepSecs; 40 m_stepSecs = Config.stepSecs;
39 m_stepSize = Config.stepSize; 41 m_stepSize = Config.stepSize;
40 42
43 m_whiten = Config.adaptiveWhitening;
44 m_whitenRelaxCoeff = Config.whiteningRelaxCoeff;
45 m_whitenFloor = Config.whiteningFloor;
46 if (m_whitenRelaxCoeff < 0) m_whitenRelaxCoeff = 0.9997;
47 if (m_whitenFloor < 0) m_whitenFloor = 0.01;
48
41 m_magHistory = new double[ m_halfLength ]; 49 m_magHistory = new double[ m_halfLength ];
42 memset(m_magHistory,0, m_halfLength*sizeof(double)); 50 memset(m_magHistory,0, m_halfLength*sizeof(double));
43 51
44 m_phaseHistory = new double[ m_halfLength ]; 52 m_phaseHistory = new double[ m_halfLength ];
45 memset(m_phaseHistory,0, m_halfLength*sizeof(double)); 53 memset(m_phaseHistory,0, m_halfLength*sizeof(double));
46 54
47 m_phaseHistoryOld = new double[ m_halfLength ]; 55 m_phaseHistoryOld = new double[ m_halfLength ];
48 memset(m_phaseHistoryOld,0, m_halfLength*sizeof(double)); 56 memset(m_phaseHistoryOld,0, m_halfLength*sizeof(double));
57
58 m_magPeaks = new double[ m_halfLength ];
59 memset(m_magPeaks,0, m_halfLength*sizeof(double));
49 60
50 m_phaseVoc = new PhaseVocoder; 61 m_phaseVoc = new PhaseVocoder;
51 62
52 m_DFWindowedFrame = new double[ m_dataLength ]; 63 m_DFWindowedFrame = new double[ m_dataLength ];
53 m_magnitude = new double[ m_halfLength ]; 64 m_magnitude = new double[ m_halfLength ];
59 void DetectionFunction::deInitialise() 70 void DetectionFunction::deInitialise()
60 { 71 {
61 delete [] m_magHistory ; 72 delete [] m_magHistory ;
62 delete [] m_phaseHistory ; 73 delete [] m_phaseHistory ;
63 delete [] m_phaseHistoryOld ; 74 delete [] m_phaseHistoryOld ;
75 delete [] m_magPeaks ;
64 76
65 delete m_phaseVoc; 77 delete m_phaseVoc;
66 78
67 delete [] m_DFWindowedFrame; 79 delete [] m_DFWindowedFrame;
68 delete [] m_magnitude; 80 delete [] m_magnitude;
75 { 87 {
76 m_window->cut( TDomain, m_DFWindowedFrame ); 88 m_window->cut( TDomain, m_DFWindowedFrame );
77 89
78 m_phaseVoc->process( m_dataLength, m_DFWindowedFrame, m_magnitude, m_thetaAngle ); 90 m_phaseVoc->process( m_dataLength, m_DFWindowedFrame, m_magnitude, m_thetaAngle );
79 91
92 if (m_whiten) whiten();
93
80 return runDF(); 94 return runDF();
81 } 95 }
82 96
83 double DetectionFunction::process( double *magnitudes, double *phases ) 97 double DetectionFunction::process( double *magnitudes, double *phases )
84 { 98 {
85 for (size_t i = 0; i < m_halfLength; ++i) { 99 for (size_t i = 0; i < m_halfLength; ++i) {
86 m_magnitude[i] = magnitudes[i]; 100 m_magnitude[i] = magnitudes[i];
87 m_thetaAngle[i] = phases[i]; 101 m_thetaAngle[i] = phases[i];
88 } 102 }
89 103
104 if (m_whiten) whiten();
105
90 return runDF(); 106 return runDF();
107 }
108
109 void DetectionFunction::whiten()
110 {
111 for (unsigned int i = 0; i < m_halfLength; ++i) {
112 double m = m_magnitude[i];
113 if (m < m_magPeaks[i]) {
114 m = m + (m_magPeaks[i] - m) * m_whitenRelaxCoeff;
115 }
116 if (m < m_whitenFloor) m = m_whitenFloor;
117 m_magPeaks[i] = m;
118 m_magnitude[i] /= m;
119 }
91 } 120 }
92 121
93 double DetectionFunction::runDF() 122 double DetectionFunction::runDF()
94 { 123 {
95 double retVal = 0; 124 double retVal = 0;
103 case DF_SPECDIFF: 132 case DF_SPECDIFF:
104 retVal = specDiff( m_halfLength, m_magnitude); 133 retVal = specDiff( m_halfLength, m_magnitude);
105 break; 134 break;
106 135
107 case DF_PHASEDEV: 136 case DF_PHASEDEV:
108 retVal = phaseDev( m_halfLength, m_magnitude, m_thetaAngle); 137 retVal = phaseDev( m_halfLength, m_thetaAngle);
109 break; 138 break;
110 139
111 case DF_COMPLEXSD: 140 case DF_COMPLEXSD:
112 retVal = complexSD( m_halfLength, m_magnitude, m_thetaAngle); 141 retVal = complexSD( m_halfLength, m_magnitude, m_thetaAngle);
113 break; 142 break;
114 143
115 case DF_BROADBAND: 144 case DF_BROADBAND:
116 retVal = broadband( m_halfLength, m_magnitude, m_thetaAngle); 145 retVal = broadband( m_halfLength, m_magnitude);
146 break;
147
148 case DF_POWER:
149 retVal = power( m_halfLength, m_magnitude );
150 break;
117 } 151 }
118 152
119 return retVal; 153 return retVal;
120 } 154 }
121 155
153 187
154 return val; 188 return val;
155 } 189 }
156 190
157 191
158 double DetectionFunction::phaseDev(unsigned int length, double *srcMagnitude, double *srcPhase) 192 double DetectionFunction::phaseDev(unsigned int length, double *srcPhase)
159 { 193 {
160 unsigned int i; 194 unsigned int i;
161 double tmpPhase = 0; 195 double tmpPhase = 0;
162 double tmpVal = 0; 196 double tmpVal = 0;
163 double val = 0; 197 double val = 0;
219 } 253 }
220 254
221 return val; 255 return val;
222 } 256 }
223 257
224 double DetectionFunction::broadband(unsigned int length, double *srcMagnitude, double *srcPhase) 258 double DetectionFunction::broadband(unsigned int length, double *src)
225 { 259 {
226 double val = 0; 260 double val = 0;
227 for (unsigned int i = 0; i < length; ++i) { 261 for (unsigned int i = 0; i < length; ++i) {
228 double sqrmag = srcMagnitude[i] * srcMagnitude[i]; 262 double sqrmag = src[i] * src[i];
229 if (m_magHistory[i] > 0.0) { 263 if (m_magHistory[i] > 0.0) {
230 double diff = 10.0 * log10(sqrmag / m_magHistory[i]); 264 double diff = 10.0 * log10(sqrmag / m_magHistory[i]);
231 if (diff > m_dbRise) val = val + 1; 265 if (diff > m_dbRise) val = val + 1;
232 } 266 }
233 m_magHistory[i] = sqrmag; 267 m_magHistory[i] = sqrmag;
234 } 268 }
235 return val; 269 return val;
236 } 270 }
237 271
272 double DetectionFunction::power(unsigned int length, double *src)
273 {
274 double val = 0;
275 for (unsigned int i = 0; i < length; ++i) {
276 val += src[i];
277 }
278 return val;
279 }
280
238 double* DetectionFunction::getSpectrumMagnitude() 281 double* DetectionFunction::getSpectrumMagnitude()
239 { 282 {
240 return m_magnitude; 283 return m_magnitude;
241 } 284 }
242 285