Namespace: DadDrivers (external module) Files: AudioManager.h / AudioManager.cpp Directory: DAD_FORGE/Drivers Description: The AudioManager module manages the full-duplex stereo SAI interface of the STM32H.
📋 Module Description
The AudioManager module manages the SAI (Serial Audio Interface) of the STM32H microcontroller in full-duplex stereo mode. It handles both reading (recording) and writing (playback) of the audio signal in a high-performance, real-time manner, relying on interrupts and DMA transfers.
Main Features
Double-buffer management: The module uses a double-buffering technique to allow continuous audio processing without audible latency: while the DMA fills one buffer, the processor can process the other in parallel.
Optimized conversions: Automatic and efficient conversion between the native int32 format of the SAI and the float format used for audio processing (and vice versa).
🎯 Associated Enumerations and Structures
AudioBuffer
Element / Variable
Type / Value (if applicable)
Description
Right
float
Right channel audio data
Left
float
Left channel audio data
User-Defined Constant
AUDIO_BUFFER_SIZE: Size of the audio buffer, typically 4 samples (determines latency).
External callback for user audio processing (must be defined in user code). Receives raw incoming audio data (converted from int32 to float) and returns processed data.
Parameter(s)
Â
pIn
Pointer to input audio data in AudioBuffer format
pOut
Pointer to output AudioBuffer audio data to be filled by the user with the processed signal
Initializes and starts double-buffer audio processing. Configures input/output buffers (In, Out1, Out2), initializes DMA rxBuffer/txBuffer to zero, attaches SAI handles to DMA transfers, and enables completion interrupts. The pOut pointer is initialized to point to Out1 for the first output buffer. Returns HAL_OK if both DMA starts (Tx and Rx) succeed.
Parameter(s)
Â
phSaiTx
Pointer to the SAI handle configured for transmission (audio output)
phSaiRx
Pointer to the SAI handle configured for reception (audio input)
Return
HAL status code: HAL_OK success, HAL_ERROR DMA initialization failure
First stereo float audio output buffer for double-buffering (non-cached, 8-byte aligned)
Out2
AudioBuffer[AUDIO_BUFFER_SIZE]
Second stereo float audio output buffer for double-buffering (non-cached, 8-byte aligned)
pOut
volatile AudioBuffer*
Current pointer to the active output buffer (swapped after each DMA reception)
rxBuffer
int32_t[SAI_BUFFER_SIZE]
DMA buffer for SAI reception (int32 format, non-cached, 8-byte aligned)
txBuffer
int32_t[SAI_BUFFER_SIZE]
DMA buffer for SAI transmission (int32 format, non-cached, 8-byte aligned)
__phSaiTx
SAI_HandleTypeDef*
Globally stored transmission SAI handle for callbacks
__phSaiRx
SAI_HandleTypeDef*
Globally stored reception SAI handle for callbacks
The audio buffers used by the DMA are placed in a non-cached memory region. This arrangement is important because it avoids data inconsistency issues between the processor cache and the memory accessible by the DMA controller. Without this measure, the DMA could read or write stale data present in the cache, leading to audio artifacts or unpredictable behavior.
💡 Usage Example
#include"DadDrivers/AudioManager.h"
#include"main.h"// User audio processing callbackvoidMyAudioCallback(AudioBuffer*pIn,AudioBuffer*pOut){// Custom DSP processing (e.g., equalizer, effects)for(size_ti=0;i<AUDIO_BUFFER_SIZE;i++){pOut[i].Left=pIn[i].Left*1.5f;// Left channel gain x1.5pOut[i].Right=pIn[i].Right*1.5f;// Right channel gain x1.5// Safety clipping protectionif(pOut[i].Left>1.0f)pOut[i].Left=1.0f;if(pOut[i].Left<-1.0f)pOut[i].Left=-1.0f;if(pOut[i].Right>1.0f)pOut[i].Right=1.0f;if(pOut[i].Right<-1.0f)pOut[i].Right=-1.0f;}}intmain(){// SAI configuration (must be done before)SAI_HandleTypeDefhSaiTx;SAI_HandleTypeDefhSaiRx;HAL_SAI_Init(&hSaiTx,&hsai1);// Configure TxHAL_SAI_Init(&hSaiRx,&hsai2);// Configure Rx// Start audio processingif(StartAudio(&hSaiTx,&hSaiRx)!=HAL_OK){Error_Handler();}// Register user callbackAudioCallback=MyAudioCallback;// Main loop - audio runs in background via DMAwhile(1){// Non real-time processing, GUI, ...// Audio processing occurs in the HAL_SAI callbacks:// - HAL_SAI_TxCpltCallback: converts float->int32 for Tx// - HAL_SAI_RxCpltCallback: converts int32->float, applies callback, swaps buffer}return0;}
DAD_FORGE/DSP - Dad Design DSP Library Copyright (c) 2024-2026 Dad Design.