From 9c7159dc364c303a7fbfa448428f0e5273ae0f69 Mon Sep 17 00:00:00 2001 From: Mark Date: Sat, 9 Jul 2022 20:34:43 -0700 Subject: [PATCH] FFT now uses framebuffer --- keyboards/betalupi_ergodox/animations/fft.h | 137 ++++++++---------- .../betalupi_ergodox/keymaps/default/config.h | 11 +- keyboards/betalupi_ergodox/rawhid.c | 72 +++++++-- keyboards/betalupi_ergodox/rawhid.h | 12 +- 4 files changed, 135 insertions(+), 97 deletions(-) diff --git a/keyboards/betalupi_ergodox/animations/fft.h b/keyboards/betalupi_ergodox/animations/fft.h index e11c649..69fd473 100644 --- a/keyboards/betalupi_ergodox/animations/fft.h +++ b/keyboards/betalupi_ergodox/animations/fft.h @@ -1,15 +1,35 @@ -#ifdef RGB_MATRIX_DATAPOINTER_ENABLED +#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS #ifndef DISABLE_RGB_MATRIX_FFT_ANIM RGB_MATRIX_EFFECT(FFT_ANIM) #ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS -// Maps fft columns to leds. -// fft_col_to_array[i] returns an array of leds in the ith bin of the fft. -// Negative indices are "invisible" leds. -// Use them when your keyboard has gaps. -// -// This layout is for the Ergodox EZ. + +static int8_t fft_array_to_col[4][14] = { + // Each number represets a bin and a height: + // x % bin_height = height, + // x / bin_height = bin + // + // Indices are [col][row]. + + // Right side + { 29, 34, 39, 44, 49, + 28, 33, 38, 43, 48, + 27, 32, 37, 42},{47, + 26, 31, 36, 41, 46, + 30, 35, 40, 45, + + // Left side, mirrored + 24, 19, 14, 9},{ 4, + 23, 18, 13, 8, 3, + 22, 17, 12, 7, 2, + 21, 16, 11},{ 6, 1, + 20, 15, 10, 5, 0, + + // No keys here, fill array length + 0, 0, 0, 0, 0, 0, 0} +}; + static int8_t fft_col_to_array[10][5] = { { 47, 43, 38, 33, 28 }, { 46, 42, 37, 32, 27 }, @@ -23,86 +43,51 @@ static int8_t fft_col_to_array[10][5] = { { 23, 19, 14, 9, 4 } }; - // TODO: // Dynamic color settings bool FFT_ANIM(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); + uint8_t led_min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter; + uint8_t led_max = led_min + RGB_MATRIX_LED_PROCESS_LIMIT; + if (led_max > sizeof(g_rgb_frame_buffer)) led_max = sizeof(g_rgb_frame_buffer); - // REQUIRED for any animation that uses this pointer. - // Clears any previous data. if (params->init) { - rgb_matrix_anim_data = NULL; - return led_max < DRIVER_LED_TOTAL; - }; + rgb_matrix_set_color_all(0, 0, 0); + memset(g_rgb_frame_buffer, 0, sizeof g_rgb_frame_buffer); + } - if (rgb_matrix_anim_data == NULL) { - // If animation data is empty, turn off all leds and exit. - for (uint8_t i = led_min; i < led_max; i++) { - rgb_matrix_set_color( - i, - 0x00, 0x00, 0x00 - ); + + // Render heatmap & decrease + for (int i = led_min; i < led_max; i++) { + uint8_t row = i % MATRIX_ROWS; + uint8_t col = i / MATRIX_ROWS; + uint8_t val = g_rgb_frame_buffer[row][col]; + + bool is_topmost = false; + int8_t height = fft_array_to_col[col][row] % 5; + int8_t bin = fft_array_to_col[col][row] / 5; + if (height == 5 - 1) { + is_topmost = true; + } else { + // Row and col of key above this one + if ( + g_rgb_frame_buffer[ + fft_col_to_array[bin][height + 1] % MATRIX_ROWS + ][ + fft_col_to_array[bin][height + 1] / MATRIX_ROWS + ] == 0 + ) { + is_topmost = true; + } } - } else { - // Data should be a pointer to 10 uint8_ts, each representing - // the height of a bar on the display. - uint8_t* data = (uint8_t*) rgb_matrix_anim_data; - - for (uint8_t bin = 0; bin < 10; bin++) { - // Scale data values - uint8_t d = data[bin]; - uint8_t bin_height = d / 50; - // Brightness of topmost key - uint8_t last_brightness = ((d % 50)/50.0) * 0xFF; - - - // Turn off leds that should be off. - // There are 5 keys in each column. - for (uint8_t i = bin_height; i < 6; i++) { - // Ignore negative indices. - // See fft_col_to_array definition. - if (fft_col_to_array[bin][i] < 0) { - continue; - } - - rgb_matrix_set_color( - fft_col_to_array[bin][i], - 0x00, 0x00, 0x00 - ); - } - - - // Turn on leds that should be on. - for (uint8_t i = 0; i < bin_height; i++) { - // Ignore negative indices. - // See fft_col_to_array definition. - if (fft_col_to_array[bin][i] < 0) { - continue; - } - - // If this is the topmost lit key, its - // brightness depends on the height of the bar. - if (i == bin_height - 1) { - rgb_matrix_set_color( - fft_col_to_array[bin][i], - last_brightness, 0x00, last_brightness - ); - - // If this isn't the topmost key, - // it has a plain full-brightness color. - } else { - rgb_matrix_set_color( - fft_col_to_array[bin][i], - 0x00, 0x00, 0xFF - ); - } - } + if (is_topmost) { + rgb_matrix_set_color(i, val, 0x00, val); + } else { + rgb_matrix_set_color(i, 0x00, 0x00, val); } } - return led_max < DRIVER_LED_TOTAL; + return led_max < sizeof(g_rgb_frame_buffer); } #endif diff --git a/keyboards/betalupi_ergodox/keymaps/default/config.h b/keyboards/betalupi_ergodox/keymaps/default/config.h index 416635a..9adfd82 100644 --- a/keyboards/betalupi_ergodox/keymaps/default/config.h +++ b/keyboards/betalupi_ergodox/keymaps/default/config.h @@ -11,9 +11,15 @@ //#define RGBLIGHT_EFFECT_STATIC_GRADIENT //#define RGBLIGHT_EFFECT_TWINKLE +// Special effects +#define RGB_MATRIX_FRAMEBUFFER_EFFECTS +//#define RGB_MATRIX_KEYPRESSES // Custom effects -#define RGB_MATRIX_DATAPOINTER_ENABLED +//#def DISABLE_RGB_MATRIX_FFT_ANIM // FFT Display (Requires framebuffer) + + + // Normal matrix effects @@ -49,14 +55,13 @@ #define DISABLE_RGB_MATRIX_PIXEL_RAIN // Randomly light keys with random hues // Framebuffer matrix effects -//#define RGB_MATRIX_FRAMEBUFFER_EFFECTS #ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS #define DISABLE_RGB_MATRIX_TYPING_HEATMAP #define DISABLE_RGB_MATRIX_DIGITAL_RAIN #endif // Keypress matrix effects -//#define RGB_MATRIX_KEYPRESSES + #ifdef RGB_MATRIX_KEYPRESSES #define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE // Pulses keys hit to hue & value then fades value out #define DISABLE_RGB_MATRIX_SOLID_REACTIVE // Static single hue, pulses keys hit to shifted hue then fades to current hue diff --git a/keyboards/betalupi_ergodox/rawhid.c b/keyboards/betalupi_ergodox/rawhid.c index edb3369..66beff5 100644 --- a/keyboards/betalupi_ergodox/rawhid.c +++ b/keyboards/betalupi_ergodox/rawhid.c @@ -15,7 +15,7 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { hid_send_state(); break; - #ifdef RGB_MATRIX_DATAPOINTER_ENABLED + #ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS case CMD_ANIM_DATA: cmd_animation(data, length); break; @@ -58,23 +58,75 @@ void hid_send_state() { raw_hid_send(packet, RAW_EPSIZE); } +#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS +// Maps fft columns to leds. +// fft_col_to_array[i] returns an array of leds in the ith bin of the fft. +// Negative indices are "invisible" leds. +// Use them when your keyboard has gaps. +// +// This layout is for the Ergodox EZ. + +static int8_t fft_col_to_array[10][5] = { + { 47, 43, 38, 33, 28 }, + { 46, 42, 37, 32, 27 }, + { 45, 41, 36, 31, 26 }, + { 44, 40, 35, 30, 25 }, + { -1, 39, 34, 29, 24 }, + { -1, 15, 10, 5, 0 }, + { 20, 16, 11, 6, 1 }, + { 21, 17, 12, 7, 2 }, + { 22, 18, 13, 8, 3 }, + { 23, 19, 14, 9, 4 } +}; -#ifdef RGB_MATRIX_DATAPOINTER_ENABLED +#define FFT_PER_KEY 50 void cmd_animation(uint8_t *data, uint8_t length) { switch (data[1]) { case CMD_ANIM_DATA_fft: // Only read data if animation is in fft mode if (rgb_matrix_get_mode() == RGB_MATRIX_CUSTOM_FFT_ANIM) { - // rgb_matrix_anim_data is set to NULL at animation init. - if (rgb_matrix_anim_data == NULL) { rgb_matrix_anim_data = hid_anim_data; } + // Data should be a pointer to 10 uint8_ts, each representing + // the height of a bar on the display. - // Copy data into rgb matrix array - memcpy( - hid_anim_data, - data + 2, - sizeof(uint8_t) + 10 - ); + for (uint8_t bin = 0; bin < 10; bin++) { + // Scale data values + uint8_t d = data[bin + 2]; + + + for (uint8_t i = 0; i < 5; i++) { + // Ignore negative indices. + // See fft_col_to_array definition. + if (fft_col_to_array[bin][i] < 0) { + if (d >= FFT_PER_KEY) { + d -= FFT_PER_KEY; + } else { + d = 0; + } + continue; + } + + uint8_t row = fft_col_to_array[bin][i] % MATRIX_ROWS; + uint8_t col = fft_col_to_array[bin][i] / MATRIX_ROWS; + + if (d >= FFT_PER_KEY) { + g_rgb_frame_buffer[row][col] = 0xFF; + d -= FFT_PER_KEY; + } else if (d > 0) { + g_rgb_frame_buffer[row][col] = ((double) d / FFT_PER_KEY) * 0xFF; + d = 0; + } else { + g_rgb_frame_buffer[row][col] = 0; + } + + /* + rgb_matrix_set_color( + fft_col_to_array[bin][i], + last_brightness, 0x00, last_brightness + ); + */ + } + } } else { // If not in fft mode and we receive fft data, send a state packet so host stops sending data. hid_send_state(); diff --git a/keyboards/betalupi_ergodox/rawhid.h b/keyboards/betalupi_ergodox/rawhid.h index 48cdcb0..62854b3 100644 --- a/keyboards/betalupi_ergodox/rawhid.h +++ b/keyboards/betalupi_ergodox/rawhid.h @@ -6,20 +6,16 @@ void raw_hid_receive(uint8_t *data, uint8_t length); void hid_send_state(void); -#ifdef RGB_MATRIX_DATAPOINTER_ENABLED - void cmd_animation(uint8_t *data, uint8_t length); - // Animation data. - // Data received from host is saved here, - // and rgb_matrix_anim_data points to this array when necessary. - extern uint8_t hid_anim_data[32]; +void cmd_animation(uint8_t *data, uint8_t length); - // Datapointer - extern void* rgb_matrix_anim_data; +#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS +extern uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS]; #endif + // Sent by host when connection is initiated. // // Packet structure: