Audio: Added Stereo Support
RainbowLine: Moved FadeOut effect to Keyboard Loudness: Changed to use Stereo Keyboard: Fixed Wrong Column Mapping
This commit is contained in:
parent
9b791f0765
commit
2e266fe038
10 changed files with 105 additions and 69 deletions
17
README.md
17
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
|
||||
- [ ] 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)
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <VulcanoLE/Visual/VIZ.h>
|
||||
#include <VulcanoLE/Audio/AudioGrabber.h>
|
||||
#include <VulcanoLE/Keyboards/Vulcan121.h>
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 |
|
||||
|
||||
|
||||
|
|
|
@ -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<std::mutex> lck(m_mtx);
|
||||
return (float) loudness;
|
||||
return loudness;
|
||||
}
|
||||
|
||||
bool AudioGrabber::work() {
|
||||
std::unique_lock<std::mutex> 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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
#include <VUtils/Math.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue