| 190 | } |
| 191 | |
| 192 | void ConvolverNode::_activateNewImpulse() |
| 193 | { |
| 194 | /// @TODO Create the kernels on the main work thread, activate should simply copy |
| 195 | /// the data from the work thread. |
| 196 | auto clip = _impulseResponseClip->valueBus(); |
| 197 | size_t len = clip->length(); |
| 198 | _scale = 1; |
| 199 | if (normalize()) |
| 200 | { |
| 201 | _scale = calculateNormalizationScale(clip.get()); |
| 202 | for (int i = 0; i < clip->numberOfChannels(); ++i) |
| 203 | { |
| 204 | float * data = clip->channel(i)->mutableData(); |
| 205 | for (int j = 0; j < len; ++j) |
| 206 | data[j] *= _scale; |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | { |
| 211 | std::unique_lock<std::mutex> kernel_guard(_kernel_mutex); |
| 212 | int c = static_cast<int>(clip->numberOfChannels()); |
| 213 | for (int i = 0; i < c; ++i) |
| 214 | { |
| 215 | // create one kernel per IR channel |
| 216 | ReverbKernel kernel; |
| 217 | |
| 218 | // ft doesn't own the data; it does retain a pointer to it. |
| 219 | sp_ftbl_bind(_sp, &kernel.ft, |
| 220 | clip->channel(0)->mutableData(), clip->channel(0)->length()); |
| 221 | |
| 222 | sp_conv_create(&kernel.conv); |
| 223 | sp_conv_init(_sp, kernel.conv, kernel.ft, 8192); |
| 224 | |
| 225 | _pending_kernels.emplace_back(std::move(kernel)); |
| 226 | } |
| 227 | _swap_ready = true; |
| 228 | } |
| 229 | |
| 230 | start(0); |
| 231 | } |
| 232 | |
| 233 | std::shared_ptr<AudioBus> ConvolverNode::getImpulse() const |
| 234 | { |
no test coverage detected