|
|
|
12-20-2019, 05:11 PM
|
#1
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,093
|
[Request] calibrated embeddable VU meter (DONE)
edit:
Done (see below), thanks ashcat_lt.
Reaper comes with the Liteon VU meter JSFX which is embedable in TCP/MCP but it doesn't seem to be calibrated/calibrateable to -18 = 0 VU (my preferred use case).
Also, maybe I used the wrong settings, but I couldn't quite get the meter ballistics matching other VU plugins.
Anyone could modify it (or make one)?
Last edited by nofish; 01-05-2020 at 07:00 PM.
|
|
|
01-05-2020, 09:26 AM
|
#2
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,264
|
Posted in the other thread a hack that makes it really rms, nice and smooth, and with both calibration and audio throughput gain adjustment.
https://forum.cockos.com/showpost.ph...0&postcount=18
|
|
|
01-05-2020, 10:09 AM
|
#3
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,093
|
Ballistic are very smooth now indeed and matching my other VUs, nice work, thank you ashcat.
I did however notice the reference level differs by 3 dB, but from what I know, both are correct, no? (depending on whether taking a sine or square wave as reference or something.)
|
|
|
01-05-2020, 10:25 AM
|
#4
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,264
|
I never really got that. RMS is RMS. It just turns out that square wave RMS is equal to the (rectified) peak level. Basically that meter is telling you what the peak level of a sine wave with that rms level would be. Or something. Seems silly, but there’s plenty of room for adjustment on the calibration slider.
I’m gonna play with it and add a couple options a little later.
|
|
|
01-05-2020, 01:08 PM
|
#5
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,093
|
Another thing I noticed, your version doesn't seem to embed in MCP anymore (which would actually be my intended use case).
|
|
|
01-05-2020, 04:27 PM
|
#6
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,264
|
Well shit yeah that really was the whole point. I haven't upgraded yet so can't test that. I wonder if there's something changed in the code to make it work? Any chance you could send me the code from your version?
|
|
|
01-05-2020, 04:44 PM
|
#7
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,264
|
But anyway, I made a "deluxe" version in case you want to check it out.
It has two new detector modes which change the ballistics pretty drastically. One is an average of rectified sample values rather than RMS and the other is slew rate limited rather than integrated. IDK which is most correct for actualy VU, but you can play around and see which feels best for you.
It also has an AutoGain feature. Set it to "1 = grab" and it will figure out how much gain it needs to hit the 0dbVU as set by the calibrate slider and then when you put it to "0 = run", it sets the gain slider to that. It works much better for more steady-state material. Can be weird with real percussive inputs.
Hopefully we can figure out the issue with the embedding.
Code:
desc: LT VU Meter Deluxe (Summed)
//tags: analysis visualization metering
//author: Liteon hacked by ashcat_lt
slider1:300<0,1000,1>Meter Time(ms)
slider2:0<0,2,1{Left,Sum,Maximum}>Channel
slider3:-18<-24,-9,0.1>Calibrate (0VU = xdbFS)
slider4:0<-24,24,0.1>Gain (db)
slider5:0<0,2,1{RMS,Average,Slew}>Detector
slider6:0<0,1,1>AutoGain (0=run, 1=grab)
in_pin:left input
in_pin:right input
out_pin:left output
out_pin:right output
@init
//rp - right channel y pading, r - radius
rp = 261;
r = 200;
yl = yr = ylt = yrt = 74;
xl = xr = 66;
ms = slider1;
cs = 0;
function ratiotodb (x)
( x = 20 * log10 (x););
function dbtoratio (x)
( x = 10 ^(x/20););
function RMS_set(rms_ms)
instance(coeff, icoeff)
(
coeff = exp(-1/(rms_ms / 1000 * srate));
icoeff = 1-coeff;
);
function set_logistic_limit (x)
instance (limit, scale)
(this.limit = x;
this.scale = 1/x;);
function slew_set(rms_ms, calib)
instance(slew)
(
this.slew = (1000 * calib) / (srate * rms_ms);
this.set_logistic_limit (this.slew);
);
function RMS(input)
instance(rms_s, coeff, icoeff)
(
rms_s = (rms_s * coeff) + (icoeff * input * input);
sqrt(rms_s);
);
function average(input)
instance(ave_s, coeff, icoeff)
(
ave_s = (ave_s * coeff) + (icoeff * abs(input));
);
function logistic (x)
instance(limit)
(log_input = x * this.scale;
log_curve = 1 / (1 + exp (-2 * log_input));
log_shifted = 2 * log_curve - 1;
log_outuput = this.limit * log_shifted;);
function slew(input)
instance(slew_s, slew)
(
input = abs(input);
diff = input - slew_s;
slew_s += this.logistic (diff);
);
@slider
rms_ms = slider1;
rms0.RMS_set(rms_ms);
calibrate = dbtoratio (slider3);
rms0.slew_set (rms_ms, calibrate);
gain = dbtoratio (slider4);
@block
rmsl_gfx = ratiotodb(rms_in);
slider6 == 1 ?
(gaindiff = min((slider3 - (rmsl_gfx - slider4)), 24)):
(last6 == 1 ? slider4 = gaindiff);
last6 = slider6;
ool = min (6, max (-60, (rmsl_gfx - slider3)));
//get x from exp scale
xlt = floor(exp(log(1.055)*2.1*ool)*285);
//get y from x and radius - r
l=sqrt(sqr(r)+sqr(212-xlt));
h=((l-r)*r/l);
m=sqrt(sqr(l-r)-sqr(h));
ylt=35+h;
xlt < 212 ? xlt=xlt+m : xlt=xlt-m;
//update x,y,out
old_xl < xlt ? (xl = min(max(xlt,66),375); yl = ylt; );
bscnt = pvl = pvr = 0;
;
//limit x
xl = min(max(xl,66),375);
olt = ratiotodb(peaksample);
@sample
spl0 *= gain;
spl1 *= gain;
slider2 == 0 ?
(rms_in_0 = spl0;);
slider2 == 1 ?
(rms_in_0 = (spl0 + spl1)/2) ;
slider2 == 2 ?
(rms_in_0 = max(spl0, spl1)) ;
slider5 == 0 ?
(rms_in = rms0.RMS(rms_in_0));
slider5 == 1 ?
(rms_in = rms0.average(rms_in_0));
slider5 == 2 ?
(rms_in = rms0.slew(rms_in_0));
peaksample = max (peaksample, rms_in_0);
@gfx 425 191
//**************************************************************** left
//red scale
gfx_r = gfx_a = 1;
gfx_g = gfx_b =0;
gfx_x = 283;
gfx_y = 28;
gfx_drawnumber(0,0);
gfx_x = 370;
gfx_y = 55;
gfx_drawnumber(3,0);
gfx_x = 405;
gfx_y = 57;
gfx_drawchar($'+');
gfx_x = 283;
gfx_y = 38;
gfx_lineto(269,76,0.5);
gfx_x = 311;
gfx_y = 43;
gfx_lineto(293,80,1);
gfx_x = 342;
gfx_y = 51;
gfx_lineto(318,85,1);
gfx_x = 370;
gfx_y = 65;
gfx_lineto(344,93,0.5);
//white scale
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 12;
gfx_y = 60;
gfx_drawchar($'-');
gfx_x = 41;
gfx_y = 53;
gfx_drawnumber(20,0);
gfx_x = 80;
gfx_y = 37;
gfx_drawnumber(10,0);
gfx_x = 125;
gfx_y = 29;
gfx_drawnumber(7,0);
gfx_x = 157;
gfx_y = 25;
gfx_drawnumber(5,0);
gfx_x = 198;
gfx_y = 24;
gfx_drawnumber(3,0);
gfx_x = 56;
gfx_y = 63;
gfx_lineto(82,92,0.5);
gfx_x = 95;
gfx_y = 47;
gfx_lineto(119,82,0.5);
gfx_x = 130;
gfx_y = 39;
gfx_lineto(146,77,0.5);
gfx_x = 145;
gfx_y = 37;
gfx_lineto(158,75,1);
gfx_x = 162;
gfx_y = 35;
gfx_lineto(171,74,0.5);
gfx_x = 180;
gfx_y = 34;
gfx_lineto(187,74,1);
gfx_x = 202;
gfx_y = 34;
gfx_lineto(204,72,0.5);
gfx_x = 227;
gfx_y = 34;
gfx_lineto(223,73,1);
gfx_x = 253;
gfx_y = 35;
gfx_lineto(245,73,1);
//vu box border
gfx_r = gfx_g = gfx_b = 0.75;
gfx_a = 1;
gfx_x = 198;
gfx_y = 108;
gfx_rectto(241,139);
//vu box
gfx_a = 1;
gfx_r = 0.5;
gfx_g = gfx_b = 0.1;
gfx_x = 200;
gfx_y = 110;
gfx_rectto(239,137);
//vu text
gfx_r = gfx_g = gfx_b = 0.85;
gfx_a = 1;
gfx_x = 212;
gfx_y = 120;
gfx_drawchar($'V');
gfx_drawchar($'U');
//meter
olt > 0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
) : (
gfx_r = gfx_g = gfx_b = 1;
);
gfx_a = 1;
gfx_x = 212;
gfx_y = 236;
gfx_lineto(xl,yl,1);
gfx_x = 211;
gfx_y = 236;
gfx_lineto(xl-1,yl,1);
gfx_x = 210;
gfx_y = 236;
gfx_lineto(xl-2,yl,1);
//big border
gfx_r = gfx_g = gfx_b = 0.55;
gfx_a = 1;
gfx_x = 0;
gfx_y = 179;
gfx_rectto(425,180);
//big box 1
gfx_r = 0.1;
gfx_g = 0.2;
gfx_b = 0.39;
gfx_a = 1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,261);
//big box 2
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 0.1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,190);
//big box 3
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 0.3;
gfx_x = 0;
gfx_y = 245;
gfx_rectto(425,261);
//ch textbox1
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 350;
gfx_y = 210;
gfx_rectto(415,227);
//ch textbox2
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 250;
gfx_y = 210;
gfx_rectto(315,227);
//ch text
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 20;
gfx_y = 215;
gfx_drawchar($'L');
gfx_drawchar($'+');
gfx_drawchar($'R');
gfx_x = 215;
slider5 == 0 ?
(gfx_drawchar($'R');
gfx_drawchar($'M');
gfx_drawchar($'S'););
slider5 == 1 ?
(gfx_drawchar($'A');
gfx_drawchar($'V');
gfx_drawchar($'G'););
slider5 == 2 ?
(gfx_drawchar($'S');
gfx_drawchar($'L');
gfx_drawchar($'W'););
gfx_x = 333;
gfx_drawchar($'P');
gfx_x = 255;
rmsl_gfx > -300 ? (
rmsl_gfx > 0.0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
gfx_drawchar($'+');
);
gfx_drawnumber(rmsl_gfx,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
gfx_r = 1;
gfx_g = gfx_b = 1;
gfx_x = 355;
olt > -300 ? (
olt >= 0.0 ? (
gfx_drawchar($'+');
gfx_r = 1;
gfx_g = gfx_b = 0;
);
gfx_drawnumber(olt,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
|
|
|
01-05-2020, 06:16 PM
|
#8
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,093
|
Quote:
Originally Posted by ashcat_lt
Any chance you could send me the code from your version?
|
That's the code for the Liteon VU meter that comes with Reaper (which was modified by the Reaper devs to be embedable afaik).
Code:
// (C) 2008-2009, Lubomir I. Ivanov
// NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
// WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO,
// ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING
// OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF
// MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN
// TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND
// USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD
// PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR
// ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS
// PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO
// ENTRUST SOMEBODY ELSE WITH DOING SO.
//
// Released under GPL:
// <http://www.gnu.org/licenses/>.
//******************************************************************************
//References: cockos, wiki, math books
//******************************************************************************
desc: VU Meter (Summed)
//tags: analysis visualization metering
//author: Liteon
slider1:50<1,300,1>Response (ms)
slider2:5<1,10,0.1>Release (Slow/Fast)
in_pin:left input
in_pin:right input
out_pin:none
@init
//st - sample time, sc - db scale, rp - right channel y pading, r - radius
sc = 6/log(2);
rp = 261;
r = 200;
yl = yr = ylt = yrt = 74;
xl = xr = 66;
ms = slider1;
cs = 0;
suml = sumr = 0;
rms_i = 0;
i_max = 36;
@slider
rel = slider2;
ms = slider1;
st = ms*srate/1000;
hold = (0.001*ms*srate);
cs = 0;
suml = sumr = 0;
@block
rmsl = floor(sc*log(sqrt(suml/cs))*100)/100;
ab1 = log(sqrt(suml/cs));
ab2 = sqrt(suml/cs);
rms_i == i_max ? (
rmsl_gfx = rmsl;
rms_i = 0;
);
rms_i += 1;
bscnt > st ? (
ool = log(pvl)*sc;
//get x from exp scale
xlt = floor(exp(log(1.055)*2.1*ool)*285);
//get y from x and radius - r
l=sqrt(sqr(r)+sqr(212-xlt));
h=((l-r)*r/l);
m=sqrt(sqr(l-r)-sqr(h));
ylt=35+h;
xlt < 212 ? xlt=xlt+m : xlt=xlt-m;
//update x,y,out
old_xl < xlt ? (xl = min(max(xlt,66),375); yl = ylt; olt = ool;);
bscnt = pvl = pvr = 0;
);
old_xl = xl;
bscnt += samplesblock;
//indicator fall-back
fallback = rel/2*samplesblock/1024;
fbi_l = exp(xl/512)*fallback;
xl > 66 ? xl -= fbi_l;
//limit x
xl = min(max(xl,66),375);
//get y after fall-back
yl=35;
l=sqrt(sqr(r)+sqr(212-xl));
h=((l-r)*r/l);
yl=floor(yl+h);
@sample
spl0 *= 7.943282347242816;
spl1 *= 7.943282347242816;
pvl = max(pvl,abs((spl0+spl1)/2));
cs == hold ? (
cs = 0;
suml = 0;
) : (
cs += 1;
suml += sqr(abs((spl0+spl1)/2));
);
@gfx 425 240
// override drawing functions for graphical window scaling
gsc = min(gfx_w/425,gfx_h/240); igsc = 1.0/gsc;
gxo = max(0, gfx_w/2 - gfx_h*425/240/2);
function gfx_lineto(x,y,aa) ( gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gfx_lineto(x*gsc+gxo,y*gsc,aa); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc; );
function gfx_rectto(x,y)(gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gsc>.5 ? gfx_rectto(x*gsc+gxo,y*gsc); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc;);
function gfx_drawnumber(y,x) (
gsc>.5 ? (
gsc<.7 && x>1 ? x=1;
gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gfx_drawnumber(y,x); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc;
);
);
function gfx_drawchar(x) ( gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gsc>.5 ? gfx_drawchar(x); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc; );
//**************************************************************** left
//red scale
gfx_r = gfx_a = 1;
gfx_g = gfx_b =0;
gfx_x = 283;
gfx_y = 28;
gfx_drawnumber(0,0);
gfx_x = 370;
gfx_y = 55;
gfx_drawnumber(3,0);
gfx_x = 405;
gfx_y = 57;
gfx_drawchar($'+');
gfx_x = 283;
gfx_y = 38;
gfx_lineto(269,76,0.5);
gfx_x = 311;
gfx_y = 43;
gfx_lineto(293,80,1);
gfx_x = 342;
gfx_y = 51;
gfx_lineto(318,85,1);
gfx_x = 370;
gfx_y = 65;
gfx_lineto(344,93,0.5);
//white scale
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 12;
gfx_y = 60;
gfx_drawchar($'-');
gfx_x = 41;
gfx_y = 53;
gfx_drawnumber(20,0);
gfx_x = 80;
gfx_y = 37;
gfx_drawnumber(10,0);
gfx_x = 125;
gfx_y = 29;
gfx_drawnumber(7,0);
gfx_x = 157;
gfx_y = 25;
gfx_drawnumber(5,0);
gfx_x = 198;
gfx_y = 24;
gfx_drawnumber(3,0);
gfx_x = 56;
gfx_y = 63;
gfx_lineto(82,92,0.5);
gfx_x = 95;
gfx_y = 47;
gfx_lineto(119,82,0.5);
gfx_x = 130;
gfx_y = 39;
gfx_lineto(146,77,0.5);
gfx_x = 145;
gfx_y = 37;
gfx_lineto(158,75,1);
gfx_x = 162;
gfx_y = 35;
gfx_lineto(171,74,0.5);
gfx_x = 180;
gfx_y = 34;
gfx_lineto(187,74,1);
gfx_x = 202;
gfx_y = 34;
gfx_lineto(204,72,0.5);
gfx_x = 227;
gfx_y = 34;
gfx_lineto(223,73,1);
gfx_x = 253;
gfx_y = 35;
gfx_lineto(245,73,1);
//vu box border
gfx_r = gfx_g = gfx_b = 0.75;
gfx_a = 1;
gfx_x = 198;
gfx_y = 108;
gfx_rectto(241,139);
//vu box
gfx_a = 1;
gfx_r = 0.5;
gfx_g = gfx_b = 0.1;
gfx_x = 200;
gfx_y = 110;
gfx_rectto(239,137);
//vu text
gfx_r = gfx_g = gfx_b = 0.85;
gfx_a = 1;
gfx_x = 212;
gfx_y = 120;
gfx_drawchar($'V');
gfx_drawchar($'U');
//meter
olt > 0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
) : (
gfx_r = gfx_g = gfx_b = 1;
);
gfx_a = 1;
gfx_x = 212;
gfx_y = 236;
gfx_lineto(xl,yl,1);
gfx_x = 211;
gfx_y = 236;
gfx_lineto(xl-1,yl,1);
gfx_x = 210;
gfx_y = 236;
gfx_lineto(xl-2,yl,1);
//big border
gfx_r = gfx_g = gfx_b = 0.55;
gfx_a = 1;
gfx_x = 0;
gfx_y = 179;
gfx_rectto(425,180);
//big box 1
gfx_r = 0.1;
gfx_g = 0.2;
gfx_b = 0.39;
gfx_a = 1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,261);
//big box 2
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 0.1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,190);
//big box 3
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 0.3;
gfx_x = 0;
gfx_y = 245;
gfx_rectto(425,261);
//ch textbox1
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 350;
gfx_y = 210;
gfx_rectto(415,227);
//ch textbox2
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 250;
gfx_y = 210;
gfx_rectto(315,227);
//ch text
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 20;
gfx_y = 215;
gfx_drawchar($'L');
gfx_drawchar($'+');
gfx_drawchar($'R');
gfx_x = 215;
gfx_drawchar($'R');
gfx_drawchar($'M');
gfx_drawchar($'S');
gfx_x = 333;
gfx_drawchar($'P');
gfx_x = 255;
rmsl_gfx > -300 ? (
rmsl_gfx > 0.0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
gfx_drawchar($'+');
);
gfx_drawnumber(rmsl_gfx,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
gfx_r = 1;
gfx_g = gfx_b = 1;
gfx_x = 355;
olt > -300 ? (
olt >= 0.0 ? (
gfx_drawchar($'+');
gfx_r = 1;
gfx_g = gfx_b = 0;
);
gfx_drawnumber(olt,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
edit:
Simply pasting the
// override drawing functions for graphical window scaling
section in your version did it.
Last edited by nofish; 01-05-2020 at 06:21 PM.
|
|
|
01-05-2020, 06:23 PM
|
#9
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,264
|
K.
Try this and LMK:
Code:
desc: LT VU Meter Deluxe (Summed)
//tags: analysis visualization metering
//author: Liteon hacked by ashcat_lt
slider1:300<0,1000,1>Meter Time(ms)
slider2:0<0,2,1{Left,Sum,Maximum}>Channel
slider3:-18<-24,-9,0.1>Calibrate (0VU = xdbFS)
slider4:0<-24,24,0.1>Gain (db)
slider5:0<0,2,1{RMS,Average,Slew}>Detector
slider6:0<0,1,1>AutoGain (0=run, 1=grab)
in_pin:left input
in_pin:right input
out_pin:left output
out_pin:right output
@init
//rp - right channel y pading, r - radius
rp = 261;
r = 200;
yl = yr = ylt = yrt = 74;
xl = xr = 66;
ms = slider1;
cs = 0;
function ratiotodb (x)
( x = 20 * log10 (x););
function dbtoratio (x)
( x = 10 ^(x/20););
function RMS_set(rms_ms)
instance(coeff, icoeff)
(
coeff = exp(-1/(rms_ms / 1000 * srate));
icoeff = 1-coeff;
);
function set_logistic_limit (x)
instance (limit, scale)
(this.limit = x;
this.scale = 1/x;);
function slew_set(rms_ms, calib)
instance(slew)
(
this.slew = (1000 * calib) / (srate * rms_ms);
this.set_logistic_limit (this.slew);
);
function RMS(input)
instance(rms_s, coeff, icoeff)
(
rms_s = (rms_s * coeff) + (icoeff * input * input);
sqrt(rms_s);
);
function average(input)
instance(ave_s, coeff, icoeff)
(
ave_s = (ave_s * coeff) + (icoeff * abs(input));
);
function logistic (x)
instance(limit)
(log_input = x * this.scale;
log_curve = 1 / (1 + exp (-2 * log_input));
log_shifted = 2 * log_curve - 1;
log_outuput = this.limit * log_shifted;);
function slew(input)
instance(slew_s, slew)
(
input = abs(input);
diff = input - slew_s;
slew_s += this.logistic (diff);
);
@slider
rms_ms = slider1;
rms0.RMS_set(rms_ms);
calibrate = dbtoratio (slider3);
rms0.slew_set (rms_ms, calibrate);
gain = dbtoratio (slider4);
@block
rmsl_gfx = ratiotodb(rms_in);
slider6 == 1 ?
(gaindiff = min((slider3 - (rmsl_gfx - slider4)), 24)):
(last6 == 1 ? slider4 = gaindiff);
last6 = slider6;
ool = min (6, max (-60, (rmsl_gfx - slider3)));
//get x from exp scale
xlt = floor(exp(log(1.055)*2.1*ool)*285);
//get y from x and radius - r
l=sqrt(sqr(r)+sqr(212-xlt));
h=((l-r)*r/l);
m=sqrt(sqr(l-r)-sqr(h));
ylt=35+h;
xlt < 212 ? xlt=xlt+m : xlt=xlt-m;
//update x,y,out
old_xl < xlt ? (xl = min(max(xlt,66),375); yl = ylt; );
bscnt = pvl = pvr = 0;
;
//limit x
xl = min(max(xl,66),375);
olt = ratiotodb(peaksample);
@sample
spl0 *= gain;
spl1 *= gain;
slider2 == 0 ?
(rms_in_0 = spl0;);
slider2 == 1 ?
(rms_in_0 = (spl0 + spl1)/2) ;
slider2 == 2 ?
(rms_in_0 = max(spl0, spl1)) ;
slider5 == 0 ?
(rms_in = rms0.RMS(rms_in_0));
slider5 == 1 ?
(rms_in = rms0.average(rms_in_0));
slider5 == 2 ?
(rms_in = rms0.slew(rms_in_0));
peaksample = max (peaksample, rms_in_0);
@gfx 425 240
// override drawing functions for graphical window scaling
gsc = min(gfx_w/425,gfx_h/240); igsc = 1.0/gsc;
gxo = max(0, gfx_w/2 - gfx_h*425/240/2);
function gfx_lineto(x,y,aa) ( gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gfx_lineto(x*gsc+gxo,y*gsc,aa); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc; );
function gfx_rectto(x,y)(gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gsc>.5 ? gfx_rectto(x*gsc+gxo,y*gsc); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc;);
function gfx_drawnumber(y,x) (
gsc>.5 ? (
gsc<.7 && x>1 ? x=1;
gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gfx_drawnumber(y,x); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc;
);
);
function gfx_drawchar(x) ( gfx_x*=gsc; gfx_y*=gsc; gfx_x+=gxo; gsc>.5 ? gfx_drawchar(x); gfx_x-=gxo; gfx_x*=igsc; gfx_y*=igsc; );
//**************************************************************** left
//red scale
gfx_r = gfx_a = 1;
gfx_g = gfx_b =0;
gfx_x = 283;
gfx_y = 28;
gfx_drawnumber(0,0);
gfx_x = 370;
gfx_y = 55;
gfx_drawnumber(3,0);
gfx_x = 405;
gfx_y = 57;
gfx_drawchar($'+');
gfx_x = 283;
gfx_y = 38;
gfx_lineto(269,76,0.5);
gfx_x = 311;
gfx_y = 43;
gfx_lineto(293,80,1);
gfx_x = 342;
gfx_y = 51;
gfx_lineto(318,85,1);
gfx_x = 370;
gfx_y = 65;
gfx_lineto(344,93,0.5);
//white scale
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 12;
gfx_y = 60;
gfx_drawchar($'-');
gfx_x = 41;
gfx_y = 53;
gfx_drawnumber(20,0);
gfx_x = 80;
gfx_y = 37;
gfx_drawnumber(10,0);
gfx_x = 125;
gfx_y = 29;
gfx_drawnumber(7,0);
gfx_x = 157;
gfx_y = 25;
gfx_drawnumber(5,0);
gfx_x = 198;
gfx_y = 24;
gfx_drawnumber(3,0);
gfx_x = 56;
gfx_y = 63;
gfx_lineto(82,92,0.5);
gfx_x = 95;
gfx_y = 47;
gfx_lineto(119,82,0.5);
gfx_x = 130;
gfx_y = 39;
gfx_lineto(146,77,0.5);
gfx_x = 145;
gfx_y = 37;
gfx_lineto(158,75,1);
gfx_x = 162;
gfx_y = 35;
gfx_lineto(171,74,0.5);
gfx_x = 180;
gfx_y = 34;
gfx_lineto(187,74,1);
gfx_x = 202;
gfx_y = 34;
gfx_lineto(204,72,0.5);
gfx_x = 227;
gfx_y = 34;
gfx_lineto(223,73,1);
gfx_x = 253;
gfx_y = 35;
gfx_lineto(245,73,1);
//vu box border
gfx_r = gfx_g = gfx_b = 0.75;
gfx_a = 1;
gfx_x = 198;
gfx_y = 108;
gfx_rectto(241,139);
//vu box
gfx_a = 1;
gfx_r = 0.5;
gfx_g = gfx_b = 0.1;
gfx_x = 200;
gfx_y = 110;
gfx_rectto(239,137);
//vu text
gfx_r = gfx_g = gfx_b = 0.85;
gfx_a = 1;
gfx_x = 212;
gfx_y = 120;
gfx_drawchar($'V');
gfx_drawchar($'U');
//meter
olt > 0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
) : (
gfx_r = gfx_g = gfx_b = 1;
);
gfx_a = 1;
gfx_x = 212;
gfx_y = 236;
gfx_lineto(xl,yl,1);
gfx_x = 211;
gfx_y = 236;
gfx_lineto(xl-1,yl,1);
gfx_x = 210;
gfx_y = 236;
gfx_lineto(xl-2,yl,1);
//big border
gfx_r = gfx_g = gfx_b = 0.55;
gfx_a = 1;
gfx_x = 0;
gfx_y = 179;
gfx_rectto(425,180);
//big box 1
gfx_r = 0.1;
gfx_g = 0.2;
gfx_b = 0.39;
gfx_a = 1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,261);
//big box 2
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 0.1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,190);
//big box 3
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 0.3;
gfx_x = 0;
gfx_y = 245;
gfx_rectto(425,261);
//ch textbox1
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 350;
gfx_y = 210;
gfx_rectto(415,227);
//ch textbox2
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 250;
gfx_y = 210;
gfx_rectto(315,227);
//ch text
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 20;
gfx_y = 215;
gfx_drawchar($'L');
gfx_drawchar($'+');
gfx_drawchar($'R');
gfx_x = 215;
slider5 == 0 ?
(gfx_drawchar($'R');
gfx_drawchar($'M');
gfx_drawchar($'S'););
slider5 == 1 ?
(gfx_drawchar($'A');
gfx_drawchar($'V');
gfx_drawchar($'G'););
slider5 == 2 ?
(gfx_drawchar($'S');
gfx_drawchar($'L');
gfx_drawchar($'W'););
gfx_x = 333;
gfx_drawchar($'P');
gfx_x = 255;
rmsl_gfx > -300 ? (
rmsl_gfx > 0.0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
gfx_drawchar($'+');
);
gfx_drawnumber(rmsl_gfx,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
gfx_r = 1;
gfx_g = gfx_b = 1;
gfx_x = 355;
olt > -300 ? (
olt >= 0.0 ? (
gfx_drawchar($'+');
gfx_r = 1;
gfx_g = gfx_b = 0;
);
gfx_drawnumber(olt,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
|
|
|
01-05-2020, 07:04 PM
|
#10
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,093
|
Yep, works. Thanks.
|
|
|
01-05-2020, 07:14 PM
|
#11
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,264
|
Woot!
|
|
|
01-12-2020, 04:54 PM
|
#12
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,264
|
Minor update here.
Added an "audio" output on channel 3 that represents the calculated value (RMS or whatever). Be careful with this. Use pin connectors to assign it to a track channel that you're not using for other things. You can use it as a sidechain or "Control Voltage" input for other plugins or as a way to analyze the dynamics of your signal. OR Render it to an audio item, adjust its volume envelope, and then copy that to an envelope on your original signal.
But then I also added a slider labeled "level" which is literally the same thing but you can write it to automation. Not sure why you'd want that, but it's there.
Code:
desc: LT VU Meter Deluxe (Summed)
//tags: analysis visualization metering
//author: Liteon hacked by ashcat_lt
slider1:300<0,1000,1>RMS size (ms)
slider2:0<0,2,1{Left,Sum,Maximum}>Channel
slider3:-18<-24,-9,0.1>Calibrate (0VU = xdbFS)
slider4:0<-24,24,0.1>Gain (db)
slider5:0<0,2,1{RMS,Average,Slew}>Detector
slider6:0<0,1,1>AutoGain
slider7:<0,1,0.001>level
in_pin:left input
in_pin:right input
out_pin:left output
out_pin:right output
out_pin:level output (CV)
@init
//rp - right channel y pading, r - radius
rp = 261;
r = 200;
yl = yr = ylt = yrt = 74;
xl = xr = 66;
ms = slider1;
cs = 0;
function ratiotodb (x)
( x = 20 * log10 (x););
function dbtoratio (x)
( x = 10 ^(x/20););
function RMS_set(rms_ms)
instance(coeff, icoeff)
(
coeff = exp(-1/(rms_ms / 1000 * srate));
icoeff = 1-coeff;
);
function set_logistic_limit (x)
instance (limit, scale)
(this.limit = x;
this.scale = 1/x;);
function slew_set(rms_ms, calib)
instance(slew)
(
this.slew = (1000 * calib) / (srate * rms_ms);
this.set_logistic_limit (this.slew);
);
function RMS(input)
instance(rms_s, coeff, icoeff)
(
rms_s = (rms_s * coeff) + (icoeff * input * input);
sqrt(rms_s);
);
function average(input)
instance(ave_s, coeff, icoeff)
(
ave_s = (ave_s * coeff) + (icoeff * abs(input));
);
function logistic (x)
instance(limit)
(log_input = x * this.scale;
log_curve = 1 / (1 + exp (-2 * log_input));
log_shifted = 2 * log_curve - 1;
log_outuput = this.limit * log_shifted;);
function slew(input)
instance(slew_s, slew)
(
input = abs(input);
diff = input - slew_s;
slew_s += this.logistic (diff);
);
@slider
rms_ms = slider1;
rms0.RMS_set(rms_ms);
calibrate = dbtoratio (slider3);
rms0.slew_set (rms_ms, calibrate);
gain = dbtoratio (slider4);
@block
slider7 = rms_in;
slider_automate (slider7);
rmsl_gfx = ratiotodb(rms_in);
slider6 == 1 ?
(gaindiff = min((slider3 - (rmsl_gfx - slider4)), 24)):
(last6 == 1 ? slider4 = gaindiff);
last6 = slider6;
ool = min (6, max (-60, (rmsl_gfx - slider3)));
//get x from exp scale
xlt = floor(exp(log(1.055)*2.1*ool)*285);
//get y from x and radius - r
l=sqrt(sqr(r)+sqr(212-xlt));
h=((l-r)*r/l);
m=sqrt(sqr(l-r)-sqr(h));
ylt=35+h;
xlt < 212 ? xlt=xlt+m : xlt=xlt-m;
//update x,y,out
old_xl < xlt ? (xl = min(max(xlt,66),375); yl = ylt; );
bscnt = pvl = pvr = 0;
;
//limit x
xl = min(max(xl,66),375);
olt = ratiotodb(peaksample);
@sample
spl0 *= gain;
spl1 *= gain;
slider2 == 0 ?
(rms_in_0 = spl0;);
slider2 == 1 ?
(rms_in_0 = (spl0 + spl1)/2) ;
slider2 == 2 ?
(rms_in_0 = max(spl0, spl1)) ;
slider5 == 0 ?
(rms_in = rms0.RMS(rms_in_0));
slider5 == 1 ?
(rms_in = rms0.average(rms_in_0));
slider5 == 2 ?
(rms_in = rms0.slew(rms_in_0));
spl2 = rms_in;
peaksample = max (peaksample, rms_in_0);
@gfx 425 191
//**************************************************************** left
//red scale
gfx_r = gfx_a = 1;
gfx_g = gfx_b =0;
gfx_x = 283;
gfx_y = 28;
gfx_drawnumber(0,0);
gfx_x = 370;
gfx_y = 55;
gfx_drawnumber(3,0);
gfx_x = 405;
gfx_y = 57;
gfx_drawchar($'+');
gfx_x = 283;
gfx_y = 38;
gfx_lineto(269,76,0.5);
gfx_x = 311;
gfx_y = 43;
gfx_lineto(293,80,1);
gfx_x = 342;
gfx_y = 51;
gfx_lineto(318,85,1);
gfx_x = 370;
gfx_y = 65;
gfx_lineto(344,93,0.5);
//white scale
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 12;
gfx_y = 60;
gfx_drawchar($'-');
gfx_x = 41;
gfx_y = 53;
gfx_drawnumber(20,0);
gfx_x = 80;
gfx_y = 37;
gfx_drawnumber(10,0);
gfx_x = 125;
gfx_y = 29;
gfx_drawnumber(7,0);
gfx_x = 157;
gfx_y = 25;
gfx_drawnumber(5,0);
gfx_x = 198;
gfx_y = 24;
gfx_drawnumber(3,0);
gfx_x = 56;
gfx_y = 63;
gfx_lineto(82,92,0.5);
gfx_x = 95;
gfx_y = 47;
gfx_lineto(119,82,0.5);
gfx_x = 130;
gfx_y = 39;
gfx_lineto(146,77,0.5);
gfx_x = 145;
gfx_y = 37;
gfx_lineto(158,75,1);
gfx_x = 162;
gfx_y = 35;
gfx_lineto(171,74,0.5);
gfx_x = 180;
gfx_y = 34;
gfx_lineto(187,74,1);
gfx_x = 202;
gfx_y = 34;
gfx_lineto(204,72,0.5);
gfx_x = 227;
gfx_y = 34;
gfx_lineto(223,73,1);
gfx_x = 253;
gfx_y = 35;
gfx_lineto(245,73,1);
//vu box border
gfx_r = gfx_g = gfx_b = 0.75;
gfx_a = 1;
gfx_x = 198;
gfx_y = 108;
gfx_rectto(241,139);
//vu box
gfx_a = 1;
gfx_r = 0.5;
gfx_g = gfx_b = 0.1;
gfx_x = 200;
gfx_y = 110;
gfx_rectto(239,137);
//vu text
gfx_r = gfx_g = gfx_b = 0.85;
gfx_a = 1;
gfx_x = 212;
gfx_y = 120;
gfx_drawchar($'V');
gfx_drawchar($'U');
//meter
olt > 0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
) : (
gfx_r = gfx_g = gfx_b = 1;
);
gfx_a = 1;
gfx_x = 212;
gfx_y = 236;
gfx_lineto(xl,yl,1);
gfx_x = 211;
gfx_y = 236;
gfx_lineto(xl-1,yl,1);
gfx_x = 210;
gfx_y = 236;
gfx_lineto(xl-2,yl,1);
//big border
gfx_r = gfx_g = gfx_b = 0.55;
gfx_a = 1;
gfx_x = 0;
gfx_y = 179;
gfx_rectto(425,180);
//big box 1
gfx_r = 0.1;
gfx_g = 0.2;
gfx_b = 0.39;
gfx_a = 1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,261);
//big box 2
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 0.1;
gfx_x = 0;
gfx_y = 180;
gfx_rectto(425,190);
//big box 3
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 0.3;
gfx_x = 0;
gfx_y = 245;
gfx_rectto(425,261);
//ch textbox1
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 350;
gfx_y = 210;
gfx_rectto(415,227);
//ch textbox2
gfx_r = gfx_g = gfx_b = 0;
gfx_a = 1;
gfx_x = 250;
gfx_y = 210;
gfx_rectto(315,227);
//ch text
gfx_r = gfx_g = gfx_b = 1;
gfx_a = 1;
gfx_x = 20;
gfx_y = 215;
gfx_drawchar($'L');
gfx_drawchar($'+');
gfx_drawchar($'R');
gfx_x = 215;
slider5 == 0 ?
(gfx_drawchar($'R');
gfx_drawchar($'M');
gfx_drawchar($'S'););
slider5 == 1 ?
(gfx_drawchar($'A');
gfx_drawchar($'V');
gfx_drawchar($'G'););
slider5 == 2 ?
(gfx_drawchar($'S');
gfx_drawchar($'L');
gfx_drawchar($'W'););
gfx_x = 333;
gfx_drawchar($'P');
gfx_x = 255;
rmsl_gfx > -300 ? (
rmsl_gfx > 0.0 ? (
gfx_r = 1;
gfx_g = gfx_b = 0;
gfx_drawchar($'+');
);
gfx_drawnumber(rmsl_gfx,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
gfx_r = 1;
gfx_g = gfx_b = 1;
gfx_x = 355;
olt > -300 ? (
olt >= 0.0 ? (
gfx_drawchar($'+');
gfx_r = 1;
gfx_g = gfx_b = 0;
);
gfx_drawnumber(olt,2);
) : (
gfx_drawchar($'-');
gfx_drawchar($'I');
gfx_drawchar($'N');
gfx_drawchar($'F');
);
|
|
|
11-01-2020, 09:23 AM
|
#13
|
Human being with feelings
Join Date: Feb 2011
Location: Budapest, Hungary
Posts: 31
|
Before I got here just happened to modify Liteon's Summed VU meter to have real VU meter like ballistics, Gain trim and Peak needle with hold that also embeds nicely to MCP. Also included FxChain to embed Gain trim to MCP.
Anyway here it is, hope someone find it useful.
Best Regards
Zsazsi
|
|
|
12-01-2020, 03:19 AM
|
#14
|
Human being with feelings
Join Date: Feb 2014
Location: London
Posts: 22
|
Quote:
Originally Posted by zsazsi
Before I got here just happened to modify Liteon's Summed VU meter to have real VU meter like ballistics, Gain trim and Peak needle with hold that also embeds nicely to MCP. Also included FxChain to embed Gain trim to MCP.
Anyway here it is, hope someone find it useful.
Best Regards
Zsazsi
|
Thanks so much, that's super useful
|
|
|
03-26-2021, 08:42 AM
|
#15
|
Human being with feelings
Join Date: Dec 2009
Location: Like, SoCal...
Posts: 344
|
Quote:
Originally Posted by zsazsi
Before I got here just happened to modify Liteon's Summed VU meter to have real VU meter like ballistics, Gain trim and Peak needle with hold that also embeds nicely to MCP. Also included FxChain to embed Gain trim to MCP.
Anyway here it is, hope someone find it useful.
Best Regards
Zsazsi
|
Helpful.
We can haz for regulr sterio VU meetr 2?
|
|
|
08-05-2022, 10:03 AM
|
#16
|
Human being with feelings
Join Date: Feb 2020
Posts: 110
|
I trust everyone here is aware of the ZenoMod VU now included with Reaper under the JS category? It scales perfectly in MCP, has awesome colour options and great VU ballistics. I'm running it first on every channel for gain staging followed by the wonderful PSP Infinistrip.
|
|
|
08-05-2022, 10:38 AM
|
#17
|
Human being with feelings
Join Date: Dec 2009
Location: Like, SoCal...
Posts: 344
|
Quote:
Originally Posted by petergreeny
I trust everyone here is aware of the ZenoMod VU now included with Reaper under the JS category? It scales perfectly in MCP, has awesome colour options and great VU ballistics. I'm running it first on every channel for gain staging followed by the wonderful PSP Infinistrip.
|
I don't have anything called 'zenomod' in my plugins. Looks nice though.
|
|
|
08-06-2022, 02:42 PM
|
#18
|
Human being with feelings
Join Date: Feb 2020
Posts: 110
|
Quote:
Originally Posted by hexSPA
I don't have anything called 'zenomod' in my plugins. Looks nice though.
|
It's a free add-on, see this thread:
https://forum.cockos.com/showthread.php?t=262611
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 05:38 AM.
|