#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include <nvs_flash.h>
#include <nvs.h>
// Wi-Fi Credentials
const char* ssid = "ESP32_Hotspot";
const char* password = "your_password";
// Audio Configuration Structure
#define NUM_EQ_BANDS 7
typedef struct {
int32_t i2s_num_high;
int32_t i2s_num_mid;
int32_t i2s_num_sub;
float crossover_high;
float crossover_mid;
float crossover_sub;
int32_t routing_high;
int32_t routing_mid;
int32_t routing_sub;
float eq_gain[NUM_EQ_BANDS]; // Gain for each EQ band
} AudioChannelConfig;
AudioChannelConfig audio_config;
AsyncWebServer server(80);
// Workaround to store floats in NVS by converting them to strings
void nvs_set_float(nvs_handle_t nvs_handle, const char* key, float value) {
char str_value[32];
snprintf(str_value, sizeof(str_value), "%f", value);
nvs_set_str(nvs_handle, key, str_value);
}
float nvs_get_float(nvs_handle_t nvs_handle, const char* key, float default_value) {
size_t required_size;
nvs_get_str(nvs_handle, key, NULL, &required_size);
char* str_value = (char*)malloc(required_size);
nvs_get_str(nvs_handle, key, str_value, &required_size);
float value = atof(str_value);
free(str_value);
return value == 0 ? default_value : value;
}
void init_nvs() {
nvs_flash_init();
}
// Read configuration from NVS
void read_config_from_nvs() {
nvs_handle_t nvs_handle;
nvs_open("storage", NVS_READWRITE, &nvs_handle);
nvs_get_i32(nvs_handle, "i2s_num_high", &audio_config.i2s_num_high);
nvs_get_i32(nvs_handle, "i2s_num_mid", &audio_config.i2s_num_mid);
nvs_get_i32(nvs_handle, "i2s_num_sub", &audio_config.i2s_num_sub);
audio_config.crossover_high = nvs_get_float(nvs_handle, "crossover_high", 1000.0);
audio_config.crossover_mid = nvs_get_float(nvs_handle, "crossover_mid", 500.0);
audio_config.crossover_sub = nvs_get_float(nvs_handle, "crossover_sub", 200.0);
nvs_get_i32(nvs_handle, "routing_high", &audio_config.routing_high);
nvs_get_i32(nvs_handle, "routing_mid", &audio_config.routing_mid);
nvs_get_i32(nvs_handle, "routing_sub", &audio_config.routing_sub);
for (int i = 0; i < NUM_EQ_BANDS; i++) {
String param_name = "eq_gain" + String(i);
audio_config.eq_gain[i] = nvs_get_float(nvs_handle, param_name.c_str(), 0.0);
}
nvs_close(nvs_handle);
}
// Save configuration to NVS
void save_config_to_nvs() {
nvs_handle_t nvs_handle;
nvs_open("storage", NVS_READWRITE, &nvs_handle);
nvs_set_i32(nvs_handle, "i2s_num_high", audio_config.i2s_num_high);
nvs_set_i32(nvs_handle, "i2s_num_mid", audio_config.i2s_num_mid);
nvs_set_i32(nvs_handle, "i2s_num_sub", audio_config.i2s_num_sub);
nvs_set_float(nvs_handle, "crossover_high", audio_config.crossover_high);
nvs_set_float(nvs_handle, "crossover_mid", audio_config.crossover_mid);
nvs_set_float(nvs_handle, "crossover_sub", audio_config.crossover_sub);
nvs_set_i32(nvs_handle, "routing_high", audio_config.routing_high);
nvs_set_i32(nvs_handle, "routing_mid", audio_config.routing_mid);
nvs_set_i32(nvs_handle, "routing_sub", audio_config.routing_sub);
for (int i = 0; i < NUM_EQ_BANDS; i++) {
String param_name = "eq_gain" + String(i);
nvs_set_float(nvs_handle, param_name.c_str(), audio_config.eq_gain[i]);
}
nvs_commit(nvs_handle);
nvs_close(nvs_handle);
}
// Web server to serve the configuration page
void init_web_server() {
server.on("/config", HTTP_GET, [](AsyncWebServerRequest *request) {
String response = "<html><body><h2>7-Band Graphic EQ</h2><form action='/update' method='POST'>";
// EQ Sliders
const char* eq_labels[NUM_EQ_BANDS] = {"60Hz", "170Hz", "310Hz", "600Hz", "1kHz", "3kHz", "6kHz"};
for (int i = 0; i < NUM_EQ_BANDS; i++) {
response += "<label for='eq_band" + String(i) + "'>" + String(eq_labels[i]) + ": </label>";
response += "<input type='range' id='eq_band" + String(i) + "' name='eq_gain" + String(i) + "' min='-12' max='12' step='0.1' value='" + String(audio_config.eq_gain[i]) + "' oninput='document.getElementById(\"val" + String(i) + "\").innerText = this.value'>";
response += "<span id='val" + String(i) + "'>" + String(audio_config.eq_gain[i]) + "</span>dB<br>";
}
// Other settings (crossover, routing) can be added here similarly...
response += "<br><input type='submit' value='Update'></form></body></html>";
request->send(200, "text/html", response);
});
server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request) {
// Update EQ settings
for (int i = 0; i < NUM_EQ_BANDS; i++) {
String param_name = "eq_gain" + String(i);
if (request->hasParam(param_name, true)) {
audio_config.eq_gain[i] = request->getParam(param_name, true)->value().toFloat();
}
}
// Update other settings (crossover, routing)...
// Save updated configuration to NVS
save_config_to_nvs();
request->send(200, "text/html", "Configuration updated! <a href='/config'>Go back</a>");
});
server.begin();
}
// Main setup function
void setup() {
Serial.begin(115200);
init_nvs();
read_config_from_nvs();
// Set up the ESP32 as an Access Point
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
init_web_server();
}
// Main loop function
void loop() {
// Process audio with EQ, crossover, and routing...
}