/* ============================================================================== CMLSDelay.cpp Created: 3 May 2025 5:39:35pm Author: Luigi ============================================================================== */ #include "CMLSDelay.h" CMLSDelay::CMLSDelay() { delayLengthRange = new juce::NormalisableRange(0, MAX_DELAY_LENGTH); feedbackRange = new juce::NormalisableRange(MIN_FEEDBACK, MAX_FEEDBACK); this->delayLength = 0.0f; this->feedback = 0.0f; this->amount = 0.0f; this->dryWetProp = 0.0f; } CMLSDelay::~CMLSDelay() {} void CMLSDelay::reset() { } void CMLSDelay::prepare(const juce::dsp::ProcessSpec& spec) { this->effectDelaySamples = spec.sampleRate * MAX_DELAY_LENGTH; this->delayLine.setMaximumDelayInSamples(this->effectDelaySamples); this->linearDelay.setMaximumDelayInSamples(this->effectDelaySamples); this->delayLine.prepare(spec); this->linearDelay.prepare(spec); this->mixer.prepare(spec); for (auto& volume : this->delayFeedbackVolume) { volume.reset(spec.sampleRate, 0.05f); } this->mixer.reset(); this->mixer.setMixingRule(juce::dsp::DryWetMixingRule::linear); std::fill(this->delayValue.begin(), this->delayValue.end(), 0.0f); std::fill(this->lastDelayOutput.begin(), this->lastDelayOutput.end(), 0.0f); } void CMLSDelay::process(const juce::dsp::ProcessContextReplacing& context) { auto audioBlock = context.getOutputBlock(); auto numChannels = audioBlock.getNumChannels(); const auto numSamples = audioBlock.getNumSamples(); const auto& input = context.getInputBlock(); const auto& output = context.getOutputBlock(); this->mixer.pushDrySamples(input); for (size_t channel = 0; channel < numChannels; ++channel) { auto* samplesIn = input.getChannelPointer(channel); auto* samplesOut = output.getChannelPointer(channel); for (size_t sample = 0; sample < input.getNumSamples(); ++sample) { auto input = samplesIn[sample] - this->lastDelayOutput[channel]; auto delayAmount = this->delayValue[channel]; this->linearDelay.pushSample(channel, input); this->linearDelay.setDelay(delayAmount); samplesOut[sample] = this->linearDelay.popSample(channel); this->lastDelayOutput[channel] = samplesOut[sample] * this->delayFeedbackVolume[channel].getNextValue(); } } this->mixer.mixWetSamples(output); } void CMLSDelay::setDryWet(float value) { this->dryWetProp = value; this->mixer.setWetMixProportion(this->dryWetProp); } void CMLSDelay::setAmount(float value) { this->delayLength = this->delayLengthRange->convertFrom0to1(value); this->feedback = this->delayLengthRange->convertFrom0to1(value); std::fill(this->delayValue.begin(), this->delayValue.end(), this->delayLength * this->effectDelaySamples); for (auto& volume : this->delayFeedbackVolume) { volume.setTargetValue(this->feedback); } } const float CMLSDelay::getDryWet() { return this->dryWetProp; } const float CMLSDelay::getAmount() { return this->amount; }