CMLSChorus.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. ==============================================================================
  3. CMLSChorus.cpp
  4. Created: 1 May 2025 11:04:18pm
  5. Author: Luigi
  6. ==============================================================================
  7. */
  8. #include "CMLSChorus.h"
  9. CMLSChorus::CMLSChorus() {
  10. freqRange = new juce::NormalisableRange<float>(LFO_MIN_FREQ, LFO_MAX_FREQ);
  11. depthRange = new juce::NormalisableRange<float>(LFO_MIN_DEPTH, LFO_MAX_DEPTH);
  12. }
  13. CMLSChorus::~CMLSChorus() {}
  14. void CMLSChorus::reset() {
  15. delayLine1.reset();
  16. delayLine2.reset();
  17. dryWetMixer.reset();
  18. }
  19. void CMLSChorus::prepare(const juce::dsp::ProcessSpec& spec) {
  20. delayLine1.prepare(spec);
  21. delayLine2.prepare(spec);
  22. delayLine1.setMix(1.0f);
  23. delayLine2.setMix(1.0f);
  24. delayLine1.setCentreDelay(DELAY_CENTER);
  25. delayLine2.setCentreDelay(DELAY_CENTER);
  26. delayLine1.setRate(LFO_MIN_FREQ);
  27. delayLine1.setRate(LFO_MIN_FREQ + LFO_FREQ_DELTA);
  28. delayLine1.setDepth(LFO_MIN_DEPTH);
  29. delayLine2.setDepth(LFO_MIN_FREQ);
  30. dryWetMixer.prepare(spec);
  31. dryWetMixer.setMixingRule(juce::dsp::DryWetMixingRule::linear);
  32. }
  33. void CMLSChorus::process(const juce::dsp::ProcessContextReplacing<float>& context) {
  34. auto audioBlock = context.getOutputBlock();
  35. auto numChannels = audioBlock.getNumChannels();
  36. const auto numSamples = audioBlock.getNumSamples();
  37. // Initialize audio buffers
  38. juce::AudioBuffer<float> firstStageWetBuffer(numChannels, numSamples);
  39. juce::dsp::AudioBlock<float> firstStageWetBlock(firstStageWetBuffer);
  40. juce::AudioBuffer<float> secondStageWetBuffer(numChannels, numSamples);
  41. juce::dsp::AudioBlock<float> secondStageWetBlock(secondStageWetBuffer);
  42. // Calculate wet signal
  43. delayLine1.process(
  44. juce::dsp::ProcessContextNonReplacing<float>(audioBlock, firstStageWetBlock)
  45. );
  46. delayLine2.process(
  47. juce::dsp::ProcessContextNonReplacing<float>(audioBlock, secondStageWetBlock)
  48. );
  49. secondStageWetBlock += firstStageWetBlock;
  50. // Apply the dry/wet mix
  51. dryWetMixer.pushDrySamples(audioBlock);
  52. dryWetMixer.mixWetSamples(secondStageWetBlock);
  53. for (int channel = 0; channel < numChannels; ++channel) {
  54. for (int sample = 0; sample < numSamples; ++sample) {
  55. audioBlock.setSample(channel, sample, secondStageWetBlock.getSample(channel, sample));
  56. }
  57. }
  58. }
  59. void CMLSChorus::setDryWet(float value) {
  60. dryWetMixer.setWetMixProportion(value);
  61. }
  62. void CMLSChorus::setAmount(float value) {
  63. float freq = freqRange->convertFrom0to1(value);
  64. float depth = depthRange->convertFrom0to1(value);
  65. delayLine1.setRate(freq);
  66. delayLine2.setRate(freq + LFO_FREQ_DELTA); //+ LFO_FREQ_DELTA
  67. delayLine1.setDepth(depth);
  68. delayLine2.setDepth(depth);
  69. }
  70. const float CMLSChorus::getDryWet() {
  71. return this->dryWetProp;
  72. }
  73. const float CMLSChorus::getAmount() {
  74. return this->amount;
  75. }