ChewProcessor.cpp (4432B)
1 #include "ChewProcessor.h" 2 3 ChewProcessor::ChewProcessor (AudioProcessorValueTreeState& vts) 4 { 5 using namespace chowdsp::ParamUtils; 6 loadParameterPointer (depth, vts, "chew_depth"); 7 loadParameterPointer (freq, vts, "chew_freq"); 8 loadParameterPointer (var, vts, "chew_var"); 9 onOff = vts.getRawParameterValue ("chew_onoff"); 10 } 11 12 void ChewProcessor::createParameterLayout (chowdsp::Parameters& params) 13 { 14 using namespace chowdsp::ParamUtils; 15 emplace_param<chowdsp::BoolParameter> (params, "chew_onoff", "Chew On/Off", false); 16 emplace_param<chowdsp::FloatParameter> (params, "chew_depth", "Chew Depth", NormalisableRange { 0.0f, 1.0f }, 0.0f, &floatValToString, &stringToFloatVal); 17 emplace_param<chowdsp::FloatParameter> (params, "chew_freq", "Chew Freq", NormalisableRange { 0.0f, 1.0f }, 0.0f, &floatValToString, &stringToFloatVal); 18 emplace_param<chowdsp::FloatParameter> (params, "chew_var", "Chew Variance", NormalisableRange { 0.0f, 1.0f }, 0.0f, &floatValToString, &stringToFloatVal); 19 } 20 21 void ChewProcessor::prepare (double sr, int samplesPerBlock, int numChannels) 22 { 23 sampleRate = (float) sr; 24 25 dropout.prepare (sr, numChannels); 26 27 filt.resize ((size_t) numChannels); 28 for (auto& filter : filt) 29 filter.reset (sampleRate, int (sr * 0.02)); 30 31 isCrinkled = false; 32 samplesUntilChange = getDryTime(); 33 sampleCounter = 0; 34 35 bypass.prepare (samplesPerBlock, numChannels, bypass.toBool (onOff)); 36 } 37 38 void ChewProcessor::processBlock (AudioBuffer<float>& buffer) 39 { 40 if (! bypass.processBlockIn (buffer, bypass.toBool (onOff))) 41 return; 42 43 const int shortBlockSize = 64; 44 if (buffer.getNumSamples() <= shortBlockSize) 45 { 46 processShortBlock (buffer); 47 } 48 else 49 { 50 int sampleIdx = 0; 51 for (; sampleIdx + shortBlockSize <= buffer.getNumSamples(); sampleIdx += shortBlockSize) 52 { 53 AudioBuffer<float> shortBuff (buffer.getArrayOfWritePointers(), 54 buffer.getNumChannels(), 55 sampleIdx, 56 shortBlockSize); 57 58 processShortBlock (shortBuff); 59 } 60 61 if (sampleIdx < buffer.getNumSamples()) 62 { 63 AudioBuffer<float> shortBuff (buffer.getArrayOfWritePointers(), 64 buffer.getNumChannels(), 65 sampleIdx, 66 buffer.getNumSamples() - sampleIdx); 67 68 processShortBlock (shortBuff); 69 } 70 } 71 72 bypass.processBlockOut (buffer, bypass.toBool (onOff)); 73 } 74 75 void ChewProcessor::processShortBlock (AudioBuffer<float>& buffer) 76 { 77 const float highFreq = jmin (22000.0f, 0.49f * sampleRate); 78 const float freqChange = highFreq - 5000.0f; 79 80 if (*freq == 0.0f) 81 { 82 mix = 0.0f; 83 for (auto& filter : filt) 84 filter.setFreq (highFreq); 85 } 86 else if (*freq == 1.0f) 87 { 88 mix = 1.0f; 89 power = 3.0f * *depth; 90 const auto filterFreq = highFreq - freqChange * *depth; 91 for (auto& filter : filt) 92 filter.setFreq (filterFreq); 93 } 94 else if (sampleCounter >= samplesUntilChange) 95 { 96 sampleCounter = 0; 97 isCrinkled = ! isCrinkled; 98 99 if (isCrinkled) // start crinkle 100 { 101 mix = 1.0f; 102 power = (1.0f + 2.0f * random.nextFloat()) * *depth; 103 const auto filterFreq = highFreq - freqChange * *depth; 104 for (auto& filter : filt) 105 filter.setFreq (filterFreq); 106 107 samplesUntilChange = getWetTime(); 108 } 109 else // end crinkle 110 { 111 mix = 0.0f; 112 for (auto& filter : filt) 113 filter.setFreq (highFreq); 114 samplesUntilChange = getDryTime(); 115 } 116 } 117 else 118 { 119 power = (1.0f + 2.0f * random.nextFloat()) * *depth; 120 if (isCrinkled) 121 { 122 const auto filterFreq = highFreq - freqChange * *depth; 123 for (auto& filter : filt) 124 filter.setFreq (filterFreq); 125 } 126 } 127 128 dropout.setMix (mix); 129 dropout.setPower (1.0f + power); 130 131 dropout.process (buffer); 132 for (int ch = 0; ch < buffer.getNumChannels(); ++ch) 133 filt[ch].process (buffer.getWritePointer (ch), buffer.getNumSamples()); 134 135 sampleCounter += buffer.getNumSamples(); 136 }