---
title: "W5300 + I2S Audio Streaming Architecture Improvement"
url: "https://maker.wiznet.io/TheoIm/projects/w5300-i2s-audio-streaming-architecture-improvement/"
markdown_url: "https://maker.wiznet.io/TheoIm/projects/w5300-i2s-audio-streaming-architecture-improvement/md"
type: "UCC: User Created Content"
author: "baram"
author_url: "https://blog.naver.com/chcbaram/223137692801?trackingCode=blog_bloghome_searchlist"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "baram"
original_url: "https://blog.naver.com/chcbaram/223137692801?trackingCode=blog_bloghome_searchlist"
published: "2025-07-29"
language: "en"
hardware: ["WIZnet W5300"]
likes: 0
views: 1059
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# W5300 + I2S Audio Streaming Architecture Improvement

> For Embedded Developers Working on Real-Time Audio over Ethernet

Original author: baram (source: https://blog.naver.com/chcbaram/223137692801?trackingCode=blog_bloghome_searchlist)

## Components

- **WIZnet W5300** x 1 ([docs](https://docs.wiznet.io/Product/Chip/Ethernet/W5300))

## Article

## 🔍 Original Architecture: Command-Driven Direct I2S Transmission

In the initial system, audio data sent from a PC is received by the **W5300 Ethernet controller**. The MCU then immediately forwards the data to the I2S peripheral via `i2sWrite()`. This approach tightly couples reception and playback.

### ✅ Pros:

Simple and easy to implement

Minimal latency in ideal conditions

### ❌ Cons:

**Tightly coupled timing**: audio data must be written exactly when I2S is ready

**Risk of underrun or data loss**, especially if transmission is delayed

**Compressed audio codecs** like OPUS or ADPCM introduce decoding latency → causes playback instability

---

## 🔄 Improved Architecture: Asynchronous Audio Queue Buffer

To solve timing issues, the system introduces an **intermediate 8KB audio buffer**, located inside the `cmdAudio` module. This buffer decouples network reception from I2S output.

### Key Components:

**Socket buffer (W5300):** 8KB

**Audio queue buffer (cmdAudio):** 8KB

**I2S ring buffer:** 4KB

---

## 🧠 Why It Works

Removes the dependency between **command timing and I2S availability**

Supports **buffered playback** for compressed codecs

Allows for **background processing**, such as FFT or sample conversion

Enables **flexible streaming** with minimal jitter

---

## 🧩 Code Overview: Key Functions

### 1. `cmdThreadUpdate()` — Core processing loop

```c
bool cmdThreadUpdate(void)
{
  for (int i = 0; i < CMD_DRIVER_MAX_CH; i++) {
    if (cmd[i].is_init == true) {
      if (cmdReceivePacket(&cmd[i]) == true) {
        ret |= cmdAudioProcess(&cmd[i]);
      }
      cmdAudioUpdate(&cmd[i]);  // Runs continuously in background
    }
  }
}
```

---

### 2. `cmdAudioReady()` — Returns available space in buffer

```c
static void cmdAudioReady(cmd_t *p_cmd)
{
  data.u32D = (AUDIO_Q_BUF_LEN - qbufferAvailable(&audio_q)) - 1;
  data.u32D = data.u32D - (data.u32D % 2);
}
```

---

### 3. `cmdAudioWrite()` — Writes to audio buffer only

```c
static void cmdAudioWrite(cmd_t *p_cmd, bool resp)
{
  memcpy(&file_index, &p_cmd->packet.data[0], 4);
  length = (p_cmd->packet.length - 4) / 2;
  qbufferWrite(&audio_q, (uint8_t *)p_buf, length);
}
```

---

### 4. `cmdAudioUpdate()` — Sends data to I2S when ready

```c
if (state == STATE_BEGIN)
{
  q_Len = qbufferAvailable(&audio_q);
  length = cmin(q_Len, p_type->availableForWrite(p_type->ch));

  if (length > 0) {
    qbufferRead(&audio_q, (uint8_t *)p_buf, length);
    p_type->write(p_type->ch, (int16_t *)p_buf, length);
  }
}
```

---

### 5. `cmdAudioInit()` — Abstracting I2S/SAI using function pointers

```c
audio_type[AUDIO_TYPE_I2S].write = i2sWrite;
audio_type[AUDIO_TYPE_SAI].write = saiWrite;
```

---

## 🎯 Where Can This Architecture Be Applied?

| MCU | Interface | Highlights |
| --- | --- | --- |
| STM32 Series | I2S / SAI | Hardware audio blocks, DMA-friendly |
| NXP i.MX RT | I2S / SAI | High-performance RTOS streaming |
| **RP2040 / RP2350** | **PIO I2S** | Software I2S via PIO + DMA (low-cost, flexible) |
| ESP32 | I2S | Integrated I2S with Wi-Fi capability |

---

## 💡 Why This Matters

This buffered streaming structure enables:

✅ Codec-ready architecture (e.g., OPUS, ADPCM)

✅ Decoupled design for robust audio playback

✅ Multi-platform MCU support

✅ Real-time DSP/FFT possibilities in background

---

## 🚀 Even Better with W6300: A Modern, SPI-Based Alternative

While the W5300 delivers excellent performance, it relies on a **parallel bus**, which requires many MCU GPIOs and introduces routing complexity. An alternative is **WIZnet’s W6300**, which uses **QSPI** (Quad SPI) for high-speed Ethernet.

### W6300 Advantages:

| Feature | W5300 (Parallel) | **W6300 (QSPI)** |
| --- | --- | --- |
| Interface type | parallel bus | QSPI (4-wire QSPI) |
| MCU compatibility | GPIO-heavy, timing-sensitive | QSPI |
| Max throughput | ~80Mbps | ~91 Mbps @ Quad QSPI |
| PCB design | Complex | Simple, compact |
| Peripheral SPI possibility | Limited | Supports basic SPI using Single QSPI mode(2-wire) |
| RP2040 & RP2350 integration | Possible | **Possible** |

If you're redesigning your audio streaming system — especially on a compact or resource-constrained board — **W6300 is a modern, viable replacement for W5300**.

---

Source: https://maker.wiznet.io/TheoIm/projects/w5300-i2s-audio-streaming-architecture-improvement/
