VulcanoLE/src/VulcanoLE/Scripts/RainbowLine.cpp

88 lines
2.8 KiB
C++

#include <VulcanoLE/Scripts/RainbowLine.h>
#include <VulcanoLE/Colors/ColorHelper.h>
#include <VUtils/Logging.h>
#include <VUtils/Math.h>
#define MAX_DELTA 1212000
#define MAX_PEAK 170
namespace VIZ {
RainbowLine::RainbowLine(AudioGrabber *pGrabber, Vulcan121 *vulcan) : VIZ(pGrabber, vulcan) {
colours = new rgba[keyboardData.num_cols];
for (int i = 0; i < keyboardData.num_cols; ++i) {
double ratio = (double) i / keyboardData.num_cols;
colours[i] = Color::Generator::rgbFromRatio(ratio, 255);
}
}
RainbowLine::~RainbowLine() {
delete[] colours;
delete data;
}
void RainbowLine::onSetup() {
currentColumn = 0;
Vulcan121::fadeOutMap(data, 0);
tailFactor = VUtils::Math::clamp(grabber->env->getAsDouble("rainbow_tail_factor", 0.3), 0.0, 0.9);
keyboard->sendToLEDs({ 0, 0, 0, 0 });
grabber->requestMode = AudioGrabber::ReqMode::FFT;
usleep(100000);
}
void RainbowLine::onTick(float delta) {
Vulcan121::fadeOutMap(data, tailFactor);
deltaElapsed += delta;
auto fftData = grabber->fft.getData()->leftChannel;
auto val = 0.0;
for (int i = 1; i < 4; ++i) {
auto avg = fftData[i] * ratios[i];
if (avg > val)
val = avg;
}
val = VUtils::Math::clamp(val, 0, 255);
double avg = deltaMove(val);
if (deltaElapsed >= deltaNeeded) {
deltaElapsed = 0;
currentColumn++;
if (currentColumn >= keyboardData.num_cols) {
currentColumn = 0;
}
}
colours[currentColumn].a = val;
auto column = keyboard->getColumn(currentColumn);
for (int i = 0; i < column->count; ++i) {
auto index = column->index[i];
data[0].key[index] = colours[currentColumn];
}
lastValue = avg;
// we clean up the map self later! :)
keyboard->sendLedMap(data, false);
}
double RainbowLine::deltaMove(double val) {
auto avg = (lastValue + val) * 0.5;
if (avg > MAX_PEAK || avg > decayValue) {
calcNextDelta(val < MAX_PEAK && firstUnder ? 160 : val);
firstUnder = val > MAX_PEAK;
decayValue = val;
}
if (val > MAX_PEAK) {
firstUnder = true;
}
if (avg < 10) {
deltaNeeded = 1000000000;
}
if (decayValue >= 0)
decayValue -= 10;
return avg;
}
const char *RainbowLine::name() {
return m_name.c_str();
}
void RainbowLine::calcNextDelta(double ratio) {
double rRatio = ratio / MAX_PEAK;
rRatio = VUtils::Math::clamp(rRatio, 0.05, 1.0);
rRatio = (VUtils::Math::easeIn(rRatio) - 1.0) * -1;
deltaNeeded = rRatio * MAX_DELTA;
}
}