diff --git a/modules/juce_dsp/frequency/juce_Convolution.cpp b/modules/juce_dsp/frequency/juce_Convolution.cpp index e09dc73df9..140557c8a0 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.cpp +++ b/modules/juce_dsp/frequency/juce_Convolution.cpp @@ -57,9 +57,10 @@ struct ConvolutionEngine AudioBuffer* buffer; double sampleRate = 0; - bool wantsStereo; - bool wantsTrimming; - size_t impulseResponseSize; + bool wantsStereo = true; + bool wantsTrimming = true; + bool wantsNormalization = true; + size_t impulseResponseSize = 0; size_t maximumBufferSize = 0; }; @@ -85,7 +86,7 @@ struct ConvolutionEngine FFTSize = blockSize > 128 ? 2 * blockSize : 4 * blockSize; - numSegments = ((size_t) info.buffer->getNumSamples()) / (FFTSize - blockSize) + 1; + numSegments = ((size_t) info.buffer->getNumSamples()) / (FFTSize - blockSize) + 1u; numInputSegments = (blockSize > 128 ? numSegments : 3 * numSegments); @@ -341,6 +342,7 @@ public: changeImpulseResponseSize, changeStereo, changeTrimming, + changeNormalization, numChangeRequestTypes }; @@ -599,12 +601,23 @@ public: bool newWantsTrimming = requestParameters[n]; if (currentInfo.wantsTrimming != newWantsTrimming) - changeLevel = jmax(1, changeLevel); + changeLevel = jmax (1, changeLevel); currentInfo.wantsTrimming = newWantsTrimming; } break; + case ChangeRequest::changeNormalization: + { + bool newWantsNormalization = requestParameters[n]; + + if (currentInfo.wantsNormalization != newWantsNormalization) + changeLevel = jmax (1, changeLevel); + + currentInfo.wantsNormalization = newWantsNormalization; + } + break; + default: jassertfalse; break; @@ -767,15 +780,19 @@ private: if (isThreadRunning() && threadShouldExit()) return; - if (currentInfo.wantsStereo) + if (currentInfo.wantsNormalization) { - normalizeImpulseResponse (currentInfo.buffer->getWritePointer(0), currentInfo.buffer->getNumSamples(), 1.0); - normalizeImpulseResponse (currentInfo.buffer->getWritePointer(1), currentInfo.buffer->getNumSamples(), 1.0); - } - else - { - normalizeImpulseResponse (currentInfo.buffer->getWritePointer (0), currentInfo.buffer->getNumSamples(), 1.0); + if (currentInfo.wantsStereo) + { + normalizeImpulseResponse (currentInfo.buffer->getWritePointer(0), currentInfo.buffer->getNumSamples(), 1.0); + normalizeImpulseResponse (currentInfo.buffer->getWritePointer(1), currentInfo.buffer->getNumSamples(), 1.0); + } + else + { + normalizeImpulseResponse (currentInfo.buffer->getWritePointer (0), currentInfo.buffer->getNumSamples(), 1.0); + } } + } /** Converts the data from an audio file into a stereo audio buffer of floats, and @@ -996,7 +1013,9 @@ Convolution::~Convolution() { } -void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceDataSize, bool wantsStereo, bool wantsTrimming, size_t size) +void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceDataSize, + bool wantsStereo, bool wantsTrimming, size_t size, + bool wantsNormalization) { if (sourceData == nullptr) return; @@ -1004,7 +1023,8 @@ void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceData Pimpl::ChangeRequest types[] = { Pimpl::ChangeRequest::changeSource, Pimpl::ChangeRequest::changeImpulseResponseSize, Pimpl::ChangeRequest::changeStereo, - Pimpl::ChangeRequest::changeTrimming }; + Pimpl::ChangeRequest::changeTrimming, + Pimpl::ChangeRequest::changeNormalization }; Array sourceParameter; @@ -1014,12 +1034,14 @@ void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceData juce::var parameters[] = { juce::var (sourceParameter), juce::var (static_cast (size)), juce::var (wantsStereo), - juce::var (wantsTrimming) }; + juce::var (wantsTrimming), + juce::var (wantsNormalization) }; - pimpl->addToFifo (types, parameters, 3); + pimpl->addToFifo (types, parameters, 5); } -void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wantsStereo, bool wantsTrimming, size_t size) +void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wantsStereo, + bool wantsTrimming, size_t size, bool wantsNormalization) { if (! fileImpulseResponse.existsAsFile()) return; @@ -1027,7 +1049,8 @@ void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wan Pimpl::ChangeRequest types[] = { Pimpl::ChangeRequest::changeSource, Pimpl::ChangeRequest::changeImpulseResponseSize, Pimpl::ChangeRequest::changeStereo, - Pimpl::ChangeRequest::changeTrimming }; + Pimpl::ChangeRequest::changeTrimming, + Pimpl::ChangeRequest::changeNormalization }; Array sourceParameter; @@ -1037,13 +1060,14 @@ void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wan juce::var parameters[] = { juce::var (sourceParameter), juce::var (static_cast (size)), juce::var (wantsStereo), - juce::var (wantsTrimming) }; + juce::var (wantsTrimming), + juce::var (wantsNormalization) }; - pimpl->addToFifo (types, parameters, 3); + pimpl->addToFifo (types, parameters, 5); } void Convolution::copyAndLoadImpulseResponseFromBuffer (const AudioBuffer& buffer, - double bufferSampleRate, bool wantsStereo, bool wantsTrimming, size_t size) + double bufferSampleRate, bool wantsStereo, bool wantsTrimming, bool wantsNormalization, size_t size) { jassert (bufferSampleRate > 0); @@ -1055,7 +1079,8 @@ void Convolution::copyAndLoadImpulseResponseFromBuffer (const AudioBuffer Pimpl::ChangeRequest types[] = { Pimpl::ChangeRequest::changeSource, Pimpl::ChangeRequest::changeImpulseResponseSize, Pimpl::ChangeRequest::changeStereo, - Pimpl::ChangeRequest::changeTrimming }; + Pimpl::ChangeRequest::changeTrimming, + Pimpl::ChangeRequest::changeNormalization }; Array sourceParameter; sourceParameter.add (juce::var ((int) ConvolutionEngine::ProcessingInformation::SourceType::sourceAudioBuffer)); @@ -1064,9 +1089,10 @@ void Convolution::copyAndLoadImpulseResponseFromBuffer (const AudioBuffer juce::var parameters[] = { juce::var (sourceParameter), juce::var (static_cast (size)), juce::var (wantsStereo), - juce::var (wantsTrimming) }; + juce::var (wantsTrimming), + juce::var (wantsNormalization) }; - pimpl->addToFifo (types, parameters, 3); + pimpl->addToFifo (types, parameters, 5); } void Convolution::prepare (const ProcessSpec& spec) @@ -1091,6 +1117,8 @@ void Convolution::prepare (const ProcessSpec& spec) dryBuffer = AudioBlock (dryBufferStorage, jmin (spec.numChannels, 2u), spec.maximumBlockSize); + + isActive = true; } void Convolution::reset() noexcept @@ -1101,6 +1129,9 @@ void Convolution::reset() noexcept void Convolution::processSamples (const AudioBlock& input, AudioBlock& output, bool isBypassed) noexcept { + if (! isActive) + return; + jassert (input.getNumChannels() == output.getNumChannels()); jassert (isPositiveAndBelow (input.getNumChannels(), static_cast (3))); // only mono and stereo is supported diff --git a/modules/juce_dsp/frequency/juce_Convolution.h b/modules/juce_dsp/frequency/juce_Convolution.h index 97c6b77761..7b462dab8a 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.h +++ b/modules/juce_dsp/frequency/juce_Convolution.h @@ -93,9 +93,11 @@ public: @param wantsStereo requests to load both stereo channels or only one mono channel @param wantsTrimming requests to trim the start and the end of the impulse response @param size the expected size for the impulse response after loading + @param wantsNormalization requests to normalize the impulse response amplitude */ void loadImpulseResponse (const void* sourceData, size_t sourceDataSize, - bool wantsStereo, bool wantsTrimming, size_t size); + bool wantsStereo, bool wantsTrimming, size_t size, + bool wantsNormalization = true); /** This function loads an impulse response from an audio file on any drive. It can load any of the audio formats registered in JUCE, and performs some @@ -105,9 +107,11 @@ public: @param wantsStereo requests to load both stereo channels or only one mono channel @param wantsTrimming requests to trim the start and the end of the impulse response @param size the expected size for the impulse response after loading + @param wantsNormalization requests to normalize the impulse response amplitude */ void loadImpulseResponse (const File& fileImpulseResponse, - bool wantsStereo, bool wantsTrimming, size_t size); + bool wantsStereo, bool wantsTrimming, size_t size, + bool wantsNormalization = true); /** This function loads an impulse response from an audio buffer, which is copied before doing anything else. Performs some resampling and @@ -117,10 +121,11 @@ public: @param bufferSampleRate the sampleRate of the data in the AudioBuffer @param wantsStereo requests to load both stereo channels or only one mono channel @param wantsTrimming requests to trim the start and the end of the impulse response + @param wantsNormalization requests to normalize the impulse response amplitude @param size the expected size for the impulse response after loading */ void copyAndLoadImpulseResponseFromBuffer (const AudioBuffer& buffer, double bufferSampleRate, - bool wantsStereo, bool wantsTrimming, size_t size); + bool wantsStereo, bool wantsTrimming, bool wantsNormalization, size_t size); private: //============================================================================== @@ -133,6 +138,7 @@ private: //============================================================================== double sampleRate; bool currentIsBypassed = false; + bool isActive = false; LinearSmoothedValue volumeDry[2], volumeWet[2]; AudioBlock dryBuffer; HeapBlock dryBufferStorage;