| 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 16 matching lines...) Expand all Loading... |
| 27 */ | 27 */ |
| 28 | 28 |
| 29 #include "config.h" | 29 #include "config.h" |
| 30 | 30 |
| 31 #if ENABLE(WEB_AUDIO) | 31 #if ENABLE(WEB_AUDIO) |
| 32 | 32 |
| 33 #include "platform/audio/FFTFrame.h" | 33 #include "platform/audio/FFTFrame.h" |
| 34 | 34 |
| 35 #include "platform/audio/VectorMath.h" | 35 #include "platform/audio/VectorMath.h" |
| 36 #include "platform/Logging.h" | 36 #include "platform/Logging.h" |
| 37 #include "wtf/Complex.h" | |
| 38 #include "wtf/MathExtras.h" | 37 #include "wtf/MathExtras.h" |
| 39 #include "wtf/OwnPtr.h" | 38 #include "wtf/OwnPtr.h" |
| 40 | 39 |
| 40 #include <complex> |
| 41 |
| 41 #ifndef NDEBUG | 42 #ifndef NDEBUG |
| 42 #include <stdio.h> | 43 #include <stdio.h> |
| 43 #endif | 44 #endif |
| 44 | 45 |
| 45 namespace blink { | 46 namespace blink { |
| 46 | 47 |
| 47 void FFTFrame::doPaddedFFT(const float* data, size_t dataSize) | 48 void FFTFrame::doPaddedFFT(const float* data, size_t dataSize) |
| 48 { | 49 { |
| 49 // Zero-pad the impulse response | 50 // Zero-pad the impulse response |
| 50 AudioFloatArray paddedResponse(fftSize()); // zero-initialized | 51 AudioFloatArray paddedResponse(fftSize()); // zero-initialized |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 double phaseAccum = 0.0; | 94 double phaseAccum = 0.0; |
| 94 double lastPhase1 = 0.0; | 95 double lastPhase1 = 0.0; |
| 95 double lastPhase2 = 0.0; | 96 double lastPhase2 = 0.0; |
| 96 | 97 |
| 97 realP[0] = static_cast<float>(s1base * realP1[0] + s2base * realP2[0]); | 98 realP[0] = static_cast<float>(s1base * realP1[0] + s2base * realP2[0]); |
| 98 imagP[0] = static_cast<float>(s1base * imagP1[0] + s2base * imagP2[0]); | 99 imagP[0] = static_cast<float>(s1base * imagP1[0] + s2base * imagP2[0]); |
| 99 | 100 |
| 100 int n = m_FFTSize / 2; | 101 int n = m_FFTSize / 2; |
| 101 | 102 |
| 102 for (int i = 1; i < n; ++i) { | 103 for (int i = 1; i < n; ++i) { |
| 103 Complex c1(realP1[i], imagP1[i]); | 104 std::complex<double> c1(realP1[i], imagP1[i]); |
| 104 Complex c2(realP2[i], imagP2[i]); | 105 std::complex<double> c2(realP2[i], imagP2[i]); |
| 105 | 106 |
| 106 double mag1 = abs(c1); | 107 double mag1 = abs(c1); |
| 107 double mag2 = abs(c2); | 108 double mag2 = abs(c2); |
| 108 | 109 |
| 109 // Interpolate magnitudes in decibels | 110 // Interpolate magnitudes in decibels |
| 110 double mag1db = 20.0 * log10(mag1); | 111 double mag1db = 20.0 * log10(mag1); |
| 111 double mag2db = 20.0 * log10(mag2); | 112 double mag2db = 20.0 * log10(mag2); |
| 112 | 113 |
| 113 double s1 = s1base; | 114 double s1 = s1base; |
| 114 double s2 = s2base; | 115 double s2 = s2base; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 deltaPhaseBlend = s1 * deltaPhase1 + s2 * deltaPhase2; | 161 deltaPhaseBlend = s1 * deltaPhase1 + s2 * deltaPhase2; |
| 161 | 162 |
| 162 phaseAccum += deltaPhaseBlend; | 163 phaseAccum += deltaPhaseBlend; |
| 163 | 164 |
| 164 // Unwrap | 165 // Unwrap |
| 165 if (phaseAccum > piDouble) | 166 if (phaseAccum > piDouble) |
| 166 phaseAccum -= twoPiDouble; | 167 phaseAccum -= twoPiDouble; |
| 167 if (phaseAccum < -piDouble) | 168 if (phaseAccum < -piDouble) |
| 168 phaseAccum += twoPiDouble; | 169 phaseAccum += twoPiDouble; |
| 169 | 170 |
| 170 Complex c = complexFromMagnitudePhase(mag, phaseAccum); | 171 std::complex<double> c = std::polar(mag, phaseAccum); |
| 171 | 172 |
| 172 realP[i] = static_cast<float>(c.real()); | 173 realP[i] = static_cast<float>(c.real()); |
| 173 imagP[i] = static_cast<float>(c.imag()); | 174 imagP[i] = static_cast<float>(c.imag()); |
| 174 } | 175 } |
| 175 } | 176 } |
| 176 | 177 |
| 177 double FFTFrame::extractAverageGroupDelay() | 178 double FFTFrame::extractAverageGroupDelay() |
| 178 { | 179 { |
| 179 float* realP = realData(); | 180 float* realP = realData(); |
| 180 float* imagP = imagData(); | 181 float* imagP = imagData(); |
| 181 | 182 |
| 182 double aveSum = 0.0; | 183 double aveSum = 0.0; |
| 183 double weightSum = 0.0; | 184 double weightSum = 0.0; |
| 184 double lastPhase = 0.0; | 185 double lastPhase = 0.0; |
| 185 | 186 |
| 186 int halfSize = fftSize() / 2; | 187 int halfSize = fftSize() / 2; |
| 187 | 188 |
| 188 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); | 189 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); |
| 189 | 190 |
| 190 // Calculate weighted average group delay | 191 // Calculate weighted average group delay |
| 191 for (int i = 0; i < halfSize; i++) { | 192 for (int i = 0; i < halfSize; i++) { |
| 192 Complex c(realP[i], imagP[i]); | 193 std::complex<double> c(realP[i], imagP[i]); |
| 193 double mag = abs(c); | 194 double mag = abs(c); |
| 194 double phase = arg(c); | 195 double phase = arg(c); |
| 195 | 196 |
| 196 double deltaPhase = phase - lastPhase; | 197 double deltaPhase = phase - lastPhase; |
| 197 lastPhase = phase; | 198 lastPhase = phase; |
| 198 | 199 |
| 199 // Unwrap | 200 // Unwrap |
| 200 if (deltaPhase < -piDouble) | 201 if (deltaPhase < -piDouble) |
| 201 deltaPhase += twoPiDouble; | 202 deltaPhase += twoPiDouble; |
| 202 if (deltaPhase > piDouble) | 203 if (deltaPhase > piDouble) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 229 | 230 |
| 230 float* realP = realData(); | 231 float* realP = realData(); |
| 231 float* imagP = imagData(); | 232 float* imagP = imagData(); |
| 232 | 233 |
| 233 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); | 234 const double kSamplePhaseDelay = (twoPiDouble) / double(fftSize()); |
| 234 | 235 |
| 235 double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay; | 236 double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay; |
| 236 | 237 |
| 237 // Add constant group delay | 238 // Add constant group delay |
| 238 for (int i = 1; i < halfSize; i++) { | 239 for (int i = 1; i < halfSize; i++) { |
| 239 Complex c(realP[i], imagP[i]); | 240 std::complex<double> c(realP[i], imagP[i]); |
| 240 double mag = abs(c); | 241 double mag = abs(c); |
| 241 double phase = arg(c); | 242 double phase = arg(c); |
| 242 | 243 |
| 243 phase += i * phaseAdj; | 244 phase += i * phaseAdj; |
| 244 | 245 |
| 245 Complex c2 = complexFromMagnitudePhase(mag, phase); | 246 std::complex<double> c2 = std::polar(mag, phase); |
| 246 | 247 |
| 247 realP[i] = static_cast<float>(c2.real()); | 248 realP[i] = static_cast<float>(c2.real()); |
| 248 imagP[i] = static_cast<float>(c2.imag()); | 249 imagP[i] = static_cast<float>(c2.imag()); |
| 249 } | 250 } |
| 250 } | 251 } |
| 251 | 252 |
| 252 void FFTFrame::multiply(const FFTFrame& frame) | 253 void FFTFrame::multiply(const FFTFrame& frame) |
| 253 { | 254 { |
| 254 FFTFrame& frame1 = *this; | 255 FFTFrame& frame1 = *this; |
| 255 FFTFrame& frame2 = const_cast<FFTFrame&>(frame); | 256 FFTFrame& frame2 = const_cast<FFTFrame&>(frame); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 266 VectorMath::zvmul(realP1, imagP1, realP2, imagP2, realP1, imagP1, halfSize); | 267 VectorMath::zvmul(realP1, imagP1, realP2, imagP2, realP1, imagP1, halfSize); |
| 267 | 268 |
| 268 // Multiply the packed DC/nyquist component | 269 // Multiply the packed DC/nyquist component |
| 269 realP1[0] = real0 * realP2[0]; | 270 realP1[0] = real0 * realP2[0]; |
| 270 imagP1[0] = imag0 * imagP2[0]; | 271 imagP1[0] = imag0 * imagP2[0]; |
| 271 } | 272 } |
| 272 | 273 |
| 273 } // namespace blink | 274 } // namespace blink |
| 274 | 275 |
| 275 #endif // ENABLE(WEB_AUDIO) | 276 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |