Just wanted to share an LED Indicator I put together today. It comes curtesy of a script that I believe @clevername27 has posted before on a VU Meter (can't find the link) as well as @d-healey 's video on LED styled buttons
For this one I just mapped it to a gain node but it could easily be routed to something else.
Enjoy and let me know if you have feedback.
HiseSnippet 2181.3oc2Y01TajbDdEv5Xzcj5tTWpKebJW4CqHJXsB33HTjCYIAnJ.RkjNewkKJpgcGIMm22pcmErxU9eZ9P9Ij+AN8Ly9xrn0XLmOebYKaX2d5tmddlt6o6gAg9VjnH+PsJUGOOfnU4y0GM2iMq8LL0SqWGsJ55NDasmMO.GEAuToxxGwGpxpqnId9ue2yvNXOKRNIMsm6SsHmPcorbpCN3ePcbNDaSFScU3dqC5Y46012wOFLik0anEfsdEdJ4LLmskz0NFGMSqx556t81lX6I6LwbSycuzdhEYycZ7MasSS71e6jI6zvbqMs2YxVfQ9nt1Tle3HFlQhzprxy7smOZl+0dxI34zH5kND9GlZifYVR9PeGa9RjSUq8Lpi8fT7IRCPhA4n0xRz5qzOkZSynmiZegX.TtDp.XkkJZdKWv7LUMuFJlWIlTEESZEoI8k5irBoAr7Q31ymo2yiQBmfg8IUSQxq1R6uldaefCO1Ft3WQNLD9HSBCyFMpifeTaupUe5SQ6m8fNoaGTqy5cZqw85elx.b1FOiFgf+4hCBH1HlOhMifNEGApEwchPt91wNj5nKiYHJCY4G6Xi9w3HFBGgH3HpybthtjfBIAwgA9QR8.ZDg8li7AEFhlD6Ywn9dHCg9v72qiNsWmdHxUvJpNhvr1n1Zbam65EVE72f43JbHhg1G00aJ0irgUHA1NDLz+xejXwLfk6ZJ7NvyokG0UnePrT7ZJg012Mv2C9v3IpL8jZ6oJOeImr52GIhx3x1cxD9b8D4HbdDhkJXmtsa8hKF1ZbWPnFar6dH.P5PrvyQCAyMksQm1u+3i6c1QWbXq1i6ODX1D8WAA1YagDGReM.cQt9.jQ8lB1iSblvG+hQi6Nr6nditX7wvuOt+IcDyVCEYmMmaejHXCUHb5DOnaWNylaCbyMaPf1wgg.XfdNmun0pFRlhrhCOA1MbNIQwEoNr.UoYRrKQfBCkKkXZOAPPzQeeOo8Egl3GpX0qUkuG3.7bTLUXY4Z9libCE2gLAbPPrq8AWTGHxSnZJO7HvW5ukBkN9Wyyjw2gU8D3azFOgxHtx7bJdFynSmcWDoYhaA0ygaLYN84lAQnFCvDpKzZcDD7BoYpg9o0phfGGeKrSBQX1NECdfgXuoDCIs57EMDnuQC9TwkHjvhC8PRKHZCW5qKQ8.uuIam+RpUQjIyRWzzs3b2SkYiHFNjGv5Y+wy5E5D8WPFfVgXBwm0PqiRjCdK6EiMAFZlQol5Za.1i3fxy.Xz0wgFDQPWSYyP1y8vtvZW3fTDAfLOE1XiHrAPXNaneLCvCiT7vXZ1Zk6PhgEIDrFwcDNgu1elermcjQ1xiyjmenK1g9uH1hDpEfkhwJKBOb4sjgpoNfk4LIdodteZ8aLoR2RtB4wfPx.YFs+FpeLOU2zPrMkmMHZF11+ZQnCmqofpQDAqRomxAliR39PnTAiWl52wQ3VNAyvFYTlAQF7kz10pivur44nmhZxeaS4aRUVxy6VkW5.kcvUYSgJabN3xHz75.sM2YaNQSIwMUHxBiImmBoS2XBX3INFFu7lZoQIJQRKggcqmOvtmW.Y644QxQtO.HScKVt+WDwLO+CAsJpsFar0B3+cELLaVBZjPLgEInuY5GEAj1DtypvuzA9+OKuns9YgIKnNyaCTrCwW+wDTpiZJioeC+GUYb.PTESariykfOcdBFH+RVjOOz8DxDdAP4ElHJlQtCKxZXXVaODpfLC4X8sKjnNwTYBH3WkcPd5jppzLFFlvfXFRz.cBxPQC+875HRWK7G0hKx4dOw3uAQbfjzkw756qTdUB2het3TOTYpGV1TOTcpG9dl5gkO0od1sBBblKOc7FmklU.mf0EpSprCTKvS87Ue8EpYr1dKp0g2AsNLWqCKUqB0V3HPnbd9IfPE1HtaqnqhQDlnAAlnDcvMleNsvQ1PTjYs8xJbv26LeFoO3PW8mptZUXS6lCMYRoiwqYOz2wAzYYCKmsaQPCuX2KIPhOQIlYLBMeUriN82cGcpMbZIagPgQeuddTV+.h26pMTsj9Nf299dcvLLuMvDZ.eAjPFkaBU5PtBZBW1T3p5cHQuh4GH3MoYEsJ+NlXz0RaYjWgiFEZL72qqtco8Z0d6mq9wLBOXMmxKNPohUf7id6+V6s7AxIyo1XcIUsE6eE5bV1EWw1oEoaxZuqPOrbWSuHJat5kR7QqG66pI9k5CnLqYkaiKUhMB6a+RXiI2LwZ5xxvxMvUzO7e9I3ZHdb18HQcCbHGkN8etddGt2x0Ioo0g3fK.S+.0lMS0EqjKbpm2Ufi+.H+T3MA4kuyqRyaeUtxc1SPTK9CZu0+ft.lenajhs9G1F4WnCoM+UxDkcPNE54KjB4n0OK1cDjg0h.lGztfC+jnJKwOyP9cC92biXDzJr3i2BOICZx+tRxfloCpBCesDF9L8e.eEQbAVBD3OJ9F5qyEcDAZRgiOleLtw3f67MF22hAlvXnu2H9kDZpp4QDW5X3.unBTugDMKUhlEyKwh8JpZIoBbwghCAnPguGePJwlpDA2lBJC9tflNkpbr6+4655gAmhQDXka2OxB.FNNqhpChgpMEQLlpBlStoJ4iwg1vdn0skqbk6Vtx2y8l+nGb2a9uAJ6nvYpqlZixyT6BG14.U5kkIeBN1gkRsXn2o9d9Ay78nE1nGRfLFSmRJ3+T5BpEiAsPlS4qNXHwgfiTBG+yGbB0ifCAbhbOwByO3+LGkte8mzklKhmu.8a2xEW9+qKW7tG8Ao.eXuK905Pp3lHwVI5Wm8xOE0.7oXNbwVg9WXI6ylGz+XAEXc6I96.uJz+.7MxTSz6sJX5BGYbgkUQUsffMuuBt48UvstuBt88Uvu49J3N2WA+12uf7SzaEy7StLAnxlAcEWbQkJxhZDgIZ+OvkIPQf
// ========== LED ANIMATION ==========
// This is mapped to the Master Gain module, but it could just as easily
// be repurposed to map any other function (modulation, MIDI event, etc.)
//Timer
const var t = Engine.createTimerObject();
const var PnlAnimation = Content.getComponent("PnlAnimation");
const var GainMaster = Synth.getEffect("MasterGain");
const DECAY_RATE = 0.9; // Decay Rate
const SMOOTHING_FACTOR = 1 - 0.75; // Fixed smoothing value
const HYSTERESIS_THRESHOLD = 0.0; // Fixed hysteresis value
const SPEED = 15.0;
// Current Values
reg curLevelL = 0.0;
reg curLevelR = 0.0;
reg smoothedLevelL = 0.0;
reg smoothedLevelR = 0.0;
// Last GUI values for hysteresis
var lastGuiValueL = 0.0;
var lastGuiValueR = 0.0;
// Define two colors for interpolation
const lowColor = PnlAnimation.get("itemColour");
const highColor = PnlAnimation.get("itemColour2");
inline function interpolateColor(low, high, factor) {
local factor = Math.range(factor, 0.0, 1.0);
return Colours.mix(low, high, factor);
}
// Cubic interpolation function
inline function cubicInterpolation(start, end, factor) {
local factor = Math.range(factor, 0.0, 1.0);
return start + (end - start) * (factor * factor * (3 - 2 * factor));
}
// Panel Animation (Ellipse with dynamic color interpolation)
PnlAnimation.setPaintRoutine(function(g) {
var a = this.getLocalBounds(0);
var normalizedGain = Math.range(smoothedLevelR, 0.0, 1.0);
var currentColor = interpolateColor(lowColor, highColor, normalizedGain);
// LED Effect: Outer gradient shadow for LED glow effect
g.setGradientFill([Colours.withAlpha(Colours.white, 0.5), a[2] / 2, a[3] / 2,
Colours.withAlpha(Colours.black, 0.2), a[0] + a[2] * 0.375, a[1] + a[3] * 0.375, true]);
g.fillEllipse([a[0] + a[2] * 0.05, a[1] + a[3] * 0.05, a[2] * 0.9, a[3] * 0.9]);
// Inner LED glow
g.setGradientFill([Colours.withAlpha(currentColor, 1.0), a[2] / 2, a[1],
Colours.withAlpha(currentColor, 0.4), a[2] / 2, a[3]]);
g.fillEllipse([a[0] + a[2] * 0.125, a[1] + a[3] * 0.125, a[2] * 0.75, a[3] * 0.75]);
// Center highlight
g.setGradientFill([Colours.withAlpha(Colours.white, 0.4), a[2] / 2, a[1],
Colours.withAlpha(Colours.white, 0.1), a[2] / 2, a[3]]);
g.drawEllipse([a[0] + a[2] * 0.125, a[1] + a[3] * 0.125, a[2] * 0.75, a[3] * 0.75], 2.0);
});
t.setTimerCallback(function() {
var GainLeft = GainMaster.getCurrentLevel(1);
var GainRight = GainMaster.getCurrentLevel(0);
var peakLevelL = GainLeft;
var peakLevelR = GainRight;
if (peakLevelL > curLevelL) {
curLevelL = peakLevelL;
} else {
curLevelL *= DECAY_RATE;
}
if (peakLevelR > curLevelR) {
curLevelR = peakLevelR;
} else {
curLevelR *= DECAY_RATE;
}
// Apply cubic interpolation smoothing
smoothedLevelL = cubicInterpolation(smoothedLevelL, curLevelL, SMOOTHING_FACTOR);
smoothedLevelR = cubicInterpolation(smoothedLevelR, curLevelR, SMOOTHING_FACTOR);
PnlAnimation.repaint();
});
// Set the timer
t.startTimer(SPEED);