Audio sur i.MX8M Plus
Guide complet du sous-systeme audio : SAI, ALSA, DSP HiFi4, NPU, effets temps reel, multivoie TDM, integration codec TI TAC5212, et pipelines de traitement.
Vue d’ensemble
L’i.MX8M Plus integre l’un des sous-systemes audio les plus complets de la famille i.MX. Il combine des interfaces serie haute performance (SAI), un DSP Cadence HiFi4 dedie au traitement audio, un NPU pour l’inference IA, et un convertisseur de frequence asynchrone (EASRC).
Architecture audio
Aperçu du pipeline cible
Voici le pipeline complet que nous allons construire dans ce tutoriel. Chaque bloc sera detaille dans les sections suivantes.
Voici le pipeline audio complet multivoie 8 canaux avec 4x TAC5212 sur SAI7 en TDM. Ce flow represente un cas reel de traitement audio embarque : capture multicanal, pre-traitement DSP, inference IA sur le NPU, post-traitement DSP avec EQ et exciter, puis sortie vers les DAC.
Configuration materielle
4 codecs TAC5212 partagent un seul bus TDM sur SAI7 (1 ligne TX, 1 ligne RX). Le TAC5212 #0 est en mode Controller (master) : il genere les signaux BCLK et FSYNC. Les 3 autres sont en mode Target (slave). Chaque codec occupe 2 slots TDM, pour un total de 8 canaux ADC + 8 canaux DAC sur un seul SAI.
graph TD
subgraph BUS["Bus TDM partage — 1 fil TX, 1 fil RX"]
direction LR
B1["BCLK = 12.288 MHz
genere par TAC #0"]
B2["FSYNC = 48 kHz
genere par TAC #0"]
B3["SDIN : i.MX8MP TX → codecs"]
B4["SDOUT : codecs TX → i.MX8MP"]
end
BUS --- T0 & T1 & T2 & T3
T0["TAC5212 #0
MASTER — I2C 0x48
Slot 0-1"]
T1["TAC5212 #1
SLAVE — I2C 0x49
Slot 2-3"]
T2["TAC5212 #2
SLAVE — I2C 0x4A
Slot 4-5"]
T3["TAC5212 #3
SLAVE — I2C 0x4B
Slot 6-7"]
T0 --- IO0["Mic/Ligne
HP/Ampli"]
T1 --- IO1["Mic/Ligne
HP/Ampli"]
T2 --- IO2["Mic/Ligne
HP/Ampli"]
T3 --- IO3["Mic/Ligne
HP/Ampli"]
style BUS fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style T0 fill:#fef3c7,stroke:#d97706,stroke-width:2px
style T1 fill:#f0fdf4,stroke:#10b981
style T2 fill:#f0fdf4,stroke:#10b981
style T3 fill:#f0fdf4,stroke:#10b981
style IO0 fill:#fff,stroke:#cbd5e1
style IO1 fill:#fff,stroke:#cbd5e1
style IO2 fill:#fff,stroke:#cbd5e1
style IO3 fill:#fff,stroke:#cbd5e1
Etape par etape : du micro a la sortie
Le flux audio traverse 7 etapes. Voici le detail de chacune :
Etape 1 — Capture analogique (monde reel → codec)
Les signaux analogiques (microphones, instruments, lignes) arrivent sur les entrees differentielles des 4 TAC5212. Chaque codec effectue la conversion analogique-numerique (ADC) a 24 bits, jusqu’a 192 kHz, avec un SNR de 119 dB. Le PGA (Programmable Gain Amplifier) integre au TAC5212 ajuste le gain d’entree par canal.
Etape 2 — Transport TDM (codec → SAI7)
Les 8 canaux PCM sont multiplexes dans le temps sur un seul fil (SDOUT). Chaque codec emet ses 2 slots pendant la fenetre temporelle qui lui est assignee. Le SAI7 de l’i.MX8MP recoit les 8 slots sur sa ligne RX unique et les demultiplexe en 8 canaux PCM en memoire via SDMA (DMA).
Etape 3 — Pre-traitement DSP HiFi4 (encodage, preparation)
Le DSP HiFi4 (800 MHz) recupere les 8 canaux PCM bruts depuis la DRAM partagee. Il effectue le pre-traitement necessaire avant l’inference IA :
- DC Block : supprime la composante continue residuelle de chaque canal
- HPF 80 Hz : filtre passe-haut pour eliminer les infra-sons (rumble, vent)
- Gain / Normalisation : ajuste le niveau de chaque canal a une reference commune
- Fenêtrage + FFT : decoupe le signal en frames de 25 ms avec hop de 10 ms, calcule la FFT
- Extraction de features : calcule les coefficients MFCC (40 bandes Mel) ou le spectrogramme pour le NPU
- Encodage format NPU : convertit les features en tenseur INT8 quantifie pour le VX Delegate
graph LR
RX["SAI7 FIFO RX
8ch PCM brut"] --> DC["DC Block
par canal"] --> HPF["HPF 80 Hz
par canal"] --> GAIN["Gain
normalisation"]
style RX fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style DC fill:#f0fdf4,stroke:#10b981
style HPF fill:#f0fdf4,stroke:#10b981
style GAIN fill:#f0fdf4,stroke:#10b981
graph LR
WIN["Fenetrage
25 ms / hop 10 ms"] --> FFT["FFT"] --> MFCC["MFCC
40 bins Mel"] --> Q["Quantize
INT8"] --> OUT["Tenseur → DRAM
pret pour NPU"]
style WIN fill:#fef3c7,stroke:#d97706
style FFT fill:#fef3c7,stroke:#d97706
style MFCC fill:#fef3c7,stroke:#d97706
style Q fill:#fef3c7,stroke:#d97706
style OUT fill:#faf5ff,stroke:#7c3aed,stroke-width:2px
Temps de traitement : < 2 ms pour 8 canaux @ 800 MHz
Etape 4 — Inference NPU (traitement IA)
Le NPU VIP8000 (2.3 TOPS) execute le modele de reseau de neurones. Le CPU A53 orchestre le transfert des tenseurs et declenche l’inference via le VX Delegate de TensorFlow Lite. Le NPU travaille sur les features preparees par le DSP, pas sur le PCM brut.
- RNNoise / DTLN : calcule un masque de gain spectral par bande de frequence pour chaque canal — les bandes contenant du bruit sont attenuees, les bandes utiles sont preservees
- Keyword Detection : detecte un mot-cle dans le flux (ex: « Hey Device ») et declenche une action
- Beamforming neuronal : estime la direction d’arrivee du son et focalise la captation
graph TD
IN["Tenseur INT8
depuis DRAM partagee"]
TF["TFLite + VX Delegate
NPU VIP8000, 2.3 TOPS"]
RNN["RNNoise INT8
40 MFCC → 40 gains
spectraux par canal"]
KWD["KWD INT8
MFCC → score mot-cle
> 0.85 = detecte"]
G["gains_spectral[8][40]
8 canaux x 40 bandes"]
K["kwd_score
notification CPU"]
DRAM["DRAM partagee
→ DSP post-traitement"]
IN --> TF
TF --> RNN & KWD
RNN --> G
KWD --> K
G & K --> DRAM
style IN fill:#faf5ff,stroke:#7c3aed
style TF fill:#faf5ff,stroke:#7c3aed,stroke-width:2px
style RNN fill:#fef3c7,stroke:#d97706,stroke-width:2px
style KWD fill:#fef3c7,stroke:#d97706,stroke-width:2px
style G fill:#f0fdf4,stroke:#10b981
style K fill:#fff7ed,stroke:#f59e0b
style DRAM fill:#eff6ff,stroke:#2563eb
Temps d’inference : ~5 ms par frame (pipeline, non bloquant)
Etape 5 — Post-traitement DSP HiFi4 (decodage, effets, mixage)
Le DSP recupere les gains spectraux du NPU et les applique au signal temporel via un filtrage overlap-add. Puis il enchaine les effets audio en temps reel :
- Application du masque NPU : multiplie chaque bande spectrale par le gain NPU (debruitage)
- IFFT + Overlap-Add : reconstruit le signal temporel debruite
- EQ parametrique IIR : 5 bandes biquad par canal (bass, low-mid, mid, high-mid, treble)
- Exciter : genere des harmoniques pour enrichir le son (saturation douce + filtre passe-haut)
- DRC multi-bande : compresseur 3 bandes (bass / mid / treble) avec attack/release independants
- Mixage : combine les 8 canaux traites en N canaux de sortie (stereo, 5.1, 7.1, ou custom)
- Limiteur de sortie : brickwall limiter a -1 dBFS pour proteger les transducteurs
graph TD
IN["Gains NPU + PCM pre-traite
8 canaux depuis DRAM"]
M["1. Masque spectral
IFFT(FFT(ch) × gains[ch])
Overlap-add, 8 canaux"]
EQ["2. EQ parametrique IIR
5 bandes biquad par canal
Low Shelf 80Hz · Peaking 250/1k/4kHz · High Shelf 12kHz"]
EX["3. Exciter
HPF 2kHz → soft clip (tanh) → mix
Wet/dry : 15-25%"]
DRC["4. DRC multi-bande
20-250Hz ratio 3:1 · 250-4kHz ratio 2:1
4k-20kHz ratio 4:1"]
MIX["5. Mixage matriciel
8ch in → N ch out
Matrice configurable"]
LIM["6. Limiteur brickwall
-1 dBFS"]
OUT["8ch PCM traites
→ SAI7 TX FIFO"]
IN --> M --> EQ --> EX --> DRC --> MIX --> LIM --> OUT
style IN fill:#faf5ff,stroke:#7c3aed
style M fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style EQ fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style EX fill:#fef3c7,stroke:#d97706,stroke-width:2px
style DRC fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style MIX fill:#eff6ff,stroke:#2563eb
style LIM fill:#fef2f2,stroke:#ef4444,stroke-width:2px
style OUT fill:#eff6ff,stroke:#2563eb,stroke-width:2px
Temps de traitement total : < 3 ms pour 8 canaux @ 800 MHz
Etape 6 — Transport TDM sortie (SAI7 → codecs DAC)
Le SAI7 TX emet les 8 canaux traites sur la ligne SDIN. Chaque TAC5212 ne lit que les 2 slots qui lui sont assignes et ignore les autres.
graph LR
SAI["SAI7 TX
8ch PCM traites"]
subgraph FRAME["Trame TDM — 1 frame FSYNC = 8 slots x 32 bits"]
direction LR
S0["Slot 0
ch L"]
S1["Slot 1
ch R"]
S2["Slot 2
ch L"]
S3["Slot 3
ch R"]
S4["Slot 4
ch L"]
S5["Slot 5
ch R"]
S6["Slot 6
ch L"]
S7["Slot 7
ch R"]
end
SAI --> S0
S0 & S1 --> D0["TAC5212 #0
DAC"]
S2 & S3 --> D1["TAC5212 #1
DAC"]
S4 & S5 --> D2["TAC5212 #2
DAC"]
S6 & S7 --> D3["TAC5212 #3
DAC"]
style SAI fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style FRAME fill:#f8fafc,stroke:#94a3b8
style D0 fill:#fef3c7,stroke:#d97706,stroke-width:2px
style D1 fill:#f0fdf4,stroke:#10b981
style D2 fill:#f0fdf4,stroke:#10b981
style D3 fill:#f0fdf4,stroke:#10b981
Chaque codec ne lit que ses 2 slots et ignore les autres (haute impedance).
Etape 7 — Conversion DAC et sortie analogique
Chaque TAC5212 convertit ses 2 canaux PCM en signal analogique via ses DAC 24-bit (120 dB SNR). Les sorties differentielles alimentent des amplificateurs de puissance ou des casques.
Schema recapitulatif du pipeline complet
graph TD
IN["🎤 8x Microphones / Lignes
Monde reel analogique"]
ADC["TAC5212 x4 — ADC
8ch analogique → 8ch PCM 24-bit
119 dB SNR, 48 kHz"]
RX["SAI7 RX — TDM 8 slots
DMA interne AudioMix
Pas de SDMA, pas de DDR"]
PRE["DSP HiFi4 @ 800 MHz
PRE-TRAITEMENT ~2 ms
DC Block → HPF 80 Hz → Gain
FFT → MFCC 40 bins → Quantize INT8"]
NPU["NPU VIP8000 — 2.3 TOPS
INFERENCE IA ~5 ms
RNNoise : 40 gains spectraux
KWD : score mot-cle"]
POST["DSP HiFi4 @ 800 MHz
POST-TRAITEMENT ~3 ms
Masque NPU → EQ 5 bandes IIR
Exciter → DRC 3 bandes
Mixage → Limiteur -1 dBFS"]
TX["SAI7 TX — TDM 8 slots
DMA interne AudioMix"]
DAC["TAC5212 x4 — DAC
8ch PCM → 8ch analogique
120 dB SNR"]
OUT["🔊 8x Haut-parleurs / Amplis
Monde reel analogique"]
IN --> ADC --> RX --> PRE
PRE -- "tenseur features
via DRAM partagee" --> NPU
NPU -- "gains spectraux[8][40]
via DRAM partagee" --> POST
POST --> TX --> DAC --> OUT
style IN fill:#fff,stroke:#94a3b8,stroke-width:1px
style ADC fill:#fef3c7,stroke:#d97706,stroke-width:2px
style RX fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style PRE fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style NPU fill:#faf5ff,stroke:#7c3aed,stroke-width:2px
style POST fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style TX fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style DAC fill:#fef3c7,stroke:#d97706,stroke-width:2px
style OUT fill:#fff,stroke:#94a3b8,stroke-width:1px
SAI (Serial Audio Interface)
Le SAI (Synchronous Audio Interface) est le peripherique de transport audio numerique de l’i.MX8MP. Chaque SAI supporte I2S, Left-Justified, Right-Justified et TDM (Time Division Multiplexing).
Caracteristiques par SAI
- Modes : I2S, Left-Justified, Right-Justified, TDM/DSP-A, TDM/DSP-B
- Largeur : 8 a 32 bits par slot
- TDM : jusqu’a 32 slots par frame
- Frequences : 8 kHz a 384 kHz
- Master / Slave : BCLK et FSYNC independants
- Data lines : 1 a 4 lignes de donnees TX/RX selon le SAI
- DMA : via SDMA, un canal par direction
- FIFO : 128 mots (32 bits) par direction
Mapping SAI sur i.MX8MP
| SAI | Adresse base | Data lines | Usage typique | Acces DSP |
|---|---|---|---|---|
| SAI1 | 0x30C10000 | 1 TX + 1 RX | Codec audio principal (WM8960 sur EVK) | Non |
| SAI2 | 0x30C20000 | 1 TX + 1 RX | Codec secondaire, Bluetooth audio | Non |
| SAI3 | 0x30C30000 | 1 TX + 2 RX | Codec externe, TDM multi-canal | Non |
| SAI5 | 0x30C50000 | 4 TX + 4 RX | HDMI RX (eARC), multi-canal 8ch+ | Non |
| SAI6 | 0x30C60000 | 1 TX + 1 RX | Interne — lien DSP HiFi4 | Oui |
| SAI7 | 0x30C70000 | 1 TX + 1 RX | DSP HiFi4 — codec externe TDM (4x TAC5212) | Oui |
SAI6 & SAI7 : le chemin direct vers le DSP
C’est le point le plus important de l’architecture audio i.MX8MP et il est tres mal documente par NXP. Comprendre la difference entre SAI1-3/SAI5 et SAI6/SAI7 est essentiel pour concevoir une carte electronique audio performante.
Le probleme : SAI1-3, SAI5 (chemin CPU)
Les SAI « normaux » (SAI1, SAI2, SAI3, SAI5) sont connectes au bus AXI principal du SoC. L’audio suit ce chemin :
graph TD
C1["Codec externe"] --> C2["SAI1/2/3/5"]
C2 --> C3["Bus AXI principal
partage GPU, USB, ETH..."]
C3 --> C4["SDMA
32 canaux DMA"]
C4 --> C5["DDR DRAM
buffer ALSA"]
C5 --> C6["CPU A53
Linux kernel"]
C6 --> C7["App userspace"]
style C1 fill:#fff,stroke:#94a3b8
style C2 fill:#fef2f2,stroke:#ef4444,stroke-width:2px
style C3 fill:#fef2f2,stroke:#ef4444,stroke-width:2px
style C4 fill:#fef2f2,stroke:#ef4444
style C5 fill:#fef2f2,stroke:#ef4444
style C6 fill:#fef2f2,stroke:#ef4444
style C7 fill:#fff,stroke:#94a3b8
❌ Contention bus AXI
❌ Double copie SAI→DDR→DSP
❌ Xruns sous charge CPU
❌ CPU ne peut pas dormir
graph TD
D1["Codec externe
4x TAC5212"] --> D2["SAI7"]
D2 --> D3["Bus interne AudioMix
dedie, sans contention"]
D3 --> D4["DSP HiFi4 @ 800 MHz
acces direct FIFO"]
D4 --> D5["DTCM / ITCM
256 KB, 1 cycle"]
style D1 fill:#fff,stroke:#94a3b8
style D2 fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style D3 fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style D4 fill:#fef3c7,stroke:#d97706,stroke-width:2px
style D5 fill:#f0fdf4,stroke:#10b981
✅ Bus dedie AudioMix
✅ Zero copie, FIFO direct
✅ Deterministe, zero xrun
✅ CPU A53 peut dormir
La solution : SAI6 & SAI7 (chemin DSP direct)
SAI6 et SAI7 sont a l’interieur du bloc AudioMix, un sous-systeme materiel dedie a l’audio. Ce bloc a son propre bus interne qui connecte directement les SAI au DSP HiFi4, sans passer par le bus AXI principal ni par le CPU A53.
Architecture du bloc AudioMix
Le bloc AudioMix (aussi appele Audio Subsystem) est un domaine d’alimentation et d’horloge separe dans le SoC i.MX8MP. Il contient :
graph TD
subgraph AUDIOMIX["AudioMix Subsystem"]
direction TB
subgraph SAI_EXT["SAI externes"]
direction LR
SAI1["SAI1
ext"]
SAI2["SAI2
ext"]
SAI3["SAI3
ext"]
SAI5["SAI5
ext"]
end
SAI1 & SAI2 & SAI3 & SAI5 --> AXI
SAI1 & SAI2 & SAI3 & SAI5 -.-> INTBUS
AXI["Bus AXI principal
vers CPU A53 / DDR"]
INTBUS["Bus interne AudioMix
dedie, sans contention"]
subgraph SAI_DSP["SAI internes DSP"]
direction LR
SAI6["SAI6
DSP IPC"]
SAI7["SAI7
DSP + codec ext"]
end
INTBUS --> SAI6 & SAI7
SAI6 & SAI7 --> DSP["DSP HiFi4
Cadence @ 800 MHz
DTCM 256 KB / ITCM 256 KB"]
subgraph PERIPH["Peripheriques audio"]
direction LR
MICFIL["MICFIL
8ch PDM"]
EASRC["EASRC
4ch SRC"]
PLL["Audio PLL1/PLL2
+ clock gates"]
end
end
AXI --> A53["CPU Cortex-A53
Linux / DDR"]
style AUDIOMIX fill:#f8fafc,stroke:#2563eb,stroke-width:2px
style SAI_EXT fill:#eff6ff,stroke:#93c5fd
style SAI_DSP fill:#f0fdf4,stroke:#6ee7b7
style PERIPH fill:#fff,stroke:#e2e8f0
style AXI fill:#fef2f2,stroke:#ef4444,stroke-width:2px
style INTBUS fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style DSP fill:#fef3c7,stroke:#d97706,stroke-width:2px
style A53 fill:#fef2f2,stroke:#ef4444
Point cle : SAI1-3 et SAI5 transitent par le bus AXI (rouge) vers le CPU A53 et la DDR. SAI6 et SAI7 ont un chemin direct (vert) vers le DSP HiFi4 via le bus interne AudioMix.
Pourquoi SAI7 pour les TAC5212 ?
Le choix de connecter les 4 TAC5212 sur SAI7 (et pas SAI1 ou SAI3) a des consequences majeures sur les performances :
| Critere | SAI1-3 (chemin CPU) | SAI7 (chemin DSP direct) |
|---|---|---|
| Latence entree → DSP | 5-25 ms (Linux scheduling + SDMA + DDR) | < 100 µs (DMA interne, FIFO direct) |
| Latence round-trip | 15-50 ms | < 1 ms (DSP seul) |
| Determinisme | Non-deterministe (Linux, IRQ, scheduling) | Deterministe (firmware DSP, boucle fixe) |
| Xruns | Possibles sous charge CPU | Impossibles (DSP dedie) |
| CPU A53 load | ~5-15% (IRQ, SDMA, ALSA, copies) | 0% (le DSP fait tout) |
| Mode sleep | Impossible (A53 doit rester actif) | A53 peut dormir, le DSP continue |
| Contention bus | Partage AXI avec GPU, USB, ETH, … | Bus dedie AudioMix |
| Acces donnees | DDR : ~100 ns par acces | DTCM : 1 cycle (~1.25 ns @ 800 MHz) |
SAI6 vs SAI7 : differences
| Caracteristique | SAI6 | SAI7 |
|---|---|---|
| Data lines | 1 TX + 1 RX | 1 TX + 1 RX |
| Acces DSP | Oui (chemin direct) | Oui (chemin direct) |
| Pins externes | Disponibles mais limites (partage pads) | Disponibles via remapping SAI2 pads |
| Usage typique | Lien interne DSP ↔ A53 (IPC audio) | Codec externe via DSP (TDM / I2S) |
| SOF support | Oui (DAI backend) | Oui (DAI backend) |
SAI6 est souvent utilise comme un « pont » audio interne : le CPU A53 envoie des donnees audio au DSP via SAI6 (par exemple un flux MP3 a decoder). SAI7 est le choix naturel pour connecter un codec externe quand on veut que le DSP traite l’audio directement, sans passer par Linux.
Firmware DSP : comment ca marche concretement
Le DSP HiFi4 execute un firmware (SOF ou NXP imx-audio-framework) qui accede directement aux registres FIFO de SAI7 :
Impact sur la conception de la carte
Horloges audio (PLL)
L’i.MX8MP possede deux PLL audio fractionnaires qui generent les horloges MCLK, BCLK et LRCLK pour les SAI.
| PLL | Frequence typique | Multiples cibles | Usage |
|---|---|---|---|
| AUDIO_PLL1 | 393.216 MHz | 8 kHz, 16k, 32k, 48k, 96k, 192k, 384k | Famille 48 kHz (standard) |
| AUDIO_PLL2 | 361.2672 MHz | 11.025k, 22.05k, 44.1k, 88.2k, 176.4k | Famille 44.1 kHz (CD audio) |
Arbre d’horloge SAI
Configuration DTS des horloges
EASRC (Enhanced Asynchronous Sample Rate Converter)
L’EASRC est un convertisseur de frequence d’echantillonnage hardware a 4 canaux. Il permet de convertir entre des domaines d’horloge differents sans artefacts (filtrage anti-alias integre).
| Parametre | Specification |
|---|---|
| Nombre de canaux | 4 (paires de contextes IN/OUT) |
| Ratio de conversion | 1:8 a 8:1 (ex: 8 kHz ↔ 192 kHz) |
| Resolutions | 16, 20, 24, 32 bits |
| Frequences | 8 kHz a 384 kHz |
| Mode | Asynchrone (domaines d’horloge independants) |
| Firmware | firmware-imx (easrc-imx8mn.bin) |
Cas d’usage
- Convertir un flux eARC (192 kHz) vers la sortie codec (48 kHz)
- Synchroniser des sources avec des horloges differentes (USB audio + SAI)
- Reechantillonner avant traitement DSP/NPU (normaliser a 16 kHz pour un modele IA)
MICFIL (Microphones PDM)
Le MICFIL (Microphone Interface) capture directement les signaux de microphones PDM (Pulse Density Modulation) sans codec externe. Il integre un decimateur et un filtre CIC.
| Parametre | Specification |
|---|---|
| Canaux | 8 canaux PDM (4 paires stereo) |
| Frequences | 16 kHz, 22.05 kHz, 44.1 kHz, 48 kHz |
| Resolutions | 16, 24 bits (apres decimation) |
| Qualite | Filtre DC offset, HPF integre |
| Detection | Voice Activity Detection (VAD) hardware |
Integration TI TAC5212
Le TAC5212 de Texas Instruments est un codec audio stereo haute performance parfaitement adapte a l’i.MX8MP pour des applications audio professionnelles et industrielles.
Famille TI TAx5212
| Variante | Type | Description |
|---|---|---|
| TAC5212 | Codec (ADC+DAC) | Stereo ADC 119dB + stereo DAC 120dB |
| TAA5212 | ADC seul | Stereo ADC 119dB (capture uniquement) |
| TAD5212 | DAC seul | Stereo DAC 120dB (lecture uniquement) |
| TAC5412-Q1 | Codec auto | Version automotive (AEC-Q100) |
Connexion hardware (4x TAC5212 sur SAI7 TDM)
Multi-codec TDM (4x TAC5212 sur SAI7)
Audio multivoie / TDM
Configuration TDM dans le driver SAI
Synchronisation sur SAI7
graph TD
MASTER["TAC5212 #0
Controller (master)
PLL interne
Genere BCLK + FSYNC"]
BUS["BCLK + FSYNC
bus TDM commun"]
SAI["SAI7
slave"]
T1["TAC5212 #1
target"]
T2["TAC5212 #2
target"]
T3["TAC5212 #3
target"]
MASTER --> BUS
BUS --> SAI & T1 & T2 & T3
style MASTER fill:#fef3c7,stroke:#d97706,stroke-width:2px
style BUS fill:#f0fdf4,stroke:#10b981,stroke-width:2px
style SAI fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style T1 fill:#f0fdf4,stroke:#10b981
style T2 fill:#f0fdf4,stroke:#10b981
style T3 fill:#f0fdf4,stroke:#10b981
Le codec master garantit un jitter minimal sur BCLK/FSYNC, critique pour le SNR de 119 dB.
Pourquoi un codec master plutot que le SAI master ?
Dans une architecture TDM multi-codec, il y a 3 options pour generer les horloges BCLK et FSYNC :
| Option | Source BCLK/FSYNC | Avantages | Inconvenients |
|---|---|---|---|
| 1. SAI master (i.MX8MP genere) |
SAI7 du SoC | Simple a configurer dans le DTS Pas de dependance sur un codec externe |
Jitter eleve : les PLL du SoC (AUDIO_PLL1/2) introduisent un jitter de ~200-500 ps, car elles derivent d’un oscillateur systeme multi-usage Degradation SNR : le jitter sur BCLK se traduit directement en bruit de phase sur la conversion ADC/DAC Routage PCB complexe : BCLK sort du SoC, va vers 4 codecs — les traces longues ajoutent du skew |
| 2. Codec master (TAC5212 #0 genere) |
PLL interne du TAC5212 #0 (pas de MCLK — horloge autonome) |
Jitter ultra-faible : la PLL audio du TAC5212 est optimisee pour l’audio, jitter < 50 ps RMS SNR maximal : 119 dB — les horloges sont generees au plus pres des convertisseurs Routage court : BCLK/FSYNC partent du codec #0 directement vers ses voisins sur le bus TDM Un seul domaine d’horloge : tous les codecs + SAI7 sont synchronises sur la meme source |
Le codec #0 doit demarrer en premier (sequence de boot) Si le codec #0 tombe, tout le bus TDM s’arrete |
| 3. Oscillateur externe (horloge independante) |
Oscillateur audio dedie sur le PCB | Jitter minimal (crystal oscillator) Independant du SoC |
Composant supplementaire, cout PCB Un signal d’horloge de plus a router Rarement necessaire avec un codec de qualite |
Conclusion : l’option 2 (codec master) est le choix standard dans l’industrie pour les raisons suivantes :
1. Qualite d’horloge superieure
Le TAC5212 integre une PLL audio dediee concue specifiquement pour generer des horloges a faible jitter. Contrairement aux PLL du SoC i.MX8MP qui doivent aussi piloter des bus memoire, des interfaces USB, Ethernet, etc., la PLL du codec n’a qu’un seul role : generer BCLK et FSYNC avec un jitter minimal.
Le jitter sur BCLK est le facteur limitant numero 1 du SNR d’un convertisseur ADC/DAC. Un jitter de 500 ps sur un signal audio a 20 kHz avec un DAC 24-bit degrade le SNR d’environ 6-10 dB. Avec le TAC5212 en master (jitter < 50 ps), on conserve les 119 dB de SNR annonces par Texas Instruments.
2. Simplicite de synchronisation multi-codec
Avec un seul codec generant BCLK/FSYNC :
- Tous les codecs voient exactement le meme front montant de BCLK — pas de desynchronisation entre canaux
- Les 3 codecs target n’ont rien a configurer cote horloge : ils detectent automatiquement BCLK et se verrouillent dessus
- Le SAI7 du i.MX8MP est aussi en mode slave : il recoit BCLK/FSYNC et n’a pas besoin de configurer ses propres PLL audio
- Pas de probleme de clock domain crossing : un seul domaine d’horloge pour tout le bus TDM
3. Routage PCB optimal
En mode codec master, les signaux BCLK et FSYNC sont generes physiquement au milieu du bus TDM, la ou sont les codecs. Le trajet est court :
4. Comportement standard I2S/TDM
La specification I2S et TDM prevoit qu’un seul device genere les horloges (le bus master). Dans la majorite des designs audio professionnels et embarques, c’est le codec qui est master, pas le SoC. Les raisons :
- Le codec connait ses propres contraintes de timing (setup/hold sur SDIN/SDOUT)
- Les drivers Linux ALSA/ASoC supportent nativement le mode
SND_SOC_DAIFMT_CBP_CFP(codec generates bit clock and frame sync) - Le device tree est plus simple : pas besoin de configurer les PLL audio du SoC
5. Changement de frequence d’echantillonnage simplifie
Un avantage majeur du mode codec master : changer la frequence d’echantillonnage ne necessite qu’une seule commande I2C vers le codec #0. Sa PLL interne recalcule automatiquement BCLK et FSYNC, et tous les devices du bus (targets + SAI7) suivent instantanement sans aucune reconfiguration.
| Codec master (TAC5212 #0) | SAI master (i.MX8MP) | |
|---|---|---|
| Passer de 48 kHz a 96 kHz | 1 ecriture I2C sur le registre PLL du codec #0 BCLK passe de 12.288 a 24.576 MHz automatiquement FSYNC passe de 48 a 96 kHz Les targets et SAI7 suivent sans intervention |
Reprogrammer AUDIO_PLL1 dans le CCM du SoC Recalculer les diviseurs SAI7 (MCLK DIV, BIT CLK DIV) Risque d’affecter d’autres peripheriques partageant la meme PLL Necessite potentiellement un arret/relance du flux DMA |
| Support multi-rate (44.1 / 48 / 96 / 192 kHz) |
Le TAC5212 supporte nativement 8 a 768 kHz Un seul registre a changer : SAMPLE_RATE_CFGLa PLL interne gere les deux familles (44.1 et 48 kHz) |
Le SoC a 2 PLL audio (AUDIO_PLL1 pour 48x, AUDIO_PLL2 pour 44.1x) Switcher de famille necessite de changer de PLL source Complexite supplementaire dans le driver fsl_sai.c |
| Runtime switch (changement a chaud) |
Possible via snd_soc_dai_set_sysclk()Le codec reconfigure sa PLL en ~1 ms Transition propre (mute automatique pendant le relock) |
Necessite clk_set_rate() sur la PLL du CCMTemps de relock PLL SoC : 5-10 ms Risque de glitch audible si le flux n’est pas coupe |
En resume, avec le codec master, le changement de sample rate est une operation locale qui ne touche qu’un seul composant (le TAC5212 #0 via I2C). Toute la chaine se reconfigure en cascade, sans intervention logicielle sur les 3 targets ni sur le SoC.
6. Tolerance aux pannes et demarrage
Le seul inconvenient du mode codec master est la dependance au codec #0 pour tout le bus TDM. En pratique, cela se gere facilement :
- Sequence de boot : le driver pcm6240 initialise d’abord le codec #0, puis les 3 targets. Dans le device tree, l’ordre des noeuds codec garantit la sequence.
- Detection de panne : si BCLK disparait, le SAI7 genere une interruption
BCLK_LOSTque le driver peut intercepter pour tenter un reset du codec #0. - Redondance : dans les systemes critiques, on peut configurer un second codec en standby master via I2C, pret a prendre le relais si le #0 ne repond plus (non implemente dans cet exemple).
Driver Linux : pcm6240 (famille TAx5212)
Le TAC5212 est supporte par le driver kernel pcm6240, un driver generique qui couvre 20+ codecs TI de la meme famille (PCM6240, PCM6260, TAA5212, TAD5212, TAC5212, TAC5412-Q1, etc.).
Localisation dans les sources kernel
Configuration kernel
Integration dans Yocto
Pour activer le driver dans votre BSP Yocto i.MX8MP, ajoutez un fragment de configuration kernel dans votre layer :
Verification du driver au boot
Device Tree (DTS)
Activation SAI7 avec pinmux
Node SAI7
Exemples DTS complets
Exemple 1 : TAC5212 simple (I2S stereo sur SAI7)
Exemple 2 : 4x TAC5212 en TDM sur SAI7 (8 canaux)
Exemple 3 : SAI7 + EASRC + HDMI
Kernel config audio
ALSA / ASoC
Le sous-systeme audio Linux repose sur ALSA (Advanced Linux Sound Architecture) et son extension ASoC (ALSA System on Chip) qui decompose le driver en trois composants :
| Composant | Role | Exemple i.MX8MP |
|---|---|---|
| Platform driver | DMA et interface materielle | snd-soc-fsl-sai, imx-pcm-dma |
| Codec driver | Pilote du codec audio (ADC/DAC) | snd-soc-wm8960, snd-soc-pcm6240 (TAC5212) |
| Machine driver | Lien entre platform et codec | snd-soc-imx-card, simple-audio-card |
DAPM (Dynamic Audio Power Management)
DAPM gere automatiquement l’alimentation des widgets audio. Seuls les chemins audio actifs sont alimentes, economisant l’energie.
Commandes ALSA
Lister les cartes et peripheriques
Lecture (aplay)
Capture (arecord)
Controle mixer (amixer / tinymix)
ALSA avance
Configuration asound.conf
Mesurer la latence
HiFi4 DSP
Le Cadence HiFi4 DSP est un processeur de signal numerique dedie, optimise pour le traitement audio. Il tourne a 800 MHz et dispose de son propre bus AXI, DTCM/ITCM et acces a la DRAM partagee.
| Parametre | Specification |
|---|---|
| Coeur | Cadence Tensilica HiFi4 |
| Frequence | 800 MHz |
| Architecture | VLIW, 2x MAC 32×32, 4x MAC 16×16 |
| ITCM | 64 Ko (instructions, acces cycle unique) |
| DTCM | 64 Ko (donnees, acces cycle unique) |
| DRAM partagee | Acces a la DRAM via AXI |
| Peripheriques | SAI6, SAI7 (acces direct) |
| Communication | Mailbox (MU) + shared memory + rpmsg |
| Firmware load | remoteproc ou custom loader |
Communication ARM ↔ DSP
graph LR
subgraph A53["Cortex-A53 (Linux)"]
direction TB
APP["Application
(aplay, gst-launch)"]
ALSA["ALSA / ASoC"]
RPMSG_A["rpmsg driver"]
SHM_A["Shared Memory"]
APP --> ALSA --> RPMSG_A --> SHM_A
end
subgraph DSP["HiFi4 DSP"]
direction TB
FW["Firmware DSP
(SOF / NXP fw)"]
PIPE["Audio Pipeline"]
RPMSG_D["rpmsg-lite"]
SHM_D["Shared Memory"]
FW --> PIPE --> RPMSG_D --> SHM_D
end
RPMSG_A -- "MU (Mailbox)" --- RPMSG_D
SHM_A -- "DRAM (DMA)" --- SHM_D
style A53 fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style DSP fill:#fef3c7,stroke:#d97706,stroke-width:2px
Firmware NXP (imx-audio-framework)
NXP fournit son propre framework DSP (imx-audio-framework) qui tourne sur le HiFi4. Il est oriente decodage audio avec offloading du CPU.
Codecs supportes (decodage DSP)
| Codec | Librairie DSP | Formats |
|---|---|---|
| MP3 | lib_dsp_mp3_dec.so | MPEG-1/2 Layer III, 8-48 kHz |
| AAC | lib_dsp_aac_dec.so | AAC-LC, HE-AAC v1/v2, 8-48 kHz |
| FLAC | lib_dsp_flac_dec.so | FLAC 1.0, 16/24-bit, jusqu’a 192 kHz |
| Vorbis | lib_dsp_vorbis_dec.so | Ogg Vorbis, 8-48 kHz |
| SBC | lib_dsp_sbc_dec.so | SBC (Bluetooth audio) |
| PCM/WAV | natif | PCM brut, 8-384 kHz, 16/24/32 bits |
Architecture du framework NXP
graph LR
subgraph LINUX["Linux (A53)"]
direction TB
APP2["Application
(aplay, gst-launch)"]
WRAP["dsp_wrapper
lib_dsp_wrap.so"]
RPMSG2["rpmsg char driver"]
SHM2["shared memory (DRAM)"]
APP2 --> WRAP --> RPMSG2 --> SHM2
end
subgraph DSP2["DSP (HiFi4)"]
direction TB
FW2["dsp_framework"]
SRC["audio_source"]
DEC["decoder
(MP3/AAC/FLAC)"]
PP["post_process"]
SINK["audio_sink (SAI7)"]
FW2 --> SRC --> DEC --> PP --> SINK
RPMSG3["rpmsg-lite"]
SBUF["shared buffer"]
RPMSG3 --> SBUF
end
RPMSG2 -- "MU" --- RPMSG3
SHM2 -- "DMA" --- SBUF
style LINUX fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style DSP2 fill:#fef3c7,stroke:#d97706,stroke-width:2px
Utilisation
SOF (Sound Open Firmware)
Sound Open Firmware est un projet open-source (Linux Foundation) qui fournit un firmware DSP complet avec un pipeline audio configurable. SOF est supporte sur i.MX8MP et represente l’avenir du traitement audio embarque.
Firmware NXP
- Proprietaire
- Oriente decodage audio
- Codecs fixes (MP3, AAC, FLAC…)
- Pas d’effets configurables
- Pipeline statique
- Mieux documente par NXP
SOF
- Open-source (BSD-3)
- Pipeline audio complet et flexible
- EQ (IIR/FIR), DRC, Volume, Mixer
- Beamforming (TDFB)
- Topologies dynamiques
- Base Zephyr RTOS sur HiFi4
- Communaute active (Intel + NXP)
Build SOF pour i.MX8MP
Installer SOF sur la cible
Composants SOF disponibles
| Composant | Description | Cas d’usage |
|---|---|---|
| Volume | Controle de gain numerique par canal | Mixage, fade in/out, mute |
| Mixer | Mixage multi-source (N entrees → 1 sortie) | Superposer musique + voix + notif |
| MUX/DEMUX | Routage de canaux, selection de source | Router mic vers enregistrement ou communication |
| IIR EQ | Egaliseur a reponse impulsionnelle infinie | Bass boost, treble, correction de salle |
| FIR EQ | Egaliseur a reponse impulsionnelle finie | Filtre passe-bas/haut precis, crossover |
| DRC | Compresseur de dynamique | Limiter, compresseur, noise gate |
| Multiband DRC | DRC multi-bande (3 bandes) | Mastering, loudness, protection HP |
| TDFB | Time Domain Fixed Beamformer | Array de microphones, rejection bruit directionnel |
| SRC | Sample Rate Converter | Conversion de frequence DSP (alternative a EASRC) |
| DCBLOCK | Filtre DC offset removal | Supprimer la composante continue |
| Crossover | Filtre de coupure multi-voie | Separer bass/mid/treble pour multi-ampli |
| SMART_AMP | Amplificateur intelligent | Protection des haut-parleurs |
| NXP EAP | Effets audio NXP (bass boost, loudness) | Enrichissement audio proprietaire |
Topologies SOF
La topologie definit le graphe de traitement audio charge sur le DSP. Elle est compilee en fichier .tplg et chargee au demarrage.
Topologies disponibles pour i.MX8MP
Changer de topologie
Exemple : pipeline EQ IIR + DRC
graph LR
CP["Capture PCM"] --> CV["Volume"] --> CE["EQ IIR"] --> CD["DRC"] --> CO["DAI SAI7 OUT"]
style CP fill:#f0fdf4,stroke:#10b981
style CV fill:#f0fdf4,stroke:#10b981
style CE fill:#f0fdf4,stroke:#10b981
style CD fill:#f0fdf4,stroke:#10b981
style CO fill:#f0fdf4,stroke:#10b981
↓ Capture → Playback
graph LR
PI["DAI SAI7 IN"] --> PD["DRC"] --> PE["EQ IIR"] --> PV["Volume"] --> PO["Playback PCM"]
style PI fill:#eff6ff,stroke:#2563eb
style PD fill:#eff6ff,stroke:#2563eb
style PE fill:#eff6ff,stroke:#2563eb
style PV fill:#eff6ff,stroke:#2563eb
style PO fill:#eff6ff,stroke:#2563eb
Effets audio DSP
Voici des exemples concrets d’effets audio realisables sur le HiFi4 avec SOF :
Egaliseur parametrique (IIR Biquad)
Compresseur de dynamique (DRC)
Filtre FIR (crossover, anti-alias)
Beamforming micro array (TDFB)
NPU pour l’audio
Le NPU VIP8000 (2.3 TOPS) peut etre utilise pour des taches d’inference IA sur l’audio, en complement du DSP pour le traitement signal classique.
Cas d’usage NPU audio
| Application | Modele type | Entree | Performance |
|---|---|---|---|
| Noise Reduction | RNNoise, DTLN, DeepFilterNet | Spectrogramme / frames PCM | < 5 ms par frame (16 kHz) |
| Keyword Detection | Micro Speech (TFLM), kws_ref_model | MFCC features (16 kHz) | < 10 ms inference |
| Speech Enhancement | Conv-TasNet, DCCRN | Signal temporel / complexe | Temps reel a 16 kHz |
| Speaker ID | X-Vector, ECAPA-TDNN | Mel spectrogramme | ~50 ms par utterance |
| Speech-to-Text | Whisper Tiny (quantize INT8) | Mel spectrogramme 80-bin | ~3x temps reel |
| Audio Classification | YAMNet, AudioSet | Mel spectrogramme | < 20 ms inference |
Exemple : RNNoise sur NPU
Pipeline complet SAI → DSP → NPU → DSP
Le pipeline audio complet multivoie combine le DSP HiFi4 et le NPU dans une chaine de traitement temps reel :
Audio temps reel
Latence et buffers
| Parametre | Valeur typique | Impact latence |
|---|---|---|
| Period size | 256 frames | 5.33 ms @ 48 kHz |
| Buffer size | 1024 frames (4 periodes) | 21.33 ms buffer total |
| Latence capture | ~5-10 ms | 1-2 periodes |
| Latence playback | ~5-10 ms | 1-2 periodes |
| Round-trip total | ~15-25 ms | Capture + DSP + Playback |
| DSP traitement | < 1 ms | Pipeline SOF complet |
| NPU inference | ~5-10 ms | Selon modele et taille |
Optimisations temps reel
PipeWire / GStreamer
PipeWire
GStreamer pipelines audio
Troubleshooting
| Probleme | Cause probable | Solution |
|---|---|---|
| Pas de carte son detectee | SAI ou codec desactive dans DTS | Verifier status = « okay » sur SAI + codec + sound node |
| Son distordu / crachements | Mauvais BCLK ratio ou PLL du codec non verrouillee | Verifier que BCLK = Fs * slot_width * nb_slots (ex: 48000 * 32 * 8 = 12.288 MHz) |
| xruns (under/overruns) | Latence trop faible ou CPU charge | Augmenter period-size, utiliser PREEMPT_RT, isoler CPU |
| Canaux permutes en TDM | Slot offset incorrect | Verifier dai-tdm-slot-tx-mask / rx-mask |
| Codec I2C non detecte | Adresse I2C ou reset GPIO | i2cdetect -y 2 pour scanner le bus |
| EASRC firmware manquant | firmware-imx absent | Verifier /lib/firmware/imx/easrc/ |
| DSP ne demarre pas | Firmware absent ou corrupted | Verifier dmesg | grep remoteproc et firmware path |
| SOF topology erreur | Incompatibilite firmware/tplg | Recompiler topologie avec meme version SOF que le firmware |
Commandes de debug
Ressources
Documentation NXP
- IMX8MPRM : Reference Manual — chapitres SAI, EASRC, MICFIL, AudioMix
- AN12195 : Low Power Audio Playback on Cortex-M7
- AN12762 : Audio Player on HiFi4 DSP
- AN13793 : FLAC Porting on HiFi4
- IMX8MNSAG : i.MX 8M Nano Soundbar Application Guide (applicable a MP)
Sound Open Firmware
- thesofproject.github.io : Documentation officielle SOF
- github.com/thesofproject/sof : Sources du firmware et topologies
- SOF i.MX8 User Guide : Guide specifique NXP
- github.com/nxp-imx/imx-audio-framework : Framework DSP NXP
Texas Instruments
- TAC5212 Datasheet : Specifications completes et registres
- TAA5212 / TAD5212 : Variantes ADC-seul et DAC-seul
- TAC5212 EVM : Carte d’evaluation TI
- pcm6240 Linux driver : sound/soc/codecs/pcm6240.c (kernel upstream >= 6.6)
Communaute
- alsa-project.org : Documentation ALSA et outils
- pipewire.org : Documentation PipeWire
- community.nxp.com : Forum NXP (section audio / i.MX)
- github.com/xiph/rnnoise : RNNoise (debruitage IA open-source)
Articles Wiki Connexes
Besoin d’expertise audio sur i.MX8MP ?
Integration codec, pipeline DSP/NPU temps reel, multivoie TDM, SOF, ALSA — c’est mon activite principale. Parlons de votre projet.
Discuter de votre projet audio →