diff --git a/plugins/community/repos/LindenbergResearch/CMakeLists.txt b/plugins/community/repos/LindenbergResearch/CMakeLists.txt
index f9232e2d..119d764f 100644
--- a/plugins/community/repos/LindenbergResearch/CMakeLists.txt
+++ b/plugins/community/repos/LindenbergResearch/CMakeLists.txt
@@ -60,7 +60,7 @@ set(SOURCE_FILES
src/widgets/FontIconWidget.cpp
src/modules/BlankPanelSmall.cpp
src/modules/Speck.cpp
- src/widgets/LRGradientWidget.cpp src/LRModule.cpp src/LRModuleWidget.cpp src/LRModel.hpp src/widgets/LRPatinaWidget.cpp src/LRGestalt.hpp src/modules/Korg35.cpp src/dsp/Korg35Filter.cpp src/dsp/Korg35Filter.hpp)
+ src/widgets/LRGradientWidget.cpp src/LRModule.cpp src/LRModuleWidget.cpp src/LRModel.hpp src/widgets/LRPatinaWidget.cpp src/LRGestalt.hpp src/modules/Type35.cpp src/dsp/Type35Filter.cpp src/dsp/Type35Filter.hpp src/dsp/RateConverter.cpp src/dsp/RateConverter.hpp)
include_directories(.)
include_directories(src)
diff --git a/plugins/community/repos/LindenbergResearch/Makefile b/plugins/community/repos/LindenbergResearch/Makefile
index 206d7d13..2bb92436 100644
--- a/plugins/community/repos/LindenbergResearch/Makefile
+++ b/plugins/community/repos/LindenbergResearch/Makefile
@@ -1,5 +1,5 @@
SLUG = LindenbergResearch
-VERSION = 0.6.4
+VERSION = 0.6.5
SOURCES += $(wildcard src/*.cpp src/dsp/*.cpp src/dsp/kiss_fft/*.c src/widgets/*.cpp src/modules/*.cpp)
DISTRIBUTABLES += $(wildcard LICENSE*) res
RACK_DIR ?= ../..
diff --git a/plugins/community/repos/LindenbergResearch/design/AlternateBigLight.afdesign b/plugins/community/repos/LindenbergResearch/design/AlternateBigLight.afdesign
index 5105b777..86f955ab 100644
Binary files a/plugins/community/repos/LindenbergResearch/design/AlternateBigLight.afdesign and b/plugins/community/repos/LindenbergResearch/design/AlternateBigLight.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/AlternateMiddleLight.afdesign b/plugins/community/repos/LindenbergResearch/design/AlternateMiddleLight.afdesign
index 093e9d3a..e14efd4a 100644
Binary files a/plugins/community/repos/LindenbergResearch/design/AlternateMiddleLight.afdesign and b/plugins/community/repos/LindenbergResearch/design/AlternateMiddleLight.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/AlternateSmallToggleLight.afdesign b/plugins/community/repos/LindenbergResearch/design/AlternateSmallToggleLight.afdesign
new file mode 100644
index 00000000..603b23c4
Binary files /dev/null and b/plugins/community/repos/LindenbergResearch/design/AlternateSmallToggleLight.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/BlankPanelLight.afdesign b/plugins/community/repos/LindenbergResearch/design/BlankPanelLight.afdesign
index 539c3392..d58313ce 100644
Binary files a/plugins/community/repos/LindenbergResearch/design/BlankPanelLight.afdesign and b/plugins/community/repos/LindenbergResearch/design/BlankPanelLight.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/IOPortBLight.afdesign b/plugins/community/repos/LindenbergResearch/design/IOPortBLight.afdesign
index cc47be27..36dc1bfd 100644
Binary files a/plugins/community/repos/LindenbergResearch/design/IOPortBLight.afdesign and b/plugins/community/repos/LindenbergResearch/design/IOPortBLight.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/LCDFrameAged.afdesign b/plugins/community/repos/LindenbergResearch/design/LCDFrameAged.afdesign
new file mode 100644
index 00000000..9f036f0f
Binary files /dev/null and b/plugins/community/repos/LindenbergResearch/design/LCDFrameAged.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/LCDFrameDark.afdesign b/plugins/community/repos/LindenbergResearch/design/LCDFrameDark.afdesign
new file mode 100644
index 00000000..a900cc0b
Binary files /dev/null and b/plugins/community/repos/LindenbergResearch/design/LCDFrameDark.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/LCDFrameLight.afdesign b/plugins/community/repos/LindenbergResearch/design/LCDFrameLight.afdesign
new file mode 100644
index 00000000..18edd84c
Binary files /dev/null and b/plugins/community/repos/LindenbergResearch/design/LCDFrameLight.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/Type35VCF.afdesign b/plugins/community/repos/LindenbergResearch/design/Type35VCF.afdesign
new file mode 100644
index 00000000..5d4d5d33
Binary files /dev/null and b/plugins/community/repos/LindenbergResearch/design/Type35VCF.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/Type35VCFAged.afdesign b/plugins/community/repos/LindenbergResearch/design/Type35VCFAged.afdesign
new file mode 100644
index 00000000..10a09ae4
Binary files /dev/null and b/plugins/community/repos/LindenbergResearch/design/Type35VCFAged.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/design/Type35VCFLight.afdesign b/plugins/community/repos/LindenbergResearch/design/Type35VCFLight.afdesign
new file mode 100644
index 00000000..92a93cf9
Binary files /dev/null and b/plugins/community/repos/LindenbergResearch/design/Type35VCFLight.afdesign differ
diff --git a/plugins/community/repos/LindenbergResearch/make.objects b/plugins/community/repos/LindenbergResearch/make.objects
index eadfe7f7..f7d7b47d 100644
--- a/plugins/community/repos/LindenbergResearch/make.objects
+++ b/plugins/community/repos/LindenbergResearch/make.objects
@@ -4,16 +4,17 @@ ALL_OBJ= \
src/dsp/FastTanWF.o \
src/dsp/Hardclip.o \
src/dsp/kiss_fft/kiss_fft.o \
- src/dsp/Korg35Filter.o \
src/dsp/LadderFilter.o \
src/dsp/LambertW.o \
src/dsp/Lockhart.o \
src/dsp/MS20zdf.o \
src/dsp/Oscillator.o \
src/dsp/Overdrive.o \
+ src/dsp/RateConverter.o \
src/dsp/RShaper.o \
src/dsp/Saturator.o \
src/dsp/Serge.o \
+ src/dsp/Type35Filter.o \
src/dsp/WaveShaper.o \
src/LRModule.o \
src/LRModuleWidget.o \
@@ -33,7 +34,7 @@ ALL_OBJ= \
src/modules/BlankPanelSmall.o \
src/modules/BlankPanelWood.o \
src/modules/DiodeVCF.o \
- src/modules/Korg35.o \
+ src/modules/Type35.o \
src/modules/MS20Filter.o \
src/modules/QuickMix.o \
src/modules/ReShaper.o \
diff --git a/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameAged.svg b/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameAged.svg
new file mode 100644
index 00000000..9fe67775
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameAged.svg
@@ -0,0 +1,39 @@
+
+
+
diff --git a/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameDark.svg b/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameDark.svg
new file mode 100644
index 00000000..c8b74bb9
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameDark.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameLight.svg b/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameLight.svg
new file mode 100644
index 00000000..1c0ec577
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/res/elements/LCDFrameLight.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/plugins/community/repos/LindenbergResearch/res/knobs/AlternateBigLight.svg b/plugins/community/repos/LindenbergResearch/res/knobs/AlternateBigLight.svg
index 09b6612b..71d2db8c 100644
--- a/plugins/community/repos/LindenbergResearch/res/knobs/AlternateBigLight.svg
+++ b/plugins/community/repos/LindenbergResearch/res/knobs/AlternateBigLight.svg
@@ -4,7 +4,7 @@
-
+
-
+
-
+
-
+
+
+
diff --git a/plugins/community/repos/LindenbergResearch/res/panels/BlankPanelLight.svg b/plugins/community/repos/LindenbergResearch/res/panels/BlankPanelLight.svg
index fae35123..36d135e4 100644
--- a/plugins/community/repos/LindenbergResearch/res/panels/BlankPanelLight.svg
+++ b/plugins/community/repos/LindenbergResearch/res/panels/BlankPanelLight.svg
@@ -29,41 +29,38 @@
style="fill:url(#_Linear1);fill-rule:nonzero;stroke:#322727;stroke-opacity:0.658824;stroke-width:1.16px;"/>
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -81,48 +78,48 @@
style="fill-opacity:0.427451;"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -305,18 +302,18 @@
-
-
+
-
-
-
-
-
diff --git a/plugins/community/repos/LindenbergResearch/res/panels/Korg35VCF.svg b/plugins/community/repos/LindenbergResearch/res/panels/Korg35VCF.svg
deleted file mode 100644
index f7ad59f8..00000000
--- a/plugins/community/repos/LindenbergResearch/res/panels/Korg35VCF.svg
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
diff --git a/plugins/community/repos/LindenbergResearch/res/panels/Type35VCF.svg b/plugins/community/repos/LindenbergResearch/res/panels/Type35VCF.svg
new file mode 100644
index 00000000..03ba698e
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/res/panels/Type35VCF.svg
@@ -0,0 +1,865 @@
+
+
+
diff --git a/plugins/community/repos/LindenbergResearch/res/panels/Type35VCFAged.svg b/plugins/community/repos/LindenbergResearch/res/panels/Type35VCFAged.svg
new file mode 100644
index 00000000..6ae1843f
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/res/panels/Type35VCFAged.svg
@@ -0,0 +1,1151 @@
+
+
+
diff --git a/plugins/community/repos/LindenbergResearch/res/panels/Type35VCFLight.svg b/plugins/community/repos/LindenbergResearch/res/panels/Type35VCFLight.svg
new file mode 100644
index 00000000..3e38ceb4
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/res/panels/Type35VCFLight.svg
@@ -0,0 +1,1161 @@
+
+
+
diff --git a/plugins/community/repos/LindenbergResearch/src/LRComponents.hpp b/plugins/community/repos/LindenbergResearch/src/LRComponents.hpp
index 6b93dead..078fc0f6 100644
--- a/plugins/community/repos/LindenbergResearch/src/LRComponents.hpp
+++ b/plugins/community/repos/LindenbergResearch/src/LRComponents.hpp
@@ -9,10 +9,12 @@
#define LCD_FONT_DIG7 "res/digital-7.ttf"
#define LCD_FONTSIZE 11
#define LCD_LETTER_SPACING 0
+#define LCD_MARGIN_VERTICAL 1.73
+#define LCD_MARGIN_HORIZONTAL 1.07
#define LCD_DEFAULT_COLOR_DARK nvgRGBAf(0.23, 0.6, 0.82, 1.0)
-#define LCD_DEFAULT_COLOR_LIGHT nvgRGBAf(0.0, 0.0, 0.0, 1.0)
-#define LCD_DEFAULT_COLOR_AGED nvgRGBAf(0.0, 0.0, 0.12, 1.0)
+#define LCD_DEFAULT_COLOR_LIGHT nvgRGBAf(0.23, 0.7, 1.0, 1.0)
+#define LCD_DEFAULT_COLOR_AGED nvgRGBAf(0.63, 0.1, 0.0, 1.0)
#define LED_DEFAULT_COLOR_DARK nvgRGBAf(0.23, 0.5, 1.0, 1.0)
#define LED_DEFAULT_COLOR_LIGHT nvgRGBAf(1.0, 0.32, 0.12, 1.0)
@@ -45,7 +47,7 @@ typedef std::vector StringVector;
/**
* @brief Emulation of a LCD monochrome display
*/
-struct LRLCDWidget : Label, LRGestaltChangeAction {
+struct LRLCDWidget : FramebufferWidget, LRGestaltVariant, LRGestaltChangeAction {
enum LCDType {
NUMERIC,
@@ -53,27 +55,32 @@ struct LRLCDWidget : Label, LRGestaltChangeAction {
LIST
};
- TrueType ttfLCDDig7;
- float fontsize;
+ TransformWidget *tw;
+ SVGWidget *sw;
- LCDType type;
+ TrueType ttfLCDDIG7;
+
+ LCDType type;
NVGcolor fg;
- NVGcolor bg;
bool active = true;
float value = 0.0;
unsigned char length = 0;
- string format;
+ string format, text;
vector items;
+ float fontsize;
+
string s1;
string s2;
/**
* @brief Constructor
*/
- LRLCDWidget(unsigned char length, string format, LCDType type, float fontsize = LCD_FONTSIZE);
+ LRLCDWidget(unsigned char length, string format, LCDType type, float fontsize);
+
+ void step() override;
/**
* @brief Draw LCD display
@@ -87,8 +94,12 @@ struct LRLCDWidget : Label, LRGestaltChangeAction {
}
+ void doResize(Vec v);
+
void onGestaltChange(LREventGestaltChange &e) override;
+ virtual void onMouseDown(EventMouseDown &e) override;
+
};
@@ -332,7 +343,6 @@ public:
*/
void unsetSnap();
-
/**
* @brief Snapping mode for knobs
* @param e
@@ -444,8 +454,8 @@ struct LRBigKnob : LRKnob {
case LRGestalt::DARK:
setIndicatorDistance(15);
setIndicatorShape(4.8, 0.12);
- shader->setShadowPosition(5, 6);
- shader->setStrength(1.f);
+ shader->setShadowPosition(4, 5);
+ shader->setStrength(0.8f);
shader->setSize(.65f);
break;
case LRGestalt::LIGHT:
@@ -489,8 +499,8 @@ struct LRMiddleKnob : LRKnob {
case LRGestalt::DARK:
setIndicatorDistance(13);
setIndicatorShape(5, 0.13);
- shader->setShadowPosition(4, 4);
- shader->setStrength(1.f);
+ shader->setShadowPosition(2, 3);
+ shader->setStrength(0.8f);
shader->setSize(.65f);
break;
case LRGestalt::LIGHT:
@@ -560,6 +570,61 @@ struct LRSmallKnob : LRKnob {
};
+/**
+ * @brief LR Small Knob
+ */
+struct LRSmallToggleKnob : LRKnob {
+ LRSmallToggleKnob(float length = 0.73) {
+ //TODO: parametrize start and end angle
+ minAngle = -length * (float) M_PI;
+ maxAngle = length * (float) M_PI;
+
+ setSVG(SVG::load(assetPlugin(plugin, "res/knobs/AlternateSmallToggleLight.svg")));
+
+ addSVGVariant(LRGestalt::DARK, SVG::load(assetPlugin(plugin, "res/knobs/AlternateSmallToggleLight.svg")));
+ addSVGVariant(LRGestalt::LIGHT, SVG::load(assetPlugin(plugin, "res/knobs/AlternateSmallToggleLight.svg")));
+ addSVGVariant(LRGestalt::AGED, SVG::load(assetPlugin(plugin, "res/knobs/AlternateSmallToggleLight.svg")));
+
+ speed = 3.0;
+ }
+
+
+ void onChange(EventChange &e) override {
+ value = round(value);
+ SVGKnob::onChange(e);
+ }
+
+
+ void onGestaltChange(LREventGestaltChange &e) override {
+ LRKnob::onGestaltChange(e);
+
+ switch (*gestalt) {
+ case LRGestalt::DARK:
+ setIndicatorDistance(13);
+ setIndicatorShape(5, 0.13);
+ shader->setShadowPosition(3, 3);
+ shader->setStrength(1.f);
+ shader->setSize(.65f);
+ break;
+ case LRGestalt::LIGHT:
+ shader->setShadowPosition(3, 3);
+ shader->setShadowPosition(2, 3);
+ shader->setStrength(0.3f);
+ shader->setSize(0.7f);
+ break;
+ case LRGestalt::AGED:
+ shader->setShadowPosition(3, 3);
+ shader->setShadowPosition(2, 3);
+ shader->setStrength(0.5f);
+ shader->setSize(0.7f);
+ break;
+ default:
+ break;
+ }
+ }
+};
+
+
/**
* @brief LR Alternate Small Knob
*/
diff --git a/plugins/community/repos/LindenbergResearch/src/LRModel.hpp b/plugins/community/repos/LindenbergResearch/src/LRModel.hpp
index 727dbad0..4728904b 100644
--- a/plugins/community/repos/LindenbergResearch/src/LRModel.hpp
+++ b/plugins/community/repos/LindenbergResearch/src/LRModel.hpp
@@ -70,7 +70,7 @@ struct LRModuleWidget : ModuleWidget {
/* Gestalt ID and UI settings */
- LRGestalt gestalt = DARK; // DARK == default
+ LRGestalt gestalt = LIGHT; // DARK == default
LRGestalt prevGestalt = NIL; // set to NIL to trigger change event on first start
bool gradient = true; // gradient used at panel
diff --git a/plugins/community/repos/LindenbergResearch/src/LindenbergResearch.cpp b/plugins/community/repos/LindenbergResearch/src/LindenbergResearch.cpp
index 85bf0314..4102a04f 100644
--- a/plugins/community/repos/LindenbergResearch/src/LindenbergResearch.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/LindenbergResearch.cpp
@@ -14,13 +14,13 @@ RACK_PLUGIN_MODEL_DECLARE(LindenbergResearch, SimpleFilter);
RACK_PLUGIN_MODEL_DECLARE(LindenbergResearch, VCO);
RACK_PLUGIN_MODEL_DECLARE(LindenbergResearch, Westcoast);
RACK_PLUGIN_MODEL_DECLARE(LindenbergResearch, DiodeVCF);
-RACK_PLUGIN_MODEL_DECLARE(LindenbergResearch, Korg35);
+RACK_PLUGIN_MODEL_DECLARE(LindenbergResearch, Type35);
RACK_PLUGIN_MODEL_DECLARE(LindenbergResearch, Speck);
RACK_PLUGIN_INIT(LindenbergResearch) {
RACK_PLUGIN_INIT_ID();
- RACK_PLUGIN_INIT_VERSION("0.6.4");
+ RACK_PLUGIN_INIT_VERSION("0.6.5");
RACK_PLUGIN_INIT_WEBSITE("https://github.com/lindenbergresearch/LRTRack");
RACK_PLUGIN_INIT_MANUAL("https://github.com/lindenbergresearch/LRTRack");
@@ -37,6 +37,6 @@ RACK_PLUGIN_INIT(LindenbergResearch) {
RACK_PLUGIN_MODEL_ADD(LindenbergResearch, VCO);
RACK_PLUGIN_MODEL_ADD(LindenbergResearch, Westcoast);
RACK_PLUGIN_MODEL_ADD(LindenbergResearch, DiodeVCF);
- RACK_PLUGIN_MODEL_ADD(LindenbergResearch, Korg35);
+ RACK_PLUGIN_MODEL_ADD(LindenbergResearch, Type35);
RACK_PLUGIN_MODEL_ADD(LindenbergResearch, Speck);
}
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/DSPEffect.hpp b/plugins/community/repos/LindenbergResearch/src/dsp/DSPEffect.hpp
index a470537f..f0ce3c8f 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/DSPEffect.hpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/DSPEffect.hpp
@@ -91,7 +91,7 @@ struct Decimator {
double kernel[RS_BUFFER_SIZE];
int inIndex;
int oversample, quality;
- double cutoff = 0.9;
+ double cutoff = 0.65;
Decimator(int oversample, int quality) {
@@ -134,7 +134,7 @@ struct Upsampler {
double kernel[RS_BUFFER_SIZE];
int inIndex;
int oversample, quality;
- double cutoff = 0.9;
+ double cutoff = 0.65;
Upsampler(int oversample, int quality) {
@@ -161,7 +161,7 @@ struct Upsampler {
inIndex++;
inIndex %= quality;
// Naively convolve each sample
- // TODO replace with polyphase filter hierarchy
+ // TODO replace with polyphase lpf hierarchy
for (int i = 0; i < oversample; i++) {
float y = 0.0;
for (int j = 0; j < quality; j++) {
@@ -228,13 +228,13 @@ struct Resampler {
* @brief Create up-sampled data out of two basic values
*/
void doUpsample(int channel, double in) {
- // interpolator[channel]->process(in * UPSAMPLE_COMPENSATION, up[channel]);
- y[channel].y0 = y[channel].y1;
- y[channel].y1 = in;
+ interpolator[channel]->process(in * UPSAMPLE_COMPENSATION, up[channel]);
+ /* y[channel].y0 = y[channel].y1;
+ y[channel].y1 = in;
- for (int i = 0; i < getFactor(); i++) {
- up[channel][i] = interpolate(channel, i + 1);
- }
+ for (int i = 0; i < getFactor(); i++) {
+ up[channel][i] = interpolate(channel, i + 1);
+ }*/
}
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.hpp b/plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.hpp
index a8973bbd..adf42e8e 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.hpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.hpp
@@ -8,7 +8,8 @@
using namespace rack;
-const static float TWOPI = lroundf(M_PI * 2.);
+const static float PI = 3.1415926535897932384626433832795;
+const static float TWOPI = PI * 2.f;
namespace dsp {
@@ -557,7 +558,7 @@ inline float fastlog(float x) {
* @param b exponent
* @return
*/
-inline double fastPow(double a, double b) {
+inline float fastPow(float a, float b) {
union {
double d;
int x[2];
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/LadderFilter.cpp b/plugins/community/repos/LindenbergResearch/src/dsp/LadderFilter.cpp
index ad79dff4..ece766db 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/LadderFilter.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/LadderFilter.cpp
@@ -42,7 +42,7 @@ void LadderFilter::process() {
b5 = ((b4 + t2) * p - b5 * f);
- // fade over filter poles from 3dB/oct (1P) => 48dB/oct (5P)
+ // fade over lpf poles from 3dB/oct (1P) => 48dB/oct (5P)
bx = fade5(b1, b2, b3, b4, b5, slope);
// saturate and add very low noise to have self oscillation with no input and high res
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/Lockhart.cpp b/plugins/community/repos/LindenbergResearch/src/dsp/Lockhart.cpp
index b23755c2..e0d5b3c5 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/Lockhart.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/Lockhart.cpp
@@ -87,7 +87,7 @@ double LockhartWavefolder::compute(double x) {
in = lh4.compute(in);
in = tanh1->next(in) * 2.f;
- //if (blockDC) in = dc->filter(in);
+ //if (blockDC) in = dc->lpf(in);
out = in * 10;
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.cpp b/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.cpp
index 43a719f4..b0ff3cc0 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.cpp
@@ -19,7 +19,7 @@ DSPBLOscillator::DSPBLOscillator(float sr) : DSPSystem(sr) {
*/
void DSPBLOscillator::invalidate() {
incr = getPhaseIncrement(param[FREQUENCY].value);
- n = (int) floorf(BLIT_HARMONICS / param[FREQUENCY].value);
+ n = floorf(sr * 0.5 / param[FREQUENCY].value);
}
@@ -33,7 +33,7 @@ void DSPBLOscillator::process() {
phase = wrapTWOPI(incr + phase);
/* pulse width */
- float w = param[PULSEWIDTH].value * (float) M_PI;
+ float w = param[PULSEWIDTH].value * PI;
/* get impulse train */
float blit1 = BLIT(n, phase);
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.hpp b/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.hpp
index 3738e96e..7075531d 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.hpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/Oscillator.hpp
@@ -124,12 +124,12 @@ public:
};
-struct DSPBLOscillator : DSPSystem<5, 5, 10> {
+struct DSPBLOscillator : DSPSystem<5, 6, 10> {
/**
* Bandwidth-limited threshold in hz.
* Should be at least SR/2 !
* */
- static constexpr float BLIT_HARMONICS = 18000.f;
+ //static constexpr float BLIT_HARMONICS = 22050.f;
static constexpr float NOTE_C4 = 261.626f;
enum Inputs {
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/Overdrive.cpp b/plugins/community/repos/LindenbergResearch/src/dsp/Overdrive.cpp
index fd1e3dc2..2849c829 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/Overdrive.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/Overdrive.cpp
@@ -40,7 +40,7 @@ double Overdrive::compute(double x) {
in = (1 + k) * (in) / (1 + k * abs(in));
in *= 1 / OVERDRIVE_GAIN * 0.3;
- // if (blockDC) in = dc->filter(in);
+ // if (blockDC) in = dc->lpf(in);
out = in;
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/RateConverter.cpp b/plugins/community/repos/LindenbergResearch/src/dsp/RateConverter.cpp
new file mode 100644
index 00000000..7368f16a
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/RateConverter.cpp
@@ -0,0 +1,867 @@
+/* *\
+** __ ___ ______ **
+** / / / _ \/_ __/ **
+** / /__/ , _/ / / Lindenberg **
+** /____/_/|_| /_/ Research Tec. **
+** **
+** **
+** https://github.com/lindenbergresearch/LRTRack **
+** heapdump@icloud.com **
+** **
+** Sound Modules for VCV Rack **
+** Copyright 2017/2018 by Patrick Lindenberg / LRT **
+** **
+** For Redistribution and use in source and binary forms, **
+** with or without modification please see LICENSE. **
+** **
+\* */
+
+#include
+#include
+#include "RateConverter.hpp"
+
+
+namespace dsp {
+
+RateConverter::RateConverter(void) {
+ irBuffer = nullptr;
+
+ inputBuffer = nullptr;
+
+ ratio = 1;
+ length = 0;
+
+ // reset all indices
+ delayPos = 0;
+ irBufferPos = 0;
+ inputPos = 0;
+ osPos = 0;
+}
+
+
+RateConverter::~RateConverter(void) {
+ delete[] inputBuffer;
+ delete[] irBuffer;
+}
+
+
+void RateConverter::init(int _ratio, int _length, float *pIRBuffer) {
+ length = _length;
+ ratio = _ratio;
+
+ delete[] irBuffer;
+
+ irBuffer = new float[_length];
+
+ memset(irBuffer, 0, _length * sizeof(float));
+
+ // memcpy(pIRBuffer, irBuffer, _length);
+
+ for (int i = 0; i < _length; i++) {
+ irBuffer[i] = pIRBuffer[i];
+ }
+
+ // dynamically allocate the input x buffers and save the pointers
+ delete[] inputBuffer;
+
+ // delete[] m_pRightInputBuffer;
+
+ inputBuffer = new float[_length];
+// m_pRightInputBuffer = new float[_length];
+
+ // flush x buffers
+ memset(inputBuffer, 0, _length * sizeof(float));
+ //memset(m_pRightInputBuffer, 0, _length * sizeof(float));
+
+ // reset all indices
+ delayPos = 0;
+ irBufferPos = 0;
+ inputPos = 0;
+ osPos = 0;
+
+}
+
+
+void RateConverter::reset() {
+ // flush x buffers
+ if (inputBuffer)
+ memset(inputBuffer, 0, length * sizeof(float));
+ /* if (m_pRightInputBuffer)
+ memset(m_pRightInputBuffer, 0, length * sizeof(float));*/
+
+ // reset all indices
+ delayPos = 0;
+ irBufferPos = 0;
+ inputPos = 0;
+ osPos = 0;
+}
+
+
+Decimator::Decimator(void) {
+}
+
+
+Decimator::~Decimator(void) {
+}
+
+
+/* L-Point Decimator
+ Input: Left and Right Input Buffers with L samples per buffer
+ Output: Left and Right Input Samples ynL, ynR
+
+ This function loops L times, decimating the outputs and returning the LAST output calculated
+
+ CALLER SUPPLIES INPUT BUFFERS!
+*/
+void Decimator::decimateSamples(float *buffer, float &out) {
+ if (!buffer)
+ return;
+
+ // counter for decimator optimization
+ osPos = -1;
+
+ for (int i = 0; i < ratio; i++) {
+ float tmp = 0;
+
+ // decimate next sample
+ //
+ // out and ynR are valid (and returned) after the last call to decimateNextOutputSample()
+ decimateNextOutputSample(buffer[i], tmp);
+
+ if (i == 0) {
+ out = tmp;
+ }
+ }
+}
+
+
+bool Decimator::decimateNextOutputSample(float x, float &out) {
+ inputBuffer[inputPos] = x;
+
+ osPos++;
+
+ if (osPos != 0) {
+ inputPos++;
+ if (inputPos >= length)
+ inputPos = 0;
+
+ return true;
+ }
+
+ // reset: read index for Delay Line -> write index
+ delayPos = inputPos;
+
+ // reset: read index for IR - > top (0)
+ irBufferPos = 0;
+
+ // accumulator
+ float yn_accumL = 0;
+
+ // This can be optimized!! Don't have to convolve on the first L-1, only need one convolution at the end
+ for (int i = 0; i < length; i++) {
+ // do the sum of products
+ yn_accumL += inputBuffer[delayPos] * irBuffer[irBufferPos];
+
+ // advance the IR index
+ irBufferPos++;
+
+ // decrement the Delay Line index
+ delayPos--;
+
+ // check for wrap of delay line (no need to check IR out)
+ if (delayPos < 0)
+ delayPos = length - 1;
+ }
+
+ // write out
+ out = yn_accumL;
+
+ // incremnent the pointers and wrap if necessaryx
+ inputPos++;
+ if (inputPos >= length)
+ inputPos = 0;
+
+ return true;
+}
+
+
+Interpolator::Interpolator(void) {
+
+}
+
+
+Interpolator::~Interpolator(void) {
+
+}
+
+
+/**
+ * @brief
+ * @param x input
+ * @param buffer buffer for oversampled values (4x = 4) etc.
+ */
+void Interpolator::interpolateSamples(float x, float *buffer) {
+ if (!buffer)
+ return;
+
+ for (int i = 0; i < ratio; i++) {
+ interpolateNextOutputSample(x, buffer[i]);
+ }
+}
+
+/* interpolateNextOutputSample
+ This does the work:
+ - first time through the loop apply inputs xnL and xnR and convolve
+ - other L-1 times, insert a zero into the delay and convolve
+*/
+// sepcial kind of convolution!
+void Interpolator::interpolateNextOutputSample(float x, float &out) {
+ // Read the Input
+ // if current L == 0 read xn
+ // else insert 0.0
+ inputBuffer[inputPos] = osPos == 0 ? x : 0.0;
+
+ // reset: read index for Delay Line -> write index
+ delayPos = inputPos;
+
+ // reset: read index for IR - > top (0)
+ irBufferPos = 0;
+
+ // accumulator
+ float sum = 0;
+
+ // convolve: OPTIMIZE THIS; can skip over delay elements with 0s in them, there are L-1 of them
+ for (int i = 0; i < length; i++) {
+ // do the sum of products
+ sum += inputBuffer[delayPos] * irBuffer[irBufferPos];
+
+ // advance the IR index
+ irBufferPos++;
+
+ // decrement the Delay Line index
+ delayPos--;
+
+ // check for wrap of delay line (no need to check IR buffer)
+ if (delayPos < 0)
+ delayPos = length - 1;
+ }
+
+ // out
+ out = sum * (float) ratio;
+
+ // incremnent the pointers and wrap if necessary
+ inputPos++;
+ if (inputPos >= length)
+ inputPos = 0;
+
+ osPos++;
+ if (osPos > ratio - 1)
+ osPos = 0;
+}
+
+
+NeoOversampler::NeoOversampler() {
+ enabled = true;
+
+ init();
+}
+
+
+/**
+ * @brief Initialize oversampler and fir filter
+ */
+void NeoOversampler::init() {
+ ratio = 4;
+ irSize = 19;
+
+
+ memset(&irBuffer, 0, 1024 * sizeof(float));
+
+ /*irBuffer[0] = 0.0000005445158422;
+ irBuffer[1] = 0.0000005707121318;
+ irBuffer[2] = -0.0000002019931742;
+ irBuffer[3] = -0.0000027811349810;
+ irBuffer[4] = -0.0000079230067058;
+ irBuffer[5] = -0.0000157045305968;
+ irBuffer[6] = -0.0000250798548223;
+ irBuffer[7] = -0.0000337998826581;
+ irBuffer[8] = -0.0000389039269066;
+ irBuffer[9] = -0.0000377439646400;
+ irBuffer[10] = -0.0000292139411613;
+ irBuffer[11] = -0.0000146474785652;
+ irBuffer[12] = 0.0000021514131276;
+ irBuffer[13] = 0.0000159797546075;
+ irBuffer[14] = 0.0000221549125854;
+ irBuffer[15] = 0.0000185557037184;
+ irBuffer[16] = 0.0000068430767897;
+ irBuffer[17] = -0.0000078581069829;
+ irBuffer[18] = -0.0000189057973330;
+ irBuffer[19] = -0.0000210210473597;
+ irBuffer[20] = -0.0000128407873490;
+ irBuffer[21] = 0.0000021356875095;
+ irBuffer[22] = 0.0000168605420185;
+ irBuffer[23] = 0.0000239175660681;
+ irBuffer[24] = 0.0000191849812836;
+ irBuffer[25] = 0.0000041909465835;
+ irBuffer[26] = -0.0000141687769428;
+ irBuffer[27] = -0.0000266804745479;
+ irBuffer[28] = -0.0000263464771706;
+ irBuffer[29] = -0.0000122119981825;
+ irBuffer[30] = 0.0000095742261692;
+ irBuffer[31] = 0.0000282986147795;
+ irBuffer[32] = 0.0000338566060236;
+ irBuffer[33] = 0.0000221132413571;
+ irBuffer[34] = -0.0000023518437047;
+ irBuffer[35] = -0.0000278249426628;
+ irBuffer[36] = -0.0000409598324040;
+ irBuffer[37] = -0.0000336766352120;
+ irBuffer[38] = -0.0000079384271885;
+ irBuffer[39] = 0.0000243380400207;
+ irBuffer[40] = 0.0000466642231913;
+ irBuffer[41] = 0.0000463036813017;
+ irBuffer[42] = 0.0000213879866351;
+ irBuffer[43] = -0.0000170829262061;
+ irBuffer[44] = -0.0000499074158142;
+ irBuffer[45] = -0.0000591524149058;
+ irBuffer[46] = -0.0000378185868612;
+ irBuffer[47] = 0.0000054448237279;
+ irBuffer[48] = 0.0000495497297379;
+ irBuffer[49] = 0.0000711093161954;
+ irBuffer[50] = 0.0000567109709664;
+ irBuffer[51] = 0.0000109462253022;
+ irBuffer[52] = -0.0000444776051154;
+ irBuffer[53] = -0.0000808542754385;
+ irBuffer[54] = -0.0000772124767536;
+ irBuffer[55] = -0.0000321749212162;
+ irBuffer[56] = 0.0000336578195856;
+ irBuffer[57] = 0.0000868840143085;
+ irBuffer[58] = 0.0000980972254183;
+ irBuffer[59] = 0.0000579376974201;
+ irBuffer[60] = -0.0000162688975252;
+ irBuffer[61] = -0.0000876213744050;
+ irBuffer[62] = -0.0001178134771180;
+ irBuffer[63] = -0.0000875171608641;
+ irBuffer[64] = -0.0000082237074821;
+ irBuffer[65] = 0.0000814914092189;
+ irBuffer[66] = 0.0001345096825389;
+ irBuffer[67] = 0.0001197328674607;
+ irBuffer[68] = 0.0000399582386308;
+ irBuffer[69] = -0.0000670430599712;
+ irBuffer[70] = -0.0001461128558731;
+ irBuffer[71] = -0.0001529414148536;
+ irBuffer[72] = -0.0000786032978795;
+ irBuffer[73] = 0.0000430524851254;
+ irBuffer[74] = 0.0001504003303126;
+ irBuffer[75] = 0.0001850285043474;
+ irBuffer[76] = 0.0001232606882695;
+ irBuffer[77] = -0.0000086719082901;
+ irBuffer[78] = -0.0001451331336284;
+ irBuffer[79] = -0.0002134631940862;
+ irBuffer[80] = -0.0001724150206428;
+ irBuffer[81] = -0.0000364416373486;
+ irBuffer[82] = 0.0001281958102481;
+ irBuffer[83] = 0.0002353741147090;
+ irBuffer[84] = 0.0002239009336336;
+ irBuffer[85] = 0.0000919931262615;
+ irBuffer[86] = -0.0000977704112302;
+ irBuffer[87] = -0.0002476811932866;
+ irBuffer[88] = -0.0002749281702563;
+ irBuffer[89] = -0.0001569569285493;
+ irBuffer[90] = 0.0000524965180375;
+ irBuffer[91] = 0.0002472368068993;
+ irBuffer[92] = 0.0003221260849386;
+ irBuffer[93] = 0.0002294945443282;
+ irBuffer[94] = 0.0000083545846792;
+ irBuffer[95] = -0.0002310073177796;
+ irBuffer[96] = -0.0003616396570578;
+ irBuffer[97] = -0.0003069138329010;
+ irBuffer[98] = -0.0000847206174512;
+ irBuffer[99] = 0.0001962697569979;
+ irBuffer[100] = 0.0003892597160302;
+ irBuffer[101] = 0.0003856586990878;
+ irBuffer[102] = 0.0001755936391419;
+ irBuffer[103] = -0.0001408394600730;
+ irBuffer[104] = -0.0004006113158539;
+ irBuffer[105] = -0.0004613618366420;
+ irBuffer[106] = -0.0002789076534100;
+ irBuffer[107] = 0.0000632931623841;
+ irBuffer[108] = 0.0003913739928976;
+ irBuffer[109] = 0.0005289468099363;
+ irBuffer[110] = 0.0003914636326954;
+ irBuffer[111] = 0.0000368107284885;
+ irBuffer[112] = -0.0003575389855541;
+ irBuffer[113] = -0.0005827903514728;
+ irBuffer[114] = -0.0005089115002193;
+ irBuffer[115] = -0.0001587389997439;
+ irBuffer[116] = 0.0002956803364214;
+ irBuffer[117] = 0.0006169307744130;
+ irBuffer[118] = 0.0006257825298235;
+ irBuffer[119] = 0.0003004157624673;
+ irBuffer[120] = -0.0002032436459558;
+ irBuffer[121] = -0.0006253321189433;
+ irBuffer[122] = -0.0007355912821367;
+ irBuffer[123] = -0.0004583036352415;
+ irBuffer[124] = 0.0000788305187598;
+ irBuffer[125] = 0.0006021905574016;
+ irBuffer[126] = 0.0008310037665069;
+ irBuffer[127] = 0.0006273413309827;
+ irBuffer[128] = 0.0000775332082412;
+ irBuffer[129] = -0.0005422755493782;
+ irBuffer[130] = -0.0009040769655257;
+ irBuffer[131] = -0.0008009540033527;
+ irBuffer[132] = -0.0002641671453603;
+ irBuffer[133] = 0.0004412865964696;
+ irBuffer[134] = 0.0009465577895753;
+ irBuffer[135] = 0.0009711356833577;
+ irBuffer[136] = 0.0004775526758749;
+ irBuffer[137] = -0.0002962144499179;
+ irBuffer[138] = -0.0009502378525212;
+ irBuffer[139] = -0.0011286106891930;
+ irBuffer[140] = -0.0007122103124857;
+ irBuffer[141] = 0.0001056927067111;
+ irBuffer[142] = 0.0009073557448573;
+ irBuffer[143] = 0.0012630778364837;
+ irBuffer[144] = 0.0009606519597583;
+ irBuffer[145] = 0.0001296803529840;
+ irBuffer[146] = -0.0008110329508781;
+ irBuffer[147] = -0.0013635336654261;
+ irBuffer[148] = -0.0012134213466197;
+ irBuffer[149] = -0.0004070691065863;
+ irBuffer[150] = 0.0006557236192748;
+ irBuffer[151] = 0.0014186699409038;
+ irBuffer[152] = 0.0014592278748751;
+ irBuffer[153] = 0.0007211973425001;
+ irBuffer[154] = -0.0004376557189971;
+ irBuffer[155] = -0.0014173235977069;
+ irBuffer[156] = -0.0016851695254445;
+ irBuffer[157] = -0.0010642196284607;
+ irBuffer[158] = 0.0001552503381390;
+ irBuffer[159] = 0.0013489727862179;
+ irBuffer[160] = 0.0018770446768031;
+ irBuffer[161] = 0.0014256818685681;
+ irBuffer[162] = 0.0001905011304189;
+ irBuffer[163] = -0.0012042585294694;
+ irBuffer[164] = -0.0020197455305606;
+ irBuffer[165] = -0.0017925744177774;
+ irBuffer[166] = -0.0005957146058790;
+ irBuffer[167] = 0.0009755205828696;
+ irBuffer[168] = 0.0020977298263460;
+ irBuffer[169] = 0.0021494934335351;
+ irBuffer[170] = 0.0010533761233091;
+ irBuffer[171] = -0.0006573111750185;
+ irBuffer[172] = -0.0020955423824489;
+ irBuffer[173] = -0.0024788931477815;
+ irBuffer[174] = -0.0015531908720732;
+ irBuffer[175] = 0.0002468732418492;
+ irBuffer[176] = 0.0019983709789813;
+ irBuffer[177] = 0.0027614291757345;
+ irBuffer[178] = 0.0020815343596041;
+ irBuffer[179] = 0.0002554488019086;
+ irBuffer[180] = -0.0017925972351804;
+ irBuffer[181] = -0.0029763551428914;
+ irBuffer[182] = -0.0026214842218906;
+ irBuffer[183] = -0.0008458612719551;
+ irBuffer[184] = 0.0014663392212242;
+ irBuffer[185] = 0.0031019740272313;
+ irBuffer[186] = 0.0031529506668448;
+ irBuffer[187] = 0.0015168727841228;
+ irBuffer[188] = -0.0010099314386025;
+ irBuffer[189] = -0.0031160889193416;
+ irBuffer[190] = -0.0036528608761728;
+ irBuffer[191] = -0.0022571331355721;
+ irBuffer[192] = 0.0004163304984104;
+ irBuffer[193] = 0.0029964295681566;
+ irBuffer[194] = 0.0040953969582915;
+ irBuffer[195] = 0.0030513887759298;
+ irBuffer[196] = 0.0003186264366377;
+ irBuffer[197] = -0.0027209594845772;
+ irBuffer[198] = -0.0044521889649332;
+ irBuffer[199] = -0.0038805003277957;
+ irBuffer[200] = -0.0011961093405262;
+ irBuffer[201] = 0.0022680191323161;
+ irBuffer[202] = 0.0046924264170229;
+ irBuffer[203] = 0.0047215311788023;
+ irBuffer[204] = 0.0022144161630422;
+ irBuffer[205] = -0.0016161559615284;
+ irBuffer[206] = -0.0047827241942286;
+ irBuffer[207] = -0.0055478112772107;
+ irBuffer[208] = -0.0033693523146212;
+ irBuffer[209] = 0.0007435118313879;
+ irBuffer[210] = 0.0046866005286574;
+ irBuffer[211] = 0.0063289487734437;
+ irBuffer[212] = 0.0046550347469747;
+ irBuffer[213] = 0.0003735880600289;
+ irBuffer[214] = -0.0043631680309772;
+ irBuffer[215] = -0.0070305466651917;
+ irBuffer[216] = -0.0060652270913124;
+ irBuffer[217] = -0.0017632801318541;
+ irBuffer[218] = 0.0037645003758371;
+ irBuffer[219] = 0.0076133953407407;
+ irBuffer[220] = 0.0075955823995173;
+ irBuffer[221] = 0.0034630466252565;
+ irBuffer[222] = -0.0028304771985859;
+ irBuffer[223] = -0.0080314734950662;
+ irBuffer[224] = -0.0092473234981298;
+ irBuffer[225] = -0.0055286134593189;
+ irBuffer[226] = 0.0014789294218645;
+ irBuffer[227] = 0.0082277162000537;
+ irBuffer[228] = 0.0110338740050793;
+ irBuffer[229] = 0.0080511523410678;
+ irBuffer[230] = 0.0004142033576500;
+ irBuffer[231] = -0.0081247519701719;
+ irBuffer[232] = -0.0129936235025525;
+ irBuffer[233] = -0.0111927380785346;
+ irBuffer[234] = -0.0030573662370443;
+ irBuffer[235] = 0.0076039703562856;
+ irBuffer[236] = 0.0152177270501852;
+ irBuffer[237] = 0.0152677698060870;
+ irBuffer[238] = 0.0068449787795544;
+ irBuffer[239] = -0.0064526787027717;
+ irBuffer[240] = -0.0179194156080484;
+ irBuffer[241] = -0.0209582298994064;
+ irBuffer[242] = -0.0126397209241986;
+ irBuffer[243] = 0.0042087305337191;
+ irBuffer[244] = 0.0216464996337891;
+ irBuffer[245] = 0.0300200320780277;
+ irBuffer[246] = 0.0227684658020735;
+ irBuffer[247] = 0.0004358185979072;
+ irBuffer[248] = -0.0281703099608421;
+ irBuffer[249] = -0.0485937669873238;
+ irBuffer[250] = -0.0463617891073227;
+ irBuffer[251] = -0.0134116141125560;
+ irBuffer[252] = 0.0474678650498390;
+ irBuffer[253] = 0.1222959980368614;
+ irBuffer[254] = 0.1901284903287888;
+ irBuffer[255] = 0.2303789854049683;
+ irBuffer[256] = 0.2303789854049683;
+ irBuffer[257] = 0.1901284903287888;
+ irBuffer[258] = 0.1222959980368614;
+ irBuffer[259] = 0.0474678650498390;
+ irBuffer[260] = -0.0134116141125560;
+ irBuffer[261] = -0.0463617891073227;
+ irBuffer[262] = -0.0485937669873238;
+ irBuffer[263] = -0.0281703099608421;
+ irBuffer[264] = 0.0004358185979072;
+ irBuffer[265] = 0.0227684658020735;
+ irBuffer[266] = 0.0300200320780277;
+ irBuffer[267] = 0.0216464996337891;
+ irBuffer[268] = 0.0042087305337191;
+ irBuffer[269] = -0.0126397209241986;
+ irBuffer[270] = -0.0209582298994064;
+ irBuffer[271] = -0.0179194156080484;
+ irBuffer[272] = -0.0064526787027717;
+ irBuffer[273] = 0.0068449787795544;
+ irBuffer[274] = 0.0152677698060870;
+ irBuffer[275] = 0.0152177270501852;
+ irBuffer[276] = 0.0076039703562856;
+ irBuffer[277] = -0.0030573662370443;
+ irBuffer[278] = -0.0111927380785346;
+ irBuffer[279] = -0.0129936235025525;
+ irBuffer[280] = -0.0081247519701719;
+ irBuffer[281] = 0.0004142033576500;
+ irBuffer[282] = 0.0080511523410678;
+ irBuffer[283] = 0.0110338740050793;
+ irBuffer[284] = 0.0082277162000537;
+ irBuffer[285] = 0.0014789294218645;
+ irBuffer[286] = -0.0055286134593189;
+ irBuffer[287] = -0.0092473234981298;
+ irBuffer[288] = -0.0080314734950662;
+ irBuffer[289] = -0.0028304771985859;
+ irBuffer[290] = 0.0034630466252565;
+ irBuffer[291] = 0.0075955823995173;
+ irBuffer[292] = 0.0076133953407407;
+ irBuffer[293] = 0.0037645003758371;
+ irBuffer[294] = -0.0017632801318541;
+ irBuffer[295] = -0.0060652270913124;
+ irBuffer[296] = -0.0070305466651917;
+ irBuffer[297] = -0.0043631680309772;
+ irBuffer[298] = 0.0003735880600289;
+ irBuffer[299] = 0.0046550347469747;
+ irBuffer[300] = 0.0063289487734437;
+ irBuffer[301] = 0.0046866005286574;
+ irBuffer[302] = 0.0007435118313879;
+ irBuffer[303] = -0.0033693523146212;
+ irBuffer[304] = -0.0055478112772107;
+ irBuffer[305] = -0.0047827241942286;
+ irBuffer[306] = -0.0016161559615284;
+ irBuffer[307] = 0.0022144161630422;
+ irBuffer[308] = 0.0047215311788023;
+ irBuffer[309] = 0.0046924264170229;
+ irBuffer[310] = 0.0022680191323161;
+ irBuffer[311] = -0.0011961093405262;
+ irBuffer[312] = -0.0038805003277957;
+ irBuffer[313] = -0.0044521889649332;
+ irBuffer[314] = -0.0027209594845772;
+ irBuffer[315] = 0.0003186264366377;
+ irBuffer[316] = 0.0030513887759298;
+ irBuffer[317] = 0.0040953969582915;
+ irBuffer[318] = 0.0029964295681566;
+ irBuffer[319] = 0.0004163304984104;
+ irBuffer[320] = -0.0022571331355721;
+ irBuffer[321] = -0.0036528608761728;
+ irBuffer[322] = -0.0031160889193416;
+ irBuffer[323] = -0.0010099314386025;
+ irBuffer[324] = 0.0015168727841228;
+ irBuffer[325] = 0.0031529506668448;
+ irBuffer[326] = 0.0031019740272313;
+ irBuffer[327] = 0.0014663392212242;
+ irBuffer[328] = -0.0008458612719551;
+ irBuffer[329] = -0.0026214842218906;
+ irBuffer[330] = -0.0029763551428914;
+ irBuffer[331] = -0.0017925972351804;
+ irBuffer[332] = 0.0002554488019086;
+ irBuffer[333] = 0.0020815343596041;
+ irBuffer[334] = 0.0027614291757345;
+ irBuffer[335] = 0.0019983709789813;
+ irBuffer[336] = 0.0002468732418492;
+ irBuffer[337] = -0.0015531908720732;
+ irBuffer[338] = -0.0024788931477815;
+ irBuffer[339] = -0.0020955423824489;
+ irBuffer[340] = -0.0006573111750185;
+ irBuffer[341] = 0.0010533761233091;
+ irBuffer[342] = 0.0021494934335351;
+ irBuffer[343] = 0.0020977298263460;
+ irBuffer[344] = 0.0009755205828696;
+ irBuffer[345] = -0.0005957146058790;
+ irBuffer[346] = -0.0017925744177774;
+ irBuffer[347] = -0.0020197455305606;
+ irBuffer[348] = -0.0012042585294694;
+ irBuffer[349] = 0.0001905011304189;
+ irBuffer[350] = 0.0014256818685681;
+ irBuffer[351] = 0.0018770446768031;
+ irBuffer[352] = 0.0013489727862179;
+ irBuffer[353] = 0.0001552503381390;
+ irBuffer[354] = -0.0010642196284607;
+ irBuffer[355] = -0.0016851695254445;
+ irBuffer[356] = -0.0014173235977069;
+ irBuffer[357] = -0.0004376557189971;
+ irBuffer[358] = 0.0007211973425001;
+ irBuffer[359] = 0.0014592278748751;
+ irBuffer[360] = 0.0014186699409038;
+ irBuffer[361] = 0.0006557236192748;
+ irBuffer[362] = -0.0004070691065863;
+ irBuffer[363] = -0.0012134213466197;
+ irBuffer[364] = -0.0013635336654261;
+ irBuffer[365] = -0.0008110329508781;
+ irBuffer[366] = 0.0001296803529840;
+ irBuffer[367] = 0.0009606519597583;
+ irBuffer[368] = 0.0012630778364837;
+ irBuffer[369] = 0.0009073557448573;
+ irBuffer[370] = 0.0001056927067111;
+ irBuffer[371] = -0.0007122103124857;
+ irBuffer[372] = -0.0011286106891930;
+ irBuffer[373] = -0.0009502378525212;
+ irBuffer[374] = -0.0002962144499179;
+ irBuffer[375] = 0.0004775526758749;
+ irBuffer[376] = 0.0009711356833577;
+ irBuffer[377] = 0.0009465577895753;
+ irBuffer[378] = 0.0004412865964696;
+ irBuffer[379] = -0.0002641671453603;
+ irBuffer[380] = -0.0008009540033527;
+ irBuffer[381] = -0.0009040769655257;
+ irBuffer[382] = -0.0005422755493782;
+ irBuffer[383] = 0.0000775332082412;
+ irBuffer[384] = 0.0006273413309827;
+ irBuffer[385] = 0.0008310037665069;
+ irBuffer[386] = 0.0006021905574016;
+ irBuffer[387] = 0.0000788305187598;
+ irBuffer[388] = -0.0004583036352415;
+ irBuffer[389] = -0.0007355912821367;
+ irBuffer[390] = -0.0006253321189433;
+ irBuffer[391] = -0.0002032436459558;
+ irBuffer[392] = 0.0003004157624673;
+ irBuffer[393] = 0.0006257825298235;
+ irBuffer[394] = 0.0006169307744130;
+ irBuffer[395] = 0.0002956803364214;
+ irBuffer[396] = -0.0001587389997439;
+ irBuffer[397] = -0.0005089115002193;
+ irBuffer[398] = -0.0005827903514728;
+ irBuffer[399] = -0.0003575389855541;
+ irBuffer[400] = 0.0000368107284885;
+ irBuffer[401] = 0.0003914636326954;
+ irBuffer[402] = 0.0005289468099363;
+ irBuffer[403] = 0.0003913739928976;
+ irBuffer[404] = 0.0000632931623841;
+ irBuffer[405] = -0.0002789076534100;
+ irBuffer[406] = -0.0004613618366420;
+ irBuffer[407] = -0.0004006113158539;
+ irBuffer[408] = -0.0001408394600730;
+ irBuffer[409] = 0.0001755936391419;
+ irBuffer[410] = 0.0003856586990878;
+ irBuffer[411] = 0.0003892597160302;
+ irBuffer[412] = 0.0001962697569979;
+ irBuffer[413] = -0.0000847206174512;
+ irBuffer[414] = -0.0003069138329010;
+ irBuffer[415] = -0.0003616396570578;
+ irBuffer[416] = -0.0002310073177796;
+ irBuffer[417] = 0.0000083545846792;
+ irBuffer[418] = 0.0002294945443282;
+ irBuffer[419] = 0.0003221260849386;
+ irBuffer[420] = 0.0002472368068993;
+ irBuffer[421] = 0.0000524965180375;
+ irBuffer[422] = -0.0001569569285493;
+ irBuffer[423] = -0.0002749281702563;
+ irBuffer[424] = -0.0002476811932866;
+ irBuffer[425] = -0.0000977704112302;
+ irBuffer[426] = 0.0000919931262615;
+ irBuffer[427] = 0.0002239009336336;
+ irBuffer[428] = 0.0002353741147090;
+ irBuffer[429] = 0.0001281958102481;
+ irBuffer[430] = -0.0000364416373486;
+ irBuffer[431] = -0.0001724150206428;
+ irBuffer[432] = -0.0002134631940862;
+ irBuffer[433] = -0.0001451331336284;
+ irBuffer[434] = -0.0000086719082901;
+ irBuffer[435] = 0.0001232606882695;
+ irBuffer[436] = 0.0001850285043474;
+ irBuffer[437] = 0.0001504003303126;
+ irBuffer[438] = 0.0000430524851254;
+ irBuffer[439] = -0.0000786032978795;
+ irBuffer[440] = -0.0001529414148536;
+ irBuffer[441] = -0.0001461128558731;
+ irBuffer[442] = -0.0000670430599712;
+ irBuffer[443] = 0.0000399582386308;
+ irBuffer[444] = 0.0001197328674607;
+ irBuffer[445] = 0.0001345096825389;
+ irBuffer[446] = 0.0000814914092189;
+ irBuffer[447] = -0.0000082237074821;
+ irBuffer[448] = -0.0000875171608641;
+ irBuffer[449] = -0.0001178134771180;
+ irBuffer[450] = -0.0000876213744050;
+ irBuffer[451] = -0.0000162688975252;
+ irBuffer[452] = 0.0000579376974201;
+ irBuffer[453] = 0.0000980972254183;
+ irBuffer[454] = 0.0000868840143085;
+ irBuffer[455] = 0.0000336578195856;
+ irBuffer[456] = -0.0000321749212162;
+ irBuffer[457] = -0.0000772124767536;
+ irBuffer[458] = -0.0000808542754385;
+ irBuffer[459] = -0.0000444776051154;
+ irBuffer[460] = 0.0000109462253022;
+ irBuffer[461] = 0.0000567109709664;
+ irBuffer[462] = 0.0000711093161954;
+ irBuffer[463] = 0.0000495497297379;
+ irBuffer[464] = 0.0000054448237279;
+ irBuffer[465] = -0.0000378185868612;
+ irBuffer[466] = -0.0000591524149058;
+ irBuffer[467] = -0.0000499074158142;
+ irBuffer[468] = -0.0000170829262061;
+ irBuffer[469] = 0.0000213879866351;
+ irBuffer[470] = 0.0000463036813017;
+ irBuffer[471] = 0.0000466642231913;
+ irBuffer[472] = 0.0000243380400207;
+ irBuffer[473] = -0.0000079384271885;
+ irBuffer[474] = -0.0000336766352120;
+ irBuffer[475] = -0.0000409598324040;
+ irBuffer[476] = -0.0000278249426628;
+ irBuffer[477] = -0.0000023518437047;
+ irBuffer[478] = 0.0000221132413571;
+ irBuffer[479] = 0.0000338566060236;
+ irBuffer[480] = 0.0000282986147795;
+ irBuffer[481] = 0.0000095742261692;
+ irBuffer[482] = -0.0000122119981825;
+ irBuffer[483] = -0.0000263464771706;
+ irBuffer[484] = -0.0000266804745479;
+ irBuffer[485] = -0.0000141687769428;
+ irBuffer[486] = 0.0000041909465835;
+ irBuffer[487] = 0.0000191849812836;
+ irBuffer[488] = 0.0000239175660681;
+ irBuffer[489] = 0.0000168605420185;
+ irBuffer[490] = 0.0000021356875095;
+ irBuffer[491] = -0.0000128407873490;
+ irBuffer[492] = -0.0000210210473597;
+ irBuffer[493] = -0.0000189057973330;
+ irBuffer[494] = -0.0000078581069829;
+ irBuffer[495] = 0.0000068430767897;
+ irBuffer[496] = 0.0000185557037184;
+ irBuffer[497] = 0.0000221549125854;
+ irBuffer[498] = 0.0000159797546075;
+ irBuffer[499] = 0.0000021514131276;
+ irBuffer[500] = -0.0000146474785652;
+ irBuffer[501] = -0.0000292139411613;
+ irBuffer[502] = -0.0000377439646400;
+ irBuffer[503] = -0.0000389039269066;
+ irBuffer[504] = -0.0000337998826581;
+ irBuffer[505] = -0.0000250798548223;
+ irBuffer[506] = -0.0000157045305968;
+ irBuffer[507] = -0.0000079230067058;
+ irBuffer[508] = -0.0000027811349810;
+ irBuffer[509] = -0.0000002019931742;
+ irBuffer[510] = 0.0000005707121318;
+ irBuffer[511] = 0.0000005445158422;*/
+
+ irBuffer[0] = 0.0000000000000001;
+ irBuffer[1] = 0.0076966499909759;
+ irBuffer[2] = 0.0251346025615931;
+ irBuffer[3] = 0.0478625856339931;
+ irBuffer[4] = 0.0784611627459526;
+ irBuffer[5] = 0.1136875599622726;
+ irBuffer[6] = 0.1501039862632751;
+ irBuffer[7] = 0.1820416748523712;
+ irBuffer[8] = 0.2040369659662247;
+ irBuffer[9] = 0.2117607295513153;
+ irBuffer[10] = 0.2040369659662247;
+ irBuffer[11] = 0.1820416748523712;
+ irBuffer[12] = 0.1501039862632751;
+ irBuffer[13] = 0.1136875599622726;
+ irBuffer[14] = 0.0784611627459526;
+ irBuffer[15] = 0.0478625856339931;
+ irBuffer[16] = 0.0251346025615931;
+ irBuffer[17] = 0.0076966499909759;
+ irBuffer[18] = 0.0000000000000001;
+
+ // now init the units
+ interpolator.init(ratio, irSize, &irBuffer[0]);
+ decimator.init(ratio, irSize, &irBuffer[0]);
+
+ // dynamically allocate the input x buffers and save the pointers
+ interpBuffer = new float[ratio];
+
+ // flush interp buffers
+ memset(interpBuffer, 0, ratio * sizeof(float));
+
+ // dynamically allocate the input x buffers and save the pointers
+ decimBuffer = new float[ratio];
+
+ // flush deci buffers
+ memset(decimBuffer, 0, ratio * sizeof(float));
+
+
+ // oversampling
+ interpolator.reset();
+ decimator.reset();
+}
+
+
+/**
+ * @brief
+ * @param x input
+ * @return output
+ */
+float NeoOversampler::compute(float x) {
+ float y;
+
+ /* just pass a single computation, if os is turned off */
+ if (!enabled) return process(x);
+
+ interpolator.interpolateSamples(x, interpBuffer);
+
+ for (int i = 0; i < ratio; ++i) {
+ // do computation n times out of the interpolated buffer and write back to decimator buffer
+ decimBuffer[i] = process(interpBuffer[i]);
+ }
+
+ decimator.decimateSamples(decimBuffer, y);
+
+ return y;
+}
+
+
+float TanhOS::process(float x) {
+ return erff(x * gain) * 5.f;
+}
+
+
+TanhOS::TanhOS() {}
+}
+
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/RateConverter.hpp b/plugins/community/repos/LindenbergResearch/src/dsp/RateConverter.hpp
new file mode 100644
index 00000000..00b97278
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/RateConverter.hpp
@@ -0,0 +1,142 @@
+/* *\
+** __ ___ ______ **
+** / / / _ \/_ __/ **
+** / /__/ , _/ / / Lindenberg **
+** /____/_/|_| /_/ Research Tec. **
+** **
+** **
+** https://github.com/lindenbergresearch/LRTRack **
+** heapdump@icloud.com **
+** **
+** Sound Modules for VCV Rack **
+** Copyright 2017/2018 by Patrick Lindenberg / LRT **
+** **
+** For Redistribution and use in source and binary forms, **
+** with or without modification please see LICENSE. **
+** **
+\* */
+
+#pragma once
+
+namespace dsp {
+
+class RateConverter {
+public:
+ RateConverter(void);
+ virtual ~RateConverter(void);
+
+ // buffer for the impulse response h[n] of the FIR
+ float *irBuffer;
+
+ // buffers for the transversal delay lines, one for each input
+ float *inputBuffer;
+ // float *m_pRightInputBuffer;
+
+ // read index for delay lines (input x buffers)
+ int delayPos;
+
+ // read index for impulse response buffers
+ int irBufferPos;
+
+ // write index for input x buffer
+ int inputPos;
+
+ int ratio; // OS value, 4 = 4X Oversampling
+
+ // counters and index values for the convolutions
+ int osPos;
+ int length;
+
+ // initializer - creates the buffers and loads the FIR IR
+ void init(int _ratio, int _length, float *pIRBuffer);
+
+ // flush buffers
+ void reset();
+
+
+ // overrides for derived objects
+ //
+ // interpolateSamples: take one pair of L/R samples and produce L-length buffers of samples
+ virtual void interpolateSamples(float xnL, float *pLeftInterpBuffer) {};
+
+
+ // inner loop function that processes just one pair of inputs
+ virtual void interpolateNextOutputSample(float xnL, float &fLeftOutput) {};
+
+
+ // decimateSamples: take one pai rL-length buffers of samples and decimate down to just one pair of output samples
+ virtual void decimateSamples(float *pLeftDeciBuffer, float &ynL) {};
+
+
+ // inner loop function that processes just one pair of inputs
+ virtual bool decimateNextOutputSample(float xnL, float &fLeftOutput) { return true; };
+};
+
+
+class Decimator : public RateConverter {
+public:
+ Decimator(void);
+ ~Decimator(void);
+
+ bool decimateNextOutputSample(float x, float &out) override;
+ void decimateSamples(float *buffer, float &out) override;
+};
+
+
+class Interpolator : public RateConverter {
+public:
+ Interpolator(void);
+ ~Interpolator(void);
+
+ void interpolateNextOutputSample(float x, float &fLeftOutput) override;
+ void interpolateSamples(float x, float *buffer) override;
+
+};
+
+
+/**
+ * @brief New oversampling class that uses polyphase
+ */
+class NeoOversampler {
+private:
+ int irSize;
+ float irBuffer[1024];
+ int ratio = 4;
+
+ void init();
+
+ Interpolator interpolator;
+ Decimator decimator;
+
+ float *interpBuffer;
+ float *decimBuffer;
+
+public:
+ bool enabled;
+
+ NeoOversampler();
+
+
+ virtual float process(float x) { return x; };
+
+ float compute(float x);
+
+};
+
+
+/**
+ * @brief Just for test!
+ */
+struct TanhOS : NeoOversampler {
+
+ float gain = 0.f;
+
+ TanhOS();
+
+ virtual float process(float x) override;
+
+};
+
+
+}
+
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.cpp b/plugins/community/repos/LindenbergResearch/src/dsp/Type35Filter.cpp
similarity index 73%
rename from plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.cpp
rename to plugins/community/repos/LindenbergResearch/src/dsp/Type35Filter.cpp
index dee88f38..ac0e1376 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/Type35Filter.cpp
@@ -16,7 +16,7 @@
** **
\* */
-#include "Korg35Filter.hpp"
+#include "Type35Filter.hpp"
#include "DSPEffect.hpp"
#include "DSPMath.hpp"
@@ -26,7 +26,7 @@
* @param sr SampleRate
* @param type Lowpass / Highpass
*/
-dsp::Korg35FilterStage::Korg35FilterStage(float sr, FilterType type) : DSPEffect(sr) {
+dsp::Type35FilterStage::Type35FilterStage(float sr, FilterType type) : DSPEffect(sr) {
this->type = type;
}
@@ -34,7 +34,7 @@ dsp::Korg35FilterStage::Korg35FilterStage(float sr, FilterType type) : DSPEffect
/**
* @brief Init stage
*/
-void dsp::Korg35FilterStage::init() {
+void dsp::Type35FilterStage::init() {
type = LP_STAGE;
alpha = 1.f;
beta = 1.f;
@@ -46,7 +46,7 @@ void dsp::Korg35FilterStage::init() {
/**
* @brief Recompute filter parameter
*/
-void dsp::Korg35FilterStage::invalidate() {
+void dsp::Type35FilterStage::invalidate() {
// only process in dedicated mode
if (!dedicated) return;
@@ -62,7 +62,7 @@ void dsp::Korg35FilterStage::invalidate() {
/**
* @brief Update filter and compute next sample
*/
-void dsp::Korg35FilterStage::process() {
+void dsp::Type35FilterStage::process() {
// v(n)
float vn = (in - zn1) * alpha;
@@ -72,7 +72,7 @@ void dsp::Korg35FilterStage::process() {
float hpf = in - lpf;
- // switch filter type
+ // switch lpf type
if (type == LP_STAGE) {
out = lpf;
} else {
@@ -85,10 +85,12 @@ void dsp::Korg35FilterStage::process() {
/**
* @brief Init main filter
*/
-void dsp::Korg35Filter::init() {
+void dsp::Type35Filter::init() {
fc = sr / 2.f;
peak = 0.f;
+
+
/* lowpass stages */
lpf1->init();
lpf2->init();
@@ -102,8 +104,18 @@ void dsp::Korg35Filter::init() {
/**
* @brief Recompute filter parameter
*/
-void dsp::Korg35Filter::invalidate() {
- float frqHz = MAX_FREQUENCY / 1000.f * powf(1000.f, fc);
+void dsp::Type35Filter::invalidate() {
+ float frqHz;
+
+ fc = clamp(fc, 0.f, 1.1f);
+ peak = clamp(peak, 0.0001, 1.1f);
+
+ if (type == LPF)
+ frqHz = (MAX_FREQUENCY / 1000.f) * powf(950.f, fc) - 20.f;
+ else
+ frqHz = (MAX_FREQUENCY / 1000.f) * powf(1000.f, fc);
+
+ peak = cubicShape(peak) * 2.f + noise.nextFloat(10e-7);
float wd = TWOPI * frqHz;
float T = 1.f / sr;
@@ -138,7 +150,7 @@ void dsp::Korg35Filter::invalidate() {
/**
* @brief Compute next sample for output depending on filter type
*/
-void dsp::Korg35Filter::process() {
+void dsp::Type35Filter::process() {
type == LPF ? processLPF() : processHPF();
}
@@ -146,8 +158,8 @@ void dsp::Korg35Filter::process() {
/**
* @brief Do the lowpass filtering and oversampling
*/
-void dsp::Korg35Filter::processLPF() {
- lpf1->in = in;
+void dsp::Type35Filter::processLPF() {
+ lpf1->in = in + noise.nextFloat(NOISE_GAIN);;
lpf1->process();
float y1 = lpf1->out;
@@ -156,7 +168,7 @@ void dsp::Korg35Filter::processLPF() {
float u = Ga * (y1 + s35h);
//float y = peak * fastatan(sat * u * 0.1) * 10.f;
- u = tanhf(sat * u * 0.1) * 10.f;
+ u = fastatan(sat * u * 0.1) * 10.f;
lpf2->in = u;
lpf2->process();
@@ -179,8 +191,8 @@ void dsp::Korg35Filter::processLPF() {
/**
* @brief Do the highpass filtering and oversampling
*/
-void dsp::Korg35Filter::processHPF() {
- hpf1->in = in;
+void dsp::Type35Filter::processHPF() {
+ hpf1->in = in + noise.nextFloat(NOISE_GAIN);
hpf1->process();
float y1 = hpf1->out;
@@ -207,14 +219,32 @@ void dsp::Korg35Filter::processHPF() {
* @brief Update samplerate
* @param sr SR
*/
-void dsp::Korg35Filter::setSamplerate(float sr) {
- DSPEffect::setSamplerate(sr);
+void dsp::Type35Filter::setSamplerate(float sr) {
+ DSPEffect::setSamplerate(sr * OVERSAMPLE);
// derive samplerate change
- lpf1->setSamplerate(sr);
- lpf2->setSamplerate(sr);
- hpf1->setSamplerate(sr);
- hpf2->setSamplerate(sr);
+ lpf1->setSamplerate(sr * OVERSAMPLE);
+ lpf2->setSamplerate(sr * OVERSAMPLE);
+ hpf1->setSamplerate(sr * OVERSAMPLE);
+ hpf2->setSamplerate(sr * OVERSAMPLE);
invalidate();
}
+
+
+/**
+ * @brief Top function which handles the oversampling
+ */
+void dsp::Type35Filter::process2() {
+ rs->doUpsample(IN, in);
+
+ for (int i = 0; i < rs->getFactor(); i++) {
+ in = (float) rs->getUpsampled(IN)[i];
+
+ process();
+
+ rs->data[IN][i] = out;
+ }
+
+ out = (float) rs->getDownsampled(IN);;
+}
diff --git a/plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.hpp b/plugins/community/repos/LindenbergResearch/src/dsp/Type35Filter.hpp
similarity index 70%
rename from plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.hpp
rename to plugins/community/repos/LindenbergResearch/src/dsp/Type35Filter.hpp
index 5fcc2e38..2ad39ee8 100644
--- a/plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.hpp
+++ b/plugins/community/repos/LindenbergResearch/src/dsp/Type35Filter.hpp
@@ -28,7 +28,7 @@ namespace dsp {
/**
* @brief Represents one filter stage
*/
-struct Korg35FilterStage : DSPEffect {
+struct Type35FilterStage : DSPEffect {
enum FilterType {
LP_STAGE, // lowpass stage
HP_STAGE // highpass stage
@@ -44,7 +44,7 @@ struct Korg35FilterStage : DSPEffect {
float in, out;
- Korg35FilterStage(float sr, FilterType type);
+ Type35FilterStage(float sr, FilterType type);
inline float getFeedback() {
@@ -61,17 +61,22 @@ struct Korg35FilterStage : DSPEffect {
/**
* @brief Actual Korg35 Filter Class
*/
-struct Korg35Filter : DSPEffect {
+struct Type35Filter : DSPEffect {
static constexpr float MAX_FREQUENCY = 20000.f;
+ static const int OVERSAMPLE = 4;
+ static constexpr float NOISE_GAIN = 10e-9f; // internal noise gain used for self-oscillation
+ static const int IN = 0;
enum FilterType {
- LPF, // lowpass
- HPF // highpass
+ LPF, // lowpass
+ HPF // highpass
};
- Korg35FilterStage *lpf1, *lpf2, *hpf1, *hpf2;
+ Type35FilterStage *lpf1, *lpf2, *hpf1, *hpf2;
FilterType type;
+ Noise noise;
+ Resampler<1> *rs;
float Ga;
@@ -81,19 +86,22 @@ struct Korg35Filter : DSPEffect {
float fc, peak, sat;
- Korg35Filter(float sr, FilterType type) : DSPEffect(sr) {
- Korg35Filter::type = type;
+ Type35Filter(float sr, FilterType type) : DSPEffect(sr * OVERSAMPLE) {
+ Type35Filter::type = type;
- lpf1 = new Korg35FilterStage(sr, Korg35FilterStage::LP_STAGE);
- lpf2 = new Korg35FilterStage(sr, Korg35FilterStage::LP_STAGE);
- hpf1 = new Korg35FilterStage(sr, Korg35FilterStage::HP_STAGE);
- hpf2 = new Korg35FilterStage(sr, Korg35FilterStage::HP_STAGE);
+ rs = new Resampler<1>(OVERSAMPLE, 8);
+
+ lpf1 = new Type35FilterStage(sr * OVERSAMPLE, Type35FilterStage::LP_STAGE);
+ lpf2 = new Type35FilterStage(sr * OVERSAMPLE, Type35FilterStage::LP_STAGE);
+ hpf1 = new Type35FilterStage(sr * OVERSAMPLE, Type35FilterStage::HP_STAGE);
+ hpf2 = new Type35FilterStage(sr * OVERSAMPLE, Type35FilterStage::HP_STAGE);
}
void init() override;
void invalidate() override;
void process() override;
+ void process2();
void processLPF();
void processHPF();
void setSamplerate(float sr) override;
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/AlmaFilter.cpp b/plugins/community/repos/LindenbergResearch/src/modules/AlmaFilter.cpp
index 5a645bcc..7a98ffe5 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/AlmaFilter.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/AlmaFilter.cpp
@@ -43,7 +43,11 @@ struct AlmaFilter : LRModule {
LRMiddleKnob *driveKnob = NULL;
- AlmaFilter() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
+ AlmaFilter() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ frqKnob = LRKnob::create(Vec(62, 150), this, AlmaFilter::CUTOFF_PARAM, 0.f, 1.f, 0.8f);
+ peakKnob = LRKnob::create(Vec(23, 228), this, AlmaFilter::RESONANCE_PARAM, -0.f, 1.5, 0.0f);
+ driveKnob = LRKnob::create(Vec(115, 227), this, AlmaFilter::DRIVE_PARAM, 0.0f, 1.f, 0.0f);
+ }
void step() override;
@@ -117,10 +121,6 @@ AlmaFilterWidget::AlmaFilterWidget(AlmaFilter *module) : LRModuleWidget(module)
// ***** SCREWS **********
// ***** MAIN KNOBS ******
- module->frqKnob = LRKnob::create(Vec(62, 150), module, AlmaFilter::CUTOFF_PARAM, 0.f, 1.f, 0.8f);
- module->peakKnob = LRKnob::create(Vec(23, 228), module, AlmaFilter::RESONANCE_PARAM, -0.f, 1.5, 0.0f);
- module->driveKnob = LRKnob::create(Vec(115, 227), module, AlmaFilter::DRIVE_PARAM, 0.0f, 1.f, 0.0f);
-
addParam(module->frqKnob);
addParam(module->peakKnob);
addParam(module->driveKnob);
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/BlankPanelWood.cpp b/plugins/community/repos/LindenbergResearch/src/modules/BlankPanelWood.cpp
index 9777b05f..a530c4a3 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/BlankPanelWood.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/BlankPanelWood.cpp
@@ -41,7 +41,7 @@ struct BlankPanelWood : LRModule {
json_t *toJson() override {
- json_t *rootJ = LRModule::toJson();
+ json_t *rootJ = json_object();
json_object_set_new(rootJ, "AGED", json_boolean(aged));
json_object_set_new(rootJ, "screws", json_boolean(screws));
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/DiodeVCF.cpp b/plugins/community/repos/LindenbergResearch/src/modules/DiodeVCF.cpp
index 6f4ec3c9..1198bf62 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/DiodeVCF.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/DiodeVCF.cpp
@@ -38,13 +38,16 @@ struct DiodeVCF : LRModule {
};
- DiodeVCF() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
+ DiodeVCF() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ frqKnob = LRKnob::create(Vec(32.5, 74.4), this, DiodeVCF::FREQUENCY_PARAM, 0.f, 1.f, 1.f);
+ resKnob = LRKnob::create(Vec(151.5, 74.4), this, DiodeVCF::RES_PARAM, 0.0f, 1.0, 0.0f);
+ saturateKnob = LRKnob::create(Vec(99.5, 164.4), this, DiodeVCF::SATURATE_PARAM, 0.f, 1.0, 0.0f);
+ }
void onRandomize() override;
void updateComponents();
- LRLCDWidget *lcd = new LRLCDWidget(12, "%00004.3f Hz", LRLCDWidget::NUMERIC);
DiodeLadderFilter *lpf = new DiodeLadderFilter(engineGetSampleRate());
LRBigKnob *frqKnob = NULL;
@@ -122,8 +125,6 @@ void DiodeVCF::step() {
lpf->low = !hidef;
- lcd->value = lpf->getFreqHz();
-
lpf->setIn(inputs[FILTER_INPUT].value / 10.f);
lpf->invalidate();
lpf->process();
@@ -183,11 +184,6 @@ DiodeVCFWidget::DiodeVCFWidget(DiodeVCF *module) : LRModuleWidget(module) {
// ***** SCREWS **********
// ***** MAIN KNOBS ******
- module->frqKnob = LRKnob::create(Vec(32.5, 74.4), module, DiodeVCF::FREQUENCY_PARAM, 0.f, 1.f, 1.f);
- module->resKnob = LRKnob::create(Vec(151.5, 74.4), module, DiodeVCF::RES_PARAM, 0.0f, 1.0, 0.0f);
- module->saturateKnob = LRKnob::create(Vec(99.5, 164.4), module, DiodeVCF::SATURATE_PARAM, 0.f, 1.0,
- 0.0f);
-
module->frqKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
module->resKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
module->saturateKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/Korg35.cpp b/plugins/community/repos/LindenbergResearch/src/modules/Korg35.cpp
deleted file mode 100644
index 0d74e4ee..00000000
--- a/plugins/community/repos/LindenbergResearch/src/modules/Korg35.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/* *\
-** __ ___ ______ **
-** / / / _ \/_ __/ **
-** / /__/ , _/ / / Lindenberg **
-** /____/_/|_| /_/ Research Tec. **
-** **
-** **
-** https://github.com/lindenbergresearch/LRTRack **
-** heapdump@icloud.com **
-** **
-** Sound Modules for VCV Rack **
-** Copyright 2017/2018 by Patrick Lindenberg / LRT **
-** **
-** For Redistribution and use in source and binary forms, **
-** with or without modification please see LICENSE. **
-** **
-\* */
-
-#include "../LindenbergResearch.hpp"
-#include "../LRModel.hpp"
-#include "../dsp/Korg35Filter.hpp"
-
-namespace rack_plugin_LindenbergResearch {
-
-using namespace rack;
-using namespace lrt;
-
-using dsp::Korg35Filter;
-
-struct Korg35 : LRModule {
- enum ParamIds {
- FREQ_PARAM,
- PEAK_PARAM,
- SAT_PARAM,
- NUM_PARAMS
- };
- enum InputIds {
- FILTER_INPUT,
- NUM_INPUTS
- };
- enum OutputIds {
- LP_OUTPUT,
- NUM_OUTPUTS
- };
- enum LightIds {
- NUM_LIGHTS
- };
-
- LRKnob *frqKnob, *peakKnob, *saturateKnob;
- Korg35Filter *filter = new Korg35Filter(engineGetSampleRate(), Korg35Filter::LPF);
-
- Korg35() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
-
-
- void step() override {
- filter->fc = params[FREQ_PARAM].value;
- filter->peak = params[PEAK_PARAM].value;
- filter->sat = quadraticBipolar(params[SAT_PARAM].value);
-
- filter->in = inputs[FILTER_INPUT].value;
- filter->invalidate();
- filter->process();
-
- outputs[LP_OUTPUT].value = filter->out;
- }
-
-
- void onSampleRateChange() override {
- Module::onSampleRateChange();
- filter->setSamplerate(engineGetSampleRate());
- }
-};
-
-
-/**
- * @brief Blank Panel with Logo
- */
-struct Korg35Widget : LRModuleWidget {
- Korg35Widget(Korg35 *module);
-};
-
-
-Korg35Widget::Korg35Widget(Korg35 *module) : LRModuleWidget(module) {
- panel->addSVGVariant(LRGestalt::DARK, SVG::load(assetPlugin(plugin, "res/panels/Korg35VCF.svg")));
- panel->addSVGVariant(LRGestalt::LIGHT, SVG::load(assetPlugin(plugin, "res/panels/Korg35VCF.svg")));
- panel->addSVGVariant(LRGestalt::AGED, SVG::load(assetPlugin(plugin, "res/panels/Korg35VCF.svg")));
-
- panel->init();
- addChild(panel);
-
- box.size = panel->box.size;
-
- // ***** SCREWS **********
- addChild(Widget::create(Vec(15, 1)));
- addChild(Widget::create(Vec(box.size.x - 30, 1)));
- addChild(Widget::create(Vec(15, 366)));
- addChild(Widget::create(Vec(box.size.x - 30, 366)));
- // ***** SCREWS **********
-
- // ***** MAIN KNOBS ******
- module->frqKnob = LRKnob::create(Vec(32.5, 74.4), module, Korg35::FREQ_PARAM, 0.f, 1.f, 1.f);
- module->peakKnob = LRKnob::create(Vec(32.5, 144.4), module, Korg35::PEAK_PARAM, 0.001f, 2.0, 0.001f);
- module->saturateKnob = LRKnob::create(Vec(40, 244.4), module, Korg35::SAT_PARAM, 1.f, 2.5, 1.0f);
-
- module->frqKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
- module->peakKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
- module->saturateKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
-
- addParam(module->frqKnob);
- addParam(module->peakKnob);
- addParam(module->saturateKnob);/*
-
- addParam(ParamWidget::create(Vec(39.9, 251.4), module, DiodeVCF::FREQUENCY_CV_PARAM, -1.f, 1.0f, 0.f));
- addParam(ParamWidget::create(Vec(177, 251.4), module, DiodeVCF::RESONANCE_CV_PARAM, -1.f, 1.0f, 0.f));
- addParam(ParamWidget::create(Vec(108.5, 251.4), module, DiodeVCF::SATURATE_CV_PARAM, -1.f, 1.0f, 0.f));*/
- // ***** MAIN KNOBS ******
-
- // ***** CV INPUTS *******
- /* addInput(Port::create(Vec(37.4, 284.4), Port::INPUT, module, DiodeVCF::FREQUCENCY_CV_INPUT));
- addInput(Port::create(Vec(175.3, 284.4), Port::INPUT, module, DiodeVCF::RESONANCE_CV_INPUT));
- addInput(Port::create(Vec(106.4, 284.4), Port::INPUT, module, DiodeVCF::SATURATE_CV_INPUT));*/
- // ***** CV INPUTS *******
-
-
- // ***** INPUTS **********
- addInput(Port::create(Vec(37.4, 318.5), Port::INPUT, module, Korg35::FILTER_INPUT));
- // ***** INPUTS **********
-
- // ***** OUTPUTS *********
- addOutput(Port::create(Vec(175.3, 318.5), Port::OUTPUT, module, Korg35::LP_OUTPUT));
- // ***** OUTPUTS *********
-}
-
-} // namespace rack_plugin_LindenbergResearch
-
-using namespace rack_plugin_LindenbergResearch;
-
-RACK_PLUGIN_MODEL_INIT(LindenbergResearch, Korg35) {
- Model *modelKorg35 = Model::create("Lindenberg Research", "KORG35 VCF", "Mrs. Sally Korg35 Type Filter", FILTER_TAG);
- return modelKorg35;
-}
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/MS20Filter.cpp b/plugins/community/repos/LindenbergResearch/src/modules/MS20Filter.cpp
index 62b63a54..bab8dbf7 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/MS20Filter.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/MS20Filter.cpp
@@ -43,7 +43,11 @@ struct MS20Filter : LRModule {
LRMiddleKnob *driveKnob = NULL;
- MS20Filter() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
+ MS20Filter() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ frqKnob = LRKnob::create(Vec(102, 64.9), this, MS20Filter::FREQUENCY_PARAM, 0.f, 1.f, 1.f);
+ peakKnob = LRKnob::create(Vec(109, 159.8), this, MS20Filter::PEAK_PARAM, 0.0f, 1.0, 0.0f);
+ driveKnob = LRKnob::create(Vec(109, 229.6), this, MS20Filter::DRIVE_PARAM, 0.f, 1.0, 0.0f);
+ }
void step() override;
@@ -114,10 +118,6 @@ MS20FilterWidget::MS20FilterWidget(MS20Filter *module) : LRModuleWidget(module)
// ***** SCREWS **********
// ***** MAIN KNOBS ******
- module->frqKnob = LRKnob::create(Vec(102, 64.9), module, MS20Filter::FREQUENCY_PARAM, 0.f, 1.f, 1.f);
- module->peakKnob = LRKnob::create(Vec(109, 159.8), module, MS20Filter::PEAK_PARAM, 0.0f, 1.0, 0.0f);
- module->driveKnob = LRKnob::create(Vec(109, 229.6), module, MS20Filter::DRIVE_PARAM, 0.f, 1.0, 0.0f);
-
addParam(module->frqKnob);
addParam(module->peakKnob);
addParam(module->driveKnob);
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/ReShaper.cpp b/plugins/community/repos/LindenbergResearch/src/modules/ReShaper.cpp
index 1851f0fc..360ebca0 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/ReShaper.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/ReShaper.cpp
@@ -61,8 +61,11 @@ ReShaperWidget::ReShaperWidget(ReShaper *module) : LRModuleWidget(module) {
// panel->addSVGVariant(SVG::load(assetPlugin(plugin, "res/panels/ReShaper.svg")));
// panel->addSVGVariant(SVG::load(assetPlugin(plugin, "res/panels/ReShaper.svg")));
+ auto newGestalt = DARK;
+
noVariants = true;
panel->init();
+ gestalt = newGestalt;
addChild(panel);
box.size = panel->box.size;
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/SimpleFilter.cpp b/plugins/community/repos/LindenbergResearch/src/modules/SimpleFilter.cpp
index b53ddfdd..caf7e7f7 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/SimpleFilter.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/SimpleFilter.cpp
@@ -93,7 +93,7 @@ void SimpleFilter::step() {
resonance = clip(params[RESONANCE_PARAM].value + resonanceCVValue, 1.f);
// normalize signal input to [-1.0...+1.0]
- // filter starts to be very unstable for input gain above 1.f and below 0.f
+ // lpf starts to be very unstable for input gain above 1.f and below 0.f
in = clip(inputs[FILTER_INPUT].value * 0.1f, 1.0f);
// Set coefficients given frequency & resonance [0.0...1.0]
@@ -142,8 +142,11 @@ SimpleFilterWidget::SimpleFilterWidget(SimpleFilter *module) : LRModuleWidget(mo
//panel->addSVGVariant(SVG::load(assetPlugin(plugin, "res/panels/SimpleFilter.svg")));
// panel->addSVGVariant(SVG::load(assetPlugin(plugin, "res/panels/SimpleFilter.svg")));
+ auto newGestalt = DARK;
+
noVariants = true;
panel->init();
+ gestalt = newGestalt;
addChild(panel);
box.size = panel->box.size;
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/Speck.cpp b/plugins/community/repos/LindenbergResearch/src/modules/Speck.cpp
index 76b03183..8fb7fc82 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/Speck.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/Speck.cpp
@@ -24,6 +24,7 @@ namespace rack_plugin_LindenbergResearch {
using namespace rack;
using namespace lrt;
+
float cabsf_LG(kiss_fft_cpx v) {
return sqrtf((v.r * v.r + v.i * v.i));
}
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/Type35.cpp b/plugins/community/repos/LindenbergResearch/src/modules/Type35.cpp
new file mode 100644
index 00000000..ee69549c
--- /dev/null
+++ b/plugins/community/repos/LindenbergResearch/src/modules/Type35.cpp
@@ -0,0 +1,264 @@
+/* *\
+** __ ___ ______ **
+** / / / _ \/_ __/ **
+** / /__/ , _/ / / Lindenberg **
+** /____/_/|_| /_/ Research Tec. **
+** **
+** **
+** https://github.com/lindenbergresearch/LRTRack **
+** heapdump@icloud.com **
+** **
+** Sound Modules for VCV Rack **
+** Copyright 2017/2018 by Patrick Lindenberg / LRT **
+** **
+** For Redistribution and use in source and binary forms, **
+** with or without modification please see LICENSE. **
+** **
+\* */
+
+#include "../LindenbergResearch.hpp"
+#include "../LRModel.hpp"
+#include "../dsp/Type35Filter.hpp"
+
+namespace rack_plugin_LindenbergResearch {
+
+using namespace rack;
+using namespace lrt;
+
+using dsp::Type35Filter;
+
+struct Type35 : LRModule {
+ enum ParamIds {
+ FREQ1_PARAM,
+ PEAK1_PARAM,
+ FREQ2_PARAM,
+ PEAK2_PARAM,
+ DRIVE_PARAM,
+ CUTOFF1_CV_PARAM,
+ PEAK1_CV_PARAM,
+ CUTOFF2_CV_PARAM,
+ PEAK2_CV_PARAM,
+ NUM_PARAMS
+ };
+ enum InputIds {
+ FILTER_INPUT,
+ CUTOFF1_CV_INPUT,
+ PEAK1_CV_INPUT,
+ CUTOFF2_CV_INPUT,
+ PEAK2_CV_INPUT,
+ DRIVE_CV_INPUT,
+ NUM_INPUTS
+ };
+ enum OutputIds {
+ OUTPUT,
+ NUM_OUTPUTS
+ };
+ enum LightIds {
+ NUM_LIGHTS
+ };
+
+ LRKnob *frqKnobLP, *peakKnobLP, *frqKnobHP, *peakKnobHP, *driveKnob;
+ Type35Filter *lpf = new Type35Filter(engineGetSampleRate(), Type35Filter::LPF);
+ Type35Filter *hpf = new Type35Filter(engineGetSampleRate(), Type35Filter::HPF);
+
+ LRLCDWidget *lcd = new LRLCDWidget(10, "%s", LRLCDWidget::LIST, 10);
+
+
+ Type35() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ frqKnobLP = LRKnob::create(Vec(32.9, 68.6 + 7), this, Type35::FREQ1_PARAM, 0.f, 1.f, 1.f);
+ peakKnobLP = LRKnob::create(Vec(39.9, 174.1 + 7), this, Type35::PEAK1_PARAM, 0.f, 1.f, 0.f);
+ frqKnobHP = LRKnob::create(Vec(196.2, 68.6 + 7), this, Type35::FREQ2_PARAM, 0.f, 1.f, 0.f);
+ peakKnobHP = LRKnob::create(Vec(203.1, 174.1 + 7), this, Type35::PEAK2_PARAM, 0.f, 1.f, 0.f);
+ driveKnob = LRKnob::create(Vec(122, 101.2), this, Type35::DRIVE_PARAM, 1.f, 2.5, 1.0f);
+ }
+
+
+ void step() override {
+ // compute all cv values
+ float frq1cv = inputs[CUTOFF1_CV_INPUT].value * 0.1f * quadraticBipolar(params[CUTOFF1_CV_PARAM].value);
+ float peak1cv = inputs[PEAK1_CV_INPUT].value * 0.1f * quadraticBipolar(params[PEAK1_CV_PARAM].value);
+
+ float frq2cv = inputs[CUTOFF2_CV_INPUT].value * 0.1f * quadraticBipolar(params[CUTOFF2_CV_PARAM].value);
+ float peak2cv = inputs[PEAK2_CV_INPUT].value * 0.1f * quadraticBipolar(params[PEAK2_CV_PARAM].value);
+
+ float drivecv = inputs[DRIVE_CV_INPUT].value;//* 0.1f * quadraticBipolar(params[DRIVE_CV_PARAM].value);
+
+ // set vc parameter and knob values
+ lpf->fc = params[FREQ1_PARAM].value + frq1cv;
+ lpf->peak = params[PEAK1_PARAM].value + peak1cv;
+ hpf->fc = params[FREQ2_PARAM].value + frq2cv;
+ hpf->peak = params[PEAK2_PARAM].value + peak2cv;
+
+ lpf->sat = params[DRIVE_PARAM].value + drivecv;
+ hpf->sat = params[DRIVE_PARAM].value + drivecv;
+
+
+ if (frqKnobLP != nullptr && frqKnobHP != nullptr && peakKnobLP != nullptr && peakKnobHP != nullptr && driveKnob != nullptr) {
+ frqKnobLP->setIndicatorActive(inputs[CUTOFF1_CV_INPUT].active);
+ peakKnobLP->setIndicatorActive(inputs[PEAK1_CV_INPUT].active);
+ frqKnobHP->setIndicatorActive(inputs[CUTOFF2_CV_INPUT].active);
+ peakKnobHP->setIndicatorActive(inputs[PEAK2_CV_INPUT].active);
+ driveKnob->setIndicatorActive(inputs[DRIVE_CV_INPUT].active);
+
+ frqKnobLP->setIndicatorValue(params[FREQ1_PARAM].value + frq1cv);
+ peakKnobLP->setIndicatorValue(params[PEAK1_PARAM].value + peak1cv);
+ frqKnobHP->setIndicatorValue(params[FREQ2_PARAM].value + frq2cv);
+ peakKnobHP->setIndicatorValue(params[PEAK2_PARAM].value + peak2cv);
+ driveKnob->setIndicatorValue(params[DRIVE_PARAM].value + drivecv);
+ }
+
+ if (lround(lcd->value) == 0) {
+ hpf->in = inputs[FILTER_INPUT].value;
+ hpf->invalidate();
+ hpf->process2();
+
+ lpf->in = hpf->out;
+ lpf->invalidate();
+ lpf->process2();
+
+ outputs[OUTPUT].value = lpf->out;
+ } else if (lround(lcd->value) == 1) {
+ lpf->in = inputs[FILTER_INPUT].value;
+ lpf->invalidate();
+ lpf->process2();
+
+ outputs[OUTPUT].value = lpf->out;
+ } else if (lround(lcd->value) == 2) {
+ lpf->in = inputs[FILTER_INPUT].value;
+ lpf->invalidate();
+ lpf->process2();
+
+ hpf->in = inputs[FILTER_INPUT].value;
+ hpf->invalidate();
+ hpf->process2();
+
+ outputs[OUTPUT].value = hpf->out + lpf->out;
+ } else if (lround(lcd->value) == 3) {
+ hpf->in = inputs[FILTER_INPUT].value;
+ hpf->invalidate();
+ hpf->process2();
+
+ outputs[OUTPUT].value = hpf->out;
+ } else if (lround(lcd->value) == 4) {
+ lpf->in = inputs[FILTER_INPUT].value;
+ lpf->invalidate();
+ lpf->process2();
+
+ hpf->in = lpf->out;
+ hpf->invalidate();
+ hpf->process2();
+
+ outputs[OUTPUT].value = hpf->out;
+ }
+
+
+ }
+
+
+ json_t *toJson() override {
+ json_t *rootJ = json_object();
+ json_object_set_new(rootJ, "filtermode", json_integer((int) lround(lcd->value)));
+
+ return rootJ;
+ }
+
+
+ void fromJson(json_t *rootJ) override {
+ LRModule::fromJson(rootJ);
+
+ json_t *mode = json_object_get(rootJ, "filtermode");
+
+ if (mode)
+ lcd->value = json_integer_value(mode);// json_real_value(mode);
+
+ lcd->dirty = true;
+ }
+
+
+ void onSampleRateChange() override {
+ LRModule::onSampleRateChange();
+ lpf->setSamplerate(engineGetSampleRate());
+ hpf->setSamplerate(engineGetSampleRate());
+ }
+};
+
+
+/**
+ * @brief Blank Panel with Logo
+ */
+struct Type35Widget : LRModuleWidget {
+ Type35Widget(Type35 *module);
+};
+
+
+Type35Widget::Type35Widget(Type35 *module) : LRModuleWidget(module) {
+ panel->addSVGVariant(LRGestalt::DARK, SVG::load(assetPlugin(plugin, "res/panels/Type35VCF.svg")));
+ panel->addSVGVariant(LRGestalt::LIGHT, SVG::load(assetPlugin(plugin, "res/panels/Type35VCFLight.svg")));
+ panel->addSVGVariant(LRGestalt::AGED, SVG::load(assetPlugin(plugin, "res/panels/Type35VCFAged.svg")));
+
+ panel->init();
+ addChild(panel);
+
+ box.size = panel->box.size;
+
+ // **** SETUP LCD ********
+ module->lcd->box.pos = Vec(100, 221);
+ module->lcd->items = {"1: LP->HP", "2: LP", "3: LP + HP", "4: HP", " 5: HP->LP"};
+ module->lcd->format = "%s";
+ addChild(module->lcd);
+ // **** SETUP LCD ********
+
+ // ***** SCREWS **********
+ addChild(Widget::create(Vec(15, 1)));
+ addChild(Widget::create(Vec(box.size.x - 30, 1)));
+ addChild(Widget::create(Vec(15, 366)));
+ addChild(Widget::create(Vec(box.size.x - 30, 366)));
+ // ***** SCREWS **********
+
+ // ***** MAIN KNOBS ******
+ module->frqKnobLP->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
+ module->peakKnobLP->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
+ module->frqKnobHP->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
+ module->peakKnobHP->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
+ module->driveKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
+
+ addParam(module->frqKnobLP);
+ addParam(module->peakKnobLP);
+ addParam(module->frqKnobHP);
+ addParam(module->peakKnobHP);
+ addParam(module->driveKnob);
+
+ addParam(ParamWidget::create(Vec(36.5 - 7.5, 269.4), module, Type35::CUTOFF1_CV_PARAM, -1.f, 1.0f, 0.f));
+ addParam(ParamWidget::create(Vec(78.5 - 7.5, 269.4), module, Type35::PEAK1_CV_PARAM, -1.f, 1.0f, 0.f));
+ addParam(ParamWidget::create(Vec(197.5 - 7.5, 269.4), module, Type35::CUTOFF2_CV_PARAM, -1.f, 1.0f, 0.f));
+ addParam(ParamWidget::create(Vec(239.5 - 7.5, 269.4), module, Type35::PEAK2_CV_PARAM, -1.f, 1.0f, 0.f));
+ // ***** MAIN KNOBS ******
+
+ // ***** CV INPUTS *******
+ addInput(Port::create(Vec(34.4 - 7.5, 312), Port::INPUT, module, Type35::CUTOFF1_CV_INPUT));
+ addInput(Port::create(Vec(76.4 - 7.5, 312), Port::INPUT, module, Type35::PEAK1_CV_INPUT));
+ addInput(Port::create(Vec(195.4 - 7.5, 312), Port::INPUT, module, Type35::CUTOFF2_CV_INPUT));
+ addInput(Port::create(Vec(237.4 - 7.5, 312), Port::INPUT, module, Type35::PEAK2_CV_INPUT));
+ addInput(Port::create(Vec(129.4, 172), Port::INPUT, module, Type35::DRIVE_CV_INPUT));
+ // ***** CV INPUTS *******
+
+ // ***** INPUTS **********
+ addInput(Port::create(Vec(118 - 8, 269), Port::INPUT, module, Type35::FILTER_INPUT));
+ // ***** INPUTS **********
+
+ // ***** OUTPUTS *********
+ addOutput(Port::create(Vec(156 - 8, 269), Port::OUTPUT, module, Type35::OUTPUT));
+ // ***** OUTPUTS *********
+
+ // addParam(ParamWidget::create(Vec(135, 55), module, Type35::MODE_SWITCH_PARAM, 0, 1, 0));
+}
+
+} // namespace rack_plugin_LindenbergResearch
+
+using namespace rack_plugin_LindenbergResearch;
+
+RACK_PLUGIN_MODEL_INIT(LindenbergResearch, Type35) {
+ Model *modelType35 = Model::create("Lindenberg Research", "TYPE35 VCF", "Vampyr type35 multimode VCF",
+ FILTER_TAG);
+ return modelType35;
+}
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/VCO.cpp b/plugins/community/repos/LindenbergResearch/src/modules/VCO.cpp
index 9d305cc9..c9f98dd7 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/VCO.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/VCO.cpp
@@ -8,6 +8,7 @@ using namespace lrt;
using dsp::DSPBLOscillator;
+
struct VCO : LRModule {
enum ParamIds {
FREQUENCY_PARAM,
@@ -42,11 +43,13 @@ struct VCO : LRModule {
};
dsp::DSPBLOscillator *osc = new dsp::DSPBLOscillator(engineGetSampleRate());
- LRLCDWidget *lcd = new LRLCDWidget(10, "%00004.3f Hz", LRLCDWidget::NUMERIC);
+ LRLCDWidget *lcd = new LRLCDWidget(10, "%00004.3f Hz", LRLCDWidget::NUMERIC, LCD_FONTSIZE);
LRBigKnob *frqKnob = NULL;
- VCO() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
+ VCO() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ frqKnob = LRKnob::create(Vec(126.0, 64.7), this, VCO::FREQUENCY_PARAM, -1.f, 1.f, 0.f);
+ }
/*
@@ -69,6 +72,7 @@ struct VCO : LRModule {
void onRandomize() override;
+
void step() override;
void onSampleRateChange() override;
};
@@ -166,7 +170,7 @@ VCOWidget::VCOWidget(VCO *module) : LRModuleWidget(module) {
// **** SETUP LCD ********
- module->lcd->box.pos = Vec(24, 242);
+ module->lcd->box.pos = Vec(22, 222);
module->lcd->format = "%00004.3f Hz";
addChild(module->lcd);
// **** SETUP LCD ********
@@ -181,8 +185,6 @@ VCOWidget::VCOWidget(VCO *module) : LRModuleWidget(module) {
// ***** MAIN KNOBS ******
- module->frqKnob = LRKnob::create(Vec(126.0, 64.7), module, VCO::FREQUENCY_PARAM, -1.f, 1.f, 0.f);
-
addParam(module->frqKnob);
addParam(LRKnob::create(Vec(133, 170.5), module, VCO::OCTAVE_PARAM, -4.f, 3.f, 0.f));
diff --git a/plugins/community/repos/LindenbergResearch/src/modules/Westcoast.cpp b/plugins/community/repos/LindenbergResearch/src/modules/Westcoast.cpp
index 969be410..288b3469 100644
--- a/plugins/community/repos/LindenbergResearch/src/modules/Westcoast.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/modules/Westcoast.cpp
@@ -50,7 +50,10 @@ struct Westcoast : LRModule {
};
- Westcoast() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
+ Westcoast() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ gainBtn = LRKnob::create(Vec(128.7, 63.0), this, Westcoast::GAIN_PARAM, 0.0, 20.f, 1.f);
+ biasBtn = LRKnob::create(Vec(135.4, 152.3), this, Westcoast::BIAS_PARAM, -6.f, 6.f, 0.f);
+ }
dsp::LockhartWavefolder *hs = new dsp::LockhartWavefolder(engineGetSampleRate());
@@ -213,9 +216,6 @@ WestcoastWidget::WestcoastWidget(Westcoast *module) : LRModuleWidget(module) {
// ***** SCREWS **********
// ***** MAIN KNOBS ******
- module->gainBtn = LRKnob::create(Vec(128.7, 63.0), module, Westcoast::GAIN_PARAM, 0.0, 20.f, 1.f);
- module->biasBtn = LRKnob::create(Vec(135.4, 152.3), module, Westcoast::BIAS_PARAM, -6.f, 6.f, 0.f);
-
addParam(module->gainBtn);
addParam(module->biasBtn);
diff --git a/plugins/community/repos/LindenbergResearch/src/widgets/LRKnob.cpp b/plugins/community/repos/LindenbergResearch/src/widgets/LRKnob.cpp
index f39ddbad..570571bc 100644
--- a/plugins/community/repos/LindenbergResearch/src/widgets/LRKnob.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/widgets/LRKnob.cpp
@@ -40,12 +40,25 @@ void LRKnob::draw(NVGcontext *vg) {
/** debug numerical values */
if (debug) {
- auto text = stringf("%4.2f", value);
- nvgFontSize(vg, 15);
+ auto text = stringf("%4.3f", value);
+ auto size = box.size.x / 2. > 15 ? 15 : box.size.x / 2.;
+ nvgFontSize(vg, size);
+
nvgFontFaceId(vg, font->handle);
+ nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
+
+ float bounds[4];
+
+ nvgTextBounds(vg, 0, 0, text.c_str(), nullptr, bounds);
+
+ nvgBeginPath(vg);
+ nvgFillColor(vg, nvgRGBAf(0., 0.1, 0.2, 0.8));
+ nvgRoundedRect(vg, bounds[0] - 4, bounds[1] - 2, (bounds[2] - bounds[0]) + 8, (bounds[3] - bounds[1]) + 4,
+ ((bounds[3] - bounds[1]) + 4) / 2 - 1);
+ nvgFill(vg);
- nvgFillColor(vg, nvgRGBAf(1.f, 1.f, 1.0f, 1.0f));
- nvgText(vg, box.size.x - 5, box.size.y + 10, text.c_str(), NULL);
+ nvgFillColor(vg, nvgRGBAf(1.0f, 1.0f, 1.0f, .99f));
+ nvgText(vg, 0, 0, text.c_str(), NULL);
}
}
diff --git a/plugins/community/repos/LindenbergResearch/src/widgets/LRLCDWidget.cpp b/plugins/community/repos/LindenbergResearch/src/widgets/LRLCDWidget.cpp
index 81ab0f38..11ce8cf6 100644
--- a/plugins/community/repos/LindenbergResearch/src/widgets/LRLCDWidget.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/widgets/LRLCDWidget.cpp
@@ -7,17 +7,23 @@ namespace lrt {
* @brief Constructor of LCD Widget
*/
LRLCDWidget::LRLCDWidget(unsigned char length, std::string format, LCDType type, float fontsize) {
+ tw = new TransformWidget();
+ addChild(tw);
+
+ sw = new SVGWidget();
+ tw->addChild(sw);
+
/** load LCD ttf font */
- ttfLCDDig7 = Font::load(assetPlugin(plugin, LCD_FONT_DIG7));
+ ttfLCDDIG7 = Font::load(assetPlugin(plugin, LCD_FONT_DIG7));
LRLCDWidget::fontsize = fontsize;
-
LRLCDWidget::type = type;
-
LRLCDWidget::length = length;
LRLCDWidget::format = format;
-
LRLCDWidget::fg = LCD_DEFAULT_COLOR_DARK;
- LRLCDWidget::bg = nvgRGBAf(fg.r, fg.g, fg.b, 0.15f);
+
+ addSVGVariant(LRGestalt::DARK, SVG::load(assetPlugin(plugin, "res/elements/LCDFrameDark.svg")));
+ addSVGVariant(LRGestalt::LIGHT, SVG::load(assetPlugin(plugin, "res/elements/LCDFrameLight.svg")));
+ addSVGVariant(LRGestalt::AGED, SVG::load(assetPlugin(plugin, "res/elements/LCDFrameAged.svg")));
for (int i = 0; i < LRLCDWidget::length; ++i) {
s1.append("O");
@@ -31,17 +37,50 @@ LRLCDWidget::LRLCDWidget(unsigned char length, std::string format, LCDType type,
* @param vg
*/
void LRLCDWidget::draw(NVGcontext *vg) {
+ FramebufferWidget::draw(vg);
+
nvgFontSize(vg, fontsize);
- nvgFontFaceId(vg, ttfLCDDig7->handle);
+ nvgFontFaceId(vg, ttfLCDDIG7->handle);
nvgTextLetterSpacing(vg, LCD_LETTER_SPACING);
+ //nvgTextAlign(vg, NVG_ALIGN_B | NVG_ALIGN_LEFT);
+
+ float bounds[4];
+ nvgTextBoxBounds(vg, 0, 0, 120, s2.c_str(), nullptr, bounds);
- auto digitsColor = nvgRGBAf(fg.r, fg.b, fg.b, 0.1);
+ auto mx = (bounds[2] - bounds[0]) * LCD_MARGIN_HORIZONTAL;
+ auto my = (bounds[3] - bounds[1]) * LCD_MARGIN_VERTICAL;
+
+ // size of frame not proper setup
+ if (!sw->box.size.isEqual(Vec(mx, my))) {
+ doResize(Vec(mx, my));
+ }
- nvgFillColor(vg, digitsColor);
+ /**
+ * @brief Remark: Due to inconsistent baseline shift on changing the
+ * font size this is set rather manual and may do not work with other
+ * fonts or sizes.
+ *
+ */
+ float xoffs = (mx - bounds[2] + 0.6f - bounds[0]) / 2.f;
+ float yoffs = (my - bounds[3] - 1.f - bounds[1]) / 2.f;
+
+
+ /*if (++foo % 100 == 0)
+ debug("bounds: (%f %f %f %f) box: %f x %f font: %f offs: (%f : %f)", bounds[0], bounds[1], bounds[2], bounds[3], box.size.x, box
+ .size.y,
+ fontsize, xoffs,
+ yoffs);*/
+
+ /*nvgFillPaint(vg, nvgBoxGradient(vg, 0 - 50, 0 - 50, mx + 50, my + 50, 10, 10,
+ nvgRGBAf(1, 0, 0, 0.25),
+ nvgRGBAf(0, 0, 0, .0)));
+ nvgFill(vg);*/
+
+ nvgFillColor(vg, nvgRGBAf(fg.r, fg.g, fg.b, 0.23));
std::string str;
- nvgTextBox(vg, 0, 0, 220, s1.c_str(), nullptr);
- nvgTextBox(vg, 0, 0, 220, s2.c_str(), nullptr);
+ nvgTextBox(vg, xoffs, yoffs, 120, s1.c_str(), nullptr);
+ nvgTextBox(vg, xoffs, yoffs, 120, s2.c_str(), nullptr);
/** if set to inactive just draw the background segments */
if (!active) return;
@@ -74,15 +113,28 @@ void LRLCDWidget::draw(NVGcontext *vg) {
index = (unsigned long) current;
}
+ value = index;
+ text = items[index];
str = stringf(format.c_str(), items[index].c_str());
}
nvgFillColor(vg, fg);
- nvgTextBox(vg, 0, 0, 220, str.c_str(), nullptr);
+ nvgTextBox(vg, xoffs, yoffs, 120, str.c_str(), nullptr);
}
void LRLCDWidget::onGestaltChange(LREventGestaltChange &e) {
+ auto svg = getSVGVariant(*gestalt);
+
+ if (svg != nullptr) {
+ tw->identity();
+
+ sw->setSVG(svg);
+ sw->wrap();
+
+ dirty = true;
+ }
+
LRGestaltChangeAction::onGestaltChange(e);
switch (*gestalt) {
@@ -102,4 +154,37 @@ void LRLCDWidget::onGestaltChange(LREventGestaltChange &e) {
e.consumed = true;
}
+
+void LRLCDWidget::doResize(Vec v) {
+ auto factor = Vec(v.x / sw->box.size.x, v.y / sw->box.size.y);
+
+ // tw->identity();
+ tw->scale(factor);
+
+ sw->box.size = v;
+ tw->box.size = sw->box.size;
+ box.size = sw->box.size;
+
+ dirty = true;
+}
+
+
+void LRLCDWidget::onMouseDown(EventMouseDown &e) {
+ Widget::onMouseDown(e);
+
+ if (type == LIST) {
+ if (value < items.size() - 1) value++;
+ else value = 0;
+
+ e.consumed = true;
+ }
+}
+
+
+void LRLCDWidget::step() {
+
+
+ FramebufferWidget::step();
+}
+
}
\ No newline at end of file
diff --git a/plugins/community/repos/LindenbergResearch/src/widgets/LRPanel.cpp b/plugins/community/repos/LindenbergResearch/src/widgets/LRPanel.cpp
index 0d4630ab..678a13e5 100644
--- a/plugins/community/repos/LindenbergResearch/src/widgets/LRPanel.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/widgets/LRPanel.cpp
@@ -31,7 +31,7 @@ void LRPanel::init() {
addChild(patinaWidgetClassic);
/* setup gradient variants */
- auto gradientDark = new LRGradientWidget(box.size, nvgRGBAf(.6f, .6f, .6f, 0.3f), nvgRGBAf(0.2f, 0.0f, 0.0f, 0.2f), Vec(50, 20));
+ auto gradientDark = new LRGradientWidget(box.size, nvgRGBAf(.6f, .6f, .6f, 0.25f), nvgRGBAf(0.0f, 0.0f, 0.0f, 0.2f), Vec(50, 20));
gradientDark->visible = false;
addChild(gradientDark);
gradients[LRGestalt::DARK] = gradientDark;
@@ -41,7 +41,7 @@ void LRPanel::init() {
addChild(gradientLight);
gradients[LRGestalt::LIGHT] = gradientLight;
- auto gradientAged = new LRGradientWidget(box.size, nvgRGBAf(0.5, 0.5, 0.f, 0.1f), nvgRGBAf(0.f, 0.f, 0.f, 0.73f), Vec(100, -20));
+ auto gradientAged = new LRGradientWidget(box.size, nvgRGBAf(0.4, 0.6, 0.f, 0.1f), nvgRGBAf(0.f, 0.f, 0.f, 0.73f), Vec(100, -20));
gradientAged->visible = false;
addChild(gradientAged);
gradients[LRGestalt::AGED] = gradientAged;
diff --git a/plugins/community/repos/LindenbergResearch/src/widgets/LRSVGRotator.cpp b/plugins/community/repos/LindenbergResearch/src/widgets/LRSVGRotator.cpp
index f1888e81..1b01f482 100644
--- a/plugins/community/repos/LindenbergResearch/src/widgets/LRSVGRotator.cpp
+++ b/plugins/community/repos/LindenbergResearch/src/widgets/LRSVGRotator.cpp
@@ -28,7 +28,7 @@ void SVGRotator::setSVG(std::shared_ptr