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