diff --git a/plugins/community/repos/bsp/README.md b/plugins/community/repos/bsp/README.md
index 95bba630..deba7a22 100644
--- a/plugins/community/repos/bsp/README.md
+++ b/plugins/community/repos/bsp/README.md
@@ -23,6 +23,7 @@ Suggested applications:
An adaption of Filatov Vadim's excellent Ob-Xd filter. Distributed under terms of the GNU General Public License V3.
+
# Scanner
A mixer that can seamlessly blend up to 16 input channels.
@@ -47,6 +48,17 @@ The switch enables the randomizer, and the button next to it is used to generate
NOTE: try modulating the position with the post output (feedback).
+
+# RMS
+
+A Root-Mean-Square based envelope follower, coupled with a slew limiter.
+
+The rise and fall rates can be configured separately.
+
+The module can be used to derive envelopes from audio signals, e.g. to implement compressor effects.
+
+
+
# Sway
A kind of slew-filtered noise generator, mainly designed for randomizing control voltages.
@@ -60,6 +72,7 @@ The "s+o" knobs are used to apply a final scaling/amplification (-5..5) and offs
NOTE: when the min/max time is set to very small values, the module can be used to generate audio-rate noise.
+
# Tuned Delay Line
This module was designed for Karplus-Strong synthesis.
diff --git a/plugins/community/repos/bsp/make.objects b/plugins/community/repos/bsp/make.objects
index a45a67bc..3b791b20 100644
--- a/plugins/community/repos/bsp/make.objects
+++ b/plugins/community/repos/bsp/make.objects
@@ -2,6 +2,7 @@ ALL_OBJ= \
src/AttenuMixer.o \
src/bsp.o \
src/Obxd_VCF.o \
+ src/RMS.o \
src/Scanner.o \
src/Sway.o \
src/TunedDelayLine.o
diff --git a/plugins/community/repos/bsp/makefile.msvc b/plugins/community/repos/bsp/makefile.msvc
index 8b70a1a3..66975906 100644
--- a/plugins/community/repos/bsp/makefile.msvc
+++ b/plugins/community/repos/bsp/makefile.msvc
@@ -5,7 +5,8 @@ include ../../../build_shared_plugin_pre.mk
include make.objects
define BIN_POST_FXN
- cp -f $(SLUG).dll ../../../../vst2_bin/plugins/$(SLUG)/plugin.dll
+ cp -f $(SLUG).dll ../../../../vst2_bin/plugins/$(SLUG)/plugin.dll.fx
+ cp -f $(SLUG).dll ../../../../vst2_bin/plugins/$(SLUG)/plugin.dll.instr
endef
include ../../../build_shared_plugin_post.mk
diff --git a/plugins/community/repos/bsp/res/RMS.svg b/plugins/community/repos/bsp/res/RMS.svg
new file mode 100644
index 00000000..90bddc56
--- /dev/null
+++ b/plugins/community/repos/bsp/res/RMS.svg
@@ -0,0 +1,503 @@
+
+
+
+
diff --git a/plugins/community/repos/bsp/src/RMS.cpp b/plugins/community/repos/bsp/src/RMS.cpp
new file mode 100644
index 00000000..55402e6e
--- /dev/null
+++ b/plugins/community/repos/bsp/src/RMS.cpp
@@ -0,0 +1,199 @@
+/*
+Copyright (c) 2018 bsp
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include
+#include // memset
+
+#include "bsp.hpp"
+
+namespace rack_plugin_bsp {
+
+typedef union fi_u {
+ float f;
+ unsigned int u;
+ int s;
+} fi_t;
+
+struct RMS : Module {
+ enum ParamIds {
+ IN_AMP_PARAM,
+ WIN_SIZE_PARAM,
+ SMOOTH_RISE_PARAM,
+ SMOOTH_FALL_PARAM,
+ OUT_AMP_PARAM,
+ NUM_PARAMS
+ };
+ enum InputIds {
+ AUDIO_INPUT,
+ NUM_INPUTS
+ };
+ enum OutputIds {
+ RMS_OUTPUT,
+ NUM_OUTPUTS
+ };
+
+ static const uint32_t MAX_WIN_SIZE = (1024u);
+
+ float buf[MAX_WIN_SIZE];
+ uint32_t buf_idx;
+
+ double integrated_val;
+ double smoothed_sign;
+ double last_smoothed_val;
+ double smoothed_val;
+
+ uint32_t last_win_size;
+
+ RMS() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {
+ last_win_size = 0u;
+ buf_idx = 0u;
+ }
+
+ void step() override;
+};
+
+
+void RMS::step() {
+
+#if 0
+ outputs[RMS_OUTPUT].value = 0.0f;
+ return;
+#endif
+
+ uint32_t winSize = (1u << uint32_t(params[WIN_SIZE_PARAM].value));
+ uint32_t winSizeMask = (winSize - 1u);
+
+ if(winSize != last_win_size)
+ {
+ last_win_size = winSize;
+ ::memset((void*)buf, 0, winSize * sizeof(float));
+ buf_idx = 0u;
+ integrated_val = 0.0;
+ smoothed_sign = 0.0;
+ last_smoothed_val = 0.0;
+ smoothed_val = 0.0;
+ }
+
+ float inAmp = params[IN_AMP_PARAM].value;
+ inAmp *= inAmp;
+ inAmp *= inAmp;
+ // amp is now in range 0..1000
+
+ // Read new input and calc square
+ float inValOrig = inputs[AUDIO_INPUT].value;
+ float inVal = inValOrig * inAmp;
+ inVal *= inVal;
+
+ // Integrate new input
+ integrated_val += inVal;
+
+ // Subtract oldest input
+ integrated_val -= buf[(buf_idx - winSize + 1u) & winSizeMask];
+
+ buf[buf_idx] = inVal;
+ buf_idx = (buf_idx + 1u) & winSizeMask;
+
+ double outVal = integrated_val / double(winSize);
+ if(outVal > 0.0)
+ outVal = sqrt(outVal);
+
+ // Smoothing
+ double smoothAmt;
+ if(smoothed_sign >= 0.0)
+ {
+ smoothAmt = params[SMOOTH_RISE_PARAM].value;
+ }
+ else
+ {
+ smoothAmt = params[SMOOTH_FALL_PARAM].value;
+ }
+
+ smoothAmt = (1.0 - smoothAmt);
+ smoothAmt *= smoothAmt;
+ smoothAmt *= smoothAmt;
+ smoothAmt *= smoothAmt;
+ smoothed_val = smoothed_val + (outVal - smoothed_val) * smoothAmt;
+
+ smoothed_sign = (smoothed_val - last_smoothed_val);
+ last_smoothed_val = smoothed_val;
+
+ // Output
+ float outAmp = params[OUT_AMP_PARAM].value;
+ outAmp *= outAmp;
+ outAmp *= outAmp;
+ // out amp is now in range 0..1000
+ outputs[RMS_OUTPUT].value = float(smoothed_val * outAmp);
+
+#if 0
+ static int xxx = 0;
+ if(0 == (++xxx & 32767))
+ {
+ printf("xxx winSize=%u winSizeMask=%u bufIdx=%u smoothAmt=%f\n", winSize, winSizeMask, buf_idx, smoothAmt);
+ }
+#endif
+}
+
+
+struct RMSWidget : ModuleWidget {
+ RMSWidget(RMS *module);
+};
+
+RMSWidget::RMSWidget(RMS *module) : ModuleWidget(module) {
+ setPanel(SVG::load(assetPlugin(plugin, "res/RMS.svg")));
+
+ addChild(Widget::create(Vec(15, 0)));
+ addChild(Widget::create(Vec(15, 365)));
+
+ float cx;
+ float cy;
+
+#define STY 33.0f
+ cx = 12.0f;
+ cy = 50.0f;
+ addInput(Port::create(Vec(11.0f, cy), Port::INPUT, module, RMS::AUDIO_INPUT));
+ cy += STY;
+ addParam(ParamWidget::create(Vec(cx, cy), module, RMS::IN_AMP_PARAM, 0.0f, 3.0f, 0.562341325191f));
+#undef STY
+
+#define STY 50.0f
+ cx = 12.0f;
+ cy = 140.0f;
+ addParam(ParamWidget::create(Vec(cx, cy), module, RMS::WIN_SIZE_PARAM, 1.0f, 10.0f, 6.0f));
+ cy += STY;
+ addParam(ParamWidget::create(Vec(cx, cy), module, RMS::SMOOTH_RISE_PARAM, 0.0f, 1.0f, 0.447f));
+ cy += STY;
+ addParam(ParamWidget::create(Vec(cx, cy), module, RMS::SMOOTH_FALL_PARAM, 0.0f, 1.0f, 0.52f));
+#undef STX
+#undef STY
+
+ addParam(ParamWidget::create(Vec(12.0f, 290.0f), module, RMS::OUT_AMP_PARAM, 0.0f, 3.0f, 1.8f));
+ addOutput(Port::create(Vec(11, 325), Port::OUTPUT, module, RMS::RMS_OUTPUT));
+}
+
+} // namespace rack_plugin_bsp
+
+using namespace rack_plugin_bsp;
+
+RACK_PLUGIN_MODEL_INIT(bsp, RMS) {
+ Model *modelRMS = Model::create("bsp", "RMS", "RMS", ENVELOPE_FOLLOWER_TAG, UTILITY_TAG);
+ return modelRMS;
+}
diff --git a/plugins/community/repos/bsp/src/Sway.cpp b/plugins/community/repos/bsp/src/Sway.cpp
index ad5e289d..4827b9e8 100644
--- a/plugins/community/repos/bsp/src/Sway.cpp
+++ b/plugins/community/repos/bsp/src/Sway.cpp
@@ -182,7 +182,7 @@ struct SwayWidget : ModuleWidget {
};
SwayWidget::SwayWidget(Sway *module) : ModuleWidget(module) {
- setPanel(SVG::load(assetPlugin(plugin, "res/sway.svg")));
+ setPanel(SVG::load(assetPlugin(plugin, "res/Sway.svg")));
addChild(Widget::create(Vec(15, 0)));
addChild(Widget::create(Vec(15, 365)));
diff --git a/plugins/community/repos/bsp/src/bsp.cpp b/plugins/community/repos/bsp/src/bsp.cpp
index 72fd2de8..0a7938ee 100644
--- a/plugins/community/repos/bsp/src/bsp.cpp
+++ b/plugins/community/repos/bsp/src/bsp.cpp
@@ -2,6 +2,7 @@
RACK_PLUGIN_MODEL_DECLARE(bsp, AttenuMixer);
RACK_PLUGIN_MODEL_DECLARE(bsp, Obxd_VCF);
+RACK_PLUGIN_MODEL_DECLARE(bsp, RMS);
RACK_PLUGIN_MODEL_DECLARE(bsp, Scanner);
RACK_PLUGIN_MODEL_DECLARE(bsp, Sway);
RACK_PLUGIN_MODEL_DECLARE(bsp, TunedDelayLine);
@@ -13,6 +14,7 @@ RACK_PLUGIN_INIT(bsp) {
RACK_PLUGIN_MODEL_ADD(bsp, AttenuMixer);
RACK_PLUGIN_MODEL_ADD(bsp, Obxd_VCF);
+ RACK_PLUGIN_MODEL_ADD(bsp, RMS);
RACK_PLUGIN_MODEL_ADD(bsp, Scanner);
RACK_PLUGIN_MODEL_ADD(bsp, Sway);
RACK_PLUGIN_MODEL_ADD(bsp, TunedDelayLine);
diff --git a/vst2_bin/plugins/bsp/README.md b/vst2_bin/plugins/bsp/README.md
index 95bba630..deba7a22 100644
--- a/vst2_bin/plugins/bsp/README.md
+++ b/vst2_bin/plugins/bsp/README.md
@@ -23,6 +23,7 @@ Suggested applications:
An adaption of Filatov Vadim's excellent Ob-Xd filter. Distributed under terms of the GNU General Public License V3.
+
# Scanner
A mixer that can seamlessly blend up to 16 input channels.
@@ -47,6 +48,17 @@ The switch enables the randomizer, and the button next to it is used to generate
NOTE: try modulating the position with the post output (feedback).
+
+# RMS
+
+A Root-Mean-Square based envelope follower, coupled with a slew limiter.
+
+The rise and fall rates can be configured separately.
+
+The module can be used to derive envelopes from audio signals, e.g. to implement compressor effects.
+
+
+
# Sway
A kind of slew-filtered noise generator, mainly designed for randomizing control voltages.
@@ -60,6 +72,7 @@ The "s+o" knobs are used to apply a final scaling/amplification (-5..5) and offs
NOTE: when the min/max time is set to very small values, the module can be used to generate audio-rate noise.
+
# Tuned Delay Line
This module was designed for Karplus-Strong synthesis.
diff --git a/vst2_bin/plugins/bsp/res/RMS.svg b/vst2_bin/plugins/bsp/res/RMS.svg
new file mode 100644
index 00000000..90bddc56
--- /dev/null
+++ b/vst2_bin/plugins/bsp/res/RMS.svg
@@ -0,0 +1,503 @@
+
+
+
+