Reply #1748 By: marc2k3
https://hydrogenaud.io/index.php/topic,110499.msg1049256.html#msg1049256
rainbow_stops = [
[ 0.0, RGB(180, 220, 255) ],
[ 0.33, RGB(45, 170, 255) ],
[ 0.66, RGB(5, 71, 219) ],
[ 1.0, RGB(0, 16, 93) ],
];
init();
JSP3 VU Meter - Blue

Thanks Air KEN for the Blue stops! Here is the marc2k3 4-bar for you using that scheme. Original stops are commented out so you can revert:
// ==PREPROCESSOR==
// @name "VU Meter"
// 4 color bars
// @author "ilovefb2k + Case + marc2003"
// @import "%fb2k_component_path%helpers.txt"
// ==/PREPROCESSOR==
var timer_interval = 60; //ms
var timer_id = 0;
var font = CreateFontString("Segoe UI", 8);
var ww = 0, wh = 0;
var minDB = -60;
var RMS_level1 = RMS_level2 = Peak_level1 = Peak_level2 = prev_time = 0;
//var stops = [
// [ 1.0, RGB(227, 9, 64) ],
// [ 0.66, RGB(231, 215, 2) ],
// [ 0.33, RGB(15, 168, 149) ],
// [ 0.0, RGB(19, 115, 232) ]
//];
var stops = [
[ 0.0, RGB(180, 220, 255) ],
[ 0.33, RGB(45, 170, 255) ],
[ 0.66, RGB(5, 71, 219) ],
[ 1.0, RGB(0, 16, 93) ],
];
var brush = {
Stops : stops,
Start : [0, 0], // x and y values
End : [0, 0], // x and y values
};
var brush_str = "";
var colours = {
text : 0,
background : 0,
};
update_colours();
if (fb.IsPlaying) start_timer();
function update_colours() {
if (window.IsDefaultUI) {
colours.text = window.GetColourDUI(ColourTypeDUI.text);
colours.background = window.GetColourDUI(ColourTypeDUI.background);
} else {
colours.text = window.GetColourCUI(ColourTypeCUI.text);
colours.background = window.GetColourCUI(ColourTypeCUI.background);
}
}
function to_db(num) {
var ret = (2000 * Math.log(num) / Math.LN10 / 100);
return clamp(ret, minDB, 0);
}
function clamp(value, min, max) {
if (value < min) return min;
if (value > max) return max;
return value;
}
function start_timer() {
if (timer_id)
return;
timer_id = window.SetInterval(function() {
var cur_time = fb.PlaybackTime;
if (cur_time) {
var chunk = fb.GetAudioChunk(cur_time - prev_time);
if (chunk) {
prev_time = cur_time;
var data = chunk.Data.toArray();
if (data) {
var ch_count = chunk.ChannelCount;
var frame_len = chunk.SampleCount;
var ch2_idx = 1;
if (ch_count < 2) ch2_idx = 0;
var sum1 = 0;
var sum2 = 0;
var peak1 = 0;
var peak2 = 0;
for (var i = 0; i < data.length; i += ch_count) {
var l = data[i];
var r = data[i + ch2_idx];
if (l > peak1) peak1 = l;
if (r > peak2) peak2 = r;
sum1 += l * l;
sum2 += r * r;
}
RMS_level1 = Math.sqrt(sum1/frame_len);
RMS_level2 = Math.sqrt(sum2/frame_len);
Peak_level1 = peak1;
Peak_level2 = peak2;
}
}
}
window.Repaint();
}, timer_interval);
}
function stop_timer(clear) {
if (timer_id)
window.ClearInterval(timer_id);
timer_id = 0;
if (clear)
clear_meter();
}
function clear_meter() {
RMS_level1 = RMS_level2 = Peak_level1 = Peak_level2 = prev_time = 0
window.Repaint();
}
function FillRectangle(gr, x, y, w, h) {
var db = to_db(w);
var rw = Math.round(ww * ((100 + db) / 65 - 40 / 65));
gr.FillRectangle(x, y, rw, h - 1, brush_str);
}
function on_colours_changed() {
update_colours();
window.Repaint();
}
function on_paint(gr) {
gr.FillRectangle(0, 0, ww, wh, colours.background);
var h = 20;
var VU_x = 20;;
var VUy = 5;
var VUw = ww - 20;
var yL = VUy + h;
var yLM = VUy + (h * 2);
var yRM = VUy + (h * 3);
var yR = VUy + (h * 4);
// labels
gr.WriteTextSimple("FL", font, colours.text, 0, yL, VU_x, h, 2, 2);
gr.WriteTextSimple("FL", font, colours.text, 0, yLM, VU_x, h, 2, 2);
gr.WriteTextSimple("FR", font, colours.text, 0, yRM, VU_x, h, 2, 2);
gr.WriteTextSimple("FR", font, colours.text, 0, yR, VU_x, h, 2, 2);
var label_width = (ww - VU_x) / 13;
var labels = [-60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0];
labels.forEach(function (label, i) {
gr.WriteTextSimple(label + "dB", font, colours.text, 10 + (i * label_width), yR + h + 10, label_width, h);
});
gr.DrawLine(VU_x, yR + h + 5, ww - VU_x, yR + h + 5, 1, colours.text);
// bars
FillRectangle(gr, VU_x, yLM, RMS_level1, h);
FillRectangle(gr, VU_x, yRM, RMS_level2, h);
FillRectangle(gr, VU_x, yL, Peak_level1, h);
FillRectangle(gr, VU_x, yR, Peak_level1, h);
}
function on_playback_new_track(handle) {
start_timer();
}
function on_playback_pause(state) {
state ? stop_timer() : start_timer();
}
function on_playback_stop(reason) {
if (reason != 2) {
stop_timer(true);
}
}
function on_size() {
ww = window.Width;
wh = window.Height;
brush.End = [ww, 0];
brush_str = JSON.stringify(brush);
}