Added Row and Column Mapping

Fixed Loudness Visual
This commit is contained in:
Maurice Grönwoldt 2021-02-20 20:19:21 +01:00
parent c13016275b
commit 238e22caf6
6 changed files with 384 additions and 44 deletions

View file

@ -2,6 +2,12 @@
Audio Visual Control for Vulcan121 Keyboard Audio Visual Control for Vulcan121 Keyboard
## Layout
Layout can find in layout.md
To see what keys are empty and which not look into docs.md
## DEPS: ## DEPS:
``` ```
libpulse -> pipewire-pulse or pulseaudio libpulse -> pipewire-pulse or pulseaudio

View file

@ -3,6 +3,8 @@
#include <VulcanoLE/API/HIDHelper.h> #include <VulcanoLE/API/HIDHelper.h>
#define NUM_KEYS 144 #define NUM_KEYS 144
#define NUM_ROWS 6
#define NUM_COLS 21
typedef struct rgba_type { typedef struct rgba_type {
int16_t r{}; int16_t r{};
@ -23,7 +25,7 @@ typedef struct led_map_type {
class Vulcan121 { class Vulcan121 {
public: public:
explicit Vulcan121(HIDHelper *helper); explicit Vulcan121(HIDHelper *helper);
~Vulcan121() = default; ~Vulcan121();
int send_led_map(led_map *src, bool deleteMap = false); int send_led_map(led_map *src, bool deleteMap = false);
int send_led_to(rgba rgb); int send_led_to(rgba rgb);
bool send_init_sequence(); bool send_init_sequence();
@ -32,17 +34,23 @@ public:
bool wait_for_ctrl_dev(); bool wait_for_ctrl_dev();
static led_map *createEmptyLEDMap(); static led_map *createEmptyLEDMap();
struct DATA { struct DATA {
int num_rows = 6; int num_rows = NUM_ROWS;
int num_cols = NUM_COLS;
int num_keys = 144; int num_keys = 144;
}; };
int getColumnsForRow(int row); int getColumnsForRow(int row);
int getRowsForColumns(int col); int getRowsForColumns(int col);
const keys * getColumn(int col);
const keys * getRow(int row);
int getIndex(int row, int col); int getIndex(int row, int col);
// PLEASE MAKE SURE YOU KNOW THE LIMITS!
int getIndexNoCheck(int row, int col);
protected: protected:
void setupMap();
// we need some mapping feature! rows and cols dont have the same amount of keys. so the struct needs // we need some mapping feature! rows and cols dont have the same amount of keys. so the struct needs
HIDHelper *m_helper; HIDHelper *m_helper;
rgba *rv_fixed[NUM_KEYS]{}; rgba *rv_fixed[NUM_KEYS]{};
rgba rv_color_off = { .r = 0x0000, .g = 0x0000, .b = 0x0000 }; rgba rv_color_off = { 0x0000, 0x0000, 0x0000 };
keys *keyMapRow[6]; keys *keyMapRow[NUM_ROWS];
keys *keyMapCols[0]; // need to find out the count! keys *keyMapCol[NUM_COLS]; // need to find out the count!
}; };

233
layout.md
View file

@ -260,6 +260,7 @@ Key Count With LEDs: 105
| 62 | L | | 62 | L |
| 68 | Ö | | 68 | Ö |
| 74 | Ä | | 74 | Ä |
| 96 | # |
| 88 | RETURN | | 88 | RETURN |
| 115 | NUM 4 | | 115 | NUM 4 |
| 121 | NUM 5 | | 121 | NUM 5 |
@ -309,3 +310,235 @@ Key Count With LEDs: 105
| 128 | NUM , | | 128 | NUM , |
| 131 | NUM RETURN | | 131 | NUM RETURN |
## COLS:
### COL 0
| Index | Key |
|--------|---------|
| 0 | ESC |
| 1 | ^ |
| 2 | TAB |
| 3 | CAPS |
| 4 | LSHIFT |
| 5 | CTRL |
### COL 1
| Index | Key |
|--------|----------|
| 6 | 1 |
| 7 | Q |
| 8 | A |
| 9 | < |
| 10 | L-SUPER |
### COL 2
| Index | Key |
|--------|--------|
| 11 | F1 |
| 12 | 2 |
| 13 | W |
| 14 | S |
| 15 | Y |
| 16 | L-ALT |
### COL 3
| Index | Key |
|--------|------|
| 17 | F2 |
| 18 | 3 |
| 19 | E |
| 20 | D |
| 27 | C |
### COL 4
| Index | Key |
|--------|------|
| 23 | F3 |
| 24 | 4 |
| 25 | R |
| 26 | F |
| 32 | V |
### COL 5
| Index | Key |
|--------|--------|
| 28 | F4 |
| 29 | 5 |
| 30 | T |
| 31 | G |
| 36 | B |
| 37 | SPACE |
### COL 6
| Index | Key |
|--------|------|
| 48 | F5 |
| 33 | 6 |
| 34 | Z |
| 35 | H |
| 52 | N |
### COL 7
| Index | Key |
|--------|------|
| 53 | F6 |
| 49 | 7 |
| 50 | U |
| 51 | J |
| 57 | M |
### COL 8
| Index | Key |
|--------|------|
| 59 | F7 |
| 54 | 8 |
| 55 | I |
| 56 | K |
| 63 | ; |
### COL 9
| Index | Key |
|--------|---------|
| 65 | F8 |
| 60 | 9 |
| 61 | o |
| 62 | L |
| 69 | : |
| 70 | ALT+GR |
### COL 10
| Index | Key |
|--------|------|
| 78 | F9 |
| 66 | 0 |
| 67 | P |
| 68 | Ö |
| 75 | - |
| 76 | FN |
### COL 11
| Index | Key |
|--------|----------|
| 84 | F10 |
| 72 | ß |
| 73 | Ü |
| 74 | Ä |
| 83 | R-SUPER |
### COL 12
| Index | Key |
|--------|---------|
| 85 | F11 |
| 79 | ´ |
| 80 | + |
| 96 | # |
| 82 | RSHIFT |
### COL 13
| Index | Key |
|--------|------------|
| 86 | F12 |
| 87 | BACKSPACE |
| 88 | RETURN |
| 89 | RCTRL |
### COL 14
| Index | Key |
|--------|-------------|
| 99 | PRINT |
| 100 | INS |
| 101 | DEL |
| 102 | ARROW LEFT |
### COL 15
| Index | Key |
|--------|-------------|
| 103 | SCROLL |
| 104 | HOME |
| 105 | END |
| 106 | ARROW UP |
| 107 | ARROW DOWN |
### COL 16
| Index | Key |
|--------|--------------|
| 108 | BREAK |
| 109 | PAGE UP |
| 110 | PAGE DOWN |
| 111 | ARROW RIGHT |
### COL 17
| Index | Key |
|--------|--------|
| 113 | NUM |
| 114 | NUM 7 |
| 115 | NUM 4 |
| 116 | NUM 1 |
| 117 | NUM 0 |
### COL 18
| Index | Key |
|--------|--------|
| 119 | NUM / |
| 120 | NUM 8 |
| 121 | NUM 5 |
| 122 | NUM 2 |
### COL 19
| Index | Key |
|--------|--------|
| 124 | NUM * |
| 125 | NUM 9 |
| 126 | NUM 6 |
| 127 | NUM 3 |
| 128 | NUM , |
### COL 20
| Index | Key |
|--------|-------------|
| 129 | NUM - |
| 130 | NUM + |
| 131 | NUM RETURN |

View file

@ -4,7 +4,27 @@
#include <VUtils/Logging.h> #include <VUtils/Logging.h>
Vulcan121::Vulcan121(HIDHelper *helper) Vulcan121::Vulcan121(HIDHelper *helper)
: m_helper(helper) {} : m_helper(helper) {
for (auto &item : keyMapRow) {
item = new keys;
}
for (auto &item : keyMapCol) {
item = new keys;
}
setupMap();
}
Vulcan121::~Vulcan121() {
for (auto &item: keyMapRow) {
delete[] item->index;
delete item;
}
for (auto &item: keyMapCol) {
delete[] item->index;
delete item;
}
}
int Vulcan121::send_led_map(led_map *src, bool deleteMap) { int Vulcan121::send_led_map(led_map *src, bool deleteMap) {
int i, k; int i, k;
@ -13,7 +33,7 @@ int Vulcan121::send_led_map(led_map *src, bool deleteMap) {
unsigned char workbuf[65]; unsigned char workbuf[65];
memset(hwmap, 0, sizeof(hwmap)); memset(hwmap, 0, sizeof(hwmap));
for (k = 0; k < NUM_KEYS; k++) { for (k = 0; k < NUM_KEYS; k++) {
rgb = rv_fixed[ k ] ? *(rv_fixed[ k ]) : (src ? src->key[ k ] : rv_color_off); rgb = rv_fixed[k] ? *(rv_fixed[k]) : (src ? src->key[k] : rv_color_off);
rgb.r = (rgb.r > 255) ? 255 : (rgb.r < 0) ? 0 : rgb.r; rgb.r = (rgb.r > 255) ? 255 : (rgb.r < 0) ? 0 : rgb.r;
rgb.g = (rgb.g > 255) ? 255 : (rgb.g < 0) ? 0 : rgb.g; rgb.g = (rgb.g > 255) ? 255 : (rgb.g < 0) ? 0 : rgb.g;
@ -25,18 +45,18 @@ int Vulcan121::send_led_map(led_map *src, bool deleteMap) {
rgb.b *= factor; rgb.b *= factor;
int offset = ((k / 12) * 36) + (k % 12); int offset = ((k / 12) * 36) + (k % 12);
hwmap[ offset + 0 ] = (unsigned char) rgb.r; hwmap[offset + 0] = (unsigned char) rgb.r;
hwmap[ offset + 12 ] = (unsigned char) rgb.g; hwmap[offset + 12] = (unsigned char) rgb.g;
hwmap[ offset + 24 ] = (unsigned char) rgb.b; hwmap[offset + 24] = (unsigned char) rgb.b;
} }
// First chunk comes with header // First chunk comes with header
workbuf[ 0 ] = 0x00; workbuf[0] = 0x00;
workbuf[ 1 ] = 0xa1; workbuf[1] = 0xa1;
workbuf[ 2 ] = 0x01; workbuf[2] = 0x01;
workbuf[ 3 ] = 0x01; workbuf[3] = 0x01;
workbuf[ 4 ] = 0xb4; workbuf[4] = 0xb4;
memcpy(&workbuf[ 5 ], hwmap, 60); memcpy(&workbuf[5], hwmap, 60);
if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) { if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) {
if (deleteMap) { if (deleteMap) {
delete src; delete src;
@ -46,8 +66,8 @@ int Vulcan121::send_led_map(led_map *src, bool deleteMap) {
// Six more chunks // Six more chunks
for (i = 1; i < 7; i++) { for (i = 1; i < 7; i++) {
workbuf[ 0 ] = 0x00; workbuf[0] = 0x00;
memcpy(&workbuf[ 1 ], &hwmap[ (i * 64) - 4 ], 64); memcpy(&workbuf[1], &hwmap[(i * 64) - 4], 64);
if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) { if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) {
if (deleteMap) { if (deleteMap) {
delete src; delete src;
@ -91,7 +111,7 @@ bool Vulcan121::query_ctrl_report(unsigned char id) {
if (id != 0x0f) return false; if (id != 0x0f) return false;
unsigned char buffer[8] = {}; unsigned char buffer[8] = {};
int length = 8; int length = 8;
buffer[ 0 ] = id; buffer[0] = id;
int res = m_helper->get_feature_report(buffer, length); int res = m_helper->get_feature_report(buffer, length);
if (res) { if (res) {
return true; return true;
@ -203,7 +223,7 @@ bool Vulcan121::wait_for_ctrl_dev() {
usleep(10000); usleep(10000);
res = m_helper->get_feature_report(buffer, sizeof(buffer)); res = m_helper->get_feature_report(buffer, sizeof(buffer));
if (res) { if (res) {
if (buffer[ 1 ] == 0x01) break; if (buffer[1] == 0x01) break;
} else { } else {
ERR("rv_wait_for_ctrl_device() failed"); ERR("rv_wait_for_ctrl_device() failed");
return false; return false;
@ -213,30 +233,105 @@ bool Vulcan121::wait_for_ctrl_dev() {
} }
int Vulcan121::getColumnsForRow(int row) { int Vulcan121::getColumnsForRow(int row) {
if (row > 5) { if (row > NUM_ROWS-1) {
WARN("Try to Access out of Bound %d max %d", row, 5) WARN("Try to Access out of Bound %d max %d", row, NUM_ROWS-1)
return 0; return 0;
} }
return keyMapRow[row]->count; return keyMapRow[row]->count;
} }
// @Todo Add Columngs
int Vulcan121::getRowsForColumns(int col) { int Vulcan121::getRowsForColumns(int col) {
if (col > 5) { if (col > NUM_COLS-1) {
WARN("Try to Access out of Bound %d max %d", col, 5) WARN("Try to Access out of Bound %d max %d", col, NUM_COLS-1)
return 0; return 0;
} }
return keyMapCols[col]->count; return keyMapCol[col]->count;
} }
int Vulcan121::getIndex(int row, int col) { int Vulcan121::getIndex(int row, int col) {
if (row > 5) { if (row > NUM_ROWS-1) {
WARN("Try to Access out of Bound %d max %d", row, 5) WARN("Try to Access out of Bound %d max %d", row, NUM_ROWS-1)
return 0; return 0;
} }
if (col > keyMapRow[ row ]->count) { if (col > keyMapRow[row]->count) {
WARN("Try to Access out of Bound %d max %d", col, keyMapRow[row]->count) WARN("Try to Access out of Bound %d max %d", col, keyMapRow[row]->count)
return 0; return 0;
} }
return keyMapRow[row]->index[col]; return keyMapRow[row]->index[col];
} }
/**
* Setup Mapping
* They are not magic! look in the layout.md
*/
void Vulcan121::setupMap() {
// Row Init
keyMapRow[0]->count = 16;
keyMapRow[0]->index = new int[16]{ 0, 11, 17, 23, 28, 48, 53, 59, 65, 78, 84, 85, 86, 99, 103, 108 };
keyMapRow[1]->count = 21;
keyMapRow[1]->index = new int[21]{ 1, 6, 12, 18, 24, 29, 33, 49, 54, 60, 66, 72,
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[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;
keyMapRow[5]->index = new int[14]{ 5, 10, 16, 37, 70, 76, 83, 89, 102, 107, 111, 117, 128, 131 };
// Col init
keyMapCol[0]->count = 6;
keyMapCol[0]->index = new int[6]{ 0, 1, 2, 3, 4, 5 };
keyMapCol[1]->count = 5;
keyMapCol[1]->index = new int[5]{ 6, 7, 8, 9, 10 };
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[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[6]->count = 5;
keyMapCol[6]->index = new int[5]{ 48, 33, 34, 35, 52 };
keyMapCol[7]->count = 5;
keyMapCol[7]->index = new int[5]{ 53, 49, 50, 51, 57 };
keyMapCol[8]->count = 5;
keyMapCol[8]->index = new int[5]{ 59, 54, 55, 56, 63 };
keyMapCol[9]->count = 6;
keyMapCol[9]->index = new int[6]{ 65, 60, 61, 62, 69, 70 };
keyMapCol[10]->count = 6;
keyMapCol[10]->index = new int[6]{ 78, 66, 67, 68, 75, 76 };
keyMapCol[11]->count = 5;
keyMapCol[11]->index = new int[5]{ 84, 72, 73, 74, 83 };
keyMapCol[12]->count = 5;
keyMapCol[12]->index = new int[5]{ 85, 79, 80, 96, 82 };
keyMapCol[13]->count = 4;
keyMapCol[13]->index = new int[4]{ 86, 87, 88, 89 };
keyMapCol[14]->count = 4;
keyMapCol[14]->index = new int[4]{ 99, 100, 101, 102 };
keyMapCol[15]->count = 5;
keyMapCol[15]->index = new int[5]{ 103, 104, 105, 106, 107 };
keyMapCol[16]->count = 4;
keyMapCol[16]->index = new int[4]{ 108, 109, 110, 111 };
keyMapCol[17]->count = 5;
keyMapCol[17]->index = new int[5]{ 113, 114, 115, 116, 117 };
keyMapCol[18]->count = 4;
keyMapCol[18]->index = new int[4]{ 119, 120, 121, 122 };
keyMapCol[19]->count = 5;
keyMapCol[19]->index = new int[5]{ 124, 125, 126, 127, 128 };
keyMapCol[20]->count = 3;
keyMapCol[20]->index = new int[3]{ 129, 130, 131 };
}
int Vulcan121::getIndexNoCheck(int row, int col) {
return keyMapRow[row]->index[col];
}
const keys * Vulcan121::getColumn(int col) {
return keyMapCol[col];
}
const keys * Vulcan121::getRow(int row) {
return keyMapRow[row];
}

View file

@ -14,10 +14,11 @@ namespace VIZ {
float val = grabber->getLoudness(); float val = grabber->getLoudness();
val = val > 1.0f ? 1.0f : val; val = val > 1.0f ? 1.0f : val;
double newVal = (val + lastVal) * 0.5; double newVal = (val + lastVal) * 0.5;
int maxCol = newVal * 24; int maxCol = newVal * keyboardData.num_cols;
for (int col = 0; col < maxCol; ++col) { for (int col = 0; col < maxCol; ++col) {
for (int i = 0; i < keyboardData.num_rows; ++i) { auto column = keyboard->getColumn(col);
auto index = col * i; 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 }; if (col >= maxCol - 1) data[ 0 ].key[ index ] = { 255, 0, 0, 100 };
else data[ 0 ].key[ index ] = { 0, 0, 255, 80 }; else data[ 0 ].key[ index ] = { 0, 0, 255, 80 };
} }

View file

@ -16,23 +16,20 @@ namespace VIZ {
auto data = grabber->fft.getData()->leftChannel; auto data = grabber->fft.getData()->leftChannel;
auto val = 0.0; auto val = 0.0;
for (int i = 1; i < 4; ++i) { for (int i = 1; i < 4; ++i) {
if (data[ i ] > val) { if (data[i] > val) {
val = data[ i ]; val = data[i];
} }
} }
switchOnPeak(val); switchOnPeak(val);
tick++; tick++;
int colorInd = left ? 0 : 1; int colorInd = left ? 0 : 1;
colors[ colorInd ].a = val; colors[colorInd].a = val;
if (left) { int colOff = left ? 0 : 9;
for (int i = 0; i < 62; ++i) { int max = left ? 10 : 12;
int ind = i; for (int i = 0; i < max; ++i) {
map[ 0 ].key[ ind ] = colors[ colorInd ]; auto col = keyboard->getColumn(i + colOff);
} for (int j = 0; j < col->count; ++j) {
} else { map[0].key[col->index[j]] = colors[colorInd];
for (int i = 62; i < keyboardData.num_keys; ++i) {
int ind = i;
map[ 0 ].key[ ind ] = colors[ colorInd ];
} }
} }
keyboard->send_led_map(map, true); keyboard->send_led_map(map, true);