Dante-interoperable AES67 audio-over-IP firmware for the ESP32-P4

Benjamin Harris 14421b5bea feat(dante): CMC device-announce responder 3 meses atrás
components 14421b5bea feat(dante): CMC device-announce responder 3 meses atrás
docs 07d7475cbd docs: mark pinout schematic-verified; note reference PDFs 3 meses atrás
main 14421b5bea feat(dante): CMC device-announce responder 3 meses atrás
.gitignore 55b0d95b52 Scaffold ESP-IDF project and vendor AES67 base 3 meses atrás
CLAUDE.md 07d7475cbd docs: mark pinout schematic-verified; note reference PDFs 3 meses atrás
CMakeLists.txt 55b0d95b52 Scaffold ESP-IDF project and vendor AES67 base 3 meses atrás
LICENSE 341c70786e first commit 3 meses atrás
README.md 14421b5bea feat(dante): CMC device-announce responder 3 meses atrás
sdkconfig.defaults 4d90ba54d7 Retarget to Waveshare ESP32-P4-ETH; confirm pinout 3 meses atrás

README.md

Dante / AES67 Audio-over-IP for ESP32-P4

Status: AES67 base vendored in, untested on hardware. The aes67-esp32p4 engine and a board-configurable app entry point are in place; not yet build-verified or run against real gear. Native Dante support is still at the notes stage.

Goal

A low-cost, network audio endpoint on the ESP32-P4 that can interoperate with Dante-based AV systems. In practice "Dante-interoperable" is being pursued in two phases:

  1. AES67 interop (primary target) — most Dante hardware from the last several years can send/receive AES67, so a solid AES67 endpoint already gets us into the same audio network as Dante gear.
  2. Native Dante protocol support (stretch goal) — Dante's proprietary discovery (mDNS records), control protocol (routing/subscription), and PTPv1 clocking, for talking to older or AES67-disabled Dante devices.

Why ESP32-P4

The original ESP32 (WiFi, Xtensa) can't hold AES67's ~1ms RTP packet timing tightly enough over WiFi to be spec-compliant. The P4 drops WiFi in favour of a real Ethernet MAC with hardware PTP timestamping, which is what makes sub-millisecond, spec-accurate AoIP achievable on this class of chip at all.

Two source projects this builds on

1. DatanoiseTV/aes67-esp32p4 — foundation (Apache-2.0)

This is what we fork from. It already solves the hard, P4-specific problems: hardware PTP timestamping via the EMAC, an I2S driver with APLL clock recovery, an RTP engine with an L2 hook that bypasses lwIP for latency, SAP/SDP, and mDNS/DNS-SD advertisement. Apache-2.0 means we can build on it freely, including for commercial client work.

2. teodly/inferno — protocol reference only (GPL-3.0-or-later / AGPL-3.0-or-later)

A full software Dante device implementation for Linux. We do not vendor or copy code from this repo. It's copyleft-licensed, and incorporating its code would obligate this whole firmware image to the same license — which rules out using it in closed commercial deliverables. Instead it's used as documentation: reading inferno_aoip to understand Dante's wire behaviour (mDNS service records, control-protocol framing, flow subscriptions) well enough to write an independent, clean-room implementation against the P4 component.

This licensing boundary is the most important constraint on this project. See CLAUDE.md for the hard rule any dev session (human or agent) needs to follow.

Hardware target

Target board: Waveshare ESP32-P4-ETH (product · wiki). Ethernet via IP101 GRI PHY (RMII); onboard ES8311 codec + NS4150B amplifier + microphone + 8Ω speaker connector; 32 MB PSRAM, 32 MB NOR flash. Pins below are verified against the board schematic (docs/esp32-p4_schematic_en.pdf) and are mirrored in main/board_config.h.

Function GPIO Notes
Ethernet MDC 31 IP101 GRI, PHY addr 1
Ethernet MDIO 52
Ethernet REF_CLK 50 50 MHz reference
Ethernet PHY_RST 51
I2S MCLK 13 18.432 MHz via APLL
I2S BCLK 12 bit clock
I2S LRCLK 10 word/frame clock
I2S DOUT 9 data out → ES8311 DAC
I2S DIN 11 data in ← ES8311 ADC / mic
PA Enable 53 active high (speaker amp)
I2C SCL / SDA 8 / 7 ES8311 control (addr 0x18)

Fixed EMAC RMII data pins (not software-configurable, listed for reference): TXD0/1 = 34/35, RXD0/1 = 30/29, TX_EN = 49, CRS_DV = 28.

Repo layout

components/aes67/   Forked from aes67-esp32p4 — AES67 engine (PTP, RTP, I2S, SAP/SDP, mDNS)
components/dante/    Clean-room Dante support (discovery now; ARC/CMC/flows/PTPv1 later)
main/                Application entry point, board config
docs/                Design notes, incl. clean-room Dante protocol notes
reference/           Local clones of both source repos, for reading only (gitignored, not part of this repo)

Build

Requires ESP-IDF v5.5+ with the ESP32-P4 target.

idf.py set-target esp32p4
idf.py build
idf.py flash monitor

components/aes67 is vendored in (from aes67-esp32p4, Apache-2.0) and main/ wires it up via main/board_config.h (pins confirmed for the Waveshare ESP32-P4-ETH). Not yet build-verified — needs an ESP-IDF v5.5+ toolchain.

Roadmap

  • Fork aes67-esp32p4's components/aes67 in as the starting point
  • Confirm pinout against actual target hardware (Waveshare ESP32-P4-ETH)
  • Build-verify with ESP-IDF v5.5+ (idf.py set-target esp32p4 build)
  • Get AES67 send/receive verified against real Dante gear in AES67 mode
  • Write clean-room Dante protocol notes (docs/dante-protocol-notes.md)
  • Prototype Dante mDNS discovery (components/dante, read-only browse)
  • Prototype Dante mDNS advertisement (_netaudio-arc/-cmc/-chan; gated off until ARC/CMC responders back it)
  • Prototype Dante CMC responder (device-announce, UDP 8800)
  • Prototype Dante ARC control protocol (routing/subscriptions, UDP 4440)
  • Investigate PTPv1 support alongside the existing PTPv2 stack

License

Apache-2.0 (see LICENSE), matching the aes67-esp32p4 base this project forks from.