| 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 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "modules/webaudio/BiquadDSPKernel.h" | 26 #include "modules/webaudio/BiquadDSPKernel.h" |
| 27 #include "platform/audio/AudioUtilities.h" | 27 #include "platform/audio/AudioUtilities.h" |
| 28 #include "wtf/MathExtras.h" | 28 #include "wtf/MathExtras.h" |
| 29 #include "wtf/Vector.h" | 29 #include "wtf/Vector.h" |
| 30 #include <limits.h> | 30 #include <limits.h> |
| 31 | 31 |
| 32 namespace blink { | 32 namespace blink { |
| 33 | 33 |
| 34 // FIXME: As a recursive linear filter, depending on its parameters, a biquad fi
lter can have | 34 // FIXME: As a recursive linear filter, depending on its parameters, a biquad |
| 35 // an infinite tailTime. In practice, Biquad filters do not usually (except for
very high resonance values) | 35 // filter can have an infinite tailTime. In practice, Biquad filters do not |
| 36 // have a tailTime of longer than approx. 200ms. This value could possibly be ca
lculated based on the | 36 // usually (except for very high resonance values) have a tailTime of longer |
| 37 // than approx. 200ms. This value could possibly be calculated based on the |
| 37 // settings of the Biquad. | 38 // settings of the Biquad. |
| 38 static const double MaxBiquadDelayTime = 0.2; | 39 static const double MaxBiquadDelayTime = 0.2; |
| 39 | 40 |
| 40 void BiquadDSPKernel::updateCoefficientsIfNecessary(int framesToProcess) { | 41 void BiquadDSPKernel::updateCoefficientsIfNecessary(int framesToProcess) { |
| 41 if (getBiquadProcessor()->filterCoefficientsDirty()) { | 42 if (getBiquadProcessor()->filterCoefficientsDirty()) { |
| 42 float cutoffFrequency[AudioUtilities::kRenderQuantumFrames]; | 43 float cutoffFrequency[AudioUtilities::kRenderQuantumFrames]; |
| 43 float Q[AudioUtilities::kRenderQuantumFrames]; | 44 float Q[AudioUtilities::kRenderQuantumFrames]; |
| 44 float gain[AudioUtilities::kRenderQuantumFrames]; | 45 float gain[AudioUtilities::kRenderQuantumFrames]; |
| 45 float detune[AudioUtilities::kRenderQuantumFrames]; // in Cents | 46 float detune[AudioUtilities::kRenderQuantumFrames]; // in Cents |
| 46 | 47 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 77 | 78 |
| 78 m_biquad.setHasSampleAccurateValues(numberOfFrames > 1); | 79 m_biquad.setHasSampleAccurateValues(numberOfFrames > 1); |
| 79 | 80 |
| 80 for (int k = 0; k < numberOfFrames; ++k) { | 81 for (int k = 0; k < numberOfFrames; ++k) { |
| 81 double normalizedFrequency = cutoffFrequency[k] / nyquist; | 82 double normalizedFrequency = cutoffFrequency[k] / nyquist; |
| 82 | 83 |
| 83 // Offset frequency by detune. | 84 // Offset frequency by detune. |
| 84 if (detune[k]) | 85 if (detune[k]) |
| 85 normalizedFrequency *= pow(2, detune[k] / 1200); | 86 normalizedFrequency *= pow(2, detune[k] / 1200); |
| 86 | 87 |
| 87 // Configure the biquad with the new filter parameters for the appropriate t
ype of filter. | 88 // Configure the biquad with the new filter parameters for the appropriate |
| 89 // type of filter. |
| 88 switch (getBiquadProcessor()->type()) { | 90 switch (getBiquadProcessor()->type()) { |
| 89 case BiquadProcessor::LowPass: | 91 case BiquadProcessor::LowPass: |
| 90 m_biquad.setLowpassParams(k, normalizedFrequency, Q[k]); | 92 m_biquad.setLowpassParams(k, normalizedFrequency, Q[k]); |
| 91 break; | 93 break; |
| 92 | 94 |
| 93 case BiquadProcessor::HighPass: | 95 case BiquadProcessor::HighPass: |
| 94 m_biquad.setHighpassParams(k, normalizedFrequency, Q[k]); | 96 m_biquad.setHighpassParams(k, normalizedFrequency, Q[k]); |
| 95 break; | 97 break; |
| 96 | 98 |
| 97 case BiquadProcessor::BandPass: | 99 case BiquadProcessor::BandPass: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 122 } | 124 } |
| 123 | 125 |
| 124 void BiquadDSPKernel::process(const float* source, | 126 void BiquadDSPKernel::process(const float* source, |
| 125 float* destination, | 127 float* destination, |
| 126 size_t framesToProcess) { | 128 size_t framesToProcess) { |
| 127 DCHECK(source); | 129 DCHECK(source); |
| 128 DCHECK(destination); | 130 DCHECK(destination); |
| 129 DCHECK(getBiquadProcessor()); | 131 DCHECK(getBiquadProcessor()); |
| 130 | 132 |
| 131 // Recompute filter coefficients if any of the parameters have changed. | 133 // Recompute filter coefficients if any of the parameters have changed. |
| 132 // FIXME: as an optimization, implement a way that a Biquad object can simply
copy its internal filter coefficients from another Biquad object. | 134 // FIXME: as an optimization, implement a way that a Biquad object can simply |
| 133 // Then re-factor this code to only run for the first BiquadDSPKernel of each
BiquadProcessor. | 135 // copy its internal filter coefficients from another Biquad object. Then |
| 136 // re-factor this code to only run for the first BiquadDSPKernel of each |
| 137 // BiquadProcessor. |
| 134 | 138 |
| 135 // The audio thread can't block on this lock; skip updating the coefficients f
or this block if | 139 // The audio thread can't block on this lock; skip updating the coefficients |
| 136 // necessary. We'll get them the next time around. | 140 // for this block if necessary. We'll get them the next time around. |
| 137 { | 141 { |
| 138 MutexTryLocker tryLocker(m_processLock); | 142 MutexTryLocker tryLocker(m_processLock); |
| 139 if (tryLocker.locked()) | 143 if (tryLocker.locked()) |
| 140 updateCoefficientsIfNecessary(framesToProcess); | 144 updateCoefficientsIfNecessary(framesToProcess); |
| 141 } | 145 } |
| 142 | 146 |
| 143 m_biquad.process(source, destination, framesToProcess); | 147 m_biquad.process(source, destination, framesToProcess); |
| 144 } | 148 } |
| 145 | 149 |
| 146 void BiquadDSPKernel::getFrequencyResponse(int nFrequencies, | 150 void BiquadDSPKernel::getFrequencyResponse(int nFrequencies, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 160 // with 1 equal to the Nyquist frequency. | 164 // with 1 equal to the Nyquist frequency. |
| 161 for (int k = 0; k < nFrequencies; ++k) | 165 for (int k = 0; k < nFrequencies; ++k) |
| 162 frequency[k] = clampTo<float>(frequencyHz[k] / nyquist); | 166 frequency[k] = clampTo<float>(frequencyHz[k] / nyquist); |
| 163 | 167 |
| 164 float cutoffFrequency; | 168 float cutoffFrequency; |
| 165 float Q; | 169 float Q; |
| 166 float gain; | 170 float gain; |
| 167 float detune; // in Cents | 171 float detune; // in Cents |
| 168 | 172 |
| 169 { | 173 { |
| 170 // Get a copy of the current biquad filter coefficients so we can update the
biquad with | 174 // Get a copy of the current biquad filter coefficients so we can update the |
| 171 // these values. We need to synchronize with process() to prevent process()
from updating | 175 // biquad with these values. We need to synchronize with process() to |
| 172 // the filter coefficients while we're trying to access them. The process wi
ll update it | 176 // prevent process() from updating the filter coefficients while we're |
| 173 // next time around. | 177 // trying to access them. The process will update it next time around. |
| 174 // | 178 // |
| 175 // The BiquadDSPKernel object here (along with it's Biquad object) is for qu
erying the | 179 // The BiquadDSPKernel object here (along with it's Biquad object) is for |
| 176 // frequency response and is NOT the same as the one in process() which is u
sed for | 180 // querying the frequency response and is NOT the same as the one in |
| 177 // performing the actual filtering. This one is is created in | 181 // process() which is used for performing the actual filtering. This one is |
| 178 // BiquadProcessor::getFrequencyResponse for this purpose. Both, however, po
int to the same | 182 // is created in BiquadProcessor::getFrequencyResponse for this purpose. |
| 179 // BiquadProcessor object. | 183 // Both, however, point to the same BiquadProcessor object. |
| 180 // | 184 // |
| 181 // FIXME: Simplify this: crbug.com/390266 | 185 // FIXME: Simplify this: crbug.com/390266 |
| 182 MutexLocker processLocker(m_processLock); | 186 MutexLocker processLocker(m_processLock); |
| 183 | 187 |
| 184 cutoffFrequency = getBiquadProcessor()->parameter1().value(); | 188 cutoffFrequency = getBiquadProcessor()->parameter1().value(); |
| 185 Q = getBiquadProcessor()->parameter2().value(); | 189 Q = getBiquadProcessor()->parameter2().value(); |
| 186 gain = getBiquadProcessor()->parameter3().value(); | 190 gain = getBiquadProcessor()->parameter3().value(); |
| 187 detune = getBiquadProcessor()->parameter4().value(); | 191 detune = getBiquadProcessor()->parameter4().value(); |
| 188 } | 192 } |
| 189 | 193 |
| 190 updateCoefficients(1, &cutoffFrequency, &Q, &gain, &detune); | 194 updateCoefficients(1, &cutoffFrequency, &Q, &gain, &detune); |
| 191 | 195 |
| 192 m_biquad.getFrequencyResponse(nFrequencies, frequency.data(), magResponse, | 196 m_biquad.getFrequencyResponse(nFrequencies, frequency.data(), magResponse, |
| 193 phaseResponse); | 197 phaseResponse); |
| 194 } | 198 } |
| 195 | 199 |
| 196 double BiquadDSPKernel::tailTime() const { | 200 double BiquadDSPKernel::tailTime() const { |
| 197 return MaxBiquadDelayTime; | 201 return MaxBiquadDelayTime; |
| 198 } | 202 } |
| 199 | 203 |
| 200 double BiquadDSPKernel::latencyTime() const { | 204 double BiquadDSPKernel::latencyTime() const { |
| 201 return 0; | 205 return 0; |
| 202 } | 206 } |
| 203 | 207 |
| 204 } // namespace blink | 208 } // namespace blink |
| OLD | NEW |