
3 minute read
JUCE PLUGIN
parallel_wet = 1 - series_wet; hard_gain = 10;
%SERIES DISTORTIONS
Advertisement
%bit reduction bit_depth = 2; bit_out = bitCrusher(x, bit_depth);
%full-wave rectification series_out = fullWaveRectification(bit_out);
%PARALLEL DISTORTIONS parallel_out = clipper(hard_gain * x, "hard", 0.2, 0.2, 1);
%OUTPUT y = level * (series_wet * series_out + parallel_wet * parallel_out);
The variables in the code that have to be changed manually in the MATLAB script are made user controllable via a JUCE plugin GUI in C++, these include:-
§ level § series_wet/parallel _ wet § hard_gain § bit_depth § alpha § upperClipLevel § lowerClipLevel § type
For a more detailed explanation of the transition made from hard coded values to user controllable parameters see below.
JUCE PLUGIN
User controllable parameters and the distortion values they modify:-
Clipping Button à clipButton (Allows the user to switch between soft arctangent clipping and hard clipping)
The button itself is implemented as type juce::TextButton. The virtual function void
buttonClicked(juce::Button *button) of the inherited juce::Button::Listener class is overridden with a condition that checks whether the pointer passed into the function holds the address of the clipButton text button. If this condition is met another if statement checks whether the current value of the scoped enumeration clipState is currently equal to hard or soft.
if (button == &clipButton) {
if (clipState == ClipState::hard) { { clipButton.onClick = [this]() { soft(); }; }else if (clipState == ClipState::soft) { } clipButton.onClick = [this]() { hard(); };
For each of the conditions a lambda function is assigned to the juce::Button class callback object onClick resulting in the lambda function being called when the button is clicked. In both cases the lambdacapturesareference of the currentobjectusing the C++ keyword this.If clipstate = hard the body of the lambda function, clipButton.onClick calls the soft() method which sets the clipstate = soft, sets the value of bool mVal = 1 and changes the text and colour of the button to indicate that the user is in ‘soft clipping’ mode. Conversely, if the clipState = soft, the body of the lambda function clipButton.onClick calls the hard() method and sets the clipState = hard, the value of mVal = 0 and changes the colour and text to indicate ‘hard clipping’ mode.
The following sliders are broadly implemented in the same way, by way of inheriting the juce::Slider::Listener class and overriding the virtual function void sliderValueChanged (juce::Slider* slider). The body of the function is populated with a ladder of if statements that determine which slider has been changed, access the variable associated with the slider and set it equal to slider.getValue(). In the PluginEditor.cpp the sliders are styled, given labels and positioned.
Output Gain à mLevel (Gives the user control over the output gain level with a range 0.0– 1.0, a step size of 0.01 (to give a continuous feel) and an initial value of 0.5 (corresponding to -6dB).
Bit Depth Rotary Slider à mBits (Allows the user to select a bit depth with a range of 2.0− 8.0, a step size of 1.0 (to give a stepped feel) and an initial value of 0.5)
float bitCrush{0.0}; //temp value for bit reduction current sample float ampValues = pow(2.0f, (mBits - 1.0f)); bitCrush = ceil(ampValues * ip) * (1.0f/ampValues);
Wet/Wet Mix à mWetWet (Dictates the contribution of series and parallel to the overall output. Range of 0.0 − 1.0 , a step size of 0.01 and an initial value of 0.5. Whereby, 0.0 is all parallel, 1.0 is all series and 0.5is equal contribution from series and parallel.)
channelDataL[n] = mLevel * (mWetWet * fullWaveRect + (1 - mWetWet) * parallel); Upper Clip Level à mUpperClipLevel (Allows the user to select an upper clip level. Range of 0.2− 0.8, step size 0.1, initial value 0.5.)
Lower Clip Level à mLowerClipLevel (Allows the user to select a lower clip level. Range of 0.2− 0.8, step size 0.1, initial value 0.5. This value is then made negative in the hard clipping algorithm in the ProcessBlock())
if (mHardGain > mUpperClipLevel) {
parallel = mUpperClipLevel; }else if (mHardGain <= -mLowerClipLevel) {
parallel = -mLowerClipLevel; }else {
parallel = mHardGain;
Hard Clipping Gain à mHardGainValue (Specifies the pre amplification going into the hard clipping distortion algorithm by multiplying the signal values by a scalar. Range of 1.0− 6.0, step size 1.0, initial value 1.0 (which represents no pre amplification) the user can then add amplification as desired.)