| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 | 67 |
| 68 reset(); // clear filter memory | 68 reset(); // clear filter memory |
| 69 } | 69 } |
| 70 | 70 |
| 71 Biquad::~Biquad() | 71 Biquad::~Biquad() |
| 72 { | 72 { |
| 73 } | 73 } |
| 74 | 74 |
| 75 void Biquad::process(const float* sourceP, float* destP, size_t framesToProcess) | 75 void Biquad::process(const float* sourceP, float* destP, size_t framesToProcess) |
| 76 { | 76 { |
| 77 // WARNING: sourceP and destP may be pointing to the same area of memory! |
| 78 // Be sure to read from sourceP before writing to destP! |
| 77 if (hasSampleAccurateValues()) { | 79 if (hasSampleAccurateValues()) { |
| 78 int n = framesToProcess; | 80 int n = framesToProcess; |
| 79 | 81 |
| 80 // Create local copies of member variables | 82 // Create local copies of member variables |
| 81 double x1 = m_x1; | 83 double x1 = m_x1; |
| 82 double x2 = m_x2; | 84 double x2 = m_x2; |
| 83 double y1 = m_y1; | 85 double y1 = m_y1; |
| 84 double y2 = m_y2; | 86 double y2 = m_y2; |
| 85 | 87 |
| 86 const double* b0 = m_b0.data(); | 88 const double* b0 = m_b0.data(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 113 // There is an assumption here that once we have sample accurate values
we can never go back | 115 // There is an assumption here that once we have sample accurate values
we can never go back |
| 114 // to not having sample accurate values. This is currently true in the
way | 116 // to not having sample accurate values. This is currently true in the
way |
| 115 // AudioParamTimline is implemented: once an event is inserted, sample a
ccurate processing | 117 // AudioParamTimline is implemented: once an event is inserted, sample a
ccurate processing |
| 116 // is always enabled. | 118 // is always enabled. |
| 117 // | 119 // |
| 118 // If so, then we never have to update the state variables for the MACOS
X path. The | 120 // If so, then we never have to update the state variables for the MACOS
X path. The |
| 119 // structure of the state variable in these cases aren't well documented
so it's not clear | 121 // structure of the state variable in these cases aren't well documented
so it's not clear |
| 120 // how to update them anyway. | 122 // how to update them anyway. |
| 121 } else { | 123 } else { |
| 122 #if OS(MACOSX) | 124 #if OS(MACOSX) |
| 125 double* inputP = m_inputBuffer.data(); |
| 126 double* outputP = m_outputBuffer.data(); |
| 127 |
| 128 // Set up filter state. This is needed in case we're switching from |
| 129 // filtering with variable coefficients (i.e., with automations) to |
| 130 // fixed coefficients (without automations). |
| 131 inputP[0] = m_x2; |
| 132 inputP[1] = m_x1; |
| 133 outputP[0] = m_y2; |
| 134 outputP[1] = m_y1; |
| 135 |
| 123 // Use vecLib if available | 136 // Use vecLib if available |
| 124 processFast(sourceP, destP, framesToProcess); | 137 processFast(sourceP, destP, framesToProcess); |
| 125 | 138 |
| 126 // Copy the last inputs and outputs to the filter memory variables. Thi
s is needed because | 139 // Copy the last inputs and outputs to the filter memory variables. |
| 127 // the next rendering quantum might be an automation which needs the his
tory to continue | 140 // This is needed because the next rendering quantum might be an |
| 128 // correctly. | 141 // automation which needs the history to continue correctly. Because |
| 129 m_x1 = sourceP[framesToProcess - 1]; | 142 // sourceP and destP can be the same block of memory, we can't read from |
| 130 m_x2 = sourceP[framesToProcess - 2]; | 143 // sourceP to get the last inputs. Fortunately, processFast has put the |
| 144 // last inputs in input[0] and input[1]. |
| 145 m_x1 = inputP[1]; |
| 146 m_x2 = inputP[0]; |
| 131 m_y1 = destP[framesToProcess - 1]; | 147 m_y1 = destP[framesToProcess - 1]; |
| 132 m_y2 = destP[framesToProcess - 2]; | 148 m_y2 = destP[framesToProcess - 2]; |
| 133 | 149 |
| 134 #else | 150 #else |
| 135 int n = framesToProcess; | 151 int n = framesToProcess; |
| 136 | 152 |
| 137 // Create local copies of member variables | 153 // Create local copies of member variables |
| 138 double x1 = m_x1; | 154 double x1 = m_x1; |
| 139 double x2 = m_x2; | 155 double x2 = m_x2; |
| 140 double y1 = m_y1; | 156 double y1 = m_y1; |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 std::complex<double> denominator = | 623 std::complex<double> denominator = |
| 608 std::complex<double>(1, 0) + (a1 + a2 * z) * z; | 624 std::complex<double>(1, 0) + (a1 + a2 * z) * z; |
| 609 std::complex<double> response = numerator / denominator; | 625 std::complex<double> response = numerator / denominator; |
| 610 magResponse[k] = static_cast<float>(abs(response)); | 626 magResponse[k] = static_cast<float>(abs(response)); |
| 611 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons
e))); | 627 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons
e))); |
| 612 } | 628 } |
| 613 } | 629 } |
| 614 | 630 |
| 615 } // namespace blink | 631 } // namespace blink |
| 616 | 632 |
| OLD | NEW |