I implemented RMS, a (pretty basic) SuperCollider UGen that calculates the root means square of an incoming signal. It is available at the sc-plugins directory.
It is a pretty rudimentary and straight forward implementation of a broadly used feature which I guess could well be part of the standard SC3 UGens collection.
Here is an example use case where it modulates delay times in a feedback patch and is used to analyse the input signal for a limiter:
// adapted from a Pd patch by Dario Sanfilippo
(
Ndef(\fb).addSpec(\modScale, [-20, 20, \lin, 1]);
Ndef(\fb).addSpec(\gain, [0, 2, \lin, 0]);
Ndef(\fb).addSpec(\amp, [0, 2, \lin, 0]);
Ndef(\fb).addSpec(\limit, [0, 1, \lin, 0]);
Ndef(\fb).addSpec(\lookahead, [0, 1, \lin, 0]);
Ndef(\fb).addSpec(\lpf, [0.01, 4, \exp, 0]);
Ndef(\fb, {
// var in = SoundIn.ar([0, 1]) * \gain.kr(0);
var in = SoundIn.ar(0) * \gain.kr(0);
var rms = RMS.ar(in, \lpf.kr(0.01));
// alternatives
// var rms = Amplitude.ar(in, 2, 2);
// var rms = EnvFollow.ar(in, 0.2);
var snd = DelayC.ar(in, 1, 0.5 + LeakDC.ar(rms, 0.9998) * \modScale.kr(0));
//////////////////
// AGC2.1 ( a limiter)
var rms500 = RMS.ar(snd, 500);
var rms1 = RMS.ar(snd, 1) * 2;
var analytics = max(rms500 - rms1, 0) + rms1;
snd = (DelayC.ar(snd, 0.02, \lookahead.kr(0) * 0.02) / max(analytics / \limit.kr(0), 1)).clip2(1, 1);
// the standard SC limiter
// snd = Limiter.ar(snd, \limit.kr(0), \lookahead.kr(0)).sum * \amp.kr(0)
snd * \amp.kr(0.1)
})
)
Ndef(\fb).edit;
![](/posts/2016-07-05-rms/media/slides/RMS01_hud1db9dd23f3200ab0e47cd3bffe5d4e1_140856_800x600_fill_q75_box_smart1.jpg.pagespeed.ce.sEvpS6W2Kc.jpg)
![](/posts/2016-07-05-rms/media/slides/RMS02_hu5f9a2ba303d4fe4cc618f6c3ac0cb9e6_139931_800x600_fill_q75_box_smart1.jpg.pagespeed.ce.I6E5jQLsZC.jpg)
![](/posts/2016-07-05-rms/media/slides/RMS03_hu121490c1e0751fdd565f03da1ca654e2_171616_800x600_fill_q75_box_smart1.jpg.pagespeed.ce.o9DJSHMnkH.jpg)