OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 double phase1 = arg(c1); | 144 double phase1 = arg(c1); |
145 double phase2 = arg(c2); | 145 double phase2 = arg(c2); |
146 | 146 |
147 double deltaPhase1 = phase1 - lastPhase1; | 147 double deltaPhase1 = phase1 - lastPhase1; |
148 double deltaPhase2 = phase2 - lastPhase2; | 148 double deltaPhase2 = phase2 - lastPhase2; |
149 lastPhase1 = phase1; | 149 lastPhase1 = phase1; |
150 lastPhase2 = phase2; | 150 lastPhase2 = phase2; |
151 | 151 |
152 // Unwrap phase deltas | 152 // Unwrap phase deltas |
153 if (deltaPhase1 > piDouble) | 153 if (deltaPhase1 > piDouble) |
154 deltaPhase1 -= 2.0 * piDouble; | 154 deltaPhase1 -= twoPiDouble; |
155 if (deltaPhase1 < -piDouble) | 155 if (deltaPhase1 < -piDouble) |
156 deltaPhase1 += 2.0 * piDouble; | 156 deltaPhase1 += twoPiDouble; |
157 if (deltaPhase2 > piDouble) | 157 if (deltaPhase2 > piDouble) |
158 deltaPhase2 -= 2.0 * piDouble; | 158 deltaPhase2 -= twoPiDouble; |
159 if (deltaPhase2 < -piDouble) | 159 if (deltaPhase2 < -piDouble) |
160 deltaPhase2 += 2.0 * piDouble; | 160 deltaPhase2 += twoPiDouble; |
161 | 161 |
162 // Blend group-delays | 162 // Blend group-delays |
163 double deltaPhaseBlend; | 163 double deltaPhaseBlend; |
164 | 164 |
165 if (deltaPhase1 - deltaPhase2 > piDouble) | 165 if (deltaPhase1 - deltaPhase2 > piDouble) |
166 deltaPhaseBlend = s1 * deltaPhase1 + s2 * (2.0 * piDouble + deltaPha
se2); | 166 deltaPhaseBlend = s1 * deltaPhase1 + s2 * (twoPiDouble + deltaPhase2
); |
167 else if (deltaPhase2 - deltaPhase1 > piDouble) | 167 else if (deltaPhase2 - deltaPhase1 > piDouble) |
168 deltaPhaseBlend = s1 * (2.0 * piDouble + deltaPhase1) + s2 * deltaPh
ase2; | 168 deltaPhaseBlend = s1 * (twoPiDouble + deltaPhase1) + s2 * deltaPhase
2; |
169 else | 169 else |
170 deltaPhaseBlend = s1 * deltaPhase1 + s2 * deltaPhase2; | 170 deltaPhaseBlend = s1 * deltaPhase1 + s2 * deltaPhase2; |
171 | 171 |
172 phaseAccum += deltaPhaseBlend; | 172 phaseAccum += deltaPhaseBlend; |
173 | 173 |
174 // Unwrap | 174 // Unwrap |
175 if (phaseAccum > piDouble) | 175 if (phaseAccum > piDouble) |
176 phaseAccum -= 2.0 * piDouble; | 176 phaseAccum -= twoPiDouble; |
177 if (phaseAccum < -piDouble) | 177 if (phaseAccum < -piDouble) |
178 phaseAccum += 2.0 * piDouble; | 178 phaseAccum += twoPiDouble; |
179 | 179 |
180 Complex c = complexFromMagnitudePhase(mag, phaseAccum); | 180 Complex c = complexFromMagnitudePhase(mag, phaseAccum); |
181 | 181 |
182 realP[i] = static_cast<float>(c.real()); | 182 realP[i] = static_cast<float>(c.real()); |
183 imagP[i] = static_cast<float>(c.imag()); | 183 imagP[i] = static_cast<float>(c.imag()); |
184 } | 184 } |
185 } | 185 } |
186 | 186 |
187 double FFTFrame::extractAverageGroupDelay() | 187 double FFTFrame::extractAverageGroupDelay() |
188 { | 188 { |
189 float* realP = realData(); | 189 float* realP = realData(); |
190 float* imagP = imagData(); | 190 float* imagP = imagData(); |
191 | 191 |
192 double aveSum = 0.0; | 192 double aveSum = 0.0; |
193 double weightSum = 0.0; | 193 double weightSum = 0.0; |
194 double lastPhase = 0.0; | 194 double lastPhase = 0.0; |
195 | 195 |
196 int halfSize = fftSize() / 2; | 196 int halfSize = fftSize() / 2; |
197 | 197 |
198 const double kSamplePhaseDelay = (2.0 * piDouble) / double(fftSize()); | 198 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); |
199 | 199 |
200 // Calculate weighted average group delay | 200 // Calculate weighted average group delay |
201 for (int i = 0; i < halfSize; i++) { | 201 for (int i = 0; i < halfSize; i++) { |
202 Complex c(realP[i], imagP[i]); | 202 Complex c(realP[i], imagP[i]); |
203 double mag = abs(c); | 203 double mag = abs(c); |
204 double phase = arg(c); | 204 double phase = arg(c); |
205 | 205 |
206 double deltaPhase = phase - lastPhase; | 206 double deltaPhase = phase - lastPhase; |
207 lastPhase = phase; | 207 lastPhase = phase; |
208 | 208 |
209 // Unwrap | 209 // Unwrap |
210 if (deltaPhase < -piDouble) | 210 if (deltaPhase < -piDouble) |
211 deltaPhase += 2.0 * piDouble; | 211 deltaPhase += twoPiDouble; |
212 if (deltaPhase > piDouble) | 212 if (deltaPhase > piDouble) |
213 deltaPhase -= 2.0 * piDouble; | 213 deltaPhase -= twoPiDouble; |
214 | 214 |
215 aveSum += mag * deltaPhase; | 215 aveSum += mag * deltaPhase; |
216 weightSum += mag; | 216 weightSum += mag; |
217 } | 217 } |
218 | 218 |
219 // Note how we invert the phase delta wrt frequency since this is how group
delay is defined | 219 // Note how we invert the phase delta wrt frequency since this is how group
delay is defined |
220 double ave = aveSum / weightSum; | 220 double ave = aveSum / weightSum; |
221 double aveSampleDelay = -ave / kSamplePhaseDelay; | 221 double aveSampleDelay = -ave / kSamplePhaseDelay; |
222 | 222 |
223 // Leave 20 sample headroom (for leading edge of impulse) | 223 // Leave 20 sample headroom (for leading edge of impulse) |
224 if (aveSampleDelay > 20.0) | 224 if (aveSampleDelay > 20.0) |
225 aveSampleDelay -= 20.0; | 225 aveSampleDelay -= 20.0; |
226 | 226 |
227 // Remove average group delay (minus 20 samples for headroom) | 227 // Remove average group delay (minus 20 samples for headroom) |
228 addConstantGroupDelay(-aveSampleDelay); | 228 addConstantGroupDelay(-aveSampleDelay); |
229 | 229 |
230 // Remove DC offset | 230 // Remove DC offset |
231 realP[0] = 0.0f; | 231 realP[0] = 0.0f; |
232 | 232 |
233 return aveSampleDelay; | 233 return aveSampleDelay; |
234 } | 234 } |
235 | 235 |
236 void FFTFrame::addConstantGroupDelay(double sampleFrameDelay) | 236 void FFTFrame::addConstantGroupDelay(double sampleFrameDelay) |
237 { | 237 { |
238 int halfSize = fftSize() / 2; | 238 int halfSize = fftSize() / 2; |
239 | 239 |
240 float* realP = realData(); | 240 float* realP = realData(); |
241 float* imagP = imagData(); | 241 float* imagP = imagData(); |
242 | 242 |
243 const double kSamplePhaseDelay = (2.0 * piDouble) / double(fftSize()); | 243 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); |
244 | 244 |
245 double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay; | 245 double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay; |
246 | 246 |
247 // Add constant group delay | 247 // Add constant group delay |
248 for (int i = 1; i < halfSize; i++) { | 248 for (int i = 1; i < halfSize; i++) { |
249 Complex c(realP[i], imagP[i]); | 249 Complex c(realP[i], imagP[i]); |
250 double mag = abs(c); | 250 double mag = abs(c); |
251 double phase = arg(c); | 251 double phase = arg(c); |
252 | 252 |
253 phase += i * phaseAdj; | 253 phase += i * phaseAdj; |
(...skipping 22 matching lines...) Expand all Loading... |
276 | 276 |
277 WTF_LOG(WebAudio, "[%d] (%f %f)\n", i, mag, phase); | 277 WTF_LOG(WebAudio, "[%d] (%f %f)\n", i, mag, phase); |
278 } | 278 } |
279 WTF_LOG(WebAudio, "****\n"); | 279 WTF_LOG(WebAudio, "****\n"); |
280 } | 280 } |
281 #endif // NDEBUG | 281 #endif // NDEBUG |
282 | 282 |
283 } // namespace WebCore | 283 } // namespace WebCore |
284 | 284 |
285 #endif // ENABLE(WEB_AUDIO) | 285 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |