|
|
3 meses atrás | |
|---|---|---|
| .. | ||
| include | 3 meses atrás | |
| private_include | 3 meses atrás | |
| src | 3 meses atrás | |
| third_party | 3 meses atrás | |
| web | 3 meses atrás | |
| CMakeLists.txt | 3 meses atrás | |
| Kconfig | 3 meses atrás | |
| Kconfig.projbuild | 3 meses atrás | |
| NOTICE | 3 meses atrás | |
| README.md | 3 meses atrás | |
| idf_component.yml | 3 meses atrás | |
AES67 / RAVENNA audio-over-IP for the ESP32-P4.
An audio-over-IP endpoint — PTP-synchronized RTP audio with SAP/SDP discovery — running on a microcontroller-class SoC. The clock is disciplined off the ESP32-P4 EMAC's IEEE-1588 hardware timestamping, audio is moved by ISR-driven I2S DMA, and the receive path can bypass lwIP for low latency.
Interop-tested on real hardware against Merging Technologies SIENNA (commercial RAVENNA) and the aes67-linux-daemon running on a Raspberry Pi.
ESP32-P4 only. The implementation depends on the P4 EMAC's hardware PTP timestamping and the P4 I2S/APLL clocking. It is not portable to other ESP32 targets as-is.
The component is the AES67 engine plus the drivers it needs:
esp_vfs_l2tap receive path that reads RTP frames at L2 and
bypasses the lwIP socket layer for low-latency reception.a=ts-refclk, a=mediaclk, fractional ptime),
mDNS _ravenna._udp advertisement.The repository's main/
example shows the board bring-up (Ethernet/PHY, ES8311 codec) and one extra
integration: an esp_eth Rx hook that intercepts RTP frames in the
driver callback — before lwIP — for the absolute lowest latency (the ~0.7 ms
figure). That hook is example code you copy and adapt to your board, not a
component API. The component's own esp_vfs_l2tap path is the portable
low-latency option.
idf.py add-dependency "datanoisetv/aes67^2.6.0"
#include "aes67.h"
#include "aes67_session.h"
aes67_config_t cfg = AES67_CONFIG_DEFAULT();
cfg.net.eth_handle = my_eth_handle; /* you install esp_eth yourself */
aes67_node_handle_t node;
aes67_node_init(&cfg, &node);
aes67_node_start(node);
aes67_session_handle_t session;
aes67_node_get_session(node, &session);
uint8_t id;
aes67_session_add_source(session, "My Source", 2, AES67_CODEC_L24, &id);
/* add a sink from a discovered SDP: */
aes67_session_add_sink(session, "My Sink", remote_sdp_text, &id);
A complete, board-specific example (ESP32-P4-Nano + ES8311) lives in the repository.
Options live under AES67 RAVENNA Component and PTP Daemon
Configuration in idf.py menuconfig — max sources/sinks, channels,
sample rate, packet time, codec, RTP port, PTP domain, jitter-buffer depth,
PSRAM usage, and task priorities.
For low-latency audio the example's sdkconfig.defaults also enables
802.3x flow control (CONFIG_ETH_*), lwIP IRAM optimizations, and pins the
network tasks to core 0 — see the repository for the full set.
esp_eth Rx hook is example wiring, not a component
API (see above).To keep the component self-contained on the registry, it vendors two Apache-2.0 components, with their license headers and per-file provenance intact:
third_party/ptpd/ — a minimal IEEE-1588 PTP daemon (Apache NuttX
ptpd, ported to ESP-IDF by Espressif).third_party/esp_eth_time/ — the EMAC time-control wrapper from the
ESP-IDF ethernet/ptp example (Espressif).See NOTICE and the SPDX headers in those files.
Apache-2.0. See the SPDX headers and NOTICE.