Added Math Class

Added Rainbow Line Visual
Added Delta-Timing to Visuals
Cleanup Code Structure
This commit is contained in:
Maurice Grönwoldt 2021-02-21 23:22:01 +01:00
commit dd06aa3e35
19 changed files with 244 additions and 34 deletions

17
src/VUtils/Math.cpp Normal file
View file

@ -0,0 +1,17 @@
#include <VUtils/Math.h>
namespace VUtils {
double Math::clamp(double value, double min, double max) {
return value > max ? max : value < min ? min : value;
}
double Math::lerp(double a, double b, double f) {
return (a + (b - a) * f);
}
double Math::bezierBlend(double t) {
return t * t * (3.0 - 2.0 * t);
}
double Math::easeIn(double ratio) {
return ratio * ratio * ratio;
}
}

View file

@ -0,0 +1,44 @@
#include <VulcanoLE/Colors/ColorHelper.h>
namespace Color {
rgba Generator::rgbFromRatio(double ratio, int16_t alpha = 255) {
int normalized = int(ratio * 256 * 6);
int x = normalized % 256;
int16_t red = 0, green = 0, blue = 0;
switch (normalized / 256) {
case 0:
red = 255;
green = x;
blue = 0;
break;
case 1:
red = 255 - x;
green = 255;
blue = 0;
break;
case 2:
red = 0;
green = 255;
blue = x;
break;
case 3:
red = 0;
green = 255 - x;
blue = 255;
break;
case 4:
red = x;
green = 0;
blue = 255;
break;
case 5:
red = 255;
green = 0;
blue = 255 - x;
break;
}
return { red, green, blue, alpha };
}
}

View file

@ -9,7 +9,7 @@ namespace VIZ {
usleep(100000);
}
void Loudness::on_tick() {
void Loudness::on_tick(float delta) {
auto data = Vulcan121::createEmptyLEDMap();
float val = grabber->getLoudness();
val = val > 1.0f ? 1.0f : val;

View file

@ -1,17 +1,17 @@
#include <VulcanoLE/Scripts/WeirdSpec.h>
#include <VulcanoLE/Scripts/PoliceLike.h>
namespace VIZ {
WeirdSpec::WeirdSpec(AudioGrabber *pGrabber, Vulcan121 *pVulcan121) : VIZ(pGrabber, pVulcan121) {
PoliceLike::PoliceLike(AudioGrabber *pGrabber, Vulcan121 *pVulcan121) : VIZ(pGrabber, pVulcan121) {
}
void WeirdSpec::on_setup() {
void PoliceLike::on_setup() {
keyboard->send_led_to({ 0, 0, 0, 0 });
grabber->requestMode = AudioGrabber::ReqMode::FFT;
usleep(100000);
}
void WeirdSpec::on_tick() {
void PoliceLike::on_tick(float delta) {
auto map = Vulcan121::createEmptyLEDMap();
auto data = grabber->fft.getData()->leftChannel;
auto val = 0.0;
@ -35,7 +35,7 @@ namespace VIZ {
keyboard->send_led_map(map, true);
}
void WeirdSpec::switchOnPeak(double peak) {
void PoliceLike::switchOnPeak(double peak) {
if (tick < 3) {
return;
}
@ -56,7 +56,7 @@ namespace VIZ {
}
}
const char *WeirdSpec::name() {
const char *PoliceLike::name() {
return m_name.c_str();
}
}

View file

@ -0,0 +1,89 @@
#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 180
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::on_setup() {
currentColumn = 0;
updateMap(0);
keyboard->send_led_to({ 0, 0, 0, 0 });
grabber->requestMode = AudioGrabber::ReqMode::FFT;
usleep(100000);
}
void RainbowLine::on_tick(float delta) {
updateMap(0.3);
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);
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 (deltaElapsed >= deltaNeeded) {
deltaElapsed = 0;
currentColumn++;
if (currentColumn >= keyboardData.num_cols) {
currentColumn = 0;
}
}
if (decayValue >= 0)
decayValue -= 10;
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->send_led_map(data, false);
}
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::updateMap(double factor) {
for (int i = 0; i < keyboardData.num_keys; ++i) {
data->key[i].a *= factor;
}
}
}

View file

@ -8,7 +8,7 @@ namespace VIZ {
grabber->requestMode = AudioGrabber::ReqMode::FFT;
usleep(100000);
}
void Spectrum::on_tick() {
void Spectrum::on_tick(float delta) {
auto map = Vulcan121::createEmptyLEDMap();
auto data = grabber->fft.getData()->leftChannel;
// find largest bass ~43hz (44100 / FFT_SIZE) range

View file

@ -1,8 +1,9 @@
#include <VulcanoLE/Visual/VisPlugins.h>
#include <VulcanoLE/Scripts/Spectrum.h>
#include <VulcanoLE/Scripts/Loudness.h>
#include <VulcanoLE/Scripts/WeirdSpec.h>
#include <VulcanoLE/Scripts/PoliceLike.h>
#include <VUtils/Logging.h>
#include <VulcanoLE/Scripts/RainbowLine.h>
namespace VIZ {
void VisPlugins::init(HIDHelper *hidHelper, AudioGrabber *audioGrabber) {
@ -10,7 +11,8 @@ namespace VIZ {
keyboard = new Vulcan121(hidHelper);
viz[0] = new Spectrum(grabber, keyboard);
viz[1] = new Loudness(grabber, keyboard);
viz[2] = new WeirdSpec(grabber, keyboard);
viz[2] = new PoliceLike(grabber, keyboard);
viz[3] = new RainbowLine(grabber, keyboard);
currentVis = viz[mode];
}
@ -20,11 +22,15 @@ namespace VIZ {
exit(1);
}
currentVis->on_setup();
start = std::chrono::high_resolution_clock::now();
}
void VisPlugins::on_tick() {
currentVis->on_tick();
auto stop = std::chrono::high_resolution_clock::now();
auto delta = std::chrono::duration_cast<micro>(stop - start).count();
currentVis->on_tick(delta);
usleep(1000);
start = stop;
}
void VisPlugins::on_shutdown() {
@ -44,7 +50,7 @@ namespace VIZ {
}
void VisPlugins::setCurrentMode(int m) {
if (m == 0 || m > VIZSIZE) {
if (m < 1 || m > VIZSIZE) {
ERR("Mode Setting Failed >> Mode is not in the available range 1 - %d", VIZSIZE)
return;
}