|
26 | 26 | #include "extra/ScopedPointer.hpp" |
27 | 27 | #include "extra/Thread.hpp" |
28 | 28 |
|
29 | | -#include "FFTConvolver/TwoStageFFTConvolver.h" |
30 | 29 | #include "dr_flac.h" |
31 | 30 | #include "dr_wav.h" |
| 31 | +// -Wunused-variable |
| 32 | +#include "r8brain/CDSPResampler.h" |
| 33 | +#include "FFTConvolver/TwoStageFFTConvolver.h" |
32 | 34 |
|
33 | 35 | START_NAMESPACE_DISTRHO |
34 | 36 |
|
@@ -317,9 +319,20 @@ class OneKnobConvolutionReverbPlugin : public OneKnobPlugin |
317 | 319 | unsigned int channels; |
318 | 320 | unsigned int sampleRate; |
319 | 321 | drwav_uint64 numFrames; |
| 322 | + const size_t valuelen = std::strlen(value); |
| 323 | + |
| 324 | + ScopedPointer<TwoStageThreadedConvolver> newConvolverL, newConvolverR; |
| 325 | + |
| 326 | + if (valuelen <= 5) |
| 327 | + { |
| 328 | + const MutexLocker cml(mutex); |
| 329 | + convolverL.swapWith(newConvolverL); |
| 330 | + convolverR.swapWith(newConvolverR); |
| 331 | + return; |
| 332 | + } |
320 | 333 |
|
321 | 334 | float* ir; |
322 | | - if (::strncasecmp(value + (std::max(size_t(0), std::strlen(value) - 5u)), ".flac", 5) == 0) |
| 335 | + if (::strncasecmp(value + (std::max(size_t(0), valuelen - 5u)), ".flac", 5) == 0) |
323 | 336 | ir = drflac_open_file_and_read_pcm_frames_f32(value, &channels, &sampleRate, &numFrames, nullptr); |
324 | 337 | else |
325 | 338 | ir = drwav_open_file_and_read_pcm_frames_f32(value, &channels, &sampleRate, &numFrames, nullptr); |
@@ -363,7 +376,29 @@ class OneKnobConvolutionReverbPlugin : public OneKnobPlugin |
363 | 376 | break; |
364 | 377 | } |
365 | 378 |
|
366 | | - ScopedPointer<TwoStageThreadedConvolver> newConvolverL, newConvolverR; |
| 379 | + if (sampleRate != getSampleRate()) |
| 380 | + { |
| 381 | + r8b::CDSPResampler16IR resampler(sampleRate, getSampleRate(), numFrames); |
| 382 | + const int numResampledFrames = resampler.getMaxOutLen(0); |
| 383 | + DISTRHO_SAFE_ASSERT_RETURN(numResampledFrames > 0,); |
| 384 | + |
| 385 | + // left channel, always present |
| 386 | + float* const irBufResampledL = new float[numResampledFrames]; |
| 387 | + resampler.oneshot(irBufL, numFrames, irBufResampledL, numResampledFrames); |
| 388 | + delete[] irBufL; |
| 389 | + irBufL = irBufResampledL; |
| 390 | + |
| 391 | + // right channel, optional |
| 392 | + if (irBufL != irBufR) |
| 393 | + { |
| 394 | + float* const irBufResampledR = new float[numResampledFrames]; |
| 395 | + resampler.oneshot(irBufR, numFrames, irBufResampledR, numResampledFrames); |
| 396 | + delete[] irBufR; |
| 397 | + irBufR = irBufResampledR; |
| 398 | + } |
| 399 | + |
| 400 | + numFrames = numResampledFrames; |
| 401 | + } |
367 | 402 |
|
368 | 403 | newConvolverL = new TwoStageThreadedConvolver(); |
369 | 404 | newConvolverL->init(headBlockSize, tailBlockSize, irBufL, numFrames); |
|
0 commit comments