Skip to content

Audio Output Example*

Tip

1. Overview*

Audio Output (DAC/SDM) sample App, demonstrating how to play local PCM audio data via DMA + double-buffer mechanism. The audio data comes from the hardcoded PCM array in test_wav.h (16kHz, 16bit, mono), and loops automatically after playback completes.

2. Features*

  • DMA double-buffer audio playback for seamless continuous output
  • Demonstrates cache coherence handling (gx_dcache_clean_range)
  • Volume control (0-100 mapped to -16dB ~ 0dB)
  • Automatic loop playback

3. Directory Structure*

app/audio_out_sample_app/
├── audio_out_sample_app.c  # Main program
├── app.mk                   # Build configuration
├── app.name                 # Kconfig option
└── test_wav.h               # Test PCM data (16kHz, 16bit, mono)
File Description
audio_out_sample_app.c Audio playback initialization, DMA configuration, double-buffer callback
app.mk Compiles audio_out_sample_app.c
app.name Defines CONFIG_APP_AUDIO_OUT option
test_wav.h Raw PCM audio data (174080 bytes)

4. Configuration*

4.1 Macro Definitions*

#define AUDIO_OUT_BUFFER_LEN  8192   // DMA buffer size, must be 64-byte aligned

The PCM data length is hardcoded in the code:

uint32_t g_all_len = 174080;   // Total byte count of PCM data in test_wav.h

4.2 Pin Configuration*

Pin Function Description
PAD 0 DAC_P DAC positive output
PAD 1 DAC_N DAC negative output

5. Working Principle*

5.1 Initialization Flow*

  1. Configure PAD 0/1 as DAC mode
  2. Enable AUDPCLK and AOUT clocks
  3. Initialize SDM, configure 16kHz mono PCM parameters
  4. Allocate 8KB DMA buffer
  5. Register frame callback _aout_new_frame_callback
  6. Enqueue the first PCM frame, enable audio routing

5.2 Double-Buffer Mechanism*

The 8KB buffer pool is divided into two 4KB halves:

Interrupt callback fills half A  →  DMA plays half A
                                  ↓
Interrupt callback fills half B  ←  DMA plays half B

Each time _aout_new_frame_callback is invoked, the other half is filled and re-enqueued, achieving seamless playback.

5.3 Event Handling*

This App does not use event-driven processing; all playback logic is completed in the DMA interrupt callback. app_event_response() is an empty implementation.

5.4 Main Loop*

app_task_loop() is an empty implementation.

6. Usage*

6.1 Compilation*

cp configs/example/app/8006_audio_out_sample_app.config .config
make defconfig
make clean; make

Or select via menuconfig:

make menuconfig
# OVP Application Settings → Applications Selection → Audio Out Sample

6.2 Flashing and Running*

cd tools/bootx/
./flash_nor.sh 0 -r 1000000

7. Expected Output*

The speaker loops playing the audio from test_wav.h.

8. Notes*

  1. Cache Coherence: Audio playback uses DMA to access memory directly without going through the Cache. gx_dcache_clean_range() must be called to flush the Cache before enqueuing each frame of data
  2. Buffer Alignment: AUDIO_OUT_BUFFER_LEN must be 64-byte aligned
  3. Interrupt Context: _aout_new_frame_callback executes in interrupt context and should not contain time-consuming operations
  4. PCM Parameters: The PCM data in test_wav.h is fixed at 16kHz, 16bit, mono format. Replacing audio data requires maintaining the same parameters
  5. Sleep/Wakeup Not Implemented: The current SDK does not support sleep functionality. app_suspend() and app_resume() can remain as empty implementations