Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 55ec7f7c19 | |||
| 062d1e074c | |||
| d8c1c90f15 | |||
| fe594a5494 | |||
| 3c3fec9b90 | |||
| a80c6276a8 | |||
| 821f3d7d65 |
13 changed files with 606 additions and 93 deletions
2
Makefile
2
Makefile
|
|
@ -3,7 +3,7 @@
|
||||||
# ------------------------------ #
|
# ------------------------------ #
|
||||||
|
|
||||||
# Define your plugins here as space-separated names
|
# Define your plugins here as space-separated names
|
||||||
PLUGINS = SquidgeDistortion
|
PLUGINS = SquidgeDistortion SquidgeFilter
|
||||||
|
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
146
core/Filter.cpp
146
core/Filter.cpp
|
|
@ -1,49 +1,129 @@
|
||||||
#include "Filter.hpp"
|
#include "Filter.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
Filter::Filter(float initCutOff, float initSampleRate)
|
#ifndef M_PI
|
||||||
: cutOff_(initCutOff), feedback_(0.0f), alpha_(0.0f),
|
#define M_PI 3.14159265358979323846
|
||||||
sampleRate_(initSampleRate), zL_(0.0f), zR_(0.0f) {
|
#endif
|
||||||
recompute();
|
|
||||||
};
|
|
||||||
|
|
||||||
void Filter::process(const float *in, float *out, uint32_t frames) {
|
Filter::Filter(float initCutOff, float initQ, float initSampleRate)
|
||||||
filter(in, out, frames, &zL_);
|
: modulation_(0.0f), cutOff_(initCutOff), q_(initQ),
|
||||||
};
|
sampleRate_(initSampleRate), type_(kLowPass), g_(0.0f), lpL_(0.0f),
|
||||||
void Filter::processStereo(const float *inLeft, const float *inRight,
|
bpL_(0.0f), lpR_(0.0f), bpR_(0.0f) {
|
||||||
float *outLeft, float *outRight, uint32_t frames) {
|
updateCoeffs();
|
||||||
filter(inLeft, outLeft, frames, &zL_);
|
}
|
||||||
filter(inRight, outRight, frames, &zR_);
|
|
||||||
};
|
|
||||||
|
|
||||||
void Filter::filter(const float *in, float *out, uint32_t frames, float *z) {
|
Filter::FilterType Filter::getType() const { return type_; }
|
||||||
for (uint32_t i = 0; i < frames; ++i) {
|
|
||||||
float feedbackInput = in[i] + (feedback_ * (*z));
|
float Filter::clampFreq(float freq) {
|
||||||
*z = *z + alpha_ * (feedbackInput - *z);
|
return std::fmin(std::fmax(freq, kFilterMin), kFilterMax);
|
||||||
out[i] = *z;
|
}
|
||||||
|
|
||||||
|
void Filter::updateCoeffs() {
|
||||||
|
float totalFreq = clampFreq(cutOff_ + modulation_);
|
||||||
|
|
||||||
|
float f = totalFreq / std::fmax(sampleRate_, 1.0f);
|
||||||
|
|
||||||
|
if (f > kMaxNormalizedFrequency)
|
||||||
|
f = kMaxNormalizedFrequency;
|
||||||
|
if (f < 0.0001f)
|
||||||
|
f = 0.0001f;
|
||||||
|
|
||||||
|
g_ = 2.0f * std::sin(M_PI * f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Filter::processFrame(float input, float &lp, float &bp) const {
|
||||||
|
float hp = input - (bp / q_) - lp;
|
||||||
|
|
||||||
|
bp = bp + g_ * hp;
|
||||||
|
lp = lp + g_ * bp;
|
||||||
|
|
||||||
|
switch (type_) {
|
||||||
|
case kHighPass:
|
||||||
|
return hp;
|
||||||
|
case kBandPass:
|
||||||
|
return bp;
|
||||||
|
case kNotch:
|
||||||
|
return input - lp;
|
||||||
|
case kLowPass:
|
||||||
|
default:
|
||||||
|
return lp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filter::recompute() {
|
void Filter::process(const float *in, float *out, uint32_t frames,
|
||||||
float fc = std::fmax(cutOff_, 1.0f);
|
const float *modulation) {
|
||||||
float rc = 1.0f / (2.0f * M_PI * fc);
|
float lp = lpL_;
|
||||||
float val = 1.0f - std::exp(-1.0f / (rc * sampleRate_));
|
float bp = bpL_;
|
||||||
alpha_ = std::fmin(val, 0.999f);
|
|
||||||
};
|
|
||||||
|
|
||||||
void Filter::setCutOff(float newCutOff) {
|
for (uint32_t i = 0; i < frames; ++i) {
|
||||||
cutOff_ = newCutOff;
|
if (modulation != nullptr) {
|
||||||
recompute();
|
if (std::abs(modulation[i] - modulation_) > 0.001f) {
|
||||||
|
setModulation(modulation[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out[i] = processFrame(in[i], lp, bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
lpL_ = lp;
|
||||||
|
bpL_ = bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::processStereo(const float *inL, const float *inR, float *outL,
|
||||||
|
float *outR, uint32_t frames,
|
||||||
|
const float *modulation) {
|
||||||
|
float lpL = lpL_, bpL = bpL_;
|
||||||
|
float lpR = lpR_, bpR = bpR_;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < frames; ++i) {
|
||||||
|
if (modulation != nullptr) {
|
||||||
|
if (std::abs(modulation[i] - modulation_) > 0.001f) {
|
||||||
|
setModulation(modulation[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float inValL = (inL != nullptr) ? inL[i] : 0.0f;
|
||||||
|
float inValR = (inR != nullptr) ? inR[i] : 0.0f;
|
||||||
|
|
||||||
|
outL[i] = processFrame(inValL, lpL, bpL);
|
||||||
|
outR[i] = processFrame(inValR, lpR, bpR);
|
||||||
|
}
|
||||||
|
|
||||||
|
lpL_ = lpL;
|
||||||
|
bpL_ = bpL;
|
||||||
|
lpR_ = lpR;
|
||||||
|
bpR_ = bpR;
|
||||||
|
}
|
||||||
|
|
||||||
float Filter::getCutOff() const { return cutOff_; }
|
float Filter::getCutOff() const { return cutOff_; }
|
||||||
|
|
||||||
void Filter::setFeedback(float newFeedback) {
|
void Filter::setCutOff(float freq) {
|
||||||
feedback_ = std::fmin(std::fmax(newFeedback, 0.0f), 0.99f);
|
cutOff_ = clampFreq(freq);
|
||||||
|
updateCoeffs();
|
||||||
}
|
}
|
||||||
float Filter::getFeedback() const { return feedback_; }
|
|
||||||
|
|
||||||
void Filter::setSampleRate(float newSampleRate) {
|
float Filter::getQ() const { return q_; }
|
||||||
sampleRate_ = newSampleRate;
|
|
||||||
recompute();
|
void Filter::setQ(float q) {
|
||||||
|
q_ = std::fmin(std::fmax(q, kQMin), kQMax);
|
||||||
|
updateCoeffs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::setType(FilterType type) { type_ = type; }
|
||||||
|
|
||||||
float Filter::getSampleRate() const { return sampleRate_; }
|
float Filter::getSampleRate() const { return sampleRate_; }
|
||||||
|
|
||||||
|
void Filter::setSampleRate(float sr) {
|
||||||
|
if (sr > 0.0f) {
|
||||||
|
sampleRate_ = sr;
|
||||||
|
updateCoeffs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Filter::getModulation() const { return modulation_; }
|
||||||
|
|
||||||
|
void Filter::setModulation(float mod) {
|
||||||
|
if (std::abs(modulation_ - mod) > 0.0001f) {
|
||||||
|
modulation_ = mod;
|
||||||
|
updateCoeffs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,33 +1,55 @@
|
||||||
#ifndef FILTER_HPP_INCLUDED
|
#ifndef FILTER_HPP_INCLUDED
|
||||||
#define FILTER_HPP_INCLUDED
|
#define FILTER_HPP_INCLUDED
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.14159265358979323846
|
|
||||||
#endif
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
constexpr float kMaxNormalizedFrequency = 0.16667f;
|
||||||
|
constexpr float kFilterMin = 20.0f;
|
||||||
|
constexpr float kFilterMax = 10000.0f;
|
||||||
|
constexpr float kQMin = 0.1f;
|
||||||
|
constexpr float kQMax = 20.0f;
|
||||||
|
|
||||||
class Filter {
|
class Filter {
|
||||||
public:
|
public:
|
||||||
Filter(float initCutOff = 1.0f, float initSampleRate = 48000.0f);
|
Filter(float initCutOff = 1000.0f, float initQ = 0.707f,
|
||||||
void process(const float *in, float *out, uint32_t frames);
|
float initSampleRate = 48000.0f);
|
||||||
void processStereo(const float *inLeft, const float *inRight, float *outLeft,
|
|
||||||
float *outRight, uint32_t frames);
|
|
||||||
|
|
||||||
void recompute();
|
enum FilterType { kLowPass, kHighPass, kBandPass, kNotch, kFilterTypeCount };
|
||||||
void setCutOff(float newCutOff);
|
|
||||||
|
void setCutOff(float freq);
|
||||||
float getCutOff() const;
|
float getCutOff() const;
|
||||||
void setFeedback(float newFeedback);
|
|
||||||
float getFeedback() const;
|
void setQ(float q);
|
||||||
void setSampleRate(float newSampleRate);
|
float getQ() const;
|
||||||
|
void setSampleRate(float sr);
|
||||||
float getSampleRate() const;
|
float getSampleRate() const;
|
||||||
|
void setType(FilterType type);
|
||||||
|
FilterType getType() const;
|
||||||
|
void setModulation(float mod);
|
||||||
|
float getModulation() const;
|
||||||
|
|
||||||
|
void process(const float *in, float *out, uint32_t frames,
|
||||||
|
const float *modulation = nullptr);
|
||||||
|
void processStereo(const float *inL, const float *inR, float *outL,
|
||||||
|
float *outR, uint32_t frames,
|
||||||
|
const float *modulation = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void filter(const float *in, float *out, uint32_t frames, float *z);
|
void updateCoeffs();
|
||||||
|
float modulation_;
|
||||||
|
|
||||||
|
float clampFreq(float freq);
|
||||||
|
float processFrame(float input, float &lp, float &bp) const;
|
||||||
|
|
||||||
float cutOff_;
|
float cutOff_;
|
||||||
float feedback_;
|
float q_;
|
||||||
float alpha_;
|
|
||||||
float sampleRate_;
|
float sampleRate_;
|
||||||
float zL_;
|
FilterType type_;
|
||||||
float zR_;
|
|
||||||
|
float g_;
|
||||||
|
|
||||||
|
float lpL_, bpL_;
|
||||||
|
float lpR_, bpR_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILTER_HPP_INCLUDED
|
#endif
|
||||||
54
core/Oscillator.cpp
Normal file
54
core/Oscillator.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "Oscillator.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
Oscillator::Oscillator(float initFreq)
|
||||||
|
: freq_(initFreq), gain_(100.0f), waveShape_(kWaveShapeSine),
|
||||||
|
sampleRate_(48000.f), phase_(0.0f), inc_(0.0f)
|
||||||
|
{
|
||||||
|
recalc_();
|
||||||
|
};
|
||||||
|
|
||||||
|
void Oscillator::process(float *out, uint32_t frames)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < frames; ++i)
|
||||||
|
{
|
||||||
|
switch (waveShape_)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case kWaveShapeSine:
|
||||||
|
out[i] = std::sinf(phase_ * 2.0f * M_PI) * gain_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
phase_ += inc_;
|
||||||
|
if (phase_ >= 1.0f)
|
||||||
|
phase_ -= 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oscillator::reset() { phase_ = 0; }
|
||||||
|
|
||||||
|
void Oscillator::recalc_() { inc_ = freq_ / sampleRate_; }
|
||||||
|
|
||||||
|
void Oscillator::setFrequency(float newFreq)
|
||||||
|
{
|
||||||
|
freq_ = std::fmax(newFreq, 0.0f);
|
||||||
|
recalc_();
|
||||||
|
}
|
||||||
|
float Oscillator::getFrequency() const { return freq_; };
|
||||||
|
|
||||||
|
void Oscillator::setGain(float newGain)
|
||||||
|
{
|
||||||
|
gain_ = newGain > 0 ? newGain : 1.0f;
|
||||||
|
}
|
||||||
|
float Oscillator::getGain() const { return gain_; };
|
||||||
|
|
||||||
|
void Oscillator::setSampleRate(float newSampleRate)
|
||||||
|
{
|
||||||
|
sampleRate_ = newSampleRate > 0 ? newSampleRate : 48000.0f;
|
||||||
|
recalc_();
|
||||||
|
}
|
||||||
|
float Oscillator::getSampleRate() const { return sampleRate_; }
|
||||||
|
|
||||||
|
void Oscillator::setWaveShape(WaveShape shape) { waveShape_ = shape; }
|
||||||
|
Oscillator::WaveShape Oscillator::getWaveShape() const { return waveShape_; }
|
||||||
41
core/Oscillator.hpp
Normal file
41
core/Oscillator.hpp
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef OSCILLATOR_HPP_INCLUDED
|
||||||
|
#define OSCILLATOR_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Oscillator {
|
||||||
|
enum WaveShape { kWaveShapeSine, kWaveShapeTriangle, kWaveShapeSquare };
|
||||||
|
|
||||||
|
public:
|
||||||
|
Oscillator(float initFreq);
|
||||||
|
void process(float *out, uint32_t frames);
|
||||||
|
|
||||||
|
void setFrequency(float newFreq);
|
||||||
|
float getFrequency() const;
|
||||||
|
|
||||||
|
void setGain(float newGain);
|
||||||
|
float getGain() const;
|
||||||
|
|
||||||
|
void setSampleRate(float newSampleRate);
|
||||||
|
float getSampleRate() const;
|
||||||
|
|
||||||
|
void setWaveShape(WaveShape shape);
|
||||||
|
WaveShape getWaveShape() const;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
float freq_;
|
||||||
|
float gain_;
|
||||||
|
WaveShape waveShape_;
|
||||||
|
float sampleRate_;
|
||||||
|
float phase_;
|
||||||
|
float inc_;
|
||||||
|
void recalc_();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OSCILLATOR_HPP_INCLUDED
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/make -f
|
#!/usr/bin/make -f
|
||||||
NAME = SquidgeDistortion
|
NAME = SquidgeDistortion
|
||||||
|
|
||||||
FILES_DSP = SquidgeDistortion.cpp ../../core/Gain.cpp ../../core/Clipper.cpp ../../core/Mixer.cpp ../../core/Filter.cpp
|
FILES_DSP = SquidgeDistortion.cpp ../../core/Gain.cpp ../../core/Clipper.cpp ../../core/Mixer.cpp
|
||||||
|
|
||||||
TARGETS = vst3 clap
|
TARGETS = vst3 clap
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "../../core/Clipper.hpp"
|
#include "../../core/Clipper.hpp"
|
||||||
#include "../../core/Filter.hpp"
|
|
||||||
#include "../../core/Gain.hpp"
|
#include "../../core/Gain.hpp"
|
||||||
#include "../../core/Mixer.hpp"
|
#include "../../core/Mixer.hpp"
|
||||||
|
|
||||||
|
|
@ -27,13 +26,11 @@ public:
|
||||||
enum Parameters {
|
enum Parameters {
|
||||||
kParamGain,
|
kParamGain,
|
||||||
kParamClipMode,
|
kParamClipMode,
|
||||||
kParamFilter,
|
|
||||||
kParamFilterFeedback,
|
|
||||||
kParamMixVolume,
|
kParamMixVolume,
|
||||||
kParameterCount // must be last
|
kParameterCount // must be last
|
||||||
};
|
};
|
||||||
SquidgeDistortion()
|
SquidgeDistortion()
|
||||||
: Plugin(kParameterCount, 0, 0), gain_(2.0f), mixer_(1.0f), filter_(440) {
|
: Plugin(kParameterCount, 0, 0), gain_(2.0f), mixer_(1.0f) {
|
||||||
mixer_.setInputGain(kChannelDry, 0.0f);
|
mixer_.setInputGain(kChannelDry, 0.0f);
|
||||||
mixer_.setInputGain(kChannelWet, 1.0f);
|
mixer_.setInputGain(kChannelWet, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
@ -74,22 +71,6 @@ protected:
|
||||||
parameter.enumValues.values =
|
parameter.enumValues.values =
|
||||||
const_cast<ParameterEnumerationValue *>(sClipModes);
|
const_cast<ParameterEnumerationValue *>(sClipModes);
|
||||||
break;
|
break;
|
||||||
case kParamFilter:
|
|
||||||
parameter.name = "Filter";
|
|
||||||
parameter.symbol = "filter";
|
|
||||||
parameter.ranges.min = 20.0f;
|
|
||||||
parameter.ranges.def = 1000.0f;
|
|
||||||
parameter.ranges.max = 10000.0f;
|
|
||||||
parameter.hints = kParameterIsAutomatable;
|
|
||||||
break;
|
|
||||||
case kParamFilterFeedback:
|
|
||||||
parameter.name = "Filter Feedback";
|
|
||||||
parameter.symbol = "filterfeedback";
|
|
||||||
parameter.ranges.min = 0.0f;
|
|
||||||
parameter.ranges.def = .1f;
|
|
||||||
parameter.ranges.max = 0.99f;
|
|
||||||
parameter.hints = kParameterIsAutomatable;
|
|
||||||
break;
|
|
||||||
case kParamMixVolume:
|
case kParamMixVolume:
|
||||||
parameter.name = "Dry/Wet";
|
parameter.name = "Dry/Wet";
|
||||||
parameter.symbol = "drywetvolume";
|
parameter.symbol = "drywetvolume";
|
||||||
|
|
@ -107,10 +88,6 @@ protected:
|
||||||
return gain_.getGain();
|
return gain_.getGain();
|
||||||
case kParamClipMode:
|
case kParamClipMode:
|
||||||
return (float)clipper_.getMode();
|
return (float)clipper_.getMode();
|
||||||
case kParamFilter:
|
|
||||||
return (float)filter_.getCutOff();
|
|
||||||
case kParamFilterFeedback:
|
|
||||||
return (float)filter_.getFeedback();
|
|
||||||
case kParamMixVolume:
|
case kParamMixVolume:
|
||||||
return mixer_.getInputGain(kChannelWet);
|
return mixer_.getInputGain(kChannelWet);
|
||||||
}
|
}
|
||||||
|
|
@ -127,12 +104,6 @@ protected:
|
||||||
static_cast<float>(Clipper::kClipperModeCount - 1));
|
static_cast<float>(Clipper::kClipperModeCount - 1));
|
||||||
clipper_.setMode(static_cast<Clipper::ClipperMode>(std::lround(value)));
|
clipper_.setMode(static_cast<Clipper::ClipperMode>(std::lround(value)));
|
||||||
break;
|
break;
|
||||||
case kParamFilter:
|
|
||||||
filter_.setCutOff(value);
|
|
||||||
break;
|
|
||||||
case kParamFilterFeedback:
|
|
||||||
filter_.setFeedback(value);
|
|
||||||
break;
|
|
||||||
case kParamMixVolume:
|
case kParamMixVolume:
|
||||||
mixer_.setInputGain(kChannelWet, value);
|
mixer_.setInputGain(kChannelWet, value);
|
||||||
mixer_.setInputGain(kChannelDry, 1.0f - value);
|
mixer_.setInputGain(kChannelDry, 1.0f - value);
|
||||||
|
|
@ -152,24 +123,17 @@ protected:
|
||||||
buffers_.clippedR, frames);
|
buffers_.clippedR, frames);
|
||||||
clipper_.processStereo(buffers_.clippedL, buffers_.clippedR,
|
clipper_.processStereo(buffers_.clippedL, buffers_.clippedR,
|
||||||
buffers_.clippedL, buffers_.clippedR, frames);
|
buffers_.clippedL, buffers_.clippedR, frames);
|
||||||
filter_.processStereo(buffers_.clippedL, buffers_.clippedR, buffers_.lpL,
|
|
||||||
buffers_.lpR, frames);
|
|
||||||
|
|
||||||
const float *inputsL[2] = {inputs[0], buffers_.lpL};
|
const float *inputsL[2] = {inputs[0], buffers_.clippedL};
|
||||||
const float *inputsR[2] = {inputs[1], buffers_.lpR};
|
const float *inputsR[2] = {inputs[1], buffers_.clippedR};
|
||||||
|
|
||||||
mixer_.processStereo(inputsL, inputsR, outputs[0], outputs[1], frames);
|
mixer_.processStereo(inputsL, inputsR, outputs[0], outputs[1], frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sampleRateChanged(double newSr) override {
|
|
||||||
filter_.setSampleRate(static_cast<float>(newSr));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gain gain_;
|
Gain gain_;
|
||||||
Clipper clipper_;
|
Clipper clipper_;
|
||||||
Mixer<2> mixer_;
|
Mixer<2> mixer_;
|
||||||
Filter filter_;
|
|
||||||
AudioBuffers buffers_;
|
AudioBuffers buffers_;
|
||||||
|
|
||||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SquidgeDistortion);
|
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SquidgeDistortion);
|
||||||
|
|
|
||||||
28
plugins/SquidgeFilter/DistrhoPluginInfo.h
Normal file
28
plugins/SquidgeFilter/DistrhoPluginInfo.h
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
|
||||||
|
#define DISTRHO_PLUGIN_INFO_H_INCLUDED
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_NAME "SquidgeFilter"
|
||||||
|
#define DISTRHO_PLUGIN_AUTHOR "SquidgeSoft"
|
||||||
|
#define DISTRHO_PLUGIN_URI "moe.liam.squidgesoft.SquidgeFilter"
|
||||||
|
#define DISTRHO_PLUGIN_CATEGORY "fx"
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
||||||
|
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_NUM_PARAMETERS 3
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0
|
||||||
|
#define DISTRHO_PLUGIN_WANT_STATE 0
|
||||||
|
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_HAS_UI 0
|
||||||
|
#define DISTRHO_PLUGIN_IS_SYNTH 0
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_PRIV_ID "moe.liam.squidgesoft.SquidgeFilter"
|
||||||
|
#define DISTRHO_PLUGIN_BRAND "SquidgeSoft"
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_CLAP_ID "moe.liam.squidgesoft.SquidgeFilter"
|
||||||
|
|
||||||
|
#endif
|
||||||
11
plugins/SquidgeFilter/Makefile
Normal file
11
plugins/SquidgeFilter/Makefile
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
NAME = SquidgeFilter
|
||||||
|
|
||||||
|
FILES_DSP = SquidgeFilter.cpp ../../core/Filter.cpp ../../core/Oscillator.cpp
|
||||||
|
|
||||||
|
TARGETS = vst3 clap
|
||||||
|
|
||||||
|
include ../../dpf/Makefile.plugins.mk
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
198
plugins/SquidgeFilter/SquidgeFilter.cpp
Normal file
198
plugins/SquidgeFilter/SquidgeFilter.cpp
Normal file
|
|
@ -0,0 +1,198 @@
|
||||||
|
#include "DistrhoDetails.hpp"
|
||||||
|
#include "DistrhoPlugin.hpp"
|
||||||
|
#include "DistrhoPluginInfo.h"
|
||||||
|
|
||||||
|
#include "../../core/Filter.hpp"
|
||||||
|
#include "../../core/Oscillator.hpp"
|
||||||
|
|
||||||
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
const int BUFFER_SIZE = 16384;
|
||||||
|
|
||||||
|
class SquidgeFilter : public Plugin {
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Parameters {
|
||||||
|
kParamFreq,
|
||||||
|
kParamResonance,
|
||||||
|
kParamType,
|
||||||
|
kParamLFOSyncMode,
|
||||||
|
kParamLFOAmount,
|
||||||
|
kParameterCount // must be last
|
||||||
|
};
|
||||||
|
|
||||||
|
SquidgeFilter()
|
||||||
|
: Plugin(kParameterCount, 0, 0), filter_(440.0f, 2.0f, 48000.0f),
|
||||||
|
lfo_(20.0f), lfoSync_(0.0f) {
|
||||||
|
filter_.setType(Filter::kLowPass);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *getLabel() const override { return "SquidgeFilter"; }
|
||||||
|
const char *getDescription() const override {
|
||||||
|
return "Simple State Variable Filter.";
|
||||||
|
}
|
||||||
|
const char *getMaker() const override { return "SquidgeSoft"; }
|
||||||
|
const char *getLicense() const override { return "GPL3"; }
|
||||||
|
uint32_t getVersion() const override { return d_version(0, 1, 0); }
|
||||||
|
int64_t getUniqueId() const override { return d_cconst('S', 'Q', 'F', 'T'); }
|
||||||
|
|
||||||
|
void initParameter(uint32_t index, Parameter ¶meter) override {
|
||||||
|
switch (index) {
|
||||||
|
case kParamFreq:
|
||||||
|
parameter.name = "Frequency";
|
||||||
|
parameter.symbol = "frequency";
|
||||||
|
parameter.ranges.min = 20.0f;
|
||||||
|
parameter.ranges.def = 440.0f;
|
||||||
|
parameter.ranges.max = 10000.0f;
|
||||||
|
parameter.hints = kParameterIsAutomatable | kParameterIsLogarithmic;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kParamResonance:
|
||||||
|
parameter.name = "Resonance";
|
||||||
|
parameter.symbol = "resonance";
|
||||||
|
parameter.ranges.min = 0.9f;
|
||||||
|
parameter.ranges.def = 2.0f;
|
||||||
|
parameter.ranges.max = 20.0f;
|
||||||
|
parameter.hints = kParameterIsAutomatable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kParamType:
|
||||||
|
parameter.name = "Filter Type";
|
||||||
|
parameter.symbol = "type";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.def = 0.0f;
|
||||||
|
parameter.ranges.max = Filter::kFilterTypeCount - 1;
|
||||||
|
parameter.hints = kParameterIsAutomatable | kParameterIsInteger;
|
||||||
|
parameter.enumValues.count = Filter::kFilterTypeCount;
|
||||||
|
parameter.enumValues.restrictedMode = true;
|
||||||
|
|
||||||
|
static const ParameterEnumerationValue sTypes[Filter::kFilterTypeCount] =
|
||||||
|
{{0.0f, "Low Pass"},
|
||||||
|
{1.0f, "High Pass"},
|
||||||
|
{2.0f, "Band Pass"},
|
||||||
|
{3.0f, "Notch"}};
|
||||||
|
parameter.enumValues.values =
|
||||||
|
const_cast<ParameterEnumerationValue *>(sTypes);
|
||||||
|
break;
|
||||||
|
case kParamLFOAmount:
|
||||||
|
parameter.name = "LFO Amount";
|
||||||
|
parameter.symbol = "lfoamount";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.def = 0.0f;
|
||||||
|
parameter.ranges.max = 1000.0f;
|
||||||
|
|
||||||
|
parameter.hints = kParameterIsAutomatable | kParameterIsInteger;
|
||||||
|
break;
|
||||||
|
case kParamLFOSyncMode:
|
||||||
|
parameter.name = "LFO Sync";
|
||||||
|
parameter.symbol = "lfosync";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.def = 3.0f;
|
||||||
|
parameter.ranges.max = 6.0f;
|
||||||
|
|
||||||
|
parameter.hints = kParameterIsAutomatable | kParameterIsInteger;
|
||||||
|
|
||||||
|
static const ParameterEnumerationValue sModes[] = {
|
||||||
|
{0.0f, "1/1 Bar"}, {1.0f, "1/2 Bar"}, {2.0f, "1/4 Bar"},
|
||||||
|
{3.0f, "1/8 Bar"}, {4.0f, "1/16 Bar"}, {5.0f, "1/32 Bar"},
|
||||||
|
{6.0f, "1/64 Bar"}};
|
||||||
|
|
||||||
|
parameter.enumValues.count = 7;
|
||||||
|
parameter.enumValues.restrictedMode = true;
|
||||||
|
parameter.enumValues.values =
|
||||||
|
const_cast<ParameterEnumerationValue *>(sModes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float getParameterValue(uint32_t index) const override {
|
||||||
|
switch (index) {
|
||||||
|
case kParamFreq:
|
||||||
|
return filter_.getCutOff();
|
||||||
|
case kParamResonance:
|
||||||
|
return filter_.getQ();
|
||||||
|
case kParamType:
|
||||||
|
return static_cast<float>(filter_.getType());
|
||||||
|
case kParamLFOAmount:
|
||||||
|
return lfo_.getGain();
|
||||||
|
break;
|
||||||
|
case kParamLFOSyncMode:
|
||||||
|
return lfoSync_;
|
||||||
|
};
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setParameterValue(uint32_t index, float value) override {
|
||||||
|
switch (index) {
|
||||||
|
case kParamFreq:
|
||||||
|
filter_.setCutOff(value);
|
||||||
|
break;
|
||||||
|
case kParamResonance:
|
||||||
|
filter_.setQ(value);
|
||||||
|
break;
|
||||||
|
case kParamLFOAmount:
|
||||||
|
lfo_.setGain(value);
|
||||||
|
break;
|
||||||
|
case kParamLFOSyncMode:
|
||||||
|
lfoSync_ = value;
|
||||||
|
break;
|
||||||
|
case kParamType:
|
||||||
|
int typeIdx = static_cast<int>(std::fmin(std::fmax(value, 0.0f), 3.0f));
|
||||||
|
filter_.setType(static_cast<Filter::FilterType>(typeIdx));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run(const float **inputs, float **outputs, uint32_t frames) override {
|
||||||
|
|
||||||
|
const TimePosition &timePos = getTimePosition();
|
||||||
|
|
||||||
|
float targetFreq = 4.0f;
|
||||||
|
|
||||||
|
if (timePos.bbt.valid && timePos.playing &&
|
||||||
|
timePos.bbt.beatsPerMinute > 0.0) {
|
||||||
|
float bpb = static_cast<float>(timePos.bbt.beatsPerBar);
|
||||||
|
float bpm = static_cast<float>(timePos.bbt.beatsPerMinute);
|
||||||
|
float bar = static_cast<float>(timePos.bbt.bar);
|
||||||
|
|
||||||
|
if (bar != currentBar_) {
|
||||||
|
lfo_.reset();
|
||||||
|
currentBar_ = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
float baseFreq = (bpm / 60.0f) / bpb;
|
||||||
|
|
||||||
|
static const float multipliers[] = {1.0f, 2.0f, 4.0f, 8.0f,
|
||||||
|
16.0f, 32.0f, 64.0f};
|
||||||
|
|
||||||
|
targetFreq = baseFreq * multipliers[static_cast<int>(lfoSync_)];
|
||||||
|
} else {
|
||||||
|
targetFreq = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfo_.setFrequency(targetFreq);
|
||||||
|
lfo_.process(lfoBuffer_, frames);
|
||||||
|
|
||||||
|
filter_.processStereo(inputs[0], inputs[1], outputs[0], outputs[1], frames,
|
||||||
|
lfoBuffer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sampleRateChanged(double newSr) override {
|
||||||
|
filter_.setSampleRate(static_cast<float>(newSr));
|
||||||
|
lfo_.setSampleRate(newSr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Filter filter_;
|
||||||
|
Oscillator lfo_;
|
||||||
|
float lfoSync_;
|
||||||
|
uint32_t currentBar_ = 0;
|
||||||
|
float lfoBuffer_[BUFFER_SIZE];
|
||||||
|
|
||||||
|
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SquidgeFilter);
|
||||||
|
};
|
||||||
|
|
||||||
|
Plugin *createPlugin() { return new SquidgeFilter(); }
|
||||||
|
|
||||||
|
END_NAMESPACE_DISTRHO
|
||||||
26
plugins/SquidgeTemplate/DistrhoPluginInfo.h
Normal file
26
plugins/SquidgeTemplate/DistrhoPluginInfo.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
|
||||||
|
#define DISTRHO_PLUGIN_INFO_H_INCLUDED
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_NAME "SquidgeTemplate"
|
||||||
|
#define DISTRHO_PLUGIN_AUTHOR "SquidgeSoft"
|
||||||
|
#define DISTRHO_PLUGIN_URI "moe.liam.squidgesoft.SquidgeTemplate"
|
||||||
|
#define DISTRHO_PLUGIN_CATEGORY "fx"
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
||||||
|
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_NUM_PARAMETERS 1
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0
|
||||||
|
#define DISTRHO_PLUGIN_WANT_STATE 0
|
||||||
|
#define DISTRHO_PLUGIN_HAS_UI 0
|
||||||
|
#define DISTRHO_PLUGIN_IS_SYNTH 0
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_PRIV_ID "moe.liam.squidgesoft.SquidgeTemplate"
|
||||||
|
#define DISTRHO_PLUGIN_BRAND "SquidgeSoft"
|
||||||
|
|
||||||
|
#define DISTRHO_PLUGIN_CLAP_ID "moe.liam.squidgesoft.SquidgeTemplate"
|
||||||
|
|
||||||
|
#endif
|
||||||
10
plugins/SquidgeTemplate/Makefile
Normal file
10
plugins/SquidgeTemplate/Makefile
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
NAME = squidgeTemplate
|
||||||
|
|
||||||
|
FILES_DSP = squidgeTemplate.cpp ../../core/Gain.cpp
|
||||||
|
|
||||||
|
TARGETS = vst3 clap
|
||||||
|
|
||||||
|
include ../../dpf/Makefile.plugins.mk
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
79
plugins/SquidgeTemplate/SquidgeTemplate.cpp
Normal file
79
plugins/SquidgeTemplate/SquidgeTemplate.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "DistrhoDetails.hpp"
|
||||||
|
#include "DistrhoPlugin.hpp"
|
||||||
|
#include "DistrhoPluginInfo.h"
|
||||||
|
|
||||||
|
#include "../../core/Gain.hpp"
|
||||||
|
|
||||||
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
class squidgeTemplate : public Plugin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Parameters
|
||||||
|
{
|
||||||
|
kParamGain,
|
||||||
|
kParameterCount
|
||||||
|
};
|
||||||
|
|
||||||
|
squidgeTemplate()
|
||||||
|
: Plugin(kParameterCount, 0, 0), gain_(1.0f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *getLabel() const override { return "squidgeTemplate"; }
|
||||||
|
const char *getDescription() const override { return "Generic squidge plugin template."; }
|
||||||
|
const char *getMaker() const override { return "SquidgeSoft"; }
|
||||||
|
const char *getLicense() const override { return "GPL3"; }
|
||||||
|
uint32_t getVersion() const override { return d_version(0, 1, 0); }
|
||||||
|
int64_t getUniqueId() const override { return d_cconst('S', 'Q', 'T', 'P'); }
|
||||||
|
|
||||||
|
void initParameter(uint32_t index, Parameter ¶meter) override
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case kParamGain:
|
||||||
|
parameter.name = "Gain";
|
||||||
|
parameter.symbol = "gain";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.def = 1.0f;
|
||||||
|
parameter.ranges.max = 2.0f;
|
||||||
|
parameter.hints = kParameterIsAutomatable;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float getParameterValue(uint32_t index) const override
|
||||||
|
{
|
||||||
|
if (index == kParamGain)
|
||||||
|
return gain_.getGain();
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setParameterValue(uint32_t index, float value) override
|
||||||
|
{
|
||||||
|
if (index == kParamGain)
|
||||||
|
gain_.setGain(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run(const float **inputs, float **outputs, uint32_t frames) override
|
||||||
|
{
|
||||||
|
gain_.processStereo(inputs[0], inputs[1], outputs[0], outputs[1], frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sampleRateChanged(double /*newSr*/) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gain gain_;
|
||||||
|
|
||||||
|
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(squidgeTemplate)
|
||||||
|
};
|
||||||
|
|
||||||
|
Plugin *createPlugin()
|
||||||
|
{
|
||||||
|
return new squidgeTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE_DISTRHO
|
||||||
Loading…
Add table
Add a link
Reference in a new issue