Compare commits

..

7 commits

14 changed files with 605 additions and 140 deletions

View file

@ -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
# -------------------------------------------------------------- # --------------------------------------------------------------

View file

@ -1,71 +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), resonance_(0.1f), a1_(0.0f), #define M_PI 3.14159265358979323846
a2_(0.0f), a3_(0.0f), g_(0.0f), k_(2.0f), sampleRate_(initSampleRate), #endif
s1L_(0.0f), s2L_(0.0f), s1R_(0.0f), s2R_(0.0f), outZL_(0.0f),
outZR_(0.0f) {
recompute();
};
void Filter::process(const float *in, float *out, uint32_t frames) { Filter::Filter(float initCutOff, float initQ, float initSampleRate)
filter(in, out, frames, &s1L_, &s2L_, &outZL_); : 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, &s1L_, &s2L_, &outZL_); }
filter(inRight, outRight, frames, &s1R_, &s2R_, &outZR_);
};
void Filter::filter(const float *in, float *out, uint32_t frames, float *s1, Filter::FilterType Filter::getType() const { return type_; }
float *s2, float *outZ) {
for (uint32_t i = 0; i < frames; ++i) { float Filter::clampFreq(float freq) {
float x = in[i] + (feedback_ * (*outZ)); return std::fmin(std::fmax(freq, kFilterMin), kFilterMax);
float v3 = x - *s2; }
if (resonance_ > 0.995f && std::fabs(v3) < 1.0e-9f) {
v3 = 1.0e-6f; void Filter::updateCoeffs() {
} float totalFreq = clampFreq(cutOff_ + modulation_);
float v1 = (a1_ * (*s1)) + (a2_ * v3);
float v2 = (*s2) + (a2_ * (*s1)) + (a3_ * v3); float f = totalFreq / std::fmax(sampleRate_, 1.0f);
*s1 = (2.0f * v1) - *s1;
*s2 = (2.0f * v2) - *s2; if (f > kMaxNormalizedFrequency)
out[i] = v2; f = kMaxNormalizedFrequency;
*outZ = v2; 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 sr = std::fmax(sampleRate_, 1.0f); const float *modulation) {
float fc = std::fmin(std::fmax(cutOff_, 1.0f), 0.45f * sr); float lp = lpL_;
g_ = std::tan(static_cast<float>(M_PI) * (fc / sr)); float bp = bpL_;
k_ = 2.0f * (1.0f - std::fmin(std::fmax(resonance_, 0.0f), 1.0f));
float denom = 1.0f + (g_ * (g_ + k_)); for (uint32_t i = 0; i < frames; ++i) {
a1_ = 1.0f / denom; if (modulation != nullptr) {
a2_ = g_ * a1_; if (std::abs(modulation[i] - modulation_) > 0.001f) {
a3_ = g_ * a2_; setModulation(modulation[i]);
}; }
}
out[i] = processFrame(in[i], lp, bp);
}
void Filter::setCutOff(float newCutOff) { lpL_ = lp;
cutOff_ = newCutOff; bpL_ = bp;
recompute();
} }
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.95f); cutOff_ = clampFreq(freq);
updateCoeffs();
} }
float Filter::getFeedback() const { return feedback_; }
void Filter::setResonance(float newResonance) { float Filter::getQ() const { return q_; }
resonance_ = std::fmin(std::fmax(newResonance, 0.0f), 1.0f);
recompute();
}
float Filter::getResonance() const { return resonance_; }
void Filter::setSampleRate(float newSampleRate) { void Filter::setQ(float q) {
sampleRate_ = newSampleRate; q_ = std::fmin(std::fmax(q, kQMin), kQMax);
recompute(); 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();
}
}

View file

@ -1,45 +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 setResonance(float newResonance); float getQ() const;
float getResonance() const; void setSampleRate(float sr);
void setSampleRate(float newSampleRate);
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 *s1, void updateCoeffs();
float *s2, float *outZ); float modulation_;
float clampFreq(float freq);
float processFrame(float input, float &lp, float &bp) const;
float cutOff_; float cutOff_;
float feedback_; float q_;
float resonance_;
float a1_;
float a2_;
float a3_;
float g_;
float k_;
float sampleRate_; float sampleRate_;
float s1L_; FilterType type_;
float s2L_;
float s1R_; float g_;
float s2R_;
float outZL_; float lpL_, bpL_;
float outZR_; float lpR_, bpR_;
}; };
#endif // FILTER_HPP_INCLUDED #endif

54
core/Oscillator.cpp Normal file
View 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
View 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

View file

@ -9,7 +9,7 @@
#define DISTRHO_PLUGIN_NUM_INPUTS 2 #define DISTRHO_PLUGIN_NUM_INPUTS 2
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 #define DISTRHO_PLUGIN_NUM_OUTPUTS 2
#define DISTRHO_PLUGIN_NUM_PARAMETERS 6 #define DISTRHO_PLUGIN_NUM_PARAMETERS 5
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0 #define DISTRHO_PLUGIN_WANT_PROGRAMS 0
#define DISTRHO_PLUGIN_WANT_STATE 0 #define DISTRHO_PLUGIN_WANT_STATE 0

View file

@ -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

View file

@ -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,14 +26,11 @@ public:
enum Parameters { enum Parameters {
kParamGain, kParamGain,
kParamClipMode, kParamClipMode,
kParamFilter,
kParamFilterFeedback,
kParamMixVolume, kParamMixVolume,
kParamResonance,
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);
} }
@ -75,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 = "Feedback";
parameter.symbol = "filterfeedback";
parameter.ranges.min = 0.0f;
parameter.ranges.def = 0.0f;
parameter.ranges.max = 0.95f;
parameter.hints = kParameterIsAutomatable;
break;
case kParamMixVolume: case kParamMixVolume:
parameter.name = "Dry/Wet"; parameter.name = "Dry/Wet";
parameter.symbol = "drywetvolume"; parameter.symbol = "drywetvolume";
@ -99,14 +79,6 @@ protected:
parameter.ranges.max = 1.0f; parameter.ranges.max = 1.0f;
parameter.hints = kParameterIsAutomatable; parameter.hints = kParameterIsAutomatable;
break; break;
case kParamResonance:
parameter.name = "Resonance";
parameter.symbol = "resonance";
parameter.ranges.min = 0.0f;
parameter.ranges.def = 0.1f;
parameter.ranges.max = 1.0f;
parameter.hints = kParameterIsAutomatable;
break;
} }
} }
@ -116,14 +88,8 @@ 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);
case kParamResonance:
return (float)filter_.getResonance();
} }
return 0.0f; return 0.0f;
} }
@ -138,19 +104,10 @@ 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);
break; break;
case kParamResonance:
filter_.setResonance(value);
break;
} }
} }
@ -166,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);

View 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

View 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)

View 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 &parameter) 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

View 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

View 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)

View 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 &parameter) 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