y@0: /* y@0: ============================================================================== y@0: y@0: This file was auto-generated! y@0: y@0: It contains the basic startup code for a Juce application. y@0: y@0: ============================================================================== y@0: */ y@0: y@0: #include "PluginProcessor.h" y@0: #include "PluginEditor.h" y@0: #include "filter.h" y@0: y@0: y@0: //============================================================================== y@0: BassPedalRackProcessor::BassPedalRackProcessor() y@0: { y@0: // Set default values: y@0: y@0: gain_ = 1.0; //Orignal volume set to one y@0: index_ = 1.0; //Index is one by default y@0: mix_ = 0.5; //as much low than high y@0: gain1_ = 1.0; //fundamental =1 y@0: gain2_ = 0.0; //no other distortion y@0: gain3_ = 0.0; y@0: gain4_ = 0.0; y@0: gain5_ = 0.0; y@0: gain6_ = 0.0; y@0: gain7_ = 0.0; y@0: gain8_ = 0.0; y@0: gain9_ = 0.0; y@0: y@0: //neutral tone stack (even is it is not strictly an allpass filter) y@0: trebleGain_ = 0.5; y@0: bassGain_ = 0.5; y@0: midGain_ = 0.5; y@0: //filterLength y@0: filterLength_ = 151; y@0: y@0: toneStack_ = true; y@0: shaper_ = false; y@0: y@0: //circular buffers initialisation y@0: currInd_ =0; y@0: for (int i = 0; i < 3; i++) y@0: { y@0: memIn_[i] = 0; y@0: memOut_[i] = 0; y@0: } y@0: y@0: for (int i = 0; i < 6; i++) y@0: { y@0: tonStackIn_[i] = 0; y@0: tonStackIn_[i] = 0; y@0: } y@0: y@0: y@0: for (int i = 0; i < 2*filterLength_; i++) y@0: inputMem_[i] = 0; y@0: y@0: y@0: //Distortion coefficients initialisation y@0: RC_ = 6.25*pow((double)10,-6); y@0: RC2_ = RC_*RC_; y@0: RC3_ = RC2_*RC_; y@0: y@0: //allpass filter y@0: highCut_ = 0; y@0: lowCut_ = 0; y@0: y@0: lastUIWidth_ = 550; y@0: lastUIHeight_ = 350; y@0: y@0: //initialise distortion y@0: coeffs_[9] = 256*gain9_; y@0: coeffs_[8] = 128*gain8_; y@0: coeffs_[7] = -576*gain9_ + 64*gain7_; y@0: coeffs_[6] = -256*gain8_ + 32*gain6_; y@0: coeffs_[5] = 432*gain9_ -112*gain7_ + 16*gain5_; y@0: coeffs_[4] = 160*gain8_ -48*gain6_ + 8*gain4_; y@0: coeffs_[3] = -120*gain9_ + 56*gain7_ -20*gain5_ + 4*gain3_; y@0: coeffs_[2] = -32*gain8_ + 18*gain6_ -8*gain4_ + 2*gain2_; y@0: coeffs_[1] = 9*gain9_ -7*gain7_ + 5*gain5_ -3*gain3_ + gain1_; y@0: coeffs_[0] = gain8_ - gain6_ + gain4_ - gain2_; y@0: } y@0: y@0: BassPedalRackProcessor::~BassPedalRackProcessor() y@0: { y@0: } y@0: y@0: //============================================================================== y@0: const String BassPedalRackProcessor::getName() const y@0: { y@0: return JucePlugin_Name; y@0: } y@0: y@0: int BassPedalRackProcessor::getNumParameters() y@0: { y@0: return kNumParameters; y@0: } y@0: y@0: float BassPedalRackProcessor::getParameter (int index) y@0: { y@0: // This method will be called by the host, probably on the audio thread, so y@0: // it's absolutely time-critical. Don't use critical sections or anything y@0: // UI-related, or anything at all that may block in any way! y@0: switch (index) y@0: { y@0: case kMixParam: return mix_; y@0: case kHighCutParam: return (float)highCut_; y@0: case kIndexParam: return index_; y@0: case kGainParam: return gain_; y@0: case kLowCutParam: return (float)lowCut_; y@0: case kGainLowParam: return bassGain_; y@0: case kGainMidParam: return midGain_; y@0: case kGainTreParam: return trebleGain_; y@0: case kGain1Param: return gain1_; y@0: case kGain2Param: return gain2_; y@0: case kGain3Param: return gain3_; y@0: case kGain4Param: return gain4_; y@0: case kGain5Param: return gain5_; y@0: case kGain6Param: return gain6_; y@0: case kGain7Param: return gain7_; y@0: case kGain8Param: return gain8_; y@0: case kGain9Param: return gain9_; y@0: default: return 0.0f; y@0: } y@0: } y@0: y@0: void BassPedalRackProcessor::setParameter (int index, float newValue) y@0: { y@0: // This method will be called by the host, probably on the audio thread, so y@0: // it's absolutely time-critical. Don't use critical sections or anything y@0: // UI-related, or anything at all that may block in any way! y@0: switch (index) y@0: { y@0: case kMixParam: y@0: mix_ = newValue; y@0: break; y@0: case kHighCutParam: y@0: highCut_ = (int)newValue; y@0: break; y@0: case kIndexParam: y@0: index_ = newValue; y@0: break; y@0: case kGainParam: y@0: gain_ = newValue; y@0: break; y@0: case kLowCutParam: y@0: lowCut_ = (int)newValue; y@0: break; y@0: case kGainTreParam: y@0: trebleGain_ = newValue; y@0: changeToneStack(); y@0: break; y@0: case kGainLowParam: y@0: bassGain_ = newValue; y@0: changeToneStack(); y@0: break; y@0: case kGainMidParam: y@0: midGain_ = newValue; y@0: changeToneStack(); y@0: break; y@0: case kGain1Param: y@0: gain1_ = newValue; y@0: changeCoefficients(kGain1Param); y@0: break; y@0: case kGain2Param: y@0: gain2_ = newValue; y@0: changeCoefficients(kGain2Param); y@0: break; y@0: case kGain3Param: y@0: gain3_ = newValue; y@0: changeCoefficients(kGain3Param); y@0: break; y@0: case kGain4Param: y@0: gain4_ = newValue; y@0: changeCoefficients(kGain4Param); y@0: break; y@0: case kGain5Param: y@0: gain5_ = newValue; y@0: changeCoefficients(kGain5Param); y@0: break; y@0: case kGain6Param: y@0: gain6_ = newValue; y@0: changeCoefficients(kGain6Param); y@0: break; y@0: case kGain7Param: y@0: gain7_ = newValue; y@0: changeCoefficients(kGain7Param); y@0: break; y@0: case kGain8Param: y@0: gain8_ = newValue; y@0: changeCoefficients(kGain8Param); y@0: break; y@0: case kGain9Param: y@0: gain9_ = newValue; y@0: changeCoefficients(kGain9Param); y@0: break; y@0: default: y@0: break; y@0: } y@0: } y@0: y@0: const String BassPedalRackProcessor::getParameterName (int index) y@0: { y@0: switch (index) y@0: { y@0: case kMixParam: return "mix"; y@0: case kLowCutParam: return "lowcut"; y@0: case kIndexParam: return "index"; y@0: case kGainParam: return "gain"; y@0: case kHighCutParam: return "highcut"; y@0: case kGainLowParam: return "low"; y@0: case kGainMidParam: return "mid"; y@0: case kGainTreParam: return "treble"; y@0: case kGain1Param: return "gain1"; y@0: case kGain2Param: return "gain2"; y@0: case kGain3Param: return "gain3"; y@0: case kGain4Param: return "gain4"; y@0: case kGain5Param: return "gain5"; y@0: case kGain6Param: return "gain6"; y@0: case kGain7Param: return "gain7"; y@0: case kGain8Param: return "gain8"; y@0: case kGain9Param: return "gain9"; y@0: default: break; y@0: } y@0: y@0: return String::empty; y@0: } y@0: y@0: const String BassPedalRackProcessor::getParameterText (int index) y@0: { y@0: return String (getParameter (index), 2); y@0: } y@0: y@0: const String BassPedalRackProcessor::getInputChannelName (int channelIndex) const y@0: { y@0: return String (channelIndex + 1); y@0: } y@0: y@0: const String BassPedalRackProcessor::getOutputChannelName (int channelIndex) const y@0: { y@0: return String (channelIndex + 1); y@0: } y@0: y@0: bool BassPedalRackProcessor::isInputChannelStereoPair (int index) const y@0: { y@0: return true; y@0: } y@0: y@0: bool BassPedalRackProcessor::isOutputChannelStereoPair (int index) const y@0: { y@0: return true; y@0: } y@0: y@0: bool BassPedalRackProcessor::silenceInProducesSilenceOut() const y@0: { y@0: #if JucePlugin_SilenceInProducesSilenceOut y@0: return true; y@0: #else y@0: return false; y@0: #endif y@0: } y@0: y@0: bool BassPedalRackProcessor::acceptsMidi() const y@0: { y@0: #if JucePlugin_WantsMidiInput y@0: return true; y@0: #else y@0: return false; y@0: #endif y@0: } y@0: y@0: bool BassPedalRackProcessor::producesMidi() const y@0: { y@0: #if JucePlugin_ProducesMidiOutput y@0: return true; y@0: #else y@0: return false; y@0: #endif y@0: } y@0: y@0: double BassPedalRackProcessor::getTailLengthSeconds() const y@0: { y@0: return 0; y@0: } y@0: y@0: int BassPedalRackProcessor::getNumPrograms() y@0: { y@0: return 0; y@0: } y@0: y@0: int BassPedalRackProcessor::getCurrentProgram() y@0: { y@0: return 0; y@0: } y@0: y@0: void BassPedalRackProcessor::setCurrentProgram (int index) y@0: { y@0: } y@0: y@0: const String BassPedalRackProcessor::getProgramName (int index) y@0: { y@0: return String::empty; y@0: } y@0: y@0: void BassPedalRackProcessor::changeProgramName (int index, const String& newName) y@0: { y@0: } y@0: y@0: //============================================================================== y@0: void BassPedalRackProcessor::prepareToPlay (double sampleRate, int samplesPerBlock) y@0: { y@0: //initialise sampling frequency y@0: fsd_ = 2*sampleRate; y@0: fsd2_ = fsd_*fsd_; y@0: fsd3_ = fsd2_*fsd_; y@0: y@0: //initilise tone control y@0: a0_ = 1; y@0: changeToneStack(); y@0: } y@0: y@0: void BassPedalRackProcessor::releaseResources() y@0: { y@0: y@0: } y@0: y@0: void BassPedalRackProcessor::changeToneStack() y@0: { y@0: if (trebleGain_ + midGain_ + bassGain_ < 0.01 ) y@0: toneStack_ = false; y@0: else y@0: { y@0: toneStack_ = true; y@0: //Transfer function update y@0: b1_ = (10*trebleGain_+80*midGain_+3240*bassGain_+81)*RC_; y@0: b2_ = 16*(1120*trebleGain_-2025*midGain_*midGain_+81000*bassGain_*midGain_+2275*midGain_+14480*bassGain_+362)*RC2_*0.2; y@0: b3_ = -512*(midGain_-40*bassGain_-1)*(280*trebleGain_+153*midGain_)*RC3_; y@0: a1_ = (400*midGain_+16200*bassGain_+2247)*RC_*0.2; y@0: a2_ = -16*(2025*midGain_*midGain_-81000*bassGain_*midGain_+2205*midGain_-193680*bassGain_-5962)*RC2_*0.2; y@0: a3_ = -512*(midGain_-40*bassGain_-1)*(153*midGain_+280)*RC3_; y@0: y@0: //Filter coefficient update y@0: B0 = -b1_*fsd_ - b2_*fsd2_ - b3_*fsd3_; y@0: B1 = -b1_*fsd_ + b2_*fsd2_ + 3*b3_*fsd3_; y@0: B2 = b1_*fsd_ + b2_*fsd2_ - 3*b3_*fsd3_; y@0: B3 = b1_*fsd_ - b2_*fsd2_ + b3_*fsd3_; y@0: A0 = 1/( -a0_ - a1_*fsd_ - a2_*fsd2_ - a3_*fsd3_); y@0: A1 = -3*a0_ - a1_*fsd_ + a2_*fsd2_ + 3*a3_*fsd3_; y@0: A2 = -3*a0_ + a1_*fsd_ + a2_*fsd2_ - 3*a3_*fsd3_; y@0: A3 = -a0_ + a1_*fsd_ - a2_*fsd2_ + a3_*fsd3_; y@0: } y@0: y@0: } y@0: y@0: void BassPedalRackProcessor::changeCoefficients(int kcase) y@0: { y@0: if (abs(gain1_-1)<0.01 && (gain2_ + gain3_ + gain4_ + gain5_ + gain6_ + gain7_ + gain8_ + gain9_)<0.01) y@0: { y@0: shaper_ = false; y@0: scale_ = 1; y@0: } y@0: else y@0: { y@0: shaper_ = true; y@0: //scale by the sum of the gains time the distortion index y@0: scale_ = (gain1_ + gain2_ + gain3_ + gain4_ + gain5_ + gain6_ + gain7_ + gain8_ + gain9_)*index_; y@0: if (scale_>1) y@0: scale_ = 1/scale_; y@0: else y@0: scale_ = 1; y@0: //switch to avoid unecessary editing (even/odd and bigger indices that degree) y@0: switch(kcase) y@0: { y@0: case 0: //Update all (initialisation) y@0: coeffs_[9] = 256*gain9_; y@0: coeffs_[8] = 128*gain8_; y@0: coeffs_[7] = -576*gain9_ + 64*gain7_; y@0: coeffs_[6] = -256*gain8_ + 32*gain6_; y@0: coeffs_[5] = 432*gain9_ -112*gain7_ + 16*gain5_; y@0: coeffs_[4] = 160*gain8_ -48*gain6_ + 8*gain4_; y@0: coeffs_[3] = -120*gain9_ + 56*gain7_ -20*gain5_ + 4*gain3_; y@0: coeffs_[2] = -32*gain8_ + 18*gain6_ -8*gain4_ + 2*gain2_; y@0: coeffs_[1] = 9*gain9_ -7*gain7_ + 5*gain5_ -3*gain3_ + gain1_; y@0: coeffs_[0] = gain8_ - gain6_ + gain4_ - gain2_; y@0: break; y@0: case kGain1Param: y@0: coeffs_[1] = 9*gain9_ -7*gain7_ + 5*gain5_ -3*gain3_ + gain1_; y@0: break; y@0: case kGain2Param: y@0: coeffs_[2] = -32*gain8_ + 18*gain6_ -8*gain4_ + 2*gain2_; y@0: coeffs_[0] = gain8_ - gain6_ + gain4_ - gain2_; y@0: break; y@0: case kGain3Param: y@0: coeffs_[3] = -120*gain9_ + 56*gain7_ -20*gain5_ + 4*gain3_; y@0: coeffs_[1] = 9*gain9_ -7*gain7_ + 5*gain5_ -3*gain3_ + gain1_; y@0: break; y@0: case kGain4Param: y@0: coeffs_[4] = 160*gain8_ -48*gain6_ + 8*gain4_; y@0: coeffs_[2] = -32*gain8_ + 18*gain6_ -8*gain4_ + 2*gain2_; y@0: coeffs_[0] = gain8_ - gain6_ + gain4_ - gain2_; y@0: break; y@0: case kGain5Param: y@0: coeffs_[5] = 432*gain9_ -112*gain7_ + 16*gain5_; y@0: coeffs_[3] = -120*gain9_ + 56*gain7_ -20*gain5_ + 4*gain3_; y@0: coeffs_[1] = 9*gain9_ -7*gain7_ + 5*gain5_ -3*gain3_ + gain1_; y@0: break; y@0: case kGain6Param: y@0: coeffs_[6] = -256*gain8_ + 32*gain6_; y@0: coeffs_[4] = 160*gain8_ -48*gain6_ + 8*gain4_; y@0: coeffs_[2] = -32*gain8_ + 18*gain6_ -8*gain4_ + 2*gain2_; y@0: coeffs_[0] = gain8_ - gain6_ + gain4_ - gain2_; y@0: break; y@0: case kGain7Param: y@0: coeffs_[7] = -576*gain9_ + 64*gain7_; y@0: coeffs_[5] = 432*gain9_ -112*gain7_ + 16*gain5_; y@0: coeffs_[3] = -120*gain9_ + 56*gain7_ -20*gain5_ + 4*gain3_; y@0: coeffs_[1] = 9*gain9_ -7*gain7_ + 5*gain5_ -3*gain3_ + gain1_; y@0: break; y@0: case kGain8Param: y@0: coeffs_[8] = 128*gain8_; y@0: coeffs_[6] = -256*gain8_ + 32*gain6_; y@0: coeffs_[4] = 160*gain8_ -48*gain6_ + 8*gain4_; y@0: coeffs_[2] = -32*gain8_ + 18*gain6_ -8*gain4_ + 2*gain2_; y@0: coeffs_[0] = gain8_ - gain6_ + gain4_ - gain2_; y@0: break; y@0: case kGain9Param: y@0: coeffs_[9] = 256*gain9_; y@0: coeffs_[7] = -576*gain9_ + 64*gain7_; y@0: coeffs_[5] = 432*gain9_ -112*gain7_ + 16*gain5_; y@0: coeffs_[3] = -120*gain9_ + 56*gain7_ -20*gain5_ + 4*gain3_; y@0: coeffs_[1] = 9*gain9_ -7*gain7_ + 5*gain5_ -3*gain3_ + gain1_; y@0: break; y@0: } y@0: } y@0: } y@0: y@0: double* BassPedalRackProcessor::applyFilter(float input) y@0: { y@0: double final[2]; //output y@0: final[0] = 0; y@0: final[1] = 0; y@0: double output = 0; // temp output y@0: lastIn_[filterInd_] = (double)input; //update the circular buffer with the new index y@0: int firstMax = filterLength_ - filterInd_; //when indice reaches the end of the circular buffer y@0: switch(highCut_) y@0: { //switch for the index of the HIgh Pass filter y@0: case 0: y@0: output = input; //allpass y@0: break; y@0: case 1: y@0: for (int i = 0; i< firstMax; i++) //until the end of the circular buffer y@0: output += lastIn_[i+filterInd_]*filter_high_1[i]; y@0: for (int i = firstMax; i< filterLength_; i++) //from the beginning of the circular buffer y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_1[i]; y@0: break; y@0: case 2: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_2[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_2[i]; y@0: break; y@0: case 3: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_3[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_3[i]; y@0: break; y@0: case 4: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_4[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_4[i]; y@0: break; y@0: case 5: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_5[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_5[i]; y@0: break; y@0: case 6: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_6[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_6[i]; y@0: break; y@0: case 7: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_7[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_7[i]; y@0: break; y@0: case 8: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_8[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_8[i]; y@0: break; y@0: y@0: case 9: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_high_9[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_high_9[i]; y@0: break; y@0: default: y@0: break; y@0: } y@0: final[0] = output; //store the output y@0: output = 0; //new output y@0: switch(lowCut_) y@0: { //switch over the Low pass Filter y@0: case 0: y@0: output = input; y@0: break; y@0: case 1: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_1[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_1[i]; y@0: break; y@0: case 2: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_2[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_2[i]; y@0: break; y@0: case 3: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_3[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_3[i]; y@0: break; y@0: case 4: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_4[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_4[i]; y@0: break; y@0: case 5: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_5[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_5[i]; y@0: break; y@0: case 6: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_6[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_6[i]; y@0: break; y@0: case 7: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_7[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_7[i]; y@0: break; y@0: case 8: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_8[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_8[i]; y@0: break; y@0: case 9: y@0: for (int i = 0; i< firstMax; i++) y@0: output += lastIn_[i+filterInd_]*filter_low_9[i]; y@0: for (int i = firstMax; i< filterLength_; i++) y@0: output += lastIn_[i+filterInd_-filterLength_]*filter_low_9[i]; y@0: break; y@0: default: y@0: break; y@0: } y@0: final[1] = output; //update output y@0: if (filterInd_==0) //update circular buffer indice (with modulo) y@0: filterInd_=filterLength_-1; y@0: else y@0: filterInd_--; y@0: return final; y@0: } y@0: y@0: float BassPedalRackProcessor::shaper(float x) y@0: { y@0: double output; y@0: if(shaper_) y@0: { y@0: double dx = (double)x * index_; //distorted input y@0: //efficient polynomial computation y@0: output = coeffs_[9]; y@0: for (int ind = 8; ind > -1; ind--) y@0: { y@0: output = output*dx + coeffs_[ind]; y@0: } y@0: output *=scale_; y@0: } y@0: else y@0: output = (double)x; y@0: y@0: return (float)output; y@0: } y@0: y@0: void BassPedalRackProcessor::saveMem(int channel) y@0: { y@0: //Store the information of this channel y@0: y@0: //divided for the cirular buffer in config indice = 0; y@0: int firstMax = filterLength_ - filterInd_; y@0: for (int i=0; i < firstMax; i++) y@0: { y@0: //offset of the size of the buffer to have both buffer stored in inputMem; y@0: inputMem_[channel*filterLength_ + i] = lastIn_[filterInd_ +i]; y@0: } y@0: for (int i=firstMax; i < filterLength_; i++) y@0: { y@0: inputMem_[channel*filterLength_ + i] = lastIn_[filterInd_ + i - filterLength_]; y@0: } y@0: y@0: //Switch for the little (3) circular buffers in configuration index = 2 y@0: switch(currInd_) y@0: { y@0: case 0: y@0: tonStackIn_[channel*3] = memIn_[1]; y@0: tonStackIn_[channel*3+1] = memIn_[2]; y@0: tonStackIn_[channel*3+2] = memIn_[0]; y@0: tonStackOut_[channel*3] = memOut_[1]; y@0: tonStackOut_[channel*3+1] = memOut_[2]; y@0: tonStackOut_[channel*3+2] = memOut_[0]; y@0: break; y@0: case 1: y@0: tonStackOut_[channel*3] = memOut_[2]; y@0: tonStackOut_[channel*3+1] = memOut_[0]; y@0: tonStackOut_[channel*3+2] = memOut_[1]; y@0: y@0: tonStackIn_[channel*3] = memIn_[2]; y@0: tonStackIn_[channel*3+1] = memIn_[0]; y@0: tonStackIn_[channel*3+2] = memIn_[1]; y@0: break; y@0: case 2: y@0: tonStackOut_[channel*3] = memOut_[0]; y@0: tonStackOut_[channel*3+1] = memOut_[1]; y@0: tonStackOut_[channel*3+2] = memOut_[2]; y@0: y@0: tonStackIn_[channel*3] = memIn_[0]; y@0: tonStackIn_[channel*3+1] = memIn_[1]; y@0: tonStackIn_[channel*3+2] = memIn_[2]; y@0: break; y@0: default: y@0: break; y@0: } y@0: } y@0: y@0: void BassPedalRackProcessor::loadMem(int channel) y@0: { y@0: //Relaod the information af the new channel y@0: //Circular buffer for high and low pass filter y@0: for (int i=0; i < filterLength_; i++) y@0: { y@0: lastIn_[i] = inputMem_[channel*filterLength_+i]; y@0: } y@0: filterInd_ = 0; y@0: y@0: //Circular buffers for Tone control y@0: memIn_[0] = tonStackIn_[channel*3]; y@0: memIn_[1] = tonStackIn_[channel*3+1]; y@0: memIn_[2] = tonStackIn_[channel*3+2]; y@0: memOut_[0] = tonStackOut_[channel*3]; y@0: memOut_[1] = tonStackOut_[channel*3+1]; y@0: memOut_[2] = tonStackOut_[channel*3+2]; y@0: currInd_ = 2; y@0: } y@0: y@0: float BassPedalRackProcessor::applyToneStack(float input) y@0: { y@0: double di = (double)input; y@0: double output = di; y@0: switch(currInd_) y@0: { y@0: y@0: case 0: y@0: if (toneStack_) y@0: output = A0*(di*B0 + memIn_[1]*B1 + memIn_[2]*B2 + memIn_[0]*B3 -( memOut_[1]*A1 + memOut_[2]*A2 + memOut_[0]*A3)); y@0: memOut_[currInd_] = output; y@0: memIn_[currInd_] = di; y@0: currInd_ = 2; y@0: break; y@0: case 1: y@0: if (toneStack_) y@0: output = A0*(di*B0 + memIn_[2]*B1 + memIn_[0]*B2 + memIn_[1]*B3 -( memOut_[2]*A1 + memOut_[0]*A2 + memOut_[1]*A3)); y@0: memOut_[currInd_] = output; y@0: memIn_[currInd_] = di; y@0: currInd_ = 0; y@0: break; y@0: case 2: y@0: if (toneStack_) y@0: output = A0*(di*B0 + memIn_[0]*B1 + memIn_[1]*B2 + memIn_[2]*B3 -( memOut_[0]*A1 + memOut_[1]*A2 + memOut_[2]*A3)); y@0: memOut_[currInd_] = output; y@0: memIn_[currInd_] = di; y@0: currInd_ = 1; y@0: break; y@0: default: y@0: break; y@0: } y@0: y@0: return (float)output; y@0: } y@0: y@0: y@0: void BassPedalRackProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) y@0: { y@0: // Helpful information about this block of samples: y@0: const int numInputChannels = getNumInputChannels(); // How many input channels for our effect? y@0: const int numOutputChannels = getNumOutputChannels(); // How many output channels for our effect? y@0: const int numSamples = buffer.getNumSamples(); // How many samples in the buffer for this block? y@0: // Go through each channel of audio that's passed in y@0: double* filtered; //output of the high/low pass filter y@0: float mixed; //mix of both y@0: for (int channel = 0; channel < numInputChannels; ++channel) y@0: { y@0: // channelData is an array of length numSamples which contains the audio for one channel y@0: float* channelData = buffer.getSampleData(channel); y@0: loadMem(channel); //load the buffers for this channel y@0: for (int i = 0; i < numSamples; ++i) y@0: { y@0: const float in = channelData[i]; y@0: y@0: filtered = applyFilter(in); //Apply Low and High Pass Filter y@0: y@0: //mix the signal while adding distortion the scaled high frequencies y@0: mixed = (1-mix_)*filtered[1] + mix_*shaper(filtered[0]); y@0: y@0: //Apply the tone control and the final gain y@0: channelData[i] = applyToneStack(mixed)*gain_; y@0: y@0: y@0: } y@0: saveMem(channel); y@0: y@0: } y@0: y@0: // In case we have more outputs than inputs, we'll clear any output y@0: // channels that didn't contain input data, (because these aren't y@0: // guaranteed to be empty - they may contain garbage). y@0: for (int i = numInputChannels; i < numOutputChannels; ++i) y@0: { y@0: buffer.clear (i, 0, buffer.getNumSamples()); y@0: } y@0: } y@0: y@0: //============================================================================== y@0: bool BassPedalRackProcessor::hasEditor() const y@0: { y@0: return true; // (change this to false if you choose to not supply an editor) y@0: } y@0: y@0: AudioProcessorEditor* BassPedalRackProcessor::createEditor() y@0: { y@0: return new BassPedalRackProcessorEditor (this); y@0: } y@0: y@0: //============================================================================== y@0: void BassPedalRackProcessor::getStateInformation (MemoryBlock& destData) y@0: { y@0: // You should use this method to store your parameters in the memory block. y@0: // You could do that either as raw data, or use the XML or ValueTree classes y@0: // as intermediaries to make it easy to save and load complex data. y@0: y@0: // Create an outer XML element.. y@0: XmlElement xml("C4DMPLUGINSETTINGS"); y@0: y@0: // add some attributes to it.. y@0: xml.setAttribute("uiWidth", lastUIWidth_); y@0: xml.setAttribute("uiHeight", lastUIHeight_); y@0: xml.setAttribute("mix", mix_); y@0: xml.setAttribute("index", index_); y@0: xml.setAttribute("gain", gain_); y@0: xml.setAttribute("highcut", highCut_); y@0: xml.setAttribute("treble", trebleGain_); y@0: xml.setAttribute("lowcut", lowCut_); y@0: xml.setAttribute("mid", midGain_); y@0: xml.setAttribute("bass", bassGain_); y@0: xml.setAttribute("gain1", gain1_); y@0: xml.setAttribute("gain2", gain2_); y@0: xml.setAttribute("gain3", gain3_); y@0: xml.setAttribute("gain4", gain4_); y@0: xml.setAttribute("gain5", gain5_); y@0: xml.setAttribute("gain6", gain6_); y@0: xml.setAttribute("gain7", gain7_); y@0: xml.setAttribute("gain8", gain8_); y@0: xml.setAttribute("gain9", gain9_); y@0: y@0: y@0: // then use this helper function to stuff it into the binary blob and return it.. y@0: copyXmlToBinary(xml, destData); y@0: } y@0: y@0: void BassPedalRackProcessor::setStateInformation (const void* data, int sizeInBytes) y@0: { y@0: // You should use this method to restore your parameters from this memory block, y@0: // whose contents will have been created by the getStateInformation() call. y@0: y@0: // This getXmlFromBinary() helper function retrieves our XML from the binary blob.. y@0: ScopedPointer xmlState (getXmlFromBinary (data, sizeInBytes)); y@0: y@0: if(xmlState != 0) y@0: { y@0: // make sure that it's actually our type of XML object.. y@0: if(xmlState->hasTagName("C4DMPLUGINSETTINGS")) y@0: { y@0: // ok, now pull out our parameters.. y@0: lastUIWidth_ = xmlState->getIntAttribute("uiWidth", lastUIWidth_); y@0: lastUIHeight_ = xmlState->getIntAttribute("uiHeight", lastUIHeight_); y@0: y@0: mix_ = (float)xmlState->getDoubleAttribute("mix", mix_); y@0: index_ = (float)xmlState->getDoubleAttribute("index", index_); y@0: gain_ = (float)xmlState->getDoubleAttribute("gain", gain_); y@0: bassGain_ = (float)xmlState->getDoubleAttribute("bass", bassGain_); y@0: midGain_ = (float)xmlState->getDoubleAttribute("mid", midGain_); y@0: trebleGain_ = (float)xmlState->getDoubleAttribute("tre", trebleGain_); y@0: highCut_ = (int)xmlState->getDoubleAttribute("highcut", highCut_); y@0: lowCut_ = (int)xmlState->getDoubleAttribute("lowcut", lowCut_); y@0: gain1_ = (float)xmlState->getDoubleAttribute("gain1", gain1_); y@0: gain2_ = (float)xmlState->getDoubleAttribute("gain2", gain2_); y@0: gain3_ = (float)xmlState->getDoubleAttribute("gain3", gain3_); y@0: gain4_ = (float)xmlState->getDoubleAttribute("gain4", gain4_); y@0: gain5_ = (float)xmlState->getDoubleAttribute("gain5", gain5_); y@0: gain6_ = (float)xmlState->getDoubleAttribute("gain6", gain6_); y@0: gain7_ = (float)xmlState->getDoubleAttribute("gain7", gain7_); y@0: gain8_ = (float)xmlState->getDoubleAttribute("gain8", gain8_); y@0: gain9_ = (float)xmlState->getDoubleAttribute("gain9", gain9_); y@0: } y@0: } y@0: } y@0: y@0: //============================================================================== y@0: // This creates new instances of the plugin.. y@0: AudioProcessor* JUCE_CALLTYPE createPluginFilter() y@0: { y@0: return new BassPedalRackProcessor(); y@0: }