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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 const int kBufferSize = 1024; | 45 const int kBufferSize = 1024; |
46 #endif | 46 #endif |
47 | 47 |
48 Biquad::Biquad() : m_hasSampleAccurateValues(false) { | 48 Biquad::Biquad() : m_hasSampleAccurateValues(false) { |
49 #if OS(MACOSX) | 49 #if OS(MACOSX) |
50 // Allocate two samples more for filter history | 50 // Allocate two samples more for filter history |
51 m_inputBuffer.allocate(kBufferSize + 2); | 51 m_inputBuffer.allocate(kBufferSize + 2); |
52 m_outputBuffer.allocate(kBufferSize + 2); | 52 m_outputBuffer.allocate(kBufferSize + 2); |
53 #endif | 53 #endif |
54 | 54 |
55 // Allocate enough space for the a-rate filter coefficients to handle a render ing quantum of 128 | 55 // Allocate enough space for the a-rate filter coefficients to handle a |
56 // rendering quantum of 128 | |
dcheng
2016/10/03 01:21:04
Nit: merge next line
Nico
2016/10/03 02:15:23
Done.
| |
56 // frames. | 57 // frames. |
57 m_b0.allocate(AudioUtilities::kRenderQuantumFrames); | 58 m_b0.allocate(AudioUtilities::kRenderQuantumFrames); |
58 m_b1.allocate(AudioUtilities::kRenderQuantumFrames); | 59 m_b1.allocate(AudioUtilities::kRenderQuantumFrames); |
59 m_b2.allocate(AudioUtilities::kRenderQuantumFrames); | 60 m_b2.allocate(AudioUtilities::kRenderQuantumFrames); |
60 m_a1.allocate(AudioUtilities::kRenderQuantumFrames); | 61 m_a1.allocate(AudioUtilities::kRenderQuantumFrames); |
61 m_a2.allocate(AudioUtilities::kRenderQuantumFrames); | 62 m_a2.allocate(AudioUtilities::kRenderQuantumFrames); |
62 | 63 |
63 // Initialize as pass-thru (straight-wire, no filter effect) | 64 // Initialize as pass-thru (straight-wire, no filter effect) |
64 setNormalizedCoefficients(0, 1, 0, 0, 1, 0, 0); | 65 setNormalizedCoefficients(0, 1, 0, 0, 1, 0, 0); |
65 | 66 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 y1 = y; | 103 y1 = y; |
103 } | 104 } |
104 | 105 |
105 // Local variables back to member. Flush denormals here so we | 106 // Local variables back to member. Flush denormals here so we |
106 // don't slow down the inner loop above. | 107 // don't slow down the inner loop above. |
107 m_x1 = DenormalDisabler::flushDenormalFloatToZero(x1); | 108 m_x1 = DenormalDisabler::flushDenormalFloatToZero(x1); |
108 m_x2 = DenormalDisabler::flushDenormalFloatToZero(x2); | 109 m_x2 = DenormalDisabler::flushDenormalFloatToZero(x2); |
109 m_y1 = DenormalDisabler::flushDenormalFloatToZero(y1); | 110 m_y1 = DenormalDisabler::flushDenormalFloatToZero(y1); |
110 m_y2 = DenormalDisabler::flushDenormalFloatToZero(y2); | 111 m_y2 = DenormalDisabler::flushDenormalFloatToZero(y2); |
111 | 112 |
112 // There is an assumption here that once we have sample accurate values we c an never go back | 113 // There is an assumption here that once we have sample accurate values we |
113 // to not having sample accurate values. This is currently true in the way | 114 // can never go back to not having sample accurate values. This is |
114 // AudioParamTimline is implemented: once an event is inserted, sample accur ate processing | 115 // currently true in the way AudioParamTimline is implemented: once an |
115 // is always enabled. | 116 // event is inserted, sample accurate processing is always enabled. |
116 // | 117 // |
117 // If so, then we never have to update the state variables for the MACOSX pa th. The | 118 // If so, then we never have to update the state variables for the MACOSX |
118 // structure of the state variable in these cases aren't well documented so it's not clear | 119 // path. The structure of the state variable in these cases aren't well |
119 // how to update them anyway. | 120 // documented so it's not clear how to update them anyway. |
120 } else { | 121 } else { |
121 #if OS(MACOSX) | 122 #if OS(MACOSX) |
122 double* inputP = m_inputBuffer.data(); | 123 double* inputP = m_inputBuffer.data(); |
123 double* outputP = m_outputBuffer.data(); | 124 double* outputP = m_outputBuffer.data(); |
124 | 125 |
125 // Set up filter state. This is needed in case we're switching from | 126 // Set up filter state. This is needed in case we're switching from |
126 // filtering with variable coefficients (i.e., with automations) to | 127 // filtering with variable coefficients (i.e., with automations) to |
127 // fixed coefficients (without automations). | 128 // fixed coefficients (without automations). |
128 inputP[0] = m_x2; | 129 inputP[0] = m_x2; |
129 inputP[1] = m_x1; | 130 inputP[1] = m_x1; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 } | 225 } |
225 } | 226 } |
226 | 227 |
227 void Biquad::processSliceFast(double* sourceP, | 228 void Biquad::processSliceFast(double* sourceP, |
228 double* destP, | 229 double* destP, |
229 double* coefficientsP, | 230 double* coefficientsP, |
230 size_t framesToProcess) { | 231 size_t framesToProcess) { |
231 // Use double-precision for filter stability | 232 // Use double-precision for filter stability |
232 vDSP_deq22D(sourceP, 1, coefficientsP, destP, 1, framesToProcess); | 233 vDSP_deq22D(sourceP, 1, coefficientsP, destP, 1, framesToProcess); |
233 | 234 |
234 // Save history. Note that sourceP and destP reference m_inputBuffer and m_ou tputBuffer respectively. | 235 // Save history. Note that sourceP and destP reference m_inputBuffer and |
235 // These buffers are allocated (in the constructor) with space for two extra s amples so it's OK to access | 236 // m_outputBuffer respectively. These buffers are allocated (in the |
236 // array values two beyond framesToProcess. | 237 // constructor) with space for two extra samples so it's OK to access array |
238 // values two beyond framesToProcess. | |
237 sourceP[0] = sourceP[framesToProcess - 2 + 2]; | 239 sourceP[0] = sourceP[framesToProcess - 2 + 2]; |
238 sourceP[1] = sourceP[framesToProcess - 1 + 2]; | 240 sourceP[1] = sourceP[framesToProcess - 1 + 2]; |
239 destP[0] = destP[framesToProcess - 2 + 2]; | 241 destP[0] = destP[framesToProcess - 2 + 2]; |
240 destP[1] = destP[framesToProcess - 1 + 2]; | 242 destP[1] = destP[framesToProcess - 1 + 2]; |
241 } | 243 } |
242 | 244 |
243 #endif // OS(MACOSX) | 245 #endif // OS(MACOSX) |
244 | 246 |
245 void Biquad::reset() { | 247 void Biquad::reset() { |
246 #if OS(MACOSX) | 248 #if OS(MACOSX) |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
578 std::complex<double> denominator = | 580 std::complex<double> denominator = |
579 std::complex<double>(1, 0) + (a1 + a2 * z) * z; | 581 std::complex<double>(1, 0) + (a1 + a2 * z) * z; |
580 std::complex<double> response = numerator / denominator; | 582 std::complex<double> response = numerator / denominator; |
581 magResponse[k] = static_cast<float>(abs(response)); | 583 magResponse[k] = static_cast<float>(abs(response)); |
582 phaseResponse[k] = | 584 phaseResponse[k] = |
583 static_cast<float>(atan2(imag(response), real(response))); | 585 static_cast<float>(atan2(imag(response), real(response))); |
584 } | 586 } |
585 } | 587 } |
586 | 588 |
587 } // namespace blink | 589 } // namespace blink |
OLD | NEW |