Mercurial > hg > qm-dsp
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 |