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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 { | 173 { |
174 float* realP = realData(); | 174 float* realP = realData(); |
175 float* imagP = imagData(); | 175 float* imagP = imagData(); |
176 | 176 |
177 double aveSum = 0.0; | 177 double aveSum = 0.0; |
178 double weightSum = 0.0; | 178 double weightSum = 0.0; |
179 double lastPhase = 0.0; | 179 double lastPhase = 0.0; |
180 | 180 |
181 int halfSize = fftSize() / 2; | 181 int halfSize = fftSize() / 2; |
182 | 182 |
183 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); | 183 const double samplePhaseDelay = (twoPiDouble) / static_cast<double>(fftSize(
)); |
184 | 184 |
185 // Calculate weighted average group delay | 185 // Calculate weighted average group delay |
186 for (int i = 0; i < halfSize; i++) { | 186 for (int i = 0; i < halfSize; i++) { |
187 std::complex<double> c(realP[i], imagP[i]); | 187 std::complex<double> c(realP[i], imagP[i]); |
188 double mag = abs(c); | 188 double mag = abs(c); |
189 double phase = arg(c); | 189 double phase = arg(c); |
190 | 190 |
191 double deltaPhase = phase - lastPhase; | 191 double deltaPhase = phase - lastPhase; |
192 lastPhase = phase; | 192 lastPhase = phase; |
193 | 193 |
194 // Unwrap | 194 // Unwrap |
195 if (deltaPhase < -piDouble) | 195 if (deltaPhase < -piDouble) |
196 deltaPhase += twoPiDouble; | 196 deltaPhase += twoPiDouble; |
197 if (deltaPhase > piDouble) | 197 if (deltaPhase > piDouble) |
198 deltaPhase -= twoPiDouble; | 198 deltaPhase -= twoPiDouble; |
199 | 199 |
200 aveSum += mag * deltaPhase; | 200 aveSum += mag * deltaPhase; |
201 weightSum += mag; | 201 weightSum += mag; |
202 } | 202 } |
203 | 203 |
204 // Note how we invert the phase delta wrt frequency since this is how group
delay is defined | 204 // Note how we invert the phase delta wrt frequency since this is how group
delay is defined |
205 double ave = aveSum / weightSum; | 205 double ave = aveSum / weightSum; |
206 double aveSampleDelay = -ave / kSamplePhaseDelay; | 206 double aveSampleDelay = -ave / samplePhaseDelay; |
207 | 207 |
208 // Leave 20 sample headroom (for leading edge of impulse) | 208 // Leave 20 sample headroom (for leading edge of impulse) |
209 if (aveSampleDelay > 20.0) | 209 if (aveSampleDelay > 20.0) |
210 aveSampleDelay -= 20.0; | 210 aveSampleDelay -= 20.0; |
211 | 211 |
212 // Remove average group delay (minus 20 samples for headroom) | 212 // Remove average group delay (minus 20 samples for headroom) |
213 addConstantGroupDelay(-aveSampleDelay); | 213 addConstantGroupDelay(-aveSampleDelay); |
214 | 214 |
215 // Remove DC offset | 215 // Remove DC offset |
216 realP[0] = 0.0f; | 216 realP[0] = 0.0f; |
217 | 217 |
218 return aveSampleDelay; | 218 return aveSampleDelay; |
219 } | 219 } |
220 | 220 |
221 void FFTFrame::addConstantGroupDelay(double sampleFrameDelay) | 221 void FFTFrame::addConstantGroupDelay(double sampleFrameDelay) |
222 { | 222 { |
223 int halfSize = fftSize() / 2; | 223 int halfSize = fftSize() / 2; |
224 | 224 |
225 float* realP = realData(); | 225 float* realP = realData(); |
226 float* imagP = imagData(); | 226 float* imagP = imagData(); |
227 | 227 |
228 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); | 228 const double samplePhaseDelay = (twoPiDouble) / static_cast<double>(fftSize(
)); |
229 | 229 |
230 double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay; | 230 double phaseAdj = -sampleFrameDelay * samplePhaseDelay; |
231 | 231 |
232 // Add constant group delay | 232 // Add constant group delay |
233 for (int i = 1; i < halfSize; i++) { | 233 for (int i = 1; i < halfSize; i++) { |
234 std::complex<double> c(realP[i], imagP[i]); | 234 std::complex<double> c(realP[i], imagP[i]); |
235 double mag = abs(c); | 235 double mag = abs(c); |
236 double phase = arg(c); | 236 double phase = arg(c); |
237 | 237 |
238 phase += i * phaseAdj; | 238 phase += i * phaseAdj; |
239 | 239 |
240 std::complex<double> c2 = std::polar(mag, phase); | 240 std::complex<double> c2 = std::polar(mag, phase); |
(...skipping 19 matching lines...) Expand all Loading... |
260 | 260 |
261 VectorMath::zvmul(realP1, imagP1, realP2, imagP2, realP1, imagP1, halfSize); | 261 VectorMath::zvmul(realP1, imagP1, realP2, imagP2, realP1, imagP1, halfSize); |
262 | 262 |
263 // Multiply the packed DC/nyquist component | 263 // Multiply the packed DC/nyquist component |
264 realP1[0] = real0 * realP2[0]; | 264 realP1[0] = real0 * realP2[0]; |
265 imagP1[0] = imag0 * imagP2[0]; | 265 imagP1[0] = imag0 * imagP2[0]; |
266 } | 266 } |
267 | 267 |
268 } // namespace blink | 268 } // namespace blink |
269 | 269 |
OLD | NEW |