CMLSDelay.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. ==============================================================================
  3. CMLSDelay.cpp
  4. Created: 3 May 2025 5:39:35pm
  5. Author: Luigi
  6. ==============================================================================
  7. */
  8. #include "CMLSDelay.h"
  9. CMLSDelay::CMLSDelay() {
  10. delayLengthRange = new juce::NormalisableRange<float>(0, MAX_DELAY_LENGTH);
  11. feedbackRange = new juce::NormalisableRange<float>(MIN_FEEDBACK, MAX_FEEDBACK);
  12. this->delayLength = 0.0f;
  13. this->feedback = 0.0f;
  14. this->amount = 0.0f;
  15. this->dryWetProp = 0.0f;
  16. }
  17. CMLSDelay::~CMLSDelay() {}
  18. void CMLSDelay::reset() {
  19. }
  20. void CMLSDelay::prepare(const juce::dsp::ProcessSpec& spec) {
  21. this->effectDelaySamples = spec.sampleRate * MAX_DELAY_LENGTH;
  22. this->delayLine.setMaximumDelayInSamples(this->effectDelaySamples);
  23. this->linearDelay.setMaximumDelayInSamples(this->effectDelaySamples);
  24. this->delayLine.prepare(spec);
  25. this->linearDelay.prepare(spec);
  26. this->mixer.prepare(spec);
  27. for (auto& volume : this->delayFeedbackVolume) {
  28. volume.reset(spec.sampleRate, 0.05f);
  29. }
  30. this->mixer.reset();
  31. this->mixer.setMixingRule(juce::dsp::DryWetMixingRule::linear);
  32. std::fill(this->delayValue.begin(), this->delayValue.end(), 0.0f);
  33. std::fill(this->lastDelayOutput.begin(), this->lastDelayOutput.end(), 0.0f);
  34. }
  35. void CMLSDelay::process(const juce::dsp::ProcessContextReplacing<float>& context) {
  36. auto audioBlock = context.getOutputBlock();
  37. auto numChannels = audioBlock.getNumChannels();
  38. const auto numSamples = audioBlock.getNumSamples();
  39. const auto& input = context.getInputBlock();
  40. const auto& output = context.getOutputBlock();
  41. this->mixer.pushDrySamples(input);
  42. for (size_t channel = 0; channel < numChannels; ++channel) {
  43. auto* samplesIn = input.getChannelPointer(channel);
  44. auto* samplesOut = output.getChannelPointer(channel);
  45. for (size_t sample = 0; sample < input.getNumSamples(); ++sample) {
  46. auto input = samplesIn[sample] - this->lastDelayOutput[channel];
  47. auto delayAmount = this->delayValue[channel];
  48. this->linearDelay.pushSample(channel, input);
  49. this->linearDelay.setDelay(delayAmount);
  50. samplesOut[sample] = this->linearDelay.popSample(channel);
  51. this->lastDelayOutput[channel] = samplesOut[sample] * this->delayFeedbackVolume[channel].getNextValue();
  52. }
  53. }
  54. this->mixer.mixWetSamples(output);
  55. }
  56. void CMLSDelay::setDryWet(float value) {
  57. this->dryWetProp = value;
  58. this->mixer.setWetMixProportion(this->dryWetProp);
  59. }
  60. void CMLSDelay::setAmount(float value) {
  61. this->delayLength = this->delayLengthRange->convertFrom0to1(value);
  62. this->feedback = this->feedbackRange->convertFrom0to1(value);
  63. std::fill(this->delayValue.begin(), this->delayValue.end(), this->delayLength * this->effectDelaySamples);
  64. for (auto& volume : this->delayFeedbackVolume) {
  65. volume.setTargetValue(this->feedback);
  66. }
  67. }
  68. const float CMLSDelay::getDryWet() {
  69. return this->dryWetProp;
  70. }
  71. const float CMLSDelay::getAmount() {
  72. return this->amount;
  73. }