#include #include #include #include #define MAX_DELTA 0.808 #define MAX_PEAK 170 namespace VIZ { RainbowLine::RainbowLine(AudioGrabber *pGrabber, Vulcan121 *vulcan) : VIZ(pGrabber, vulcan) { maxCols = keyboardData.num_cols * 5; colours = new rgba[maxCols]; for (int i = 0; i < maxCols; ++i) { double ratio = (double) i / maxCols; colours[i] = Color::Generator::rgbFromRatio(ratio, 255); } } RainbowLine::~RainbowLine() { delete[] colours; } 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; } void RainbowLine::onTick(float delta) { deltaElapsed += delta; auto val = grabber->getBass(); val = VUtils::Math::clamp(val, 0, 255); double avg = deltaMove(val); if (deltaElapsed >= deltaNeeded) { deltaElapsed = 0; currentColumn++; if (currentColumn >= keyboardData.num_cols) { currentColumn = 0; } } moveLine(val, tailFactor); lastValue = avg; // we clean up the map self later! :) keyboard->sendLedMap(data); } double RainbowLine::deltaMove(double val) { auto avg = VUtils::Math::clamp((lastValue + val) * 0.5, 0, 200); 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 = 10; } 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; } void RainbowLine::moveLine(double val, double d) { keyboard->fadeOutMapColumn(data, d); colours[currentColumn].a = val; int col = currentColumn % keyboardData.num_cols; auto column = keyboard->getColumn(col); for (int i = 0; i < column->count; ++i) { auto index = column->index[i]; data.key[index] = colours[currentColumn]; } } }