Added Row and Column Mapping
Fixed Loudness Visual
This commit is contained in:
parent
c13016275b
commit
238e22caf6
6 changed files with 384 additions and 44 deletions
|
@ -2,6 +2,12 @@
|
|||
|
||||
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:
|
||||
```
|
||||
libpulse -> pipewire-pulse or pulseaudio
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <VulcanoLE/API/HIDHelper.h>
|
||||
|
||||
#define NUM_KEYS 144
|
||||
#define NUM_ROWS 6
|
||||
#define NUM_COLS 21
|
||||
|
||||
typedef struct rgba_type {
|
||||
int16_t r{};
|
||||
|
@ -23,7 +25,7 @@ typedef struct led_map_type {
|
|||
class Vulcan121 {
|
||||
public:
|
||||
explicit Vulcan121(HIDHelper *helper);
|
||||
~Vulcan121() = default;
|
||||
~Vulcan121();
|
||||
int send_led_map(led_map *src, bool deleteMap = false);
|
||||
int send_led_to(rgba rgb);
|
||||
bool send_init_sequence();
|
||||
|
@ -32,17 +34,23 @@ public:
|
|||
bool wait_for_ctrl_dev();
|
||||
static led_map *createEmptyLEDMap();
|
||||
struct DATA {
|
||||
int num_rows = 6;
|
||||
int num_rows = NUM_ROWS;
|
||||
int num_cols = NUM_COLS;
|
||||
int num_keys = 144;
|
||||
};
|
||||
int getColumnsForRow(int row);
|
||||
int getRowsForColumns(int col);
|
||||
const keys * getColumn(int col);
|
||||
const keys * getRow(int row);
|
||||
int getIndex(int row, int col);
|
||||
// PLEASE MAKE SURE YOU KNOW THE LIMITS!
|
||||
int getIndexNoCheck(int row, int col);
|
||||
protected:
|
||||
void setupMap();
|
||||
// we need some mapping feature! rows and cols dont have the same amount of keys. so the struct needs
|
||||
HIDHelper *m_helper;
|
||||
rgba *rv_fixed[NUM_KEYS]{};
|
||||
rgba rv_color_off = { .r = 0x0000, .g = 0x0000, .b = 0x0000 };
|
||||
keys *keyMapRow[6];
|
||||
keys *keyMapCols[0]; // need to find out the count!
|
||||
rgba rv_color_off = { 0x0000, 0x0000, 0x0000 };
|
||||
keys *keyMapRow[NUM_ROWS];
|
||||
keys *keyMapCol[NUM_COLS]; // need to find out the count!
|
||||
};
|
||||
|
|
233
layout.md
233
layout.md
|
@ -260,6 +260,7 @@ Key Count With LEDs: 105
|
|||
| 62 | L |
|
||||
| 68 | Ö |
|
||||
| 74 | Ä |
|
||||
| 96 | # |
|
||||
| 88 | RETURN |
|
||||
| 115 | NUM 4 |
|
||||
| 121 | NUM 5 |
|
||||
|
@ -309,3 +310,235 @@ Key Count With LEDs: 105
|
|||
| 128 | NUM , |
|
||||
| 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 |
|
||||
|
||||
|
|
|
@ -4,7 +4,27 @@
|
|||
#include <VUtils/Logging.h>
|
||||
|
||||
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 i, k;
|
||||
|
@ -13,7 +33,7 @@ int Vulcan121::send_led_map(led_map *src, bool deleteMap) {
|
|||
unsigned char workbuf[65];
|
||||
memset(hwmap, 0, sizeof(hwmap));
|
||||
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.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;
|
||||
|
||||
int offset = ((k / 12) * 36) + (k % 12);
|
||||
hwmap[ offset + 0 ] = (unsigned char) rgb.r;
|
||||
hwmap[ offset + 12 ] = (unsigned char) rgb.g;
|
||||
hwmap[ offset + 24 ] = (unsigned char) rgb.b;
|
||||
hwmap[offset + 0] = (unsigned char) rgb.r;
|
||||
hwmap[offset + 12] = (unsigned char) rgb.g;
|
||||
hwmap[offset + 24] = (unsigned char) rgb.b;
|
||||
}
|
||||
|
||||
// First chunk comes with header
|
||||
workbuf[ 0 ] = 0x00;
|
||||
workbuf[ 1 ] = 0xa1;
|
||||
workbuf[ 2 ] = 0x01;
|
||||
workbuf[ 3 ] = 0x01;
|
||||
workbuf[ 4 ] = 0xb4;
|
||||
memcpy(&workbuf[ 5 ], hwmap, 60);
|
||||
workbuf[0] = 0x00;
|
||||
workbuf[1] = 0xa1;
|
||||
workbuf[2] = 0x01;
|
||||
workbuf[3] = 0x01;
|
||||
workbuf[4] = 0xb4;
|
||||
memcpy(&workbuf[5], hwmap, 60);
|
||||
if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) {
|
||||
if (deleteMap) {
|
||||
delete src;
|
||||
|
@ -46,8 +66,8 @@ int Vulcan121::send_led_map(led_map *src, bool deleteMap) {
|
|||
|
||||
// Six more chunks
|
||||
for (i = 1; i < 7; i++) {
|
||||
workbuf[ 0 ] = 0x00;
|
||||
memcpy(&workbuf[ 1 ], &hwmap[ (i * 64) - 4 ], 64);
|
||||
workbuf[0] = 0x00;
|
||||
memcpy(&workbuf[1], &hwmap[(i * 64) - 4], 64);
|
||||
if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) {
|
||||
if (deleteMap) {
|
||||
delete src;
|
||||
|
@ -91,7 +111,7 @@ bool Vulcan121::query_ctrl_report(unsigned char id) {
|
|||
if (id != 0x0f) return false;
|
||||
unsigned char buffer[8] = {};
|
||||
int length = 8;
|
||||
buffer[ 0 ] = id;
|
||||
buffer[0] = id;
|
||||
int res = m_helper->get_feature_report(buffer, length);
|
||||
if (res) {
|
||||
return true;
|
||||
|
@ -203,7 +223,7 @@ bool Vulcan121::wait_for_ctrl_dev() {
|
|||
usleep(10000);
|
||||
res = m_helper->get_feature_report(buffer, sizeof(buffer));
|
||||
if (res) {
|
||||
if (buffer[ 1 ] == 0x01) break;
|
||||
if (buffer[1] == 0x01) break;
|
||||
} else {
|
||||
ERR("rv_wait_for_ctrl_device() failed");
|
||||
return false;
|
||||
|
@ -213,30 +233,105 @@ bool Vulcan121::wait_for_ctrl_dev() {
|
|||
}
|
||||
|
||||
int Vulcan121::getColumnsForRow(int row) {
|
||||
if (row > 5) {
|
||||
WARN("Try to Access out of Bound %d max %d", row, 5)
|
||||
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;
|
||||
}
|
||||
|
||||
// @Todo Add Columngs
|
||||
|
||||
int Vulcan121::getRowsForColumns(int col) {
|
||||
if (col > 5) {
|
||||
WARN("Try to Access out of Bound %d max %d", col, 5)
|
||||
if (col > NUM_COLS-1) {
|
||||
WARN("Try to Access out of Bound %d max %d", col, NUM_COLS-1)
|
||||
return 0;
|
||||
}
|
||||
return keyMapCols[col]->count;
|
||||
return keyMapCol[col]->count;
|
||||
}
|
||||
|
||||
int Vulcan121::getIndex(int row, int col) {
|
||||
if (row > 5) {
|
||||
WARN("Try to Access out of Bound %d max %d", row, 5)
|
||||
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) {
|
||||
if (col > keyMapRow[row]->count) {
|
||||
WARN("Try to Access out of Bound %d max %d", col, keyMapRow[row]->count)
|
||||
return 0;
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -14,10 +14,11 @@ namespace VIZ {
|
|||
float val = grabber->getLoudness();
|
||||
val = val > 1.0f ? 1.0f : val;
|
||||
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 i = 0; i < keyboardData.num_rows; ++i) {
|
||||
auto index = col * i;
|
||||
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 };
|
||||
}
|
||||
|
|
|
@ -16,23 +16,20 @@ namespace VIZ {
|
|||
auto data = grabber->fft.getData()->leftChannel;
|
||||
auto val = 0.0;
|
||||
for (int i = 1; i < 4; ++i) {
|
||||
if (data[ i ] > val) {
|
||||
val = data[ i ];
|
||||
if (data[i] > val) {
|
||||
val = data[i];
|
||||
}
|
||||
}
|
||||
switchOnPeak(val);
|
||||
tick++;
|
||||
int colorInd = left ? 0 : 1;
|
||||
colors[ colorInd ].a = val;
|
||||
if (left) {
|
||||
for (int i = 0; i < 62; ++i) {
|
||||
int ind = i;
|
||||
map[ 0 ].key[ ind ] = colors[ colorInd ];
|
||||
}
|
||||
} else {
|
||||
for (int i = 62; i < keyboardData.num_keys; ++i) {
|
||||
int ind = i;
|
||||
map[ 0 ].key[ ind ] = colors[ colorInd ];
|
||||
colors[colorInd].a = val;
|
||||
int colOff = left ? 0 : 9;
|
||||
int max = left ? 10 : 12;
|
||||
for (int i = 0; i < max; ++i) {
|
||||
auto col = keyboard->getColumn(i + colOff);
|
||||
for (int j = 0; j < col->count; ++j) {
|
||||
map[0].key[col->index[j]] = colors[colorInd];
|
||||
}
|
||||
}
|
||||
keyboard->send_led_map(map, true);
|
||||
|
|
Loading…
Reference in a new issue