Add live VU-meter readback via ADAU1701 Data Capture Register
Implements GET /api/audio/levels, reading all six 1×RTA level-detector cells on demand (no background polling, no caching -- only runs when called, per explicit request this session). The read mechanism is the ADAU1701's documented Data Capture Register (address 2074/0x081A, datasheet Rev.0 pp.30,36: write a (program-step, register-select) pair to configure what the register mirrors, then read back a 3-byte 5.19 twos-complement value). The per-meter program- step indices are taken verbatim from SigmaStudio's own compiler output (Firmware/ADAU1701-Firmware/IC 1_DigiRadioFinale/net_list_out2/ trap.dat), not invented -- the datasheet explicitly says these indices must come from that compiler-generated file. Confirmed live: all six points return distinct, plausible dBFS values, and the output meters track a master-volume change. Also folds two pieces of live user feedback into the app brief: the volume slider should reach +12 dB (the firmware's real ceiling), not stop at 0 dB, and the new levels endpoint is what a "VU meter" UI section should poll instead of faking one. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -971,6 +971,39 @@ esp_err_t audioBeepPostHandler(httpd_req_t* req)
|
||||
return httpd_resp_send(req, json.c_str(), json.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief audioLevelsGetHandler — serve GET /api/audio/levels as JSON.
|
||||
*
|
||||
* @dname audioLevelsGetHandler
|
||||
* @param req HTTP request handle from esp_http_server.
|
||||
* @return ESP_OK on success, or an esp_err_t error code.
|
||||
* @pubstate Reads all six 1×RTA level meters live on every call -- no
|
||||
* background polling, no caching.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
esp_err_t audioLevelsGetHandler(httpd_req_t* req)
|
||||
{
|
||||
auto* ctx = routeContextFrom(req);
|
||||
if (ctx == nullptr || ctx->audio == nullptr) {
|
||||
httpd_resp_set_status(req, "503 Service Unavailable");
|
||||
return httpd_resp_send(req, nullptr, 0);
|
||||
}
|
||||
|
||||
const auto levels = ctx->audio->readLevels();
|
||||
if (!levels) {
|
||||
const std::string json = core::serializeAudioErrorJson("dsp_failed");
|
||||
httpd_resp_set_status(req, "500 Internal Server Error");
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
return httpd_resp_send(req, json.c_str(), json.size());
|
||||
}
|
||||
|
||||
const std::string json = core::serializeAudioLevelsJson(*levels);
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
return httpd_resp_send(req, json.c_str(), json.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief dspParamsGetHandler — serve GET /api/dsp/params as JSON.
|
||||
*
|
||||
@@ -2252,6 +2285,14 @@ std::expected<void, NetError> SetupWebServer::start(
|
||||
};
|
||||
httpd_register_uri_handler(server_, &audioBeepUri);
|
||||
|
||||
const httpd_uri_t audioLevelsUri = {
|
||||
.uri = "/api/audio/levels",
|
||||
.method = HTTP_GET,
|
||||
.handler = audioLevelsGetHandler,
|
||||
.user_ctx = routeCtx,
|
||||
};
|
||||
httpd_register_uri_handler(server_, &audioLevelsUri);
|
||||
|
||||
const httpd_uri_t dspParamsUri = {
|
||||
.uri = "/api/dsp/params",
|
||||
.method = HTTP_GET,
|
||||
|
||||
Reference in New Issue
Block a user