Skip to content

Platforms

pschatzmann edited this page Oct 25, 2026 · 3 revisions

The library is header-only and is based on the AudioTools, so it can be used on all platforms which are supported by the AudioTools and which provide a network (or serial) connection. This page describes how the different platforms and network libraries are used and what has been tested.

Overview

Platform Network Status
Desktop (Linux) sockets via the Arduino Emulator, audio via miniaudio automated tests, interoperability tests with the official aoo library, command line tool
ESP32-S3 WiFi tested on hardware: sender and receiver (PCM and Opus), against the official aoo library
ESP32-P4 (Waveshare ESP32-P4-WIFI6) WiFi via the ESP32-C6 co-processor (esp-hosted) tested on hardware: receiver (PCM and Opus) with I2SCodecStream
ESP32, ESP32-S3, ESP32-C3, ESP32-C6, ESP32-P4 WiFi, Ethernet (ETH.h) all examples compile
ESP8266 WiFi sender and receiver examples compile
RP2040 (arduino-pico): Pico W, Pico 2 W WiFi, lwIP Ethernet (e.g. W5500lwIP) sender and receiver examples compile
Arduino UNO R4 WiFi WiFiS3 compiles with a provided WiFiUDP object
Arduino UNO R4 Minima, STM32 (Nucleo F767ZI) Arduino Ethernet library compiles
Arduino MKR WiFi 1010 (WiFiNINA) WiFiNINA not verified
RP2040 (Arduino Mbed OS core) - not supported: the AudioTools I2S driver of this core does not compile

"compiles" means that the sketch has been compiled, but not been tested on the hardware. The AOOReceiverTask (and its example) is only available on the ESP32 (or with FreeRTOS).

Network

All network libraries are used via AOOStreamUDP, which is a template on the UDP class: any class which provides the Arduino UDP API (begin, beginMulticast, parsePacket, beginPacket, endPacket, ...) can be used.

You can either let the stream create the UDP object

AOOStreamUDP udp(9999);  // creates a WiFiUDP

or provide your own UDP object:

EthernetUDP eth_udp;
AOOStreamUDP<EthernetUDP> udp(eth_udp, 9999);

The class which is created by default is defined by AOO_DEFAULT_UDP: it is WiFiUDP on the ESP32, ESP8266, RP2040 (arduino-pico) and the desktop. On all other platforms there is no default and you need to provide a UDP object (or define AOO_DEFAULT_UDP before including AOO.h), e.g. on the Arduino UNO R4 WiFi:

#include <WiFiS3.h>
WiFiUDP wifi_udp;
AOOStreamUDP<WiFiUDP> udp(wifi_udp, 9999);

AOOStreamUDP udp(9999) without the template arguments needs C++17: with older compilers (e.g. the SAMD core) write AOOStreamUDP<> udp(9999) or indicate the UDP class.

If no network is available, you can use AOOStreamSerial, which sends the messages over any serial connection (UART) with HDLC framing. This is limited by the baud rate (about 11 KB/s at 115200 baud), so it is only useful for low sample rates or Opus.

Keep the UDP packets below the network MTU: see Packet Size and MTU.

ESP32

The ESP32 is the best supported platform: the examples are using WiFi and I2S. Here you can also use the AOOReceiverTask, which receives the messages in a separate task on the other core.

  • WiFi: call WiFi.setSleep(false) after connecting: the power saving mode adds a lot of latency and causes packet loss.
  • Ethernet: with the Arduino ESP32 core 3.x the WiFiUDP class (NetworkUDP) also works with Ethernet (ETH.h), so you can just use the default AOOStreamUDP udp(9999) after ETH.begin().
  • Opus: increase the loop stack size (e.g. SET_LOOP_TASK_STACK_SIZE(30000)) and use complexity = 1 on the sender.
  • Logging: use the log level Warning: logging at Info level on a serial port with 115200 baud slows down the loop so much that the receiver can not keep up with the audio.
  • Fragmented packets: the lwIP stack of the Arduino ESP32 core does not reassemble IP fragments, so packets which are bigger than the MTU are dropped silently.

ESP32-P4

The ESP32-P4 has no radio: WiFi is provided by the ESP32-C6 co-processor via esp-hosted, which is transparent for the sketch. Select the correct chip revision in the board settings: the boards with a chip revision 3 or newer (e.g. the ROM reports esp32p4-eco7) need Chip Variant: v3.00 or newer (ChipVariant=postv3), otherwise the board ends up in a boot loop (CHIP_LP_WDT_RESET). E.g.

arduino-cli compile -u -p /dev/ttyACM0 \
  --fqbn esp32:esp32:esp32p4:ChipVariant=postv3,PSRAM=enabled,FlashSize=16M,PartitionScheme=huge_app \
  examples/aoo-receiver

The Waveshare ESP32-P4-WIFI6 prints the log via Serial0 (UART bridge) and can output the audio with an I2SCodecStream out(WaveshareESP32P4WIFI6). Set the volume to about 0.5 after out.begin(): the ES8311 driver maps the volume 1.0 to a digital gain of +32 dB (0.5 is about 0 dB), so music is clipped into white noise, while a sine still sounds clean.

out.begin(cfg_out);
out.setVolume(0.5);

ESP8266

The ESP8266 is used like the ESP32, but the WiFi is included with #include <ESP8266WiFi.h> (the examples do this automatically). Its WiFiUDP::beginMulticast() needs the interface address: this is handled by AOOStreamUDP. There is no AOOReceiverTask and with about 50 KB of free RAM you should use PCM (mono, low sample rate) and a small buffer_depth on the receiver.

RP2040 (arduino-pico)

The arduino-pico core provides WiFi (Pico W) and Ethernet (e.g. W5500lwIP, ENC28J60lwIP) via lwIP: both are used with the WiFiUDP class, so the default AOOStreamUDP works:

#include <W5500lwIP.h>
Wiznet5500lwIP eth(17);    // chip select pin
AOOStreamUDP<> udp(9999);  // WiFiUDP

void setup() {
  eth.begin();
  while (!eth.connected()) delay(100);
  ...
}

Don't use the Arduino Ethernet library on this core: it conflicts with the lwIP Ethernet of the core. The AOOReceiverTask is not available: use the AOOReceiver (e.g. on the second core with loop1()).

Other Platforms with Ethernet

On the other platforms (e.g. STM32, Arduino UNO R4) you can use an Ethernet shield (W5100/W5500) with the Arduino Ethernet library and provide the EthernetUDP object:

#include <SPI.h>
#include <Ethernet.h>
#include "AOO.h"
#include "AudioTools.h"

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
EthernetUDP eth_udp;
AOOStreamUDP<EthernetUDP> udp(eth_udp, 9999);
AOOReceiver aoo_receiver(1, udp);

void setup() {
  Ethernet.begin(mac);
  ...
}

On platforms with little RAM and no I2S support use PCM with a low sample rate and mono: decoding Opus needs about 50-100 KB of RAM.

Desktop

On the desktop the library is built with CMake using the Arduino Emulator: WiFiUDP is mapped to the sockets of the operating system and the audio is output via miniaudio. This is used for the automated tests and the command line tool. See Desktop Build & Tests.

Clone this wiki locally