diff --git a/README.md b/README.md index 0d777c4..0922256 100644 --- a/README.md +++ b/README.md @@ -49,13 +49,18 @@ shutdown_color_red=235 shutdown_color_green=0 shutdown_color_blue=141 shutdown_brightness=50 +rainbow_tail_factor=30 ``` # TODO -- Support for custom Scripts without writing C++ -- VWeb Interface to control Configs without restarting -- Less CPU Usage -- Keyboard Mapping -- Macro Support -- Execute of Script on Hotkeys \ No newline at end of file +- [ ] Support for custom Scripts without writing C++ + - [ ] LUA (sol2) + - [ ] Helper Functions + - [ ] Keyboard Mapper +- [ ] Web Interface to control Configs without restarting + - [ ] VWeb Implementing +- [x] Keyboard Mapping +- [ ] Keyboard Input Event-Handler +- [ ] Macro Support + - [ ] Execute of Script on Hotkeys (LUA) \ No newline at end of file diff --git a/headers/VulcanoLE/Audio/AudioGrabber.h b/headers/VulcanoLE/Audio/AudioGrabber.h index 6d5f8b6..c5cffa9 100644 --- a/headers/VulcanoLE/Audio/AudioGrabber.h +++ b/headers/VulcanoLE/Audio/AudioGrabber.h @@ -35,8 +35,8 @@ public: void init(); FFT fft; ReqMode requestMode = ReqMode::FFT; - double loudness = 0.0; - float getLoudness(); + stereoSampleFrame loudness = {0.0, 0.0}; + stereoSampleFrame getLoudness(); bool work(); VUtils::Environment *env = nullptr; private: diff --git a/headers/VulcanoLE/Keyboards/Vulcan121.h b/headers/VulcanoLE/Keyboards/Vulcan121.h index c50bbe4..89ed710 100644 --- a/headers/VulcanoLE/Keyboards/Vulcan121.h +++ b/headers/VulcanoLE/Keyboards/Vulcan121.h @@ -39,6 +39,7 @@ public: int getIndex(int row, int col); // PLEASE MAKE SURE YOU KNOW THE LIMITS! int getIndexNoCheck(int row, int col); + static void fadeOutMap(led_map* map, double factor); protected: void setupMap(); // we need some mapping feature! rows and cols dont have the same amount of keys. so the struct needs diff --git a/headers/VulcanoLE/Scripts/Loudness.h b/headers/VulcanoLE/Scripts/Loudness.h index 6a76380..f0b4c42 100644 --- a/headers/VulcanoLE/Scripts/Loudness.h +++ b/headers/VulcanoLE/Scripts/Loudness.h @@ -1,4 +1,5 @@ #pragma once + #include #include #include @@ -10,9 +11,18 @@ namespace VIZ { ~Loudness() override = default; void onSetup() override; void onTick(float delta) override; - float lastVal = 0; + void setForChannel(float value, int channel); + void drawFrame(int toRow); const char *name() override; std::string m_name = "Loudness Meter"; + protected: + rgba colours[3] = { + { 0, 0, 255, 80 }, + { 0, 255, 0, 80 }, + { 255, 0, 0, 40 } + }; + double tailFactor = 0; + led_map *data = Vulcan121::createEmptyLEDMap(); }; } diff --git a/headers/VulcanoLE/Scripts/RainbowLine.h b/headers/VulcanoLE/Scripts/RainbowLine.h index a8806dc..7a7e574 100644 --- a/headers/VulcanoLE/Scripts/RainbowLine.h +++ b/headers/VulcanoLE/Scripts/RainbowLine.h @@ -10,7 +10,7 @@ namespace VIZ { rgba *colours = nullptr; double lastValue = 0; double decayValue = 0; - double ratios[4] = {1.3,1.2,1.3,1.4}; + double ratios[4] = {1.3,1.3,1.3,1.2}; double tailFactor = 0.3; public: RainbowLine(AudioGrabber *pGrabber, Vulcan121 *vulcan); @@ -18,7 +18,6 @@ namespace VIZ { void onSetup() override; void onTick(float delta) override; void calcNextDelta(double ratio); - void updateMap(double factor); const char *name() override; std::string m_name = "Rainbow Line"; led_map *data = Vulcan121::createEmptyLEDMap(); diff --git a/layout.md b/layout.md index 6112b6c..e8615ff 100644 --- a/layout.md +++ b/layout.md @@ -356,7 +356,7 @@ Key Count With LEDs: 105 | 18 | 3 | | 19 | E | | 20 | D | -| 27 | C | +| 21 | X | ### COL 4 @@ -367,7 +367,7 @@ Key Count With LEDs: 105 | 24 | 4 | | 25 | R | | 26 | F | -| 32 | V | +| 27 | C | ### COL 5 @@ -379,6 +379,7 @@ Key Count With LEDs: 105 | 30 | T | | 31 | G | | 36 | B | +| 32 | V | | 37 | SPACE | diff --git a/src/VulcanoLE/Audio/AudioGrabber.cpp b/src/VulcanoLE/Audio/AudioGrabber.cpp index f42e5f5..2c4d8e4 100644 --- a/src/VulcanoLE/Audio/AudioGrabber.cpp +++ b/src/VulcanoLE/Audio/AudioGrabber.cpp @@ -134,45 +134,49 @@ void AudioGrabber::init() { if (env != nullptr) m_scale = env->getAsDouble("audio_scale", 1.0); DBG("SET Audio Scale: %.3f", m_scale) - loudness = 0.0; + loudness = { 0.0, 0.0 }; } void AudioGrabber::calculateRMS(stereoSample *pFrame) { - float square = 0, mean; + float squareL = 0, meanL; + float squareR = 0, meanR; for (int i = 0; i < BUFFER_SIZE; i++) { - float left = pFrame[0].l; - square += std::pow(left, 2); + squareL += std::pow(pFrame[0].l, 2); + squareR += std::pow(pFrame[0].r, 2); } - mean = (square / (float) (BUFFER_SIZE)); - loudness = std::sqrt(mean); + meanL = (squareL / (float) (BUFFER_SIZE)); + meanR = (squareR / (float) (BUFFER_SIZE)); + loudness = { std::sqrt(meanL), std::sqrt(meanR) }; } void AudioGrabber::calculatePEAK(stereoSample *pFrame) { - float max = 0; + stereoSampleFrame max = { 0, 0 }; for (int i = 0; i < BUFFER_SIZE; i++) { float left = std::abs(pFrame[0].l); - if (left > max) { - max = left; - } + float right = std::abs(pFrame[0].r); + if (left > max.l) + max.l = left; + if (right > max.r) + max.r = right; } loudness = max; } -float AudioGrabber::getLoudness() { +stereoSampleFrame AudioGrabber::getLoudness() { std::unique_lock lck(m_mtx); - return (float) loudness; + return loudness; } bool AudioGrabber::work() { std::unique_lock lck(m_mtx); if (this->read(m_buffer, BUFFER_SIZE)) { - for (int i = 0; i < BUFFER_SIZE; ++i) { - // my system is fucking quite - m_buffer[i].l *= m_scale; - m_buffer[i].r *= m_scale; - } switch (requestMode) { case ReqMode::FFT: + // FFT get's better results with maybe a bit scaling.. for RMS and PEAK this gets "worse" + for (int i = 0; i < BUFFER_SIZE; ++i) { + m_buffer[i].l *= m_scale; + m_buffer[i].r *= m_scale; + } fft.process(m_buffer); break; case ReqMode::RMS: diff --git a/src/VulcanoLE/Keyboards/Vulcan121.cpp b/src/VulcanoLE/Keyboards/Vulcan121.cpp index 65f7ed3..28d4a56 100644 --- a/src/VulcanoLE/Keyboards/Vulcan121.cpp +++ b/src/VulcanoLE/Keyboards/Vulcan121.cpp @@ -233,8 +233,8 @@ bool Vulcan121::waitForCtrlDev() { } int Vulcan121::getColumnsForRow(int row) { - if (row > NUM_ROWS-1) { - WARN("Try to Access out of Bound %d max %d", row, NUM_ROWS-1) + if (row > NUM_ROWS - 1) { + WARN("Try to Access out of Bound %d max %d", row, NUM_ROWS - 1) return 0; } return keyMapRow[row]->count; @@ -242,16 +242,16 @@ int Vulcan121::getColumnsForRow(int row) { int Vulcan121::getRowsForColumns(int col) { - if (col > NUM_COLS-1) { - WARN("Try to Access out of Bound %d max %d", col, NUM_COLS-1) + if (col > NUM_COLS - 1) { + WARN("Try to Access out of Bound %d max %d", col, NUM_COLS - 1) return 0; } return keyMapCol[col]->count; } int Vulcan121::getIndex(int row, int col) { - if (row > NUM_ROWS-1) { - WARN("Try to Access out of Bound %d max %d", row, NUM_ROWS-1) + if (row > NUM_ROWS - 1) { + WARN("Try to Access out of Bound %d max %d", row, NUM_ROWS - 1) return 0; } if (col > keyMapRow[row]->count) { @@ -274,8 +274,8 @@ void Vulcan121::setupMap() { 79, 87, 100, 104, 109, 113, 119, 124, 129 }; keyMapRow[2]->count = 19; keyMapRow[2]->index = new int[19]{ 2, 7, 13, 19, 25, 30, 34, 50, 55, 61, 67, 73, 80, 101, 105, 110, 114, 120, 125 }; - keyMapRow[3]->count = 17; - keyMapRow[3]->index = new int[17]{ 3, 8, 14, 20, 26, 31, 35, 51, 56, 62, 68, 74, 88, 115, 121, 126, 130 }; + keyMapRow[3]->count = 18; + keyMapRow[3]->index = new int[18]{ 3, 8, 14, 20, 26, 31, 35, 51, 56, 62, 68, 74, 96, 88, 115, 121, 126, 130 }; keyMapRow[4]->count = 17; keyMapRow[4]->index = new int[17]{ 4, 9, 15, 21, 27, 32, 36, 52, 57, 63, 69, 75, 82, 106, 116, 122, 127 }; keyMapRow[5]->count = 14; @@ -288,11 +288,11 @@ void Vulcan121::setupMap() { keyMapCol[2]->count = 6; keyMapCol[2]->index = new int[6]{ 11, 12, 13, 14, 15, 16 }; keyMapCol[3]->count = 5; - keyMapCol[3]->index = new int[5]{ 17, 18, 19, 20, 27 }; + keyMapCol[3]->index = new int[5]{ 17, 18, 19, 20, 21 }; keyMapCol[4]->count = 5; - keyMapCol[4]->index = new int[5]{ 23, 24, 25, 26, 32 }; - keyMapCol[5]->count = 6; - keyMapCol[5]->index = new int[6]{ 28, 29, 30, 31, 36, 37 }; + keyMapCol[4]->index = new int[5]{ 23, 24, 25, 26, 27 }; + keyMapCol[5]->count = 7; + keyMapCol[5]->index = new int[7]{ 28, 29, 30, 31, 36, 32, 37 }; keyMapCol[6]->count = 5; keyMapCol[6]->index = new int[5]{ 48, 33, 34, 35, 52 }; keyMapCol[7]->count = 5; @@ -329,9 +329,15 @@ int Vulcan121::getIndexNoCheck(int row, int col) { return keyMapRow[row]->index[col]; } -const keys * Vulcan121::getColumn(int col) { +const keys *Vulcan121::getColumn(int col) { return keyMapCol[col]; } -const keys * Vulcan121::getRow(int row) { +const keys *Vulcan121::getRow(int row) { return keyMapRow[row]; } + +void Vulcan121::fadeOutMap(led_map *map, double factor = 0.3) { + for (auto &i : map->key) { + i.a *= factor; + } +} diff --git a/src/VulcanoLE/Scripts/Loudness.cpp b/src/VulcanoLE/Scripts/Loudness.cpp index 214d2b2..387898f 100644 --- a/src/VulcanoLE/Scripts/Loudness.cpp +++ b/src/VulcanoLE/Scripts/Loudness.cpp @@ -10,25 +10,41 @@ namespace VIZ { } void Loudness::onTick(float delta) { - auto data = Vulcan121::createEmptyLEDMap(); - float val = grabber->getLoudness(); - val = val > 1.0f ? 1.0f : val; - double newVal = (val + lastVal) * 0.5; - int maxCol = newVal * keyboardData.num_cols; - for (int col = 0; col < maxCol; ++col) { - auto column = keyboard->getColumn(col); - for (int i = 0; i < column->count; ++i) { - auto index = column->index[i]; - if (col >= maxCol - 1) data[ 0 ].key[ index ] = { 255, 0, 0, 100 }; - else data[ 0 ].key[ index ] = { 0, 0, 255, 80 }; - } - } - // delete map! ;) - lastVal = val; - keyboard->sendLedMap(data, true); + Vulcan121::fadeOutMap(data, tailFactor); + stereoSample val = grabber->getLoudness(); + val.l = val.l > 1.0f ? 1.0f : val.l; + val.r = val.r > 1.0f ? 1.0f : val.r; + setForChannel(val.l, 0); + setForChannel(val.r, 1); + keyboard->sendLedMap(data, false); } const char *Loudness::name() { return m_name.c_str(); } + + void Loudness::setForChannel(float value, int channel) { + // because we have stereo we need to move on the rows + int offset = channel == 0 ? 1 : 3; + int until = channel == 0 ? 3 : 5; + colours[channel].a = value * 128.0; + for (int i = offset; i < until; ++i) { + auto row = keyboard->getRow(i); + int to = row->count * value; + for (int j = 0; j < to; ++j) { + auto index = row->index[j]; + data[0].key[index] = colours[channel]; + } + } + drawFrame(0); + drawFrame(5); + } + + void Loudness::drawFrame(int toRow) { + auto row = keyboard->getRow(toRow); + for (int j = 0; j < row->count; ++j) { + auto index = row->index[j]; + data[0].key[index] = colours[2]; + } + } } \ No newline at end of file diff --git a/src/VulcanoLE/Scripts/RainbowLine.cpp b/src/VulcanoLE/Scripts/RainbowLine.cpp index d4cf22d..cd5aa72 100644 --- a/src/VulcanoLE/Scripts/RainbowLine.cpp +++ b/src/VulcanoLE/Scripts/RainbowLine.cpp @@ -4,7 +4,7 @@ #include #define MAX_DELTA 1212000 -#define MAX_PEAK 180 +#define MAX_PEAK 170 namespace VIZ { RainbowLine::RainbowLine(AudioGrabber *pGrabber, Vulcan121 *vulcan) : VIZ(pGrabber, vulcan) { @@ -20,7 +20,7 @@ namespace VIZ { } void RainbowLine::onSetup() { currentColumn = 0; - updateMap(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; @@ -28,7 +28,7 @@ namespace VIZ { } void RainbowLine::onTick(float delta) { - updateMap(tailFactor); + Vulcan121::fadeOutMap(data, tailFactor); deltaElapsed += delta; auto fftData = grabber->fft.getData()->leftChannel; auto val = 0.0; @@ -85,10 +85,4 @@ namespace VIZ { 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; - } - } } \ No newline at end of file