Skip to content

Commit

Permalink
Add dry wet knob just for the heck of it
Browse files Browse the repository at this point in the history
  • Loading branch information
dchan3 committed Jul 23, 2019
1 parent ca5d201 commit e08e9d3
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 98 deletions.
5 changes: 3 additions & 2 deletions Krush3x.jucer
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT name="Krush3x" projectType="audioplug" jucerVersion="5.3.1" version="0.1.0"
<JUCERPROJECT name="Krush3x" projectType="audioplug" jucerVersion="5.4.3" version="0.2.0"
companyName="sunquan8094" companyEmail="[email protected]"
bundleIdentifier="com.sunquan8094.Krush3x" companyWebsite="https://github.com/sunquan8094"
pluginManufacturerCode="SQen" pluginManufacturer="sunquan8094"
pluginName="Krush3x" buildVST3="1" buildAUv3="1" buildVST="1"
buildRTAS="0" buildAAX="0" pluginDesc="Experimental bitcrusher plugin"
buildAU="1" pluginAUMainType="'aufx'" pluginFormats="buildVST,buildVST3,buildAU,buildAUv3"
pluginVST3Category="Distortion" buildStandalone="0" enableIAA="0">
pluginVST3Category="Distortion" buildStandalone="0" enableIAA="0"
id="iycgZg">
<MAINGROUP id="neIaro" name="Krush3x">
<GROUP id="{B18682F7-B182-CE07-D0E4-A1C224AB1DE0}" name="Source">
<FILE id="i1Iiys" name="PluginProcessor.cpp" compile="1" resource="0"
Expand Down
16 changes: 11 additions & 5 deletions Source/PluginEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Krush3xAudioProcessorEditor::Krush3xAudioProcessorEditor (Krush3xAudioProcessor&
{
// Make sure that before the constructor has finished, you've set the
// editor's size to whatever you need it to be.
setSize (400, 300);
setSize (500, 300);

bitDepthAttachment.reset(new juce::AudioProcessorValueTreeState::SliderAttachment(valueTreeState, "bitDepth", bitDepthController));
bitDepthController.setTextValueSuffix( "Bits");
Expand All @@ -33,7 +33,12 @@ Krush3xAudioProcessorEditor::Krush3xAudioProcessorEditor (Krush3xAudioProcessor&
addAndMakeVisible(freqReductionController);
addAndMakeVisible(freqReductionLabel);

freqReductionLabel.attachToComponent(&freqReductionController, true);
dryWetAttachment.reset(new juce::AudioProcessorValueTreeState::SliderAttachment(valueTreeState, "dryWet", dryWetController));
dryWetController.setTextValueSuffix("x Wet");
dryWetLabel.setText("Dry Wet Mix", dontSendNotification);
dryWetLabel.attachToComponent(&dryWetController, true);
addAndMakeVisible(dryWetController);
addAndMakeVisible(dryWetLabel);
}

Krush3xAudioProcessorEditor::~Krush3xAudioProcessorEditor()
Expand All @@ -44,7 +49,7 @@ Krush3xAudioProcessorEditor::~Krush3xAudioProcessorEditor()
void Krush3xAudioProcessorEditor::paint (Graphics& g)
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (Colours::white);
g.fillAll (Colours::blue);
g.setColour(Colours::black);
g.setFont(18.0f);
}
Expand All @@ -54,6 +59,7 @@ void Krush3xAudioProcessorEditor::resized()
// This is generally where you'll want to lay out the positions of any
// subcomponents in your editor..

bitDepthController.setBounds(50, 50, 300, 75);
freqReductionController.setBounds(50, 100, 300, 75);
bitDepthController.setBounds(50, 50, 400, 75);
freqReductionController.setBounds(50, 100, 400, 75);
dryWetController.setBounds(50, 150, 400, 75);
}
20 changes: 4 additions & 16 deletions Source/PluginEditor.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
/*
==============================================================================
This file was auto-generated!
It contains the basic framework code for a JUCE plugin editor.
==============================================================================
*/

#pragma once

#include "../JuceLibraryCode/JuceHeader.h"
#include "PluginProcessor.h"

//==============================================================================
/**
*/
class Krush3xAudioProcessorEditor : public AudioProcessorEditor
{
public:
Expand All @@ -27,9 +14,6 @@ class Krush3xAudioProcessorEditor : public AudioProcessorEditor
void resized() override;

private:

// This reference is provided as a quick way for your editor to
// access the processor object that created it.
Krush3xAudioProcessor& processor;

AudioProcessorValueTreeState& valueTreeState;
Expand All @@ -41,6 +25,10 @@ class Krush3xAudioProcessorEditor : public AudioProcessorEditor
Slider freqReductionController;
Label freqReductionLabel;
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> freqReductionAttachment;

Slider dryWetController;
Label dryWetLabel;
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> dryWetAttachment;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Krush3xAudioProcessorEditor)
};
103 changes: 33 additions & 70 deletions Source/PluginProcessor.cpp
Original file line number Diff line number Diff line change
@@ -1,39 +1,17 @@
/*
==============================================================================
This file was auto-generated!
It contains the basic framework code for a JUCE plugin processor.
==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"
#include <cmath>

//==============================================================================
Krush3xAudioProcessor::Krush3xAudioProcessor()
#ifndef JucePlugin_PreferredChannelConfigurations
: AudioProcessor (BusesProperties()
#if ! JucePlugin_IsMidiEffect
#if ! JucePlugin_IsSynth
.withInput ("Input", AudioChannelSet::stereo(), true)
#endif
.withOutput ("Output", AudioChannelSet::stereo(), true)
#endif
), parameters(*this, nullptr)
#endif
.withInput ("Input", AudioChannelSet::stereo())
.withOutput ("Output", AudioChannelSet::stereo())), parameters(new AudioProcessorValueTreeState(*this, nullptr, "PARAMETERS", {
std::make_unique<AudioParameterInt>("bitDepth", "Bit Depth", 2, 24, 24),
std::make_unique<AudioParameterFloat>("freqReduction", "Frequency Reduction", NormalisableRange<float>(0.1f, 1.0f, 0.1f), 1.0f),
std::make_unique<AudioParameterFloat>("dryWet", "Dry Wet Mix", NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f)
}))
{
phase = 0.0f;
lastValue = 0.5f;
parameters.createAndAddParameter("bitDepth", "Bit Depth", String(), NormalisableRange<float>(2.0f, 24.0f, 1.0f), 24.0f, nullptr, nullptr);
parameters.createAndAddParameter("freqReduction", "Frequency Reduction", String(), NormalisableRange<float>(0.1f, 1.0f, 0.1f), 1, nullptr, nullptr);
parameters.state = ValueTree(Identifier("Krush3x"));


bitDepthParam = parameters.getRawParameterValue("bitDepth");
freqReductionParam = parameters.getRawParameterValue("freqReduction");
}

Krush3xAudioProcessor::~Krush3xAudioProcessor()
Expand Down Expand Up @@ -80,8 +58,7 @@ double Krush3xAudioProcessor::getTailLengthSeconds() const

int Krush3xAudioProcessor::getNumPrograms()
{
return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,
// so this should be at least 1, even if you're not really implementing programs.
return 1;
}

int Krush3xAudioProcessor::getCurrentProgram()
Expand All @@ -105,14 +82,12 @@ void Krush3xAudioProcessor::changeProgramName (int index, const String& newName)
//==============================================================================
void Krush3xAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
// Use this method as the place to do any pre-playback
// initialisation that you need..

}

void Krush3xAudioProcessor::releaseResources()
{
// When playback stops, you can use this as an opportunity to free up any
// spare memory, etc.

}

#ifndef JucePlugin_PreferredChannelConfigurations
Expand All @@ -122,13 +97,10 @@ bool Krush3xAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts)
ignoreUnused (layouts);
return true;
#else
// This is the place where you check if the layout is supported.
// In this template code we only support mono or stereo.
if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
&& layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
return false;

// This checks if the input layout matches the output layout
#if ! JucePlugin_IsSynth
if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
return false;
Expand All @@ -145,69 +117,60 @@ void Krush3xAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
auto totalNumInputChannels = getTotalNumInputChannels();
auto totalNumOutputChannels = getTotalNumOutputChannels();

// In case we have more outputs than inputs, this code clears any output
// channels that didn't contain input data, (because these aren't
// guaranteed to be empty - they may contain garbage).
// This is here to avoid people getting screaming feedback
// when they first compile a plugin, but obviously you don't need to keep
// this code if your algorithm always overwrites all the output channels.
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
buffer.clear (i, 0, buffer.getNumSamples());

// This is the place where you'd normally do the guts of your plugin's
// audio processing...
// Make sure to reset the state if your inner loop is processing
// the samples and the outer loop is handling the channels.
// Alternatively, you can process the samples with the channels
// interleaved by keeping the same state.

for (int channel = 0; channel < totalNumInputChannels; ++channel) {
float sum = 0, avg = 0;
float* channelData = buffer.getWritePointer (channel);
float* channelData = buffer.getWritePointer (channel), bitDepthValue = (float)*parameters->getRawParameterValue(StringRef("bitDepth")), dryWetVal = (float)*parameters->getRawParameterValue(StringRef("dryWet"));
for (int i = 0; i < buffer.getNumSamples(); i++) {
float twoPowerLessOne = exp2(*bitDepthParam) - 1.0f, rawNum = floor(channelData[i] * twoPowerLessOne);
phase += (*freqReductionParam);
float twoPower = exp2(bitDepthValue) - 1.0f,
rawNum = floor(channelData[i] * twoPower) / twoPower,
wetSig = rawNum * dryWetVal, drySig = channelData[i] * (1.0f - dryWetVal);
phase += (float)*parameters->getRawParameterValue(StringRef("freqReduction"));
if (phase >= 1.0f) {
phase -= 1.0f;
lastValue = (float)(rawNum / twoPowerLessOne);
}
channelData[i] = lastValue;
sum += lastValue;
}
avg = sum / buffer.getNumSamples();
for (int i = 0; i < buffer.getNumSamples(); i++) {
channelData[i] -= avg;
channelData[i] = wetSig + drySig;
}
}
}

//==============================================================================
bool Krush3xAudioProcessor::hasEditor() const
{
return true; // (change this to false if you choose to not supply an editor)
return true;
}

AudioProcessorEditor* Krush3xAudioProcessor::createEditor()
{
return new Krush3xAudioProcessorEditor (*this, parameters);
return new Krush3xAudioProcessorEditor (*this, *parameters);
}

//==============================================================================
void Krush3xAudioProcessor::getStateInformation (MemoryBlock& destData)
{
// You should use this method to store your parameters in the memory block.
// You could do that either as raw data, or use the XML or ValueTree classes
// as intermediaries to make it easy to save and load complex data.
std::unique_ptr<XmlElement> xml (new XmlElement ("Krush3x"));
xml->setAttribute ("bitDepth", (int)*(parameters->getRawParameterValue(StringRef("bitDepth"))));
xml->setAttribute ("freqReduction", (double) *(parameters->getRawParameterValue(StringRef("freqReduction"))));
xml->setAttribute ("dryWet", (double) *(parameters->getRawParameterValue(StringRef("dryWet"))));
copyXmlToBinary (*xml, destData);
}

void Krush3xAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
// You should use this method to restore your parameters from this memory block,
// whose contents will have been created by the getStateInformation() call.
std::unique_ptr<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
if (xmlState.get() != nullptr)
{
if (xmlState->hasTagName ("Krush3x"))
{
Value bitDepth = parameters->getParameterAsValue("bitDepth"), freqReduction = parameters->getParameterAsValue("freqReduction"), dryWet = parameters->getParameterAsValue("dryWet");
bitDepth = (int) xmlState->getIntAttribute ("bitDepth", 24);
freqReduction = (float) xmlState->getDoubleAttribute ("freqReduction", 1.0);
dryWet = (float) xmlState->getDoubleAttribute ("dryWet", 0.5f);
}
}
}

//==============================================================================
// This creates new instances of the plugin..
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
return new Krush3xAudioProcessor();
Expand Down
7 changes: 2 additions & 5 deletions Source/PluginProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ class Krush3xAudioProcessor : public AudioProcessor
private:
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Krush3xAudioProcessor)
AudioProcessorValueTreeState parameters;

float* bitDepthParam = nullptr;
float* freqReductionParam = nullptr;
float phase, lastValue;
AudioProcessorValueTreeState* parameters;
float phase;
};

0 comments on commit e08e9d3

Please sign in to comment.