// Use with MIDItoReaControlPath.
// Right click the display to change it.

slider1:0<-97,97,1>Input Volume (dB)
slider2:50<10,1000,10>RMS Window (ms)
slider3:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Channel
slider4:3<0,127,1{0 Bank Sel M,1 Mod Wheel M,2 Breath M,3,4 Foot P M,5 Porta M,6 Data Entry M,7 Vol M,8 Balance M,9,10 Pan M,11 Expression M,12 Ctrl 1 M,13 Ctrl 2 M,14,15,16 GP Slider 1,17 GP Slider 2,18 GP Slider 3,19 GP Slider 4,20,21,22,23,24,25,26,27,28,29,30,31,32 Bank Sel L,33 Mod Wheel L,34 Breath L,35,36 Foot P L,37 Porta L,38 Data Entry L,39 Vol L,40 Balance L,41,42 Pan L,43 Expression L,44 Ctrl 1 L,45 Ctrl 2 L,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64 Hold P sw,65 Porta sw,66 Sustenuto sw,67 Soft P sw,68 Legato P sw,69 Hold 2 P sw,70 S.Variation,71 S.Timbre,72 S.Release,73 S.Attack,74 S.Brightness,75 S.Ctrl 6,76 S.Ctrl 7,77 S.Ctrl 8,78 S.Ctrl 9,79 S.Ctrl 10,80 GP B.1 sw,81 GP B.2 sw,82 GP B.3 sw,83 GP B.4 sw,84,85,86,87,88,89,90,91 Effects Lv,92 Trem Lv,93 Chorus Lv,94 Celeste Lv,95 Phaser Lv,96 Data B. Inc,97 Data B. Dec,98 NRP L,99 NRP M,100 RP L,101 RP M,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127}>CC Number
slider5:0<0,127,1>Start from CC Value
slider6:0<0,1,1{Positive,Negative}>Mode
slider7:100<0,100,1>Original Signal Mix (%)

in_pin:L in
in_pin:R in
out_pin:L out
out_pin:R out

@init
ext_noinit = 1;

log2db = 8.6858896380650365530225783783321;

DB_LO = -97;
peak0 = peak1 = 0;
sumsq0 = sumsq1 = 0;
peakdb0 = peakdb1 = DB_LO;

CC_MESG_MIN = 176;
BYTE_SIZE = 256;
offset = 0;
send_cc = 0;
last_value = 0;

dtor = 1/360 * 2 * $pi;
pi150 = $pi * 3 / 2;
r1_range = 330/360;

RIGHT_CLICK = 2;
NO_CLICK = 0;
NO = 0; YES = 1;
first_click = YES;

@slider
RMS_MS = slider2;
decay = exp(-1/(RMS_MS*srate*0.001));
buf = 0;
buflen = (RMS_MS*srate*0.001)|0;
memset(0, 0, 2*buflen);
pos = 0;

channel = slider3;
cc = slider4;

mix = slider7 / 100;

@block
peak0 <= 0.0 ? peakdb0 = DB_LO : peakdb0 = log2db*log(peak0);
peak1 <= 0.0 ? peakdb1 = DB_LO : peakdb1 = log2db*log(peak1);

peakdb = (peakdb0+peakdb1)*0.5;
peakdb >= 0 ? peakdb = 0;

slider6==1 ? (
value = -(sqrt(127^2/10^((-peakdb-slider1)/20)));
):(
value = (sqrt(127^2/10^((-peakdb-slider1)/20)));
);
value = (value + 0.5) | 0;
value += slider5;
value <= 0 ? value=0;
value >= 127 ? value=127;
( value != last_value ) ? send_cc = 1;

send_cc ? (
msg1 = channel + CC_MESG_MIN;
msg23 = cc + ( value * BYTE_SIZE );
midisend( offset, msg1, msg23 ); 

send_cc = 0;
last_value = value;
);

@sample
new = abs(spl0);
new > peak0 ? peak0 = new : peak0 = peak0*decay;
newsq = new*new;
oldsq = buf[pos];
buf[pos] = newsq;
sumsq0 = sumsq0+newsq-oldsq;
pos = pos+1;

new = abs(spl1);
new > peak1 ? peak1 = new : peak1 = peak1*decay;
newsq = new*new;
oldsq = buf[pos];
buf[pos] = newsq;
sumsq1 = sumsq1+newsq-oldsq;
pos = pos+1;

pos == 2*buflen ? pos = 0;

spl0 = spl0 * mix;
spl1 = spl1 * mix;

@gfx 0 147
disp_mode == 0 ? (
gfx_clear = 0;

gfx_r = 1; gfx_g = 0.8; gfx_b = 0.2;
xx = (gfx_w*0.5)-20|0;
yy = (gfx_h*0.5)|0;
rad = 40;
rotator = value/127;

gfx_r = 1; gfx_g = 0.8; gfx_b = 0.2;
gfx_a = 0.75;
gfx_circle(xx, yy, rad -12, 1, 1);
gfx_a = 1; gfx_g = 0.5;

rotator > 0.5 ? (
gfx_arc (xx, yy, rad-0, 0 * dtor, 150 * (rotator- 0.5)*2 * dtor,1);
gfx_arc (xx, yy, rad-1, 0 * dtor, 150 * (rotator- 0.5)*2 * dtor,1);
gfx_arc (xx, yy, rad-2, 0 * dtor, 150 * (rotator- 0.5)*2 * dtor,1);
gfx_arc (xx, yy, rad-3, 0 * dtor, 150 * (rotator- 0.5)*2 * dtor,1);
gfx_arc (xx, yy, rad-4, 0 * dtor, 150 * (rotator- 0.5)*2 * dtor,1);
);

gfx_arc (xx, yy, rad-0, 210 * dtor, (min(359.9, 210 + 150 * rotator*2)) * dtor,1);
gfx_arc (xx, yy, rad-1, 210 * dtor, (min(359.9, 210 + 150 * rotator*2)) * dtor,1);
gfx_arc (xx, yy, rad-2, 210 * dtor, (min(359.9, 210 + 150 * rotator*2)) * dtor,1);
gfx_arc (xx, yy, rad-3, 210 * dtor, (min(359.9, 210 + 150 * rotator*2)) * dtor,1);
gfx_arc (xx, yy, rad-4, 210 * dtor, (min(359.9, 210 + 150 * rotator*2)) * dtor,1);

r1_delta = pi150 / r1_range; 
r1_phase = - r1_delta * (r1_range / 2 + 0);
rotator -= 15/360;

gfx_r = 0.1; gfx_g = 0; gfx_b = 0.1;
sin_x = sin(rotator * r1_delta + r1_phase);
cos_y = cos(rotator * r1_delta + r1_phase);
gfx_x = xx + 5 * sin_x;
gfx_y = yy - 5 * cos_y;
gfx_lineto(xx + 25 * sin_x, yy - 25 * cos_y, 1);

font_size = 50;
gfx_setfont(1, "Lucida Sans Unicode", font_size);
gfx_r = 1; gfx_g = 0.8; gfx_b = 0.2;
gfx_x = xx +60; gfx_y = yy -floor(font_size/2);
gfx_drawnumber(value,0);

gfx_a = 1;
gfx_r=1; gfx_g=0.2; gfx_b=0.2;
gfx_x = gfx_w-45;
gfx_y = 137-value;
gfx_lineto(gfx_x+40,gfx_y);

gfx_a = 0.3;
gfx_r=gfx_g=gfx_b=1;
gfx_x = gfx_w-45;
gfx_y = 10;
gfx_lineto(gfx_x+40,gfx_y);
gfx_x = gfx_w-45;
gfx_y = 137;
gfx_lineto(gfx_x+40,gfx_y);
);

disp_mode == 1 ? (
gfx_clear = -1;

gfx_x = -1;
gfx_y = 0;
gfx_blit(-1,1,0);

gfx_a = 1;
gfx_y = 137-value;
gfx_x = gfx_w-5;
gfx_setpixel(1,0.2,0.2);

gfx_a = 0.3;
gfx_y = 10;
gfx_setpixel(1,1,1);
gfx_y = 137;
gfx_setpixel(1,1,1);
);

mouse_cap == RIGHT_CLICK && first_click ? (
first_click = NO;

gfx_r=gfx_g=gfx_b=0; gfx_a=1;
gfx_x=gfx_y=0;
gfx_rectto(gfx_w,gfx_h);

disp_mode +=1;
disp_mode > 1 ? disp_mode = 0;
);
mouse_cap == NO_CLICK ? first_click = YES;
