Commit Graph

4 Commits

Author SHA1 Message Date
bsncubed c9e06da47c aes67_tx: mono sum; the source always delivers stereo
The pull callback's contract said "stream channels", but the player always
delivers stereo, so a 1-channel stream went out as L,R,L,R at half speed.
Sources now always deliver AES67_TX_SRC_CHANNELS (2); TX maps to the stream:
2 ch as is, 1 ch = (L+R)/2 in 64 bit with mono_sum (can't clip), else L.
Checked: mono packets 156 B, 1000/s, 48 samples each, SDP L24/48000/1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:26:48 +10:00
bsncubed bae6a8a2f9 Step 4.2: PTP-paced AES67 RTP sender with 1 kHz test tone
- aes67_tx: TX task woken by an esp_timer every packet time; sends every
  packet whose last sample is in the past (PTP time), RTP ts =
  (sample index from PTP + clk_offset) mod 2^32, packets aligned to
  multiples of the packet size. Sends only while PTP is locked; resyncs
  on lock, clock step or > 20 ms lag. L24/L16 big-endian, TTL/DSCP/
  multicast IF from config; a config save restarts TX.
- Built-in 1 kHz tone at -18 dBFS, phase from the PTP sample index;
  aes67_tx_set_source() pull callback for later sources (underruns
  counted, padded with silence). status: tx_packets, underruns.
- Verified with a receiver script on the PC: 1 ms L24 stereo 1000/s,
  0 gaps, ts step 48, tone -18.00 dBFS within 1.2 LSB of the ideal
  PTP-phased sine; also L16 mono 0.333 ms, 0.125 ms (8000/s) and 4 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 06:43:12 +10:00
bsncubed c2621f192a Step 2.2: config registry and NVS store, GET/POST /api/config
- aes67_web/cfg.c: cfg_register(group, defaults, validate, apply),
  cfg_override_defaults() for project defaults, cfg_get(). Stored values
  are loaded on register and merged over defaults (known keys, matching
  types). NVS keeps only keys that differ from defaults, one JSON string
  per group, so new firmware defaults still reach untouched settings.
- POST /api/config: type check against defaults, per-group validation,
  nothing stored unless every group passes; 400 "group.key: reason".
  Unknown keys/groups are ignored. Returns the new config.
- Core groups registered by their components with the UI's ranges:
  ptp (aes67_ptp), aes67 (aes67_tx, incl. multicast range and mono_sum
  => 1 channel), net/inet (aes67_net), log (aes67_syslog).
- Project: PROJECT.def overrides (hostname p4-aes67, name P4 AES67) and
  the "source" group in main/project_cfg.c.
- Config is stored only; nothing is applied live yet.
- Verified on board: defaults, valid save, 8 rejected values (nothing
  stored), persistence across reboot, restore to defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:00:55 +10:00
bsncubed bbfd3506bf Step 0: IDF project skeleton for esp32p4 with core component stubs
- Board checked with esptool: ESP32-P4 rev v1.3 (engineering silicon),
  32 MB GigaDevice flash. Rev <3 support and 32 MB set in sdkconfig.defaults.
- OTA partition layout: nvs, otadata, phy_init, ota_0/ota_1 (6 MB each,
  below 16 MB), coredump; no factory app. Partition table at 0x10000 so
  the bootloader can grow.
- App rollback enabled in the bootloader from the start.
- PROJECT_VER from git describe --tags --always --dirty.
- Empty stubs for the nine aes67_* core components; main logs version
  and chip revision.
- Built with ESP-IDF v5.5.5; not yet flashed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:47:21 +10:00