Handle de-zippered panning to a target value.
| 125 | |
| 126 | // Handle de-zippered panning to a target value. |
| 127 | virtual void panToTargetValue(const AudioBus * inputBus, AudioBus * outputBus, float panValue, size_t framesToProcess) |
| 128 | { |
| 129 | size_t numberOfInputChannels = inputBus->numberOfChannels(); |
| 130 | |
| 131 | bool isInputSafe = inputBus && (inputBus->numberOfChannels() == Channels::Mono || inputBus->numberOfChannels() == Channels::Stereo) && framesToProcess <= inputBus->length(); |
| 132 | |
| 133 | ASSERT(isInputSafe); |
| 134 | |
| 135 | if (!isInputSafe) |
| 136 | return; |
| 137 | |
| 138 | bool isOutputSafe = outputBus && framesToProcess <= outputBus->length(); |
| 139 | |
| 140 | ASSERT(isOutputSafe); |
| 141 | |
| 142 | if (!isOutputSafe) |
| 143 | return; |
| 144 | |
| 145 | const float * sourceL = inputBus->channel(0)->data(); |
| 146 | const float * sourceR = numberOfInputChannels > Channels::Mono ? inputBus->channel(1)->data() : sourceL; |
| 147 | |
| 148 | float * destinationL = outputBus->channelByType(Channel::Left)->mutableData(); |
| 149 | float * destinationR = outputBus->channelByType(Channel::Right)->mutableData(); |
| 150 | |
| 151 | if (!sourceL || !sourceR || !destinationL || !destinationR) |
| 152 | return; |
| 153 | |
| 154 | float targetPan = clampTo(panValue, -1.f, 1.f); |
| 155 | |
| 156 | // Don't de-zipper on first render call. |
| 157 | if (m_isFirstRender) |
| 158 | { |
| 159 | m_isFirstRender = false; |
| 160 | m_pan = targetPan; |
| 161 | } |
| 162 | |
| 163 | double gainL, gainR, panRadian; |
| 164 | const double smoothingConstant = m_smoothingConstant; |
| 165 | size_t n = framesToProcess; |
| 166 | |
| 167 | // For mono source case. |
| 168 | if (numberOfInputChannels == Channels::Mono) |
| 169 | { |
| 170 | while (n--) |
| 171 | { |
| 172 | float inputL = *sourceL++; |
| 173 | |
| 174 | m_pan += (targetPan - m_pan) * smoothingConstant; |
| 175 | |
| 176 | // Pan from left to right [-1; 1] will be normalized as [0; 1]. |
| 177 | panRadian = (m_pan * 0.5 + 0.5) * LAB_HALF_PI; |
| 178 | |
| 179 | gainL = std::cos(panRadian); |
| 180 | gainR = std::sin(panRadian); |
| 181 | |
| 182 | *destinationL++ = static_cast<float>(inputL * gainL); |
| 183 | *destinationR++ = static_cast<float>(inputL * gainR); |
| 184 | } |
no test coverage detected