Mercurial > hg > qm-dsp
comparison dsp/onsets/DetectionFunction.cpp @ 347:e3dedded9c4d
Merge from pvoc branch
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Fri, 04 Oct 2013 16:43:44 +0100 |
parents | 04d134031a15 |
children | 2053a308bb4d |
comparison
equal
deleted
inserted
replaced
336:f665f9ce2fd1 | 347:e3dedded9c4d |
---|---|
38 | 38 |
39 | 39 |
40 void DetectionFunction::initialise( DFConfig Config ) | 40 void DetectionFunction::initialise( DFConfig Config ) |
41 { | 41 { |
42 m_dataLength = Config.frameLength; | 42 m_dataLength = Config.frameLength; |
43 m_halfLength = m_dataLength/2; | 43 m_halfLength = m_dataLength/2 + 1; |
44 | 44 |
45 m_DFType = Config.DFType; | 45 m_DFType = Config.DFType; |
46 m_stepSize = Config.stepSize; | 46 m_stepSize = Config.stepSize; |
47 | 47 |
48 m_whiten = Config.adaptiveWhitening; | 48 m_whiten = Config.adaptiveWhitening; |
61 memset(m_phaseHistoryOld,0, m_halfLength*sizeof(double)); | 61 memset(m_phaseHistoryOld,0, m_halfLength*sizeof(double)); |
62 | 62 |
63 m_magPeaks = new double[ m_halfLength ]; | 63 m_magPeaks = new double[ m_halfLength ]; |
64 memset(m_magPeaks,0, m_halfLength*sizeof(double)); | 64 memset(m_magPeaks,0, m_halfLength*sizeof(double)); |
65 | 65 |
66 // See note in process(const double *) below | 66 // See note in processTimeDomain below |
67 int actualLength = MathUtilities::previousPowerOfTwo(m_dataLength); | 67 int actualLength = MathUtilities::previousPowerOfTwo(m_dataLength); |
68 m_phaseVoc = new PhaseVocoder(actualLength); | 68 m_phaseVoc = new PhaseVocoder(actualLength, m_stepSize); |
69 | 69 |
70 m_DFWindowedFrame = new double[ m_dataLength ]; | |
71 m_magnitude = new double[ m_halfLength ]; | 70 m_magnitude = new double[ m_halfLength ]; |
72 m_thetaAngle = new double[ m_halfLength ]; | 71 m_thetaAngle = new double[ m_halfLength ]; |
72 m_unwrapped = new double[ m_halfLength ]; | |
73 | 73 |
74 m_window = new Window<double>(HanningWindow, m_dataLength); | 74 m_window = new Window<double>(HanningWindow, m_dataLength); |
75 m_windowed = new double[ m_dataLength ]; | |
75 } | 76 } |
76 | 77 |
77 void DetectionFunction::deInitialise() | 78 void DetectionFunction::deInitialise() |
78 { | 79 { |
79 delete [] m_magHistory ; | 80 delete [] m_magHistory ; |
81 delete [] m_phaseHistoryOld ; | 82 delete [] m_phaseHistoryOld ; |
82 delete [] m_magPeaks ; | 83 delete [] m_magPeaks ; |
83 | 84 |
84 delete m_phaseVoc; | 85 delete m_phaseVoc; |
85 | 86 |
86 delete [] m_DFWindowedFrame; | |
87 delete [] m_magnitude; | 87 delete [] m_magnitude; |
88 delete [] m_thetaAngle; | 88 delete [] m_thetaAngle; |
89 delete [] m_windowed; | |
90 delete [] m_unwrapped; | |
89 | 91 |
90 delete m_window; | 92 delete m_window; |
91 } | 93 } |
92 | 94 |
93 double DetectionFunction::process( const double *TDomain ) | 95 double DetectionFunction::processTimeDomain(const double *samples) |
94 { | 96 { |
95 m_window->cut( TDomain, m_DFWindowedFrame ); | 97 m_window->cut(samples, m_windowed); |
96 | 98 |
97 // Our own FFT implementation supports power-of-two sizes only. | 99 // Our own FFT implementation supports power-of-two sizes only. |
98 // If we have to use this implementation (as opposed to the | 100 // If we have to use this implementation (as opposed to the |
99 // version of process() below that operates on frequency domain | 101 // version of process() below that operates on frequency domain |
100 // data directly), we will have to use the next smallest power of | 102 // data directly), we will have to use the next smallest power of |
109 m_magnitude[i] = 0; | 111 m_magnitude[i] = 0; |
110 m_thetaAngle[0] = 0; | 112 m_thetaAngle[0] = 0; |
111 } | 113 } |
112 } | 114 } |
113 | 115 |
114 m_phaseVoc->process(m_DFWindowedFrame, m_magnitude, m_thetaAngle); | 116 m_phaseVoc->processTimeDomain(m_windowed, |
117 m_magnitude, m_thetaAngle, m_unwrapped); | |
115 | 118 |
116 if (m_whiten) whiten(); | 119 if (m_whiten) whiten(); |
117 | 120 |
118 return runDF(); | 121 return runDF(); |
119 } | 122 } |
120 | 123 |
121 double DetectionFunction::process( const double *magnitudes, const double *phases ) | 124 double DetectionFunction::processFrequencyDomain(const double *reals, |
122 { | 125 const double *imags) |
123 for (size_t i = 0; i < m_halfLength; ++i) { | 126 { |
124 m_magnitude[i] = magnitudes[i]; | 127 m_phaseVoc->processFrequencyDomain(reals, imags, |
125 m_thetaAngle[i] = phases[i]; | 128 m_magnitude, m_thetaAngle, m_unwrapped); |
126 } | |
127 | 129 |
128 if (m_whiten) whiten(); | 130 if (m_whiten) whiten(); |
129 | 131 |
130 return runDF(); | 132 return runDF(); |
131 } | 133 } |
156 case DF_SPECDIFF: | 158 case DF_SPECDIFF: |
157 retVal = specDiff( m_halfLength, m_magnitude); | 159 retVal = specDiff( m_halfLength, m_magnitude); |
158 break; | 160 break; |
159 | 161 |
160 case DF_PHASEDEV: | 162 case DF_PHASEDEV: |
163 // Using the instantaneous phases here actually provides the | |
164 // same results (for these calculations) as if we had used | |
165 // unwrapped phases, but without the possible accumulation of | |
166 // phase error over time | |
161 retVal = phaseDev( m_halfLength, m_thetaAngle); | 167 retVal = phaseDev( m_halfLength, m_thetaAngle); |
162 break; | 168 break; |
163 | 169 |
164 case DF_COMPLEXSD: | 170 case DF_COMPLEXSD: |
165 retVal = complexSD( m_halfLength, m_magnitude, m_thetaAngle); | 171 retVal = complexSD( m_halfLength, m_magnitude, m_thetaAngle); |
235 val += tmpVal ; | 241 val += tmpVal ; |
236 | 242 |
237 m_phaseHistoryOld[ i ] = m_phaseHistory[ i ] ; | 243 m_phaseHistoryOld[ i ] = m_phaseHistory[ i ] ; |
238 m_phaseHistory[ i ] = srcPhase[ i ]; | 244 m_phaseHistory[ i ] = srcPhase[ i ]; |
239 } | 245 } |
240 | |
241 | 246 |
242 return val; | 247 return val; |
243 } | 248 } |
244 | 249 |
245 | 250 |