Skip to content

Commit

Permalink
Initial commit (working app)
Browse files Browse the repository at this point in the history
  • Loading branch information
0x07dc committed Oct 29, 2021
0 parents commit b0c0a88
Show file tree
Hide file tree
Showing 13 changed files with 1,368 additions and 0 deletions.
424 changes: 424 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions Declicker/Declicker.jucer
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="dUyrcg" name="Declicker" projectType="audioplug" useAppConfig="0"
addUsingNamespaceToJuceHeader="0" displaySplashScreen="1" jucerFormatVersion="1"
companyName="Paradigm E" cppLanguageStandard="17">
<MAINGROUP id="Dr2ioZ" name="Declicker">
<GROUP id="{3651B683-C007-EBE3-E10E-C182976BF3BA}" name="Source">
<GROUP id="{C09DCE5D-2472-FFE2-DA81-377CBC449FF4}" name="Filter">
<FILE id="RsjI9T" name="Filters.cpp" compile="1" resource="0" file="Source/Filters.cpp"/>
<FILE id="bAflhF" name="Filters.h" compile="0" resource="0" file="Source/Filters.h"/>
</GROUP>
<FILE id="X2rSPw" name="CustomParameter.cpp" compile="1" resource="0"
file="Source/CustomParameter.cpp"/>
<FILE id="eK1yWZ" name="CustomParameter.h" compile="0" resource="0"
file="Source/CustomParameter.h"/>
<FILE id="hS1xkz" name="PluginProcessor.cpp" compile="1" resource="0"
file="Source/PluginProcessor.cpp"/>
<FILE id="xCCioC" name="PluginProcessor.h" compile="0" resource="0"
file="Source/PluginProcessor.h"/>
<FILE id="hFOumK" name="PluginEditor.cpp" compile="1" resource="0"
file="Source/PluginEditor.cpp"/>
<FILE id="FMQfsg" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
</GROUP>
</MAINGROUP>
<JUCEOPTIONS JUCE_STRICT_REFCOUNTEDPOINTER="1" JUCE_VST3_CAN_REPLACE_VST2="0"/>
<EXPORTFORMATS>
<VS2019 targetFolder="Builds/VisualStudio2019">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug" targetName="Declicker"/>
<CONFIGURATION isDebug="0" name="Release" targetName="Declicker"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_devices" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_formats" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_processors" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_utils" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_core" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_data_structures" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_events" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_graphics" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_gui_basics" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_gui_extra" path="../../../../../Program Files/JUCE/JUCE/modules"/>
</MODULEPATHS>
</VS2019>
<XCODE_MAC targetFolder="Builds/MacOSX">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug" targetName="Declicker"/>
<CONFIGURATION isDebug="0" name="Release" targetName="Declicker"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_devices" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_formats" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_processors" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_audio_utils" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_core" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_data_structures" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_events" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_graphics" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_gui_basics" path="../../../../../Program Files/JUCE/JUCE/modules"/>
<MODULEPATH id="juce_gui_extra" path="../../../../../Program Files/JUCE/JUCE/modules"/>
</MODULEPATHS>
</XCODE_MAC>
</EXPORTFORMATS>
<MODULES>
<MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="0"
useGlobalPath="1"/>
<MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
</MODULES>
<LIVE_SETTINGS>
<WINDOWS/>
</LIVE_SETTINGS>
</JUCERPROJECT>
55 changes: 55 additions & 0 deletions Declicker/Source/CustomParameter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "CustomParameter.h"

using namespace juce;

//CustomParameter::CustomParameter(NormalisableRange<double> normalisableRange, float newDefaultValue)
// : range(normalisableRange), defaultValue(newDefaultValue), value(newDefaultValue)
//{
//}

float CustomParameter::getValue() const
{
return value;
}

void CustomParameter::setValue(float newValue)
{
value = newValue;
}

void CustomParameter::setValue(float newValue, ValueTree& state)
{
state.setProperty(getName(999), newValue, nullptr);
setValue(newValue);
}

void CustomParameter::setValueNotifyingHost(float newValue, ValueTree& state)
{
state.setProperty(getName(999), newValue, nullptr);
this->AudioProcessorParameter::setValueNotifyingHost(newValue);
}

float CustomParameter::getDefaultValue() const
{
return defaultValue;
}

String CustomParameter::getName(int maximumStringLength) const
{
return name.substring(0, maximumStringLength - 1);
}

void CustomParameter::setName(String name)
{
this->name = name;
}

String CustomParameter::getLabel() const
{
return String();
}

float CustomParameter::getValueForText(const String& text) const
{
return 0.0f;
}
25 changes: 25 additions & 0 deletions Declicker/Source/CustomParameter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <JuceHeader.h>

using namespace std;
using namespace juce;

class CustomParameter : public AudioProcessorParameter {
public:

// Inherited via AudioProcessorParameter
float getValue() const;
void setValue(float newValue);
void setValue(float newValue, ValueTree& state);
void setValueNotifyingHost(float newValue, ValueTree& state);
float getDefaultValue() const;
String getName(int maximumStringLength) const;
void setName(String name);
String getLabel() const;
float getValueForText(const String& text) const;
private:
float value = 0;
float defaultValue = 0;
String name;
};
119 changes: 119 additions & 0 deletions Declicker/Source/Filters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
==============================================================================
Filters.cpp
Created: 28 Oct 2021 6:00:45pm
Author: vossj
==============================================================================
*/

#include "Filters.h"

void FilterBase::setSampleRateCallback()
{
}

void FilterBase::setSampleRate(double newSampleRate)
{
lock_guard<mutex> l(filterMutex);
sampleRate = newSampleRate;
timeAdjustmentFactor = getReferenceSampleRate() / sampleRate;
setSampleRateCallback();
}

void SmootheningFilter::setRatio(const double& newRatio)
{
lock_guard<mutex> l(filterMutex);
filterRatio = newRatio;
}

float SmootheningFilter::getNextSample(const float& currentSample)
{
lock_guard<mutex> l(filterMutex);
float lastDelta = currentSample - lastSample * FilterBase::timeAdjustmentFactor;
float newDelta = filterRatio * lastDelta;
float result = lastSample + newDelta;
result = clamp<float>(result, -1, 1);
lastSample = result;
return result;
}

double SmootheningFilter::getReferenceSampleRate()
{
return referenceSampleRate;
}

void MaxDeltaFilter::setMaxDelta(const double& newMaxDelta)
{
lock_guard<mutex> l(filterMutex);
maxDelta = newMaxDelta;
}

float MaxDeltaFilter::getNextSample(const float& currentSample)
{
lock_guard<mutex> l(filterMutex);
float lastDelta = currentSample - lastSample * FilterBase::timeAdjustmentFactor;
float lastDeltaAbs = fabs(lastDelta);
float newDelta = lastDeltaAbs <= maxDelta
? lastDelta
: maxDelta * (lastDelta/lastDeltaAbs);
float result = lastSample + newDelta;
result = clamp<float>(result, -1, 1);
lastSample = result;
return result;
}

double MaxDeltaFilter::getReferenceSampleRate()
{
return referenceSampleRate;
}

void Max2ndDeltaFilter::setMax2ndDelta(const double& newMax2ndDelta)
{
lock_guard<mutex> l(filterMutex);
_max2ndDelta = newMax2ndDelta;
}

float Max2ndDeltaFilter::getNextSample(const float& currentSample)
{
lock_guard<mutex> l(filterMutex);
double currentSampleD = (double)currentSample;
double lastDelta = currentSampleD - _lastSample * FilterBase::timeAdjustmentFactor;
double last2ndDelta = lastDelta - _lastDelta;
double last2ndDeltaAbs = fabs(last2ndDelta);
double new2ndDelta = last2ndDeltaAbs <= _max2ndDelta
? last2ndDelta
: _max2ndDelta * (last2ndDelta / last2ndDeltaAbs);
double newDelta = _lastDelta + new2ndDelta;
double result = _lastSample + newDelta;
result = clamp<float>(result, -1, 1);

_lastDelta = lastDelta;
_lastSample = result;
return result;
}

double Max2ndDeltaFilter::getReferenceSampleRate()
{
return referenceSampleRate;
}

Filters::Filters()
{
setSampleRate(sampleRate, true);
}

void Filters::setSampleRate(const double& newSampleRate, const bool& force)
{
lock_guard<mutex> l(filterMutex);
if (force || sampleRate != newSampleRate) {
sampleRate = newSampleRate;
smootheningFilter->setSampleRate(newSampleRate);
maxDeltaFilter->setSampleRate(newSampleRate);
max2ndDeltaFilter->setSampleRate(newSampleRate);

}
}


90 changes: 90 additions & 0 deletions Declicker/Source/Filters.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
==============================================================================
Filters.h
Created: 28 Oct 2021 6:00:45pm
Author: vossj
==============================================================================
*/

#pragma once
#include <math.h>
#include <memory>
#include <mutex>
#include <algorithm>
using namespace std;

class FilterBase {
protected:
mutex filterMutex;
double sampleRate = 48000;
double timeAdjustmentFactor = 1;
virtual float getNextSample(const float& currentSample) = 0;
virtual double getReferenceSampleRate() = 0;
/// <summary>
/// Runs after the sampleRate parameter has been set
/// </summary>
virtual void setSampleRateCallback();

public:
void setSampleRate(double sampleRate);
};

class SmootheningFilter : public FilterBase {
const double referenceSampleRate = 48000;
double filterRatio = 0.5;
float lastSample = 0;
public:
/// <summary>
/// Sets the filter's divisor (the difference between last sample and new sample, times newRatio, added to last sample)
/// </summary>
/// <param name="newRatio"></param>
void setRatio(const double& newRatio);

// Imported from FilterBase
float getNextSample(const float& currentSample) override;
double getReferenceSampleRate() override;
};

class MaxDeltaFilter : public FilterBase {
const double referenceSampleRate = 48000;
double timeAdjustmentFactor = 1;
double maxDelta = 0.2;
float lastSample = 0;
public:
void setMaxDelta(const double& newMaxDelta);

// Imported from FilterBase
float getNextSample(const float& currentSample) override;
double getReferenceSampleRate() override;
};

class Max2ndDeltaFilter : public FilterBase {
const double referenceSampleRate = 48000;
double timeAdjustmentFactor = 1;
double _max2ndDelta = 1;
double _lastDelta = 0;
float _lastSample = 0;
public:
void setMax2ndDelta(const double& newMax2ndDelta);

// Imported from FilterBase
float getNextSample(const float& currentSample) override;
double getReferenceSampleRate() override;

};

class Filters {
mutex filterMutex;
double sampleRate = 48000.0;
public:
unique_ptr<SmootheningFilter> smootheningFilter = make_unique<SmootheningFilter>();
unique_ptr<MaxDeltaFilter> maxDeltaFilter = make_unique<MaxDeltaFilter>();
unique_ptr<Max2ndDeltaFilter> max2ndDeltaFilter = make_unique<Max2ndDeltaFilter>();

Filters();

void setSampleRate(const double& newSampleRate, const bool& force = false);

};
Loading

0 comments on commit b0c0a88

Please sign in to comment.