From 7d25f48e3dceedfab1ac1ba71b143f78d8de8e16 Mon Sep 17 00:00:00 2001 From: Lixie Labs <5051485+connornishijima@users.noreply.github.com> Date: Tue, 28 May 2024 21:15:46 -0600 Subject: [PATCH] BROKEN VERSION - Halfway through revamping the config struct --- .vscode/settings.json | 3 +- data/js/websockets_connection.js | 2 +- platformio.ini | 2 +- src/EMOTISCOPE_FIRMWARE.ino | 1 - src/audio_debug.h | 6 - src/commands.h | 226 ++++-------------- src/configuration.h | 291 ++++++----------------- src/goertzel.h | 23 -- src/gpu_core.h | 18 +- src/led_driver.h | 2 +- src/leds.h | 33 ++- src/light_modes.h | 6 +- src/light_modes/active/analog.h | 6 +- src/light_modes/active/bloom.h | 8 +- src/light_modes/active/hype.h | 10 +- src/light_modes/active/metronome.h | 10 +- src/light_modes/active/octave.h | 6 +- src/light_modes/active/perlin.h | 8 +- src/light_modes/active/spectrum.h | 6 +- src/light_modes/beta/plot.h | 2 +- src/light_modes/beta/waveform.h | 10 +- src/light_modes/inactive/neutral.h | 6 +- src/light_modes/inactive/starfield.h | 6 +- src/microphone.h | 19 -- src/ota.h | 14 +- src/screensaver.h | 4 +- src/system.h | 7 +- src/touch.h | 16 +- src/types.h | 45 ++-- src/ui.h | 4 +- src/web_core.h | 1 - src/wireless.h | 330 ++++++++++++--------------- 32 files changed, 382 insertions(+), 749 deletions(-) delete mode 100644 src/audio_debug.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 001a902..2c7bd40 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,6 +24,7 @@ "span": "cpp", "random": "cpp", "list": "cpp", - "limits": "cpp" + "limits": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/data/js/websockets_connection.js b/data/js/websockets_connection.js index dd5d810..b2bfd15 100644 --- a/data/js/websockets_connection.js +++ b/data/js/websockets_connection.js @@ -286,7 +286,7 @@ function connect_to_emotiscope() { attempt_to_reach_emotiscope_interval = setInterval(attempt_to_reach_emotiscope, 250); setInterval(function(){ - wstx("EMO~stats|CPU-FPS|249.12|GPU-FPS|471.37~config|brightness|float|0.991|slider|softness|float|1.000|slider~modes|0Analog|0Spectrum"); + wstx("EMO~config|brightness|float|0.991|slider|1|softness|float|1.000|slider|1"); }, 500); }; diff --git a/platformio.ini b/platformio.ini index 00e75fb..99a6264 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,7 +11,7 @@ [env:esp32-s3-devkitc-1] platform = https://github.com/platformio/platform-espressif32.git#develop platform_packages = - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3 + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0 platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 board = esp32-s3-devkitc-1 framework = arduino diff --git a/src/EMOTISCOPE_FIRMWARE.ino b/src/EMOTISCOPE_FIRMWARE.ino index ebd90bd..7cdff3e 100644 --- a/src/EMOTISCOPE_FIRMWARE.ino +++ b/src/EMOTISCOPE_FIRMWARE.ino @@ -95,7 +95,6 @@ #include "vu.h" // ................. Tracks music loudness from moment to moment #include "goertzel.h" // ........... GDFT or God Damn Fast Transform is implemented here #include "tempo.h" // .............. Comupation of (and syncronization) to the music tempo -#include "audio_debug.h" // ........ Print audio data over UART #include "screensaver.h" // ........ Colorful dots play on screen when no audio is present #include "standby.h" // ............ Handles sleep/wake + animations #include "light_modes.h" // ........ Definition and handling of light modes diff --git a/src/audio_debug.h b/src/audio_debug.h deleted file mode 100644 index 5e45058..0000000 --- a/src/audio_debug.h +++ /dev/null @@ -1,6 +0,0 @@ -void print_audio_data() { - /* - Serial.printf(">waveform:%f\n", sample_history[8191]); - Serial.printf(">magnitude:%f\n", frequencies_musical[NUM_FREQS/2]); - */ -} \ No newline at end of file diff --git a/src/commands.h b/src/commands.h index 9e07377..e5616cd 100644 --- a/src/commands.h +++ b/src/commands.h @@ -2,60 +2,10 @@ #include #include -#define COMMAND_QUEUE_SLOTS (32) - -command command_queue[COMMAND_QUEUE_SLOTS]; -uint16_t commands_queued = 0; - extern float clip_float(float input); extern int16_t set_lightshow_mode_by_name(char* name); -extern void transmit_to_client_in_slot(const char* message, uint8_t client_slot); -extern void reboot_into_wifi_config_mode();; - -// Function to return the selected index as a null-terminated string with custom delimiter -// The result is stored in the provided buffer -bool load_substring_from_split_index(const char* input, int index, char* result, size_t result_size, char delimiter = '|') { - // Ensure input and result buffer are not NULL - if (input == NULL || result == NULL) { - return false; - } - - int len = strlen(input); - int start = 0; - int end = 0; - int current_index = 0; +extern void reboot_into_wifi_config_mode(); - // Iterate over the input to find the desired index - for (int i = 0; i <= len; i++) { - // Check for custom delimiter or end of string - if (input[i] == delimiter || input[i] == '\0') { - if (current_index == index) { - end = i; - break; - } - start = i + 1; - current_index++; - } - } - - // Check if the index was not found or if the result buffer is too small - int segment_length = end - start; - if (current_index != index || segment_length + 1 > result_size) { - return false; - } - - // Copy the substring to the result buffer - memset(result, 0, result_size); - strncpy(result, input + start, segment_length); - result[segment_length] = '\0'; - - return true; -} - -void shift_command_queue_left() { - memmove(command_queue, command_queue + 1, (COMMAND_QUEUE_SLOTS - 1) * (sizeof(command))); - memset(command_queue + COMMAND_QUEUE_SLOTS - 1, 0, 1 * sizeof(command)); -} void unrecognized_command_error(char* command){ printf("UNRECOGNIZED COMMAND: %s\n", command); @@ -78,109 +28,109 @@ void parse_command(char* command, PsychicWebSocketRequest *request) { // Get brightness value fetch_substring(command, '|', 2); float setting_value = clip_float(atof(substring)); - configuration.brightness = setting_value; + configuration.brightness.value.f32 = setting_value; - update_ui(UI_NEEDLE_EVENT, configuration.brightness); + update_ui(UI_NEEDLE_EVENT, setting_value); } else if (fastcmp(substring, "softness")) { // Get softness value fetch_substring(command, '|', 2); - float setting_value = atof(substring); - configuration.softness = setting_value; + float setting_value = clip_float(atof(substring)); + configuration.softness.value.f32 = setting_value; - update_ui(UI_NEEDLE_EVENT, configuration.softness); + update_ui(UI_NEEDLE_EVENT, setting_value); } else if (fastcmp(substring, "speed")) { // Get speed value fetch_substring(command, '|', 2); - float setting_value = atof(substring); - configuration.speed = setting_value; + float setting_value = clip_float(atof(substring)); + configuration.speed.value.f32 = setting_value; - update_ui(UI_NEEDLE_EVENT, configuration.speed); + update_ui(UI_NEEDLE_EVENT, setting_value); } else if (fastcmp(substring, "blur")) { // Get blur value fetch_substring(command, '|', 2); - float setting_value = atof(substring); - configuration.blur = setting_value; + float setting_value = clip_float(atof(substring)); + configuration.blur.value.f32 = setting_value; - //update_ui(UI_NEEDLE_EVENT, configuration.blur); + update_ui(UI_NEEDLE_EVENT, setting_value); } else if (fastcmp(substring, "color")) { // Get color value fetch_substring(command, '|', 2); float setting_value = clip_float(atof(substring)); - configuration.color = setting_value; + configuration.color.value.f32 = setting_value; - //update_ui(UI_HUE_EVENT, configuration.hue); + update_ui(UI_HUE_EVENT, setting_value); } else if (fastcmp(substring, "mirror_mode")) { // Get mirror_mode value fetch_substring(command, '|', 2); - bool setting_value = (bool)atoi(substring); - configuration.mirror_mode = setting_value; + uint32_t setting_value = (bool)atoi(substring); + configuration.mirror_mode.value.u32 = setting_value; } else if (fastcmp(substring, "warmth")) { // Get warmth value fetch_substring(command, '|', 2); - float setting_value = atof(substring); - configuration.warmth = setting_value; + float setting_value = clip_float(atof(substring)); + configuration.warmth.value.f32 = setting_value; - update_ui(UI_NEEDLE_EVENT, configuration.warmth); + update_ui(UI_NEEDLE_EVENT, setting_value); } else if (fastcmp(substring, "color_range")) { // Get color_range value fetch_substring(command, '|', 2); - float setting_value = atof(substring); - configuration.color_range = setting_value; + float setting_value = clip_float(atof(substring)); + configuration.color_range.value.f32 = setting_value; - //update_ui(UI_HUE_EVENT, configuration.hue); + update_ui(UI_HUE_EVENT, setting_value); } else if (fastcmp(substring, "saturation")) { // Get saturation value fetch_substring(command, '|', 2); - float setting_value = atof(substring); - configuration.saturation = sqrt(sqrt(clip_float(setting_value))); + float setting_value = sqrt(sqrt(clip_float(atof(substring)))); + configuration.saturation.value.f32 = setting_value; - //update_ui(UI_NEEDLE_EVENT, configuration.saturation); + update_ui(UI_HUE_EVENT, setting_value); } else if (fastcmp(substring, "background")) { // Get background value fetch_substring(command, '|', 2); - float setting_value = atof(substring); - configuration.background = setting_value; + float setting_value = clip_float(atof(substring)); + configuration.background.value.f32 = setting_value; - update_ui(UI_NEEDLE_EVENT, configuration.background); + update_ui(UI_NEEDLE_EVENT, setting_value); } else if (fastcmp(substring, "screensaver")) { // Get screensaver value fetch_substring(command, '|', 2); - bool setting_value = (bool)atoi(substring); - configuration.screensaver = setting_value; + uint32_t setting_value = (bool)atoi(substring); + configuration.screensaver.value.u32 = setting_value; } else if (fastcmp(substring, "temporal_dithering")){ // Get temporal_dithering value fetch_substring(command, '|', 2); - bool setting_value = (bool)atoi(substring); - configuration.temporal_dithering = setting_value; + uint32_t setting_value = (bool)atoi(substring); + configuration.temporal_dithering.value.u32 = setting_value; } else if (fastcmp(substring, "reverse_color_range")){ // Get reverse_color_range value fetch_substring(command, '|', 2); - bool setting_value = (bool)atoi(substring); - configuration.reverse_color_range = setting_value; + uint32_t setting_value = (bool)atoi(substring); + configuration.reverse_color_range.value.u32 = setting_value; } else if (fastcmp(substring, "auto_color_cycle")){ // Get auto_color_cycle value fetch_substring(command, '|', 2); - bool setting_value = (bool)atoi(substring); - configuration.auto_color_cycle = setting_value; + uint32_t setting_value = (bool)atoi(substring); + configuration.auto_color_cycle.value.u32 = setting_value; } - else if (fastcmp(substring, "show_interface")){ + else if (fastcmp(substring, "show_ui")){ // Get show_interface value fetch_substring(command, '|', 2); - bool setting_value = (bool)atoi(substring); - configuration.show_interface = setting_value; + uint32_t setting_value = (bool)atoi(substring); + configuration.show_ui.value.u32 = setting_value; } else if (fastcmp(substring, "mode")) { @@ -212,71 +162,9 @@ void parse_command(char* command, PsychicWebSocketRequest *request) { if (fastcmp(substring, "config")) { // Wake on command EMOTISCOPE_ACTIVE = true; - sync_configuration_to_client(); load_menu_toggles(); } - // If getting mode list - else if (fastcmp(substring, "modes")) { - request->client()->sendMessage("clear_modes"); - - uint16_t num_modes = sizeof(light_modes) / sizeof(light_mode); - for(uint16_t mode_index = 0; mode_index < num_modes; mode_index++){ - char command_string[128]; - uint8_t mode_type = (uint8_t)light_modes[mode_index].type; - - snprintf(command_string, 128, "new_mode|%d|%d|%.64s", mode_index, mode_type, light_modes[mode_index].name); - request->client()->sendMessage(command_string); - } - - request->client()->sendMessage("modes_ready"); - } - // If getting slider list - else if (fastcmp(substring, "sliders")) { - request->client()->sendMessage("clear_sliders"); - - for(uint16_t i = 0; i < sliders_active; i++){ - char command_string[128]; - snprintf(command_string, 128, "new_slider|%s|%.3f|%.3f|%.3f", sliders[i].name, sliders[i].slider_min, sliders[i].slider_max, sliders[i].slider_step); - request->client()->sendMessage(command_string); - } - - request->client()->sendMessage("sliders_ready"); - } - - // If getting toggle list - else if (fastcmp(substring, "toggles")) { - request->client()->sendMessage("clear_toggles"); - - for(uint16_t i = 0; i < toggles_active; i++){ - char command_string[128]; - snprintf(command_string, 128, "new_toggle|%s", toggles[i].name); - request->client()->sendMessage(command_string); - } - - request->client()->sendMessage("toggles_ready"); - } - - // If getting menu toggle list - else if (fastcmp(substring, "menu_toggles")) { - request->client()->sendMessage("clear_menu_toggles"); - - for(uint16_t i = 0; i < menu_toggles_active; i++){ - char command_string[128]; - snprintf(command_string, 128, "new_menu_toggle|%s", menu_toggles[i].name); - request->client()->sendMessage(command_string); - } - - request->client()->sendMessage("menu_toggles_ready"); - } - - // If getting touch values - else if (fastcmp(substring, "touch_vals")) { - char command_string[128]; - snprintf(command_string, 128, "touch_vals|%lu|%lu|%lu", uint32_t(touch_pins[0].touch_value), uint32_t(touch_pins[1].touch_value), uint32_t(touch_pins[2].touch_value)); - request->client()->sendMessage(command_string); - } - // If getting version number else if (fastcmp(substring, "version")) { char command_string[128]; @@ -343,8 +231,8 @@ void parse_command(char* command, PsychicWebSocketRequest *request) { } } else if (fastcmp(substring, "perform_update")) { - //extern void perform_update(int16_t client_slot); - //perform_update(com.origin_client_slot); + extern void perform_update(PsychicWebSocketRequest *request); + perform_update(request); } else if (fastcmp(substring, "self_test")) { if(t_now_ms >= 1000){ // Wait 1 second before checking boot button @@ -361,42 +249,10 @@ void parse_command(char* command, PsychicWebSocketRequest *request) { load_toggles_relevant_to_mode(next_mode_index); broadcast("reload_config"); } - else if (fastcmp(substring, "start_debug_recording")) { - audio_recording_index = 0; - memset(audio_debug_recording, 0, sizeof(int16_t)*MAX_AUDIO_RECORDING_SAMPLES); - audio_recording_live = true; - } else{ unrecognized_command_error(substring); } // printf("current brightness value: %.3f\n", configuration.brightness); -} - -void process_command_queue() { - if (commands_queued > 0) { - //parse_command(t_now_ms, command_queue[0]); - shift_command_queue_left(); - commands_queued -= 1; - } -} - -bool queue_command(const char* command, uint16_t length, uint8_t client_slot) { - if (length < MAX_COMMAND_LENGTH) { - if (commands_queued < COMMAND_QUEUE_SLOTS - 1) { - memset(command_queue[commands_queued].command, 0, MAX_COMMAND_LENGTH); - memcpy(command_queue[commands_queued].command, command, length); - command_queue[commands_queued].origin_client_slot = client_slot; - commands_queued += 1; - } - else { - return false; - } - } - else { - return false; - } - - return true; } \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index 00fcbbe..ef3713c 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -1,25 +1,15 @@ -#define NOISE_SPECTRUM_FILENAME "/noise_spectrum.bin" #define NETWORK_CONFIG_FILENAME "/secrets/network.txt" -#define AUDIO_DEBUG_RECORDING_FILENAME "/audio.bin" #define MIN_SAVE_WAIT_MS (3 * 1000) // Values must stabilize for this many seconds to be written to NVS -#define MAX_AUDIO_RECORDING_SAMPLES ( 12800 * 3 ) // 3 seconds at [SAMPLE_RATE] - Preferences preferences; // NVS storage for configuration +config configuration; // configuration struct to be filled by NVS or defaults on boot + extern light_mode light_modes[]; extern PsychicWebSocketHandler websocket_handler; volatile bool wifi_config_mode = false; -config configuration; // configuration struct to be filled by NVS or defaults on boot - -float noise_spectrum[NUM_FREQS] = {0.0}; - -int16_t audio_debug_recording[MAX_AUDIO_RECORDING_SAMPLES]; -uint32_t audio_recording_index = 0; -volatile bool audio_recording_live = false; - volatile uint32_t last_save_request_ms = 0; volatile bool save_request_open = false; @@ -28,213 +18,108 @@ volatile bool filesystem_ready = true; void load_config(){ // Load configuration from NVS + memset(&configuration, 0, sizeof(config)); // Clear the configuration struct + // Brightness - configuration.brightness = preferences.getFloat("brightness", 1.00); + strcpy(configuration.brightness.name, "brightness"); + strcpy(configuration.brightness.pretty_name, "Brightness"); + configuration.brightness.value.f32 = preferences.getFloat(configuration.brightness.name, 1.00); // Softness - configuration.softness = preferences.getFloat("softness", 0.25); + strcpy(configuration.softness.name, "softness"); + strcpy(configuration.softness.pretty_name, "Softness"); + configuration.softness.value.f32 = preferences.getFloat(configuration.softness.name, 0.25); // Color - configuration.color = preferences.getFloat("color", 0.33); + strcpy(configuration.color.name, "color"); + strcpy(configuration.color.pretty_name, "Color"); + configuration.color.value.f32 = preferences.getFloat(configuration.color.name, 0.33); // Color Range - configuration.color_range = preferences.getFloat("color_range", 0.00); + strcpy(configuration.color_range.name, "color_range"); + strcpy(configuration.color_range.pretty_name, "Color Range"); + configuration.color_range.value.f32 = preferences.getFloat(configuration.color_range.name, 0.0); // Warmth - configuration.warmth = preferences.getFloat("warmth", 0.00); + strcpy(configuration.warmth.name, "warmth"); + strcpy(configuration.warmth.pretty_name, "Warmth"); + configuration.warmth.value.f32 = preferences.getFloat(configuration.warmth.name, 0.50); // Speed - configuration.speed = preferences.getFloat("speed", 0.50); + strcpy(configuration.speed.name, "speed"); + strcpy(configuration.speed.pretty_name, "Speed"); + configuration.speed.value.f32 = preferences.getFloat(configuration.speed.name, 0.50); // Saturation - configuration.saturation = preferences.getFloat("saturation", 0.75); + strcpy(configuration.saturation.name, "saturation"); + strcpy(configuration.saturation.pretty_name, "Saturation"); + configuration.saturation.value.f32 = preferences.getFloat(configuration.saturation.name, 0.85); // Background - configuration.background = preferences.getFloat("background", 0.25); + strcpy(configuration.background.name, "background"); + strcpy(configuration.background.pretty_name, "Background"); + configuration.background.value.f32 = preferences.getFloat(configuration.background.name, 0.25); // Current Mode - configuration.current_mode = preferences.getInt("current_mode", 1); + strcpy(configuration.current_mode.name, "current_mode"); + strcpy(configuration.current_mode.pretty_name, "Current Mode"); + configuration.current_mode.value.u32 = (uint32_t)preferences.getInt(configuration.current_mode.name, 1); // Mirror Mode - configuration.mirror_mode = preferences.getBool("mirror_mode", true); + strcpy(configuration.mirror_mode.name, "mirror_mode"); + strcpy(configuration.mirror_mode.pretty_name, "Mirror Mode"); + configuration.mirror_mode.value.u32 = (uint32_t)preferences.getBool(configuration.mirror_mode.name, true); // Screensaver - configuration.screensaver = preferences.getBool("screensaver", true); + strcpy(configuration.screensaver.name, "screensaver"); + strcpy(configuration.screensaver.pretty_name, "Screensaver"); + configuration.screensaver.value.u32 = (uint32_t)preferences.getBool(configuration.screensaver.name, true); // Temporal Dithering - configuration.temporal_dithering = preferences.getBool("dithering", true); - + strcpy(configuration.temporal_dithering.name, "dithering"); + strcpy(configuration.temporal_dithering.pretty_name, "Temporal Dithering"); + configuration.temporal_dithering.value.u32 = (uint32_t)preferences.getBool(configuration.temporal_dithering.name, true); + // Reverse Color - configuration.reverse_color_range = preferences.getBool("reverse_color", false); + strcpy(configuration.reverse_color_range.name, "reverse_color"); + strcpy(configuration.reverse_color_range.pretty_name, "Reverse Color Range"); + configuration.reverse_color_range.value.u32 = (uint32_t)preferences.getBool(configuration.reverse_color_range.name, false); // Auto Color Cycling - configuration.auto_color_cycle = preferences.getBool("auto_color", false); + strcpy(configuration.auto_color_cycle.name, "auto_color"); + strcpy(configuration.auto_color_cycle.pretty_name, "Auto Color Cycle"); + configuration.auto_color_cycle.value.u32 = (uint32_t)preferences.getBool(configuration.auto_color_cycle.name, false); // Blur - configuration.blur = preferences.getFloat("blur", 0.00); + strcpy(configuration.blur.name, "blur"); + strcpy(configuration.blur.pretty_name, "Blur"); + configuration.blur.value.f32 = preferences.getFloat(configuration.blur.name, 0.00); // Show Interface - configuration.show_interface = preferences.getBool("show_interface", true); -} - -void sync_configuration_to_client() { - char config_item_buffer[120]; - - websocket_handler.sendAll("clear_config"); - - // brightness - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|brightness|float|%.3f", configuration.brightness); - websocket_handler.sendAll(config_item_buffer); - - // softness - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|softness|float|%.3f", configuration.softness); - websocket_handler.sendAll(config_item_buffer); - - // speed - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|speed|float|%.3f", configuration.speed); - websocket_handler.sendAll(config_item_buffer); - - // color - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|color|float|%.3f", configuration.color); - websocket_handler.sendAll(config_item_buffer); - - // current_mode - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|current_mode|int|%li", configuration.current_mode); - websocket_handler.sendAll(config_item_buffer); - - // mirror_mode - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|mirror_mode|int|%d", configuration.mirror_mode); - websocket_handler.sendAll(config_item_buffer); - - // warmth - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|warmth|float|%.3f", configuration.warmth); - websocket_handler.sendAll(config_item_buffer); - - // color_range - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|color_range|float|%.3f", configuration.color_range); - websocket_handler.sendAll(config_item_buffer); - - // saturation - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|saturation|float|%.3f", configuration.saturation); - websocket_handler.sendAll(config_item_buffer); - - // background - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|background|float|%.3f", configuration.background); - websocket_handler.sendAll(config_item_buffer); - - // screensaver - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|screensaver|int|%d", configuration.screensaver); - websocket_handler.sendAll(config_item_buffer); - - // temporal_dithering - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|temporal_dithering|int|%d", configuration.temporal_dithering); - websocket_handler.sendAll(config_item_buffer); - - // reverse_color_range - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|reverse_color_range|int|%d", configuration.reverse_color_range); - websocket_handler.sendAll(config_item_buffer); - - // auto_color_cycle - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|auto_color_cycle|int|%d", configuration.auto_color_cycle); - websocket_handler.sendAll(config_item_buffer); - - // blur - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|blur|float|%.3f", configuration.blur); - websocket_handler.sendAll(config_item_buffer); - - // show_interface - memset(config_item_buffer, 0, 120); - snprintf(config_item_buffer, 120, "new_config|show_interface|int|%d", configuration.show_interface); - websocket_handler.sendAll(config_item_buffer); - - websocket_handler.sendAll("config_ready"); + strcpy(configuration.show_ui.name, "show_ui"); + strcpy(configuration.show_ui.pretty_name, "Show Interface"); + configuration.show_ui.value.u32 = (uint32_t)preferences.getBool(configuration.show_ui.name, true); } // Save configuration to LittleFS bool save_config() { - preferences.putFloat("brightness", configuration.brightness); - preferences.putFloat("softness", configuration.softness); - preferences.putFloat("color", configuration.color); - preferences.putFloat("color_range", configuration.color_range); - preferences.putFloat("warmth", configuration.warmth); - preferences.putFloat("speed", configuration.speed); - preferences.putFloat("saturation", configuration.saturation); - preferences.putFloat("background", configuration.background); - preferences.putInt("current_mode", configuration.current_mode); - preferences.putBool("mirror_mode", configuration.mirror_mode); - preferences.putBool("screensaver", configuration.screensaver); - preferences.putBool("dithering", configuration.temporal_dithering); - preferences.putBool("reverse_color", configuration.reverse_color_range); - preferences.putBool("auto_color", configuration.auto_color_cycle); - preferences.putFloat("blur", configuration.blur); - preferences.putBool("show_interface", configuration.show_interface); - - return true; -} - -// Save noise spectrum to LittleFS -bool save_noise_spectrum() { - File file = LittleFS.open(NOISE_SPECTRUM_FILENAME, FILE_WRITE); - if (!file) { - printf("Failed to open %s for writing!", NOISE_SPECTRUM_FILENAME); - return false; - } - else { - const uint8_t* ptr = (const uint8_t*)&noise_spectrum; - - // Iterate over the size of noise_spectrum and write each byte to the file - for (size_t i = 0; i < sizeof(float) * NUM_FREQS; i++) { - file.write(ptr[i]); - } - } - file.close(); - return true; -} - -// Load noise_spectrum from LittleFS -bool load_noise_spectrum() { - // Open the file for reading - File file = LittleFS.open(NOISE_SPECTRUM_FILENAME, FILE_READ); - if (!file) { - printf("Failed to open %s for reading!\n", NOISE_SPECTRUM_FILENAME); - return false; - } - else { - // Ensure the noise_spectrum array is sized properly - if (file.size() != sizeof(float) * NUM_FREQS) { - printf("Noise spectrum size does not match expected size! (%zu != %zu)\n", file.size(), sizeof(float) * NUM_FREQS); - file.close(); - return false; - } + preferences.putFloat(configuration.brightness.name, configuration.brightness.value.f32); + preferences.putFloat(configuration.softness.name, configuration.softness.value.f32); + preferences.putFloat(configuration.color.name, configuration.color.value.f32); + preferences.putFloat(configuration.color_range.name, configuration.color_range.value.f32); + preferences.putFloat(configuration.warmth.name, configuration.warmth.value.f32); + preferences.putFloat(configuration.speed.name, configuration.speed.value.f32); + preferences.putFloat(configuration.saturation.name, configuration.saturation.value.f32); + preferences.putFloat(configuration.background.name, configuration.background.value.f32); + preferences.putInt(configuration.current_mode.name, configuration.current_mode.value.u32); + preferences.putBool(configuration.mirror_mode.name, configuration.mirror_mode.value.u32); + preferences.putBool(configuration.screensaver.name, configuration.screensaver.value.u32); + preferences.putBool(configuration.temporal_dithering.name, configuration.temporal_dithering.value.u32); + preferences.putBool(configuration.reverse_color_range.name, configuration.reverse_color_range.value.u32); + preferences.putBool(configuration.auto_color_cycle.name, configuration.auto_color_cycle.value.u32); + preferences.putFloat(configuration.blur.name, configuration.blur.value.f32); + preferences.putBool(configuration.show_ui.name, configuration.show_ui.value.u32); - uint8_t* ptr = (uint8_t*)&noise_spectrum; // Pointer to the noise_spectrum array - - // Read the file content into the noise_spectrum array - for (size_t i = 0; i < sizeof(float) * NUM_FREQS; i++) { - int byte = file.read(); // Read a byte - if (byte == -1) { // Check for read error or end of file - printf("Error reading %s!\n", NOISE_SPECTRUM_FILENAME); - break; - } - ptr[i] = (uint8_t)byte; // Store the byte in the noise_spectrum array - } - } - file.close(); // Close the file after reading return true; } @@ -249,7 +134,6 @@ void sync_configuration_to_file_system() { filesystem_ready = false; printf("SAVING\n"); save_config(); - //save_noise_spectrum(); save_request_open = false; filesystem_ready = true; } @@ -283,7 +167,6 @@ void load_network_credentials(){ memset(wifi_ssid, 0, 64); memset(wifi_pass, 0, 64); - // Load network credentials from NVS with Preferences library, just like the config struct using getBytes on the char arrays: // SSID preferences.getBytes("wifi_ssid", wifi_ssid, 64); // Password @@ -303,44 +186,8 @@ void init_configuration() { // Attempt to load config from flash printf("LOADING CONFIG..."); load_config(); - printf("PASS\n"); - - // Attempt to load noise_spectrum from flash - printf("LOADING NOISE SPECTRUM..."); - bool load_success = load_noise_spectrum(); - - // If we couldn't load the file, save a fresh copy - if (load_success == false) { - printf("FAIL\n"); - save_noise_spectrum(); - } - else { - printf("PASS\n"); - } // Attempt to load wifi creds from flash printf("LOADING NETWORK..."); load_network_credentials(); - printf("PASS\n"); } - -// Save debug audio recording to LittleFS -bool save_audio_debug_recording() { - File file = LittleFS.open(AUDIO_DEBUG_RECORDING_FILENAME, FILE_WRITE); - if (!file) { - printf("Failed to open %s for writing!", AUDIO_DEBUG_RECORDING_FILENAME); - return false; - } - else { - const uint8_t* ptr = (const uint8_t*)&audio_debug_recording; - - // Iterate over the size of noise_spectrum and write each byte to the file - for (size_t i = 0; i < sizeof(int16_t) * MAX_AUDIO_RECORDING_SAMPLES; i++) { - file.write(ptr[i]); - } - - printf("Audio debug recording saved!\n"); - } - file.close(); - return true; -} \ No newline at end of file diff --git a/src/goertzel.h b/src/goertzel.h index 5bf4e4e..9c88c74 100644 --- a/src/goertzel.h +++ b/src/goertzel.h @@ -292,22 +292,6 @@ void calculate_magnitudes() { } } - if(noise_calibration_wait_frames_remaining > 0){ - noise_calibration_wait_frames_remaining -= 1; - } - else if(noise_calibration_active_frames_remaining > 0){ - // Not done yet? Decrement... - noise_calibration_active_frames_remaining -= 1; - - // If background noise calibration just finished - if(noise_calibration_active_frames_remaining == 0){ - // Let the UI know - broadcast("noise_cal_ready"); - save_config(); - save_noise_spectrum(); - } - } - // Smooth max_val with different speed limits for increases vs. decreases if (max_val > max_val_smooth) { float delta = max_val - max_val_smooth; @@ -353,13 +337,6 @@ void calculate_magnitudes() { ___(); } -void start_noise_calibration() { - Serial.println("Starting noise cal..."); - memset(noise_spectrum, 0, sizeof(float) * NUM_FREQS); - noise_calibration_wait_frames_remaining = NOISE_CALIBRATION_WAIT_FRAMES; - noise_calibration_active_frames_remaining = NOISE_CALIBRATION_ACTIVE_FRAMES; -} - void get_chromagram(){ profile_function([&]() { memset(chromagram, 0, sizeof(float) * 12); diff --git a/src/gpu_core.h b/src/gpu_core.h index fff814f..22b03d5 100644 --- a/src/gpu_core.h +++ b/src/gpu_core.h @@ -45,20 +45,20 @@ void run_gpu() { // ------------------------------------------------------------ clear_display(); - light_modes[configuration.current_mode].draw(); + light_modes[configuration.current_mode.value.u32].draw(); // If silence is detected, show a blue debug LED // leds[NUM_LEDS - 1] = add(leds[NUM_LEDS - 1], {0.0, 0.0, silence_level}); - apply_background(configuration.background); + apply_background(configuration.background.value.f32); //scramble_image( configuration.blur * 50.0 ); - apply_blur( configuration.blur * 12.0 ); + apply_blur( configuration.blur.value.f32 * 12.0 ); draw_ui_overlay(); // (ui.h) - if( EMOTISCOPE_ACTIVE == true && configuration.screensaver == true){ + if( EMOTISCOPE_ACTIVE == true && configuration.screensaver.value.u32 == true){ run_screensaver(); } @@ -86,20 +86,20 @@ void run_gpu() { // When I got into all this in 2012, I had a 16MHz single core AVR // // The DMA and SIMD-style stuff inside the ESP32-S3 is some pretty crazy shit. - float lpf_cutoff_frequency = 0.5 + (1.0-(sqrt(configuration.softness)))*14.5; + float lpf_cutoff_frequency = 0.5 + (1.0-(sqrt(configuration.softness.value.f32)))*14.5; lpf_cutoff_frequency = lpf_cutoff_frequency * (1.0 - lpf_drag) + 0.5 * lpf_drag; apply_image_lpf(lpf_cutoff_frequency); //clip_leds(); apply_tonemapping(); - //apply_fractional_blur( leds, NUM_LEDS, configuration.blur * 10.0 ); + //apply_fractional_blur( leds, NUM_LEDS, configuration.blur.value.f32 * 10.0 ); - //apply_frame_blending( configuration.softness ); - //apply_phosphor_decay( configuration.softness ); + //apply_frame_blending( configuration.softness.value.f32 ); + //apply_phosphor_decay( configuration.softness.value.f32 ); // Apply an incandescent LUT to reduce harsh blue tones - apply_warmth( configuration.warmth ); // (leds.h) + apply_warmth( configuration.warmth.value.f32 ); // (leds.h) // Apply white balance multiply_CRGBF_array_by_LUT( leds, WHITE_BALANCE, NUM_LEDS ); diff --git a/src/led_driver.h b/src/led_driver.h index 762114f..a7fe4ef 100644 --- a/src/led_driver.h +++ b/src/led_driver.h @@ -290,7 +290,7 @@ IRAM_ATTR void transmit_leds() { // The contents of the floating point CRGBF "leds" array are downsampled into pseudo-random 8-bit // dither patterns hundreds of times per second. Your eyes see these patterns as a smooth, higher // dynamic range image with deeper color reproduction. - quantize_color_error( configuration.temporal_dithering ); + quantize_color_error( configuration.temporal_dithering.value.u32 ); // Get to safety, THE PHOTONS ARE COMING!!! if( filesystem_ready == true ){ diff --git a/src/leds.h b/src/leds.h index 662c6d7..271bf3f 100644 --- a/src/leds.h +++ b/src/leds.h @@ -242,10 +242,9 @@ CRGBF hsv(float h, float s, float v) { void apply_warmth(float mix) { profile_function([&]() { - if(light_modes[configuration.current_mode].type == LIGHT_MODE_TYPE_SYSTEM){ return; } + if(light_modes[configuration.current_mode.value.u32].type == LIGHT_MODE_TYPE_SYSTEM){ return; } float mix_inv = 1.0 - mix; - if(mix > 0.0){ multiply_CRGBF_array_by_LUT( leds, @@ -446,9 +445,9 @@ void draw_dot(CRGBF* layer, uint16_t fx_dots_slot, CRGBF color, float position, void update_auto_color(){ profile_function([&]() { - if(light_modes[configuration.current_mode].type != LIGHT_MODE_TYPE_ACTIVE){ return; } + if(light_modes[configuration.current_mode.value.u32].type != LIGHT_MODE_TYPE_ACTIVE){ return; } - if(configuration.auto_color_cycle == true){ + if(configuration.auto_color_cycle.value.u32 == true){ float novelty = novelty_curve_normalized[NOVELTY_HISTORY_LENGTH - 1] * 0.75; novelty = novelty*novelty*novelty*novelty*novelty*novelty; @@ -458,7 +457,7 @@ void update_auto_color(){ color_momentum = 0.1; } - configuration.color += color_momentum*0.05; + configuration.color.value.f32 += color_momentum*0.05; } }, __func__ ); } @@ -678,9 +677,9 @@ void apply_gamma_correction() { void apply_brightness() { profile_function([&]() { - if(light_modes[configuration.current_mode].type == LIGHT_MODE_TYPE_SYSTEM){ return; } + if(light_modes[configuration.current_mode.value.u32].type == LIGHT_MODE_TYPE_SYSTEM){ return; } - float brightness_val = 0.3 + (configuration.brightness*0.7); + float brightness_val = 0.3 + (configuration.brightness.value.f32*0.7); scale_CRGBF_array_by_constant(leds, brightness_val, NUM_LEDS); }, __func__); @@ -689,17 +688,17 @@ void apply_brightness() { float get_color_range_hue(float progress){ float return_val; //profile_function([&]() { - float color_range = configuration.color_range; + float color_range = configuration.color_range.value.f32; if(color_range == 0.0){ - return_val = configuration.color; + return_val = configuration.color.value.f32; } - else if(configuration.reverse_color_range == true){ + else if(configuration.reverse_color_range.value.u32 == true){ color_range *= -1.0; - return_val = (1.0-configuration.color) + (color_range * progress); + return_val = (1.0-configuration.color.value.f32) + (color_range * progress); } else{ - return_val = configuration.color + (color_range * progress); + return_val = configuration.color.value.f32 + (color_range * progress); } //}, __func__); @@ -708,16 +707,16 @@ float get_color_range_hue(float progress){ void apply_background(float background_level){ profile_function([&]() { - if(light_modes[configuration.current_mode].type == LIGHT_MODE_TYPE_SYSTEM){ return; } + if(light_modes[configuration.current_mode.value.u32].type == LIGHT_MODE_TYPE_SYSTEM){ return; } background_level *= 0.25; // Max 25% brightness if(background_level > 0.0){ - if(configuration.mirror_mode == false){ + if(configuration.mirror_mode.value.u32 == false){ for(uint16_t i = 0; i < NUM_LEDS; i++){ float progress = num_leds_float_lookup[i]; CRGBF background_color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, 1.0 ); @@ -729,7 +728,7 @@ void apply_background(float background_level){ float progress = num_leds_float_lookup[i << 1]; CRGBF background_color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, 1.0 ); @@ -760,7 +759,7 @@ void clear_display(float keep = 0.0){ } void fade_display(){ - scale_CRGBF_array_by_constant(leds, configuration.softness, NUM_LEDS); + scale_CRGBF_array_by_constant(leds, configuration.softness.value.f32, NUM_LEDS); } float soft_clip_hdr(float input) { diff --git a/src/light_modes.h b/src/light_modes.h index 6e73e13..f258613 100644 --- a/src/light_modes.h +++ b/src/light_modes.h @@ -72,7 +72,7 @@ void init_light_mode_list(){ } void set_light_mode_by_index(uint16_t mode_index){ - configuration.current_mode = mode_index; + configuration.current_mode.value.u32 = mode_index; lpf_drag = 1.0; // Causes slow fade using low pass filtered image save_config_delayed(); } @@ -102,7 +102,7 @@ int16_t set_light_mode_by_name(const char* name){ } int16_t increment_mode(){ - int16_t next_mode_index = (configuration.current_mode + 1) % NUM_LIGHT_MODES; + int16_t next_mode_index = (configuration.current_mode.value.u32 + 1) % NUM_LIGHT_MODES; set_light_mode_by_index(next_mode_index); return next_mode_index; @@ -121,7 +121,7 @@ void queue_light_mode_by_index(uint16_t mode_index){ } void trigger_self_test(){ - queue_light_mode_by_index( configuration.current_mode ); // Save current mode to return to + queue_light_mode_by_index( configuration.current_mode.value.u32 ); // Save current mode to return to self_test_step = SELF_TEST_STEP_START; // Set the self test to starting state set_light_mode_by_name("Self Test"); // Jump to self test mode } \ No newline at end of file diff --git a/src/light_modes/active/analog.h b/src/light_modes/active/analog.h index 3d6b007..dd363ee 100644 --- a/src/light_modes/active/analog.h +++ b/src/light_modes/active/analog.h @@ -2,17 +2,17 @@ float vu_level_smooth = 0.000001; void draw_analog(){ profile_function([&]() { - float mix_speed = 0.005 + 0.145*configuration.speed; + float mix_speed = 0.005 + 0.145*configuration.speed.value.f32; vu_level_smooth = (vu_level) * mix_speed + vu_level_smooth*(1.0-mix_speed); float dot_pos = clip_float(vu_level_smooth); CRGBF dot_color = hsv( get_color_range_hue(dot_pos), - configuration.saturation, + configuration.saturation.value.f32, 1.0 ); - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ dot_pos = 0.05 + dot_pos * 0.95; draw_dot(leds, NUM_RESERVED_DOTS+0, dot_color, 0.5 + (dot_pos* 0.5), 1.0); diff --git a/src/light_modes/active/bloom.h b/src/light_modes/active/bloom.h index 2f4bb4e..0a7b4f0 100644 --- a/src/light_modes/active/bloom.h +++ b/src/light_modes/active/bloom.h @@ -3,19 +3,19 @@ float novelty_image_prev[NUM_LEDS] = { 0.0 }; void draw_bloom() { float novelty_image[NUM_LEDS] = { 0.0 }; - float spread_speed = 0.125 + 0.875*configuration.speed; + float spread_speed = 0.125 + 0.875*configuration.speed.value.f32; draw_sprite(novelty_image, novelty_image_prev, NUM_LEDS, NUM_LEDS, spread_speed, 0.99); novelty_image[0] = (vu_level); novelty_image[0] = min( 1.0f, novelty_image[0] ); - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ for(uint16_t i = 0; i < NUM_LEDS>>1; i++){ float progress = num_leds_float_lookup[i<<1]; float novelty_pixel = clip_float(novelty_image[i]*1.0); CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, novelty_pixel ); leds[ (NUM_LEDS>>1) + i] = color; @@ -28,7 +28,7 @@ void draw_bloom() { float novelty_pixel = clip_float(novelty_image[i]*2.0); CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, novelty_pixel ); leds[i] = color; diff --git a/src/light_modes/active/hype.h b/src/light_modes/active/hype.h index 654e7be..f84b8df 100644 --- a/src/light_modes/active/hype.h +++ b/src/light_modes/active/hype.h @@ -27,16 +27,16 @@ void draw_hype() { CRGBF dot_color_odd = hsv( get_color_range_hue(beat_color_odd), - configuration.saturation, + configuration.saturation.value.f32, 1.0 ); CRGBF dot_color_even = hsv( - get_color_range_hue(beat_color_even+0.5*configuration.color_range), - configuration.saturation, + get_color_range_hue(beat_color_even+0.5*configuration.color_range.value.f32), + configuration.saturation.value.f32, 1.0 ); - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ beat_sum_odd *= 0.5; beat_sum_even *= 0.5; } @@ -44,7 +44,7 @@ void draw_hype() { draw_dot(leds, NUM_RESERVED_DOTS + 0, dot_color_odd, 1.0-beat_sum_odd, 0.1 + 0.8*strength); draw_dot(leds, NUM_RESERVED_DOTS + 1, dot_color_even, 1.0-beat_sum_even, 0.1 + 0.8*strength); - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ draw_dot(leds, NUM_RESERVED_DOTS + 2, dot_color_odd, beat_sum_odd, 0.1 + 0.8*strength); draw_dot(leds, NUM_RESERVED_DOTS + 3, dot_color_even, beat_sum_even, 0.1 + 0.8*strength); } diff --git a/src/light_modes/active/metronome.h b/src/light_modes/active/metronome.h index 6cec9df..8428e3a 100644 --- a/src/light_modes/active/metronome.h +++ b/src/light_modes/active/metronome.h @@ -16,7 +16,7 @@ void draw_metronome() { else if(sine < -1.0){ sine = -1.0; } float metronome_width; - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ metronome_width = 0.5; } else{ @@ -29,17 +29,17 @@ void draw_metronome() { CRGBF dot_color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, 1.0 ); - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ dot_pos -= 0.25; } draw_dot(leds, NUM_RESERVED_DOTS + tempo_bin * 2 + 0, dot_color, dot_pos, opacity); - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ draw_dot(leds, NUM_RESERVED_DOTS + tempo_bin * 2 + 1, dot_color, 1.0 - dot_pos, opacity); } } @@ -47,7 +47,7 @@ void draw_metronome() { // Put inactive dots in the middle fx_dots[NUM_RESERVED_DOTS + tempo_bin * 2 + 0].position = 0.5; - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ fx_dots[NUM_RESERVED_DOTS + tempo_bin * 2 + 0].position = 0.25; fx_dots[NUM_RESERVED_DOTS + tempo_bin * 2 + 1].position = 0.75; } diff --git a/src/light_modes/active/octave.h b/src/light_modes/active/octave.h index 22d7b6c..5ec8cf7 100644 --- a/src/light_modes/active/octave.h +++ b/src/light_modes/active/octave.h @@ -1,11 +1,11 @@ void draw_octave() { - if(configuration.mirror_mode == true){ // Mirror mode + if(configuration.mirror_mode.value.u32 == true){ // Mirror mode for (uint16_t i = 0; i < (NUM_LEDS >> 1); i++) { float progress = num_leds_float_lookup[i<<1]; float mag = clip_float(interpolate(progress, chromagram, 12)); CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, mag ); @@ -19,7 +19,7 @@ void draw_octave() { float mag = clip_float(interpolate(progress, chromagram, 12)); CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, mag ); diff --git a/src/light_modes/active/perlin.h b/src/light_modes/active/perlin.h index b0e7cf0..01320e7 100644 --- a/src/light_modes/active/perlin.h +++ b/src/light_modes/active/perlin.h @@ -7,7 +7,7 @@ void draw_perlin(){ static float momentum = 0.0; - float push = vu_level*vu_level*vu_level*vu_level*configuration.speed*0.1f; + float push = vu_level*vu_level*vu_level*vu_level*configuration.speed.value.f32*0.1f; momentum *= 0.99; @@ -30,11 +30,11 @@ void draw_perlin(){ dsps_mulc_f32_ae32(ptr, ptr, NUM_LEDS, 0.98, 1, 1); dsps_addc_f32_ae32(ptr, ptr, NUM_LEDS, 0.02, 1, 1); - if(configuration.mirror_mode == false){ + if(configuration.mirror_mode.value.u32 == false){ for(uint16_t i = 0; i < NUM_LEDS; i++){ CRGBF color = hsv( get_color_range_hue(perlin_image_hue[i]), - configuration.saturation, + configuration.saturation.value.f32, perlin_image_lum[i]*perlin_image_lum[i] ); @@ -45,7 +45,7 @@ void draw_perlin(){ for(uint16_t i = 0; i < NUM_LEDS>>1; i++){ CRGBF color = hsv( get_color_range_hue(perlin_image_hue[i<<1]), - configuration.saturation, + configuration.saturation.value.f32, perlin_image_lum[i<<1]*perlin_image_lum[i<<1] ); diff --git a/src/light_modes/active/spectrum.h b/src/light_modes/active/spectrum.h index 1a71f5f..a221d50 100644 --- a/src/light_modes/active/spectrum.h +++ b/src/light_modes/active/spectrum.h @@ -1,12 +1,12 @@ void draw_spectrum() { // Mirror mode - if(configuration.mirror_mode == true){ + if(configuration.mirror_mode.value.u32 == true){ for (uint16_t i = 0; i < NUM_LEDS>>1; i++) { float progress = num_leds_float_lookup[i<<1]; float mag = (spectrogram_smooth[i]); CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, mag ); @@ -21,7 +21,7 @@ void draw_spectrum() { float mag = (clip_float(interpolate(progress, spectrogram_smooth, NUM_FREQS))); CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, mag ); diff --git a/src/light_modes/beta/plot.h b/src/light_modes/beta/plot.h index c47a0f4..42b2237 100644 --- a/src/light_modes/beta/plot.h +++ b/src/light_modes/beta/plot.h @@ -83,7 +83,7 @@ void draw_plot(){ float progress = float(i) / NUM_LEDS; float pixel = clip_float( image[i] * auto_scale ); pixel *= pixel; - CRGBF pixel_color = hsv(configuration.color + linear_to_tri(progress)*configuration.color_range, configuration.saturation, pixel); + CRGBF pixel_color = hsv(configuration.color.value.f32 + linear_to_tri(progress)*configuration.color_range.value.f32, configuration.saturation.value.f32, pixel); leds[i] = pixel_color; } } \ No newline at end of file diff --git a/src/light_modes/beta/waveform.h b/src/light_modes/beta/waveform.h index 249d4c2..8d7cc2e 100644 --- a/src/light_modes/beta/waveform.h +++ b/src/light_modes/beta/waveform.h @@ -14,13 +14,13 @@ void draw_waveform(){ float auto_scale = 1.0 / max_val; - if(configuration.mirror_mode == false){ + if(configuration.mirror_mode.value.u32 == false){ for(uint16_t i = 0; i < NUM_LEDS; i++){ float progress = float(i) / NUM_LEDS; float sample = clip_float(samples[i]) * auto_scale; CRGBF pixel_color = hsv( - configuration.color + (configuration.color_range*progress), - configuration.saturation, + configuration.color.value.f32 + (configuration.color_range.value.f32*progress), + configuration.saturation.value.f32, sample ); @@ -32,8 +32,8 @@ void draw_waveform(){ float progress = float(i) / (NUM_LEDS>>1); float sample = clip_float(samples[i]) * auto_scale; CRGBF pixel_color = hsv( - configuration.color + (configuration.color_range*progress), - configuration.saturation, + configuration.color.value.f32 + (configuration.color_range.value.f32*progress), + configuration.saturation.value.f32, sample ); diff --git a/src/light_modes/inactive/neutral.h b/src/light_modes/inactive/neutral.h index 2aa4944..7f28724 100644 --- a/src/light_modes/inactive/neutral.h +++ b/src/light_modes/inactive/neutral.h @@ -1,10 +1,10 @@ void draw_neutral() { - if(configuration.mirror_mode == true){ // Mirror mode + if(configuration.mirror_mode.value.u32 == true){ // Mirror mode for (uint16_t i = 0; i < (NUM_LEDS >> 1); i++) { float progress = num_leds_float_lookup[i<<1]; CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, 1.0 ); @@ -17,7 +17,7 @@ void draw_neutral() { float progress = num_leds_float_lookup[i]; CRGBF color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, 1.0 ); diff --git a/src/light_modes/inactive/starfield.h b/src/light_modes/inactive/starfield.h index 5df09f1..9ba23b1 100644 --- a/src/light_modes/inactive/starfield.h +++ b/src/light_modes/inactive/starfield.h @@ -10,7 +10,7 @@ void draw_starfield(){ float progress = (float)i / (float)(NUM_LEDS>>1); leds[i] = hsv( 1.0, - configuration.saturation, + configuration.saturation.value.f32, progress*1.0 ); } @@ -19,7 +19,7 @@ void draw_starfield(){ float progress = (float)i / (float)(NUM_LEDS>>1); leds[(NUM_LEDS >> 1) + i] = hsv( 1.0, - configuration.saturation, + configuration.saturation.value.f32, 1.0 + (progress*3.0) ); } @@ -43,7 +43,7 @@ void draw_starfield_real(){ float progress = (float)i / (float)num_stars; CRGBF dot_color = hsv( get_color_range_hue(progress), - configuration.saturation, + configuration.saturation.value.f32, star_brightness[i]*4.0 ); diff --git a/src/microphone.h b/src/microphone.h index 36264c8..9228cf3 100644 --- a/src/microphone.h +++ b/src/microphone.h @@ -107,25 +107,6 @@ void acquire_sample_chunk() { // Add new chunk to audio history waveform_locked = true; shift_and_copy_arrays(sample_history, SAMPLE_HISTORY_LENGTH, new_samples, CHUNK_SIZE); - - // If debug recording was triggered - if(audio_recording_live == true){ - int16_t out_samples[CHUNK_SIZE]; - for(uint16_t i = 0; i < CHUNK_SIZE; i += 4){ - out_samples[i+0] = new_samples[i+0] * 32767; - out_samples[i+1] = new_samples[i+1] * 32767; - out_samples[i+2] = new_samples[i+2] * 32767; - out_samples[i+3] = new_samples[i+3] * 32767; - } - memcpy(&audio_debug_recording[audio_recording_index], out_samples, sizeof(int16_t)*CHUNK_SIZE); - audio_recording_index += CHUNK_SIZE; - if(audio_recording_index >= MAX_AUDIO_RECORDING_SAMPLES){ - audio_recording_index = 0; - audio_recording_live = false; - broadcast("debug_recording_ready"); - save_audio_debug_recording(); - } - } // Used to sync GPU to this when needed waveform_locked = false; diff --git a/src/ota.h b/src/ota.h index 9dba5f8..ee866dc 100644 --- a/src/ota.h +++ b/src/ota.h @@ -9,7 +9,7 @@ bool update_running = false; String latest_version; -bool update_firmware(const char* url, update_type type, int16_t client_slot) { +bool update_firmware(const char* url, update_type type, PsychicWebSocketRequest *request) { http.begin(url); int32_t http_code = http.GET(); @@ -26,7 +26,7 @@ bool update_firmware(const char* url, update_type type, int16_t client_slot) { if (can_begin) { WiFiClient* stream = http.getStreamPtr(); - Update.onProgress([type, client_slot](size_t progress, size_t total) { + Update.onProgress([type, request](size_t progress, size_t total) { float percent = (progress / (total / 100)); char update_message[64]; @@ -39,7 +39,7 @@ bool update_firmware(const char* url, update_type type, int16_t client_slot) { snprintf(update_message, 64, "ota_filesystem_progress|%d", (int)percent); } - transmit_to_client_in_slot(update_message, client_slot); + request->client()->sendMessage(update_message); }); size_t written = 0; @@ -109,21 +109,21 @@ bool check_update(){ } } -void perform_update(int16_t client_slot){ +void perform_update(PsychicWebSocketRequest *request){ update_running = true; // Update firmware String new_firmware = "https://app.emotiscope.rocks/versions/" + latest_version + "/firmware.bin"; printf("DOWNLOADING/INSTALLING FIRMWARE UPDATE\n"); - update_firmware(new_firmware.c_str(), FLASH, client_slot); + update_firmware(new_firmware.c_str(), FLASH, request); // Update filesystem String new_filesystem = "https://app.emotiscope.rocks/versions/" + latest_version + "/littlefs.bin"; printf("DOWNLOADING/INSTALLING FILESYSTEM UPDATE\n"); - update_firmware(new_filesystem.c_str(), FILESYSTEM, client_slot); + update_firmware(new_filesystem.c_str(), FILESYSTEM, request); printf("UPDATE COMPLETE\n"); - delay(1000); + delay(100); printf("REBOOTING...\n"); delay(100); ESP.restart(); diff --git a/src/screensaver.h b/src/screensaver.h index 6cdc2b0..ac9c00f 100644 --- a/src/screensaver.h +++ b/src/screensaver.h @@ -14,8 +14,8 @@ bool inactive = false; void run_screensaver(){ profile_function([&]() { - if(configuration.screensaver == false){ return; } - if(light_modes[configuration.current_mode].type != LIGHT_MODE_TYPE_ACTIVE){ return; } + if(configuration.screensaver.value.u32 == false){ return; } + if(light_modes[configuration.current_mode.value.u32].type != LIGHT_MODE_TYPE_ACTIVE){ return; } float mag_sum = 0; for(uint16_t i = 0; i < NUM_FREQS; i++){ diff --git a/src/system.h b/src/system.h index 1eeda51..0409a35 100644 --- a/src/system.h +++ b/src/system.h @@ -30,8 +30,6 @@ void init_serial(uint32_t baud_rate) { } void check_serial() { - extern bool queue_command(const char* command, uint16_t length, uint8_t client_slot); - if(Serial.available() > 0){ char c = Serial.read(); @@ -39,7 +37,6 @@ void check_serial() { if(c == '\n'){ printf("Serial command received: %s\n", serial_buffer); - queue_command(serial_buffer, serial_buffer_index, 255); memset(serial_buffer, 0, 256); serial_buffer_index = 0; } @@ -110,8 +107,8 @@ void init_system() { init_vu(); // (vu.h) // Load sliders - load_sliders_relevant_to_mode(configuration.current_mode); + load_sliders_relevant_to_mode(configuration.current_mode.value.u32); // Load toggles - load_toggles_relevant_to_mode(configuration.current_mode); + load_toggles_relevant_to_mode(configuration.current_mode.value.u32); } \ No newline at end of file diff --git a/src/touch.h b/src/touch.h index af0fa7a..94f1c4b 100644 --- a/src/touch.h +++ b/src/touch.h @@ -189,17 +189,17 @@ void read_touch(){ } if(touch_pins[TOUCH_LEFT].hold_active == true && touch_pins[TOUCH_RIGHT].touch_active == false){ // Left hold active - configuration.color -= 0.0015; - if(configuration.color < 0.0){ - configuration.color += 1.0; + configuration.color.value.f32 -= 0.0015; + if(configuration.color.value.f32 < 0.0){ + configuration.color.value.f32 += 1.0; } save_config_delayed(); } else if(touch_pins[TOUCH_RIGHT].hold_active == true && touch_pins[TOUCH_LEFT].touch_active == false){ // Right hold active - configuration.color += 0.0015; - if(configuration.color > 1.0){ - configuration.color -= 1.0; + configuration.color.value.f32 += 0.0015; + if(configuration.color.value.f32 > 1.0){ + configuration.color.value.f32 -= 1.0; } save_config_delayed(); @@ -209,7 +209,7 @@ void read_touch(){ if(EMOTISCOPE_ACTIVE){ if(t_now_ms - last_mirror_mode_toggle >= 1000){ - configuration.mirror_mode = !configuration.mirror_mode; + configuration.mirror_mode.value.u32 = (bool)!(configuration.mirror_mode.value.u32); save_config_delayed(); last_mirror_mode_toggle = t_now_ms; } @@ -219,7 +219,7 @@ void read_touch(){ void render_touches(){ profile_function([&]() { - if(light_modes[configuration.current_mode].type == LIGHT_MODE_TYPE_SYSTEM){ return; } + if(light_modes[configuration.current_mode.value.u32].type == LIGHT_MODE_TYPE_SYSTEM){ return; } if(touch_pins[TOUCH_LEFT].touch_value > 0.001){ float glow_hue = 0.870; diff --git a/src/types.h b/src/types.h index 3009a53..6e78bc8 100644 --- a/src/types.h +++ b/src/types.h @@ -145,22 +145,35 @@ struct touch_pin { float touch_history[50]; // 5 seconds at 10 FPS }; +// union that stores the value of a config item +union config_value { + uint32_t u32; + int32_t i32; + float f32; +}; + +struct config_item { + char name[32]; + char pretty_name[32]; + config_value value; +}; + // Stores all of Emotiscope's configurable settings struct config { - float brightness; - float softness; - float color; - float warmth; - float color_range; - float speed; - float saturation; - float background; - int32_t current_mode; - bool mirror_mode; - bool screensaver; - bool temporal_dithering; - bool auto_color_cycle; - bool reverse_color_range; - float blur; - bool show_interface; + config_item brightness; + config_item softness; + config_item color; + config_item warmth; + config_item color_range; + config_item speed; + config_item saturation; + config_item background; + config_item current_mode; + config_item mirror_mode; + config_item screensaver; + config_item temporal_dithering; + config_item auto_color_cycle; + config_item reverse_color_range; + config_item blur; + config_item show_ui; }; \ No newline at end of file diff --git a/src/ui.h b/src/ui.h index c5ac91f..2f6d8c2 100644 --- a/src/ui.h +++ b/src/ui.h @@ -18,8 +18,8 @@ float ui_needle_position = 0.0; void draw_ui_overlay(){ profile_function([&]() { - if(light_modes[configuration.current_mode].type == LIGHT_MODE_TYPE_SYSTEM){ return; } - if(configuration.show_interface == false){ return; } + if(light_modes[configuration.current_mode.value.u32].type == LIGHT_MODE_TYPE_SYSTEM){ return; } + if(configuration.show_ui.value.u32 == false){ return; } if(overlay_size >= 0.01){ // ----------------------------- diff --git a/src/web_core.h b/src/web_core.h index 17ee229..0be53fd 100644 --- a/src/web_core.h +++ b/src/web_core.h @@ -4,7 +4,6 @@ void run_web() { dns_server.processNextRequest(); if (web_server_ready == true && wifi_config_mode == false) { - process_command_queue(); discovery_check_in(); // Write pending changes to LittleFS diff --git a/src/wireless.h b/src/wireless.h index cd3d522..d027c84 100644 --- a/src/wireless.h +++ b/src/wireless.h @@ -7,51 +7,13 @@ String WEB_VERSION = ""; -const IPAddress ap_ip(192, 168, 4, 1); // IP address for the ESP32-S3 in AP mode -const IPAddress ap_gateway(192, 168, 4, 1); // Gateway IP address, same as ESP32-S3 IP -const IPAddress ap_subnet(255, 255, 255, 0); // Subnet mask for the WiFi network DNSServer dns_server; // DNS server instance // Define a char array to hold the formatted MAC address string char mac_str[18]; // MAC address string format "XX:XX:XX:XX:XX:XX" + '\0' -// HTTPS not working yet, PsychicHTTP can't initialize the SSL server -bool app_enable_ssl = false; -const char server_cert[] = "-----BEGIN CERTIFICATE-----\n" - "MIIEIjCCAwqgAwIBAgISBH7YjHKyJu9WiS8x5r5AoQBbMA0GCSqGSIb3DQEBCwUA\n" - "MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\n" - "EwJSMzAeFw0yNDAzMTIyMjI1MTBaFw0yNDA2MTAyMjI1MDlaMBsxGTAXBgNVBAMT\n" - "EGVtb3Rpc2NvcGUucm9ja3MwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATQHjaY\n" - "I+CdZFEl7b4uLJQvM9wc4PQuP3bwNYT22xgF+vMqZan+dFPQ2aivqTQTmfpZf7P4\n" - "i5Zabvke7fLcVgL6o4ICEjCCAg4wDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQG\n" - "CCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTKbZV5\n" - "T6G16rxt/6U4ceZ47dH38DAfBgNVHSMEGDAWgBQULrMXt1hWy65QCUDmH6+dixTC\n" - "xjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9yMy5vLmxlbmNy\n" - "Lm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3JnLzAbBgNVHREE\n" - "FDASghBlbW90aXNjb3BlLnJvY2tzMBMGA1UdIAQMMAowCAYGZ4EMAQIBMIIBBAYK\n" - "KwYBBAHWeQIEAgSB9QSB8gDwAHYASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/\n" - "qznYhHMAAAGONPvyqwAABAMARzBFAiByFzLVHoKxCHjMzswH9uorSMDLaRT7R0Qd\n" - "p7GS/wRmxAIhAO+vULdM8/l57nfNbHTO7ZDaPNaHdXtnpB2iPZl1VV+RAHYA7s3Q\n" - "ZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZsAAAGONPvyZQAABAMARzBFAiEA\n" - "0N6+Jcg5MIQSY8npJf+z6Sos+YvL6oAgBct8ho45J5kCIF4W1k1QmJSDDbT7UvI5\n" - "6vM3mNME7+FDsv7Dx+SxXJpHMA0GCSqGSIb3DQEBCwUAA4IBAQAWNeX3A+1elo4H\n" - "HclveVrcw1vbJfJWIfN+GYr6EXzWlUtDWHQNzpwNZWy5KhizypJV2nKEMEaZrkMp\n" - "hg0nVfU1EIlT7gDmLrxLneZMig5G1HFuikf5iS28qasG+WWwlR6lOPKWmnGb+Eyg\n" - "N7KpKPOolfggrmt1n1PjR3CEI9b31ISNW1WiedFZf0WKfva8yhjH+vqM8H179z+H\n" - "j3Ly0aEo80dX4CtPhsvuS//Zp8ICeac6Bp7hiy45hOMJVba7e+khdXQOjA5NIf1w\n" - "Fg0zi3hBsQ1OuoKirhAXYgMvjhIqVR6hZQCl0Qo04OeGib12o1oIryun9XjElM7A\n" - "IAEFbV9H\n" - "-----END CERTIFICATE-----\n"; - -const char server_key[] = "-----BEGIN PRIVATE KEY-----\n" - "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgQhojjmRxKkBrJ2J+\n" - "N0xPI/w2QqYFwegoEvwHt2pNF/OhRANCAARM1A650C1wbnD3LDFeYEnBYJU9UG8x\n" - "4fFbE06zxFwt04nZJ9RLHu5uwKffSkZzhOAUAB+EjvA+9x4h4vbAM+nd\n" - "----------END PRIVATE KEY----------\n"; - PsychicHttpServer server; PsychicWebSocketHandler websocket_handler; -websocket_client websocket_clients[MAX_WEBSOCKET_CLIENTS]; volatile bool web_server_ready = false; int16_t connection_status = -1; @@ -120,124 +82,185 @@ void discovery_check_in() { } } -int16_t get_slot_of_client(PsychicWebSocketClient client) { - for (uint16_t i = 0; i < MAX_WEBSOCKET_CLIENTS; i++) { - if (websocket_clients[i].socket == client.socket()) { - return i; - } - } +bool load_section_at( char* section_buffer, char* command, int16_t* byte_index ){ + memset(section_buffer, 0, 128); - return -1; -} + int16_t output_index = 0; + bool solved = false; + bool hit_end_of_chunk = false; -PsychicWebSocketClient *get_client_in_slot(uint8_t slot) { - PsychicWebSocketClient *client = websocket_handler.getClient(websocket_clients[slot].socket); - if (client != NULL) { - return client; - } + while(solved == false){ + char current_byte = command[*byte_index]; - return NULL; -} + if(current_byte == '~' || current_byte == '\0'){ // 0 is EOF + hit_end_of_chunk = true; + solved = true; + } + else if(current_byte == '|'){ + hit_end_of_chunk = false; + solved = true; + } + else{ + // read data + section_buffer[output_index] = current_byte; + output_index++; + } -void init_websocket_clients() { - for (uint16_t i = 0; i < MAX_WEBSOCKET_CLIENTS; i++) { - websocket_clients[i] = { - -1, // int socket; - 0, // uint32_t last_ping; - }; + (*byte_index)++; } + + return hit_end_of_chunk; } -bool welcome_websocket_client(PsychicWebSocketClient client) { - bool client_welcome_status = true; - //uint32_t t_now_ms = millis(); +void parse_config_data(char* config_name, char* config_type, char* config_value, char* config_ui_type, char* config_preset_enabled){ + printf("CONFIG DATA: %s|%s|%s|%s|%s\n", config_name, config_type, config_value, config_ui_type, config_preset_enabled); - uint16_t current_client_count = 0; - int16_t first_open_slot = -1; - for (uint16_t i = 0; i < MAX_WEBSOCKET_CLIENTS; i++) { - if (websocket_clients[i].socket != -1) { - current_client_count += 1; - } - else { - if (first_open_slot == -1) { - first_open_slot = i; - } - } + if(fastcmp(config_type, "float")){ + float value = atof(config_value); + printf("FLOAT VALUE: %f\n", value); + //place_float_in_config_by_key( TBD ); } - - // If no room left for new clients - if (current_client_count >= MAX_WEBSOCKET_CLIENTS || first_open_slot == -1) { - client_welcome_status = false; + else if(fastcmp(config_type, "int")){ + int value = atoi(config_value); + printf("INT VALUE: %i\n", value); } - - // If there is room in the party, client is welcome and should be initialized - if (client_welcome_status == true) { - websocket_clients[first_open_slot] = { - client.socket(), // int socket; - t_now_ms, // uint32_t last_ping; - }; - printf("PLAYER WELCOMED INTO OPEN SLOT #%i\n", first_open_slot); + else if(fastcmp(config_type, "bool")){ + bool value = fastcmp(config_value, "true"); + printf("BOOL VALUE: %i\n", value); + } + else if(fastcmp(config_type, "string")){ + printf("STRING VALUE: %s\n", config_value); + } + else{ + printf("UNKNOWN CONFIG TYPE: %s\n", config_type); } - - return client_welcome_status; } -void websocket_client_left(uint16_t client_index) { - printf("PLAYER #%i LEFT\n", client_index); - PsychicWebSocketClient *client = get_client_in_slot(client_index); - if (client != NULL) { - client->close(); - } +void broadcast_emotiscope_state(){ + char output_string[2048]; + memset(output_string, 0, 2048); - websocket_clients[client_index].socket = -1; + // Packet Header + strcat(output_string, "EMO~"); } -void websocket_client_left(PsychicWebSocketClient client) { - int socket = client.socket(); - for (uint16_t i = 0; i < MAX_WEBSOCKET_CLIENTS; i++) { - if (websocket_clients[i].socket == socket) { - websocket_client_left((uint16_t)i); - break; +void parse_emotiscope_state(char* command, PsychicWebSocketRequest *request){ + printf("Parsing Emotiscope State...\n"); + int16_t num_bytes = strlen(command); + int16_t byte_index = 0; + + char section_buffer[128]; + memset(section_buffer, 0, 128); + + char chunk_type[32]; + memset(chunk_type, 0, 32); + + static int16_t config_data_index = 0; + + while(byte_index <= num_bytes){ + bool chunk_ended = load_section_at(section_buffer, command, &byte_index); + printf("LOADED SECTION: %s\n", section_buffer); + if(fastcmp(chunk_type, "config")){ + static char config_name[32]; + static char config_type[32]; + static char config_value[32]; + static char config_ui_type[32]; + static char config_preset_enabled[32]; + + if(config_data_index == 0){ + memcpy(config_name, section_buffer, 32); + config_data_index = 1; + } + else if(config_data_index == 1){ + memcpy(config_type, section_buffer, 32); + config_data_index = 2; + } + else if(config_data_index == 2){ + memcpy(config_value, section_buffer, 32); + config_data_index = 3; + } + else if(config_data_index == 3){ + memcpy(config_ui_type, section_buffer, 32); + config_data_index = 4; + } + else if(config_data_index == 4){ + memcpy(config_preset_enabled, section_buffer, 32); + config_data_index = 0; + + parse_config_data(config_name, config_type, config_value, config_ui_type, config_preset_enabled); + } } - } -} + else{ + printf("UNKNOWN CHUNK TYPE: %s\n", chunk_type); + } + + if(chunk_ended == true){ + printf("Chunk ended.\n"); + + if(byte_index < num_bytes){ + // Prepare for new chunk type + memset(chunk_type, 0, 32); + load_section_at(section_buffer, command, &byte_index); + memcpy(chunk_type, section_buffer, 32); + printf("NEW CHUNK TYPE: %s\n"); -void check_if_websocket_client_still_present(uint16_t client_slot) { - if (websocket_clients[client_slot].socket != -1) { - // make sure our client is still connected. - PsychicWebSocketClient *client = get_client_in_slot(client_slot); - if (client == NULL) { - websocket_client_left(client_slot); + config_data_index = 0; + } + else{ + printf("EOF\n"); + } } } } -void transmit_to_client_in_slot(const char *message, uint8_t client_slot) { - PsychicWebSocketClient *client = get_client_in_slot(client_slot); - if (client != NULL) { - printf("TX: %s\n", message); - client->sendMessage(message); +void init_web_server() { + const char *local_hostname = "emotiscope"; + if (MDNS.begin(local_hostname) == true) { + MDNS.addService("http", "tcp", 80); + } + else{ + Serial.println("Error starting mDNS"); } -} -void init_web_server() { - server.config.max_uri_handlers = 20; // maximum number of .on() calls + server.config.max_uri_handlers = 40; // maximum number of .on() calls server.listen(80); //WEB_VERSION = "?v=" + String(SOFTWARE_VERSION_MAJOR) + "." + String(SOFTWARE_VERSION_MINOR) + "." + String(SOFTWARE_VERSION_PATCH); - //server.serveStatic("/", LittleFS, "/"); + websocket_handler.onOpen([](PsychicWebSocketClient *client) { + printf("[socket] connection #%i connected from %s\n", client->socket(), client->remoteIP().toString().c_str()); + }); - server.on("/ws", &websocket_handler); + websocket_handler.onFrame([](PsychicWebSocketRequest *request, httpd_ws_frame *frame) { + // printf("[socket] #%d sent: %s\n", request->client()->socket(), (char*)frame->payload); + httpd_ws_type_t frame_type = frame->type; - server.on("/audio", [](PsychicRequest *request) { - String filename = "/audio.bin"; - PsychicFileResponse response(request, LittleFS, filename); + // If it's text, it might be a command + if (frame_type == HTTPD_WS_TYPE_TEXT) { + char* command = (char*)frame->payload; + printf("RX: %s\n", command); - return response.send(); + if(command[0] == 'E' && command[1] == 'M' && command[2] == 'O'){ + parse_emotiscope_state(command, request); + } + else{ + parse_command(command, request); + } + } + else { + printf("UNSUPPORTED WS FRAME TYPE: %d\n", (uint8_t)frame->type); + } + + return ESP_OK; + }); + + websocket_handler.onClose([](PsychicWebSocketClient *client) { + printf("[socket] connection #%i closed from %s\n", client->socket(), client->remoteIP().toString().c_str()); }); + server.on("/ws", &websocket_handler); + server.on("/mac", HTTP_GET, [](PsychicRequest *request) { return request->reply(mac_str); }); @@ -310,64 +333,11 @@ void init_web_server() { } else { result = request->reply(404); + printf("404: %s\n", path.c_str()); } return result; }); - const char *local_hostname = "emotiscope"; - if (MDNS.begin(local_hostname) == true) { - MDNS.addService("http", "tcp", 80); - } - else{ - Serial.println("Error starting mDNS"); - } - - websocket_handler.onOpen([](PsychicWebSocketClient *client) { - printf("[socket] connection #%i connected from %s\n", client->socket(), client->remoteIP().toString().c_str()); - - /* - if (welcome_websocket_client(client) == true) { - client->sendMessage("welcome"); - } - else { - // Room is full, client not welcome - printf("PLAYER WAS DENIED ENTRY (ROOM FULL)\n"); - client->close(); - } - */ - }); - - websocket_handler.onFrame([](PsychicWebSocketRequest *request, httpd_ws_frame *frame) { - // printf("[socket] #%d sent: %s\n", request->client()->socket(), (char*)frame->payload); - httpd_ws_type_t frame_type = frame->type; - - // If it's text, it might be a command - if (frame_type == HTTPD_WS_TYPE_TEXT) { - char* command = (char*)frame->payload; - printf("RX: %s\n", command); - - if(command[0] == 'E' && command[1] == 'M' && command[2] == 'O'){ - printf("Parsing Emotiscope State...\n"); - //parse_emotiscope_state(command, request); - } - else{ - parse_command(command, request); - } - } - else { - printf("UNSUPPORTED WS FRAME TYPE: %d\n", (uint8_t)frame->type); - } - - return ESP_OK; - }); - - websocket_handler.onClose([](PsychicWebSocketClient *client) { - printf("[socket] connection #%i closed from %s\n", client->socket(), client->remoteIP().toString().c_str()); - websocket_client_left(client); - }); - - init_websocket_clients(); - web_server_ready = true; } @@ -388,16 +358,18 @@ void get_mac(){ } void init_wifi() { + esp_wifi_set_ps(WIFI_PS_NONE); + if(wifi_config_mode == true){ WiFi.begin("testnet", "testpass"); get_mac(); WiFi.softAP("Emotiscope Setup"); - dns_server.start(53, "*", WiFi.softAPIP()); printf("Entered AP Mode: %s\n", WiFi.softAPIP().toString().c_str()); if (web_server_ready == false) { + dns_server.start(53, "*", WiFi.softAPIP()); init_web_server(); } } @@ -408,8 +380,6 @@ void init_wifi() { get_mac(); } - - esp_wifi_set_ps(WIFI_PS_NONE); } void handle_wifi() { @@ -482,7 +452,7 @@ void handle_wifi() { } } else{ - //printf("WIFI CONFIG MODE ACTIVE, NOT RECONNECTING\n"); + printf("WIFI CONFIG MODE ACTIVE, NOT RECONNECTING\n"); } }