La Teensy Audio Library fait du Teensy une plateforme de traitement audio temps réel : synthèse, filtrage, mélange, effets, FFT. On y construit une chaîne d’objets (oscillateurs, filtres, mixeurs, entrées/sorties) reliés par des cordons, que l’on câble graphiquement dans l’Audio System Design Tool avant que l’outil n’en génère le code. C’est la signature du Teensy, et l’apport qui justifie le plus souvent de le choisir. Cette fiche enseigne à assembler et piloter une chaîne audio, pas à concevoir un filtre : la théorie du traitement du signal relève d’un cours dédié.

À quoi ça sert ?

Faire de l’audio « à la main » sur un microcontrôleur (échantillonner, filtrer, sortir le son sans accroc, le tout en respectant la cadence) est difficile. La bibliothèque résout ce problème par une abstraction par objets :

  • Composer plutôt que coder le DSP. On choisit des objets (un oscillateur, un filtre, un mixeur…) et on les relie. Chaque objet encapsule son traitement, optimisé pour le Teensy.
  • Le temps réel est géré pour vous. Le son est traité en tâche de fond, par paquets d’échantillons, porté par le DMA : la boucle loop() reste libre.
  • Concevoir en cliquant. L’Audio System Design Tool (interface web de PJRC) permet de poser les objets et tracer les cordons, puis génère le code correspondant.

Les objets et les cordons

Trois briques structurent toute chaîne audio :

  • les objets — des blocs de traitement : entrées (AudioInputI2S, AudioInputUSB…), générateurs (AudioSynthWaveform…), traitements (AudioFilterStateVariable, AudioMixer4, AudioEffectReverb…), sorties (AudioOutputI2S, AudioOutputUSB…) ;
  • les cordons (AudioConnection) — qui relient la sortie d’un objet à l’entrée d’un autre, comme des câbles de patch ;
  • la mémoire. AudioMemory(n) réserve n blocs d’échantillons partagés par la chaîne. À appeler dans setup(), sans quoi rien ne sonne.

Une chaîne audio Teensy : entrée USB, synthétiseur et filtre reliés par des cordons vers un mixeur, puis sortie I2S vers l'Audio Shield.|640

L’Audio System Design Tool

Plutôt que d’écrire à la main les déclarations d’objets et de cordons, on les dessine : l’Audio System Design Tool (sur pjrc.com) propose tous les objets en bibliothèque. On les glisse sur le plan de travail, on tire les cordons, et un clic sur Export génère le bloc de code (déclarations + AudioConnection) à coller dans le sketch. Le même graphe que le SVG ci-dessus produit ainsi quelques lignes prêtes à l’emploi. C’est l’outil de référence pour concevoir une chaîne audio Teensy.

Prendre capture d’écran de l’Audio System Design Tool ouvert dans le navigateur, avec quelques objets posés — un générateur, un filtre, une sortie I2S — reliés par des cordons.

Le traitement tourne en tâche de fond

Point clé : une fois la chaîne déclarée, le son est traité automatiquement, par interruptions et DMA, indépendamment de loop(). On ne « pousse » pas les échantillons soi-même. Le rôle de loop() se réduit à piloter les paramètres : changer une fréquence, un gain, déclencher une note. C’est la même idée que les modes asynchrones d’un périphérique : le travail se fait en arrière-plan, le programme principal ne fait que le diriger.

Exemple — Un oscillateur vers l’Audio Shield

Cette chaîne minimale joue un la à 440 Hz. Elle suppose l’Audio Shield (codec SGTL5000) branché sur le Teensy, relié par le bus I2S (données) et I2C (contrôle).

L'Audio Shield s'empile directement sur le Teensy : les broches I2S de données et I2C de contrôle passent par les connecteurs, il n'y a rien à relier à la main. Le shield porte la sortie casque, les entrées ligne et le lecteur de carte SD.|560

#include <Audio.h>
 
AudioSynthWaveform   forme;       // un oscillateur
AudioOutputI2S       sortie;      // sortie I2S vers l'Audio Shield
AudioControlSGTL5000 codec;       // contrôle du codec de l'Audio Shield
 
AudioConnection cordonG(forme, 0, sortie, 0);   // forme -> canal gauche
AudioConnection cordonD(forme, 0, sortie, 1);   // forme -> canal droit
 
void setup() {
  AudioMemory(8);                 // réserver 8 blocs audio (sinon : pas de son)
  codec.enable();
  codec.volume(0.5);
  forme.begin(WAVEFORM_SINE);
  forme.frequency(440);           // la 440 Hz
  forme.amplitude(0.3);
}
 
void loop() {
  // le son joue en tâche de fond ; loop() ne fait que piloter les paramètres
}

Les déclarations d’objets et les deux AudioConnection sont exactement ce que l’Audio Design Tool génère. Sans Audio Shield, on reste autonome en remplaçant AudioOutputI2S par AudioOutputUSB et en réglant USB Type sur Audio (voir le Teensy comme appareil USB) : le Teensy devient une carte son et joue le signal dans l’ordinateur.

Pièges

Oublier AudioMemory(). Sans réservation de blocs dans setup(), la chaîne ne dispose d’aucune mémoire de travail : aucun son. C’est l’oubli n°1.

Attendre du son analogique sur une broche (Teensy 4.x). Les Teensy 4.x n’ont pas de DAC intégré : la sortie analogique passe par l’Audio Shield (I2S), par l’USB audio, ou par la sortie MQS (qualité moyenne sur 2 broches). Les anciens Teensy 3.x avaient une broche DAC. Ce n’est plus le cas.

Sous-dimensionner la mémoire. Trop peu de blocs AudioMemory() provoque des coupures. Surveiller AudioMemoryUsageMax() (et AudioProcessorUsageMax() pour la charge CPU) et ajuster.

Vouloir traiter l’audio dans loop(). Le traitement est en tâche de fond. loop() ne fait que régler les paramètres. Tenter d’y manipuler les échantillons à la main casse la cadence.

Câblage de l’Audio Shield. Les broches I2S sont fixes et le codec se contrôle en I2C : oublier codec.enable() laisse le shield muet.

Exercices

Exercice 1 — Une sirène

À partir de l’exemple, faites varier la fréquence dans le temps (par exemple un balayage de 300 à 1000 Hz puis retour), pour entendre une sirène. Où écrit-on ce code, et pourquoi est-ce possible sans interrompre le son ?

Exercice 2 — Insérer un filtre

Vous voulez adoucir le son en plaçant un filtre passe-bas entre l’oscillateur et la sortie. Quels objets et quels cordons faut-il, et quel outil vous évite de tout écrire à la main ?

Cas particulier — Audio Shield, USB audio, sorties sans codec

  • Audio Shield (SGTL5000) — le compagnon de référence : entrée/sortie ligne, casque, micro, le tout par I2S + contrôle I2C. La voie analogique propre.
  • USB audio. Sans aucun matériel : USB Type → Audio fait du Teensy une carte son (objets AudioInputUSB/AudioOutputUSB). Idéal pour expérimenter (voir USB).
  • MQS / I2S externe. Sur Teensy 4.x sans shield, la sortie MQS (2 broches, qualité moyenne) ou un codec I2S externe permettent une sortie analogique. Il n’y a pas de DAC intégré.

Raccrochage projet

  • Étape 4 de la phase de preuve de concept. Pour un projet à dimension sonore (instrument, retour audio, analyse de son), la chaîne audio se prototype tôt : valider qu’un signal sort proprement, sans accroc, conditionne tout le reste.
  • Charge maîtrisée. Surveiller AudioProcessorUsageMax() dès la PoC donne une marge de calcul réaliste avant d’empiler les effets.

Comprendre que l’audio Teensy se compose (objets + cordons) et tourne en tâche de fond déplace l’effort du « comment traiter le signal » vers le « quelle chaîne assembler » : c’est ce qui rend le DSP accessible à un projet école.

Aller plus loin

Voir aussi