Table des matières:

Traitement audio et numérique du signal Bluetooth : un framework Arduino : 10 étapes
Traitement audio et numérique du signal Bluetooth : un framework Arduino : 10 étapes

Vidéo: Traitement audio et numérique du signal Bluetooth : un framework Arduino : 10 étapes

Vidéo: Traitement audio et numérique du signal Bluetooth : un framework Arduino : 10 étapes
Vidéo: Seconde partie du prototypage de l'interphone sans-fil à base d'ESP32-LyraT-mini. 2024, Novembre
Anonim
Image
Image
Traitement audio et numérique du signal Bluetooth: un framework Arduino
Traitement audio et numérique du signal Bluetooth: un framework Arduino

Sommaire

Quand je pense à Bluetooth, je pense à la musique, mais malheureusement, la plupart des microcontrôleurs ne peuvent pas lire de musique via Bluetooth. Le Raspberry Pi peut mais c'est un ordinateur. Je souhaite développer un framework basé sur Arduino pour que les microcontrôleurs puissent lire de l'audio via Bluetooth. Pour fléchir complètement les muscles de mon microcontrôleur, je vais ajouter un traitement du signal numérique (DSP) en temps réel à l'audio (filtrage passe-haut, filtrage passe-bas et compression de la plage dynamique). Pour la cerise sur le gâteau, je vais ajouter un serveur Web qui peut être utilisé pour configurer le DSP sans fil. La vidéo intégrée montre les bases de l'audio Bluetooth en action. Il me montre également que j'utilise le serveur Web pour effectuer un filtrage passe-haut, un filtrage passe-bas et une compression de plage dynamique. La première utilisation de la compression de plage dynamique provoque délibérément une distorsion comme exemple de mauvais choix de paramètres. Le deuxième exemple élimine cette distorsion.

Pour ce projet, l'ESP32 est le microcontrôleur de choix. Il coûte moins de 10 £ et regorge de fonctionnalités avec ADC, DAC, Wifi, Bluetooth Low Energy, Bluetooth Classic et un processeur dual-core 240MHz. Le DAC embarqué peut techniquement lire l'audio, mais il ne sonnera pas très bien. Au lieu de cela, j'utiliserai le décodeur stéréo Adafruit I2S pour produire un signal de sortie de ligne. Ce signal peut facilement être envoyé à n'importe quel système HiFi pour ajouter instantanément de l'audio sans fil à votre système HiFi existant.

Fournitures

Espérons que la plupart des fabricants auront des maquettes, des cavaliers, des câbles USB, des fers à souder pour alimentation et n'auront à dépenser que 15 £ pour l'ESP32 et le décodeur stéréo. Sinon, toutes les pièces requises sont listées ci-dessous.

  • Un ESP32 - testé sur ESP32-PICO-KIT et TinyPico - 9,50 £/ 24 £
  • Décodeur stéréo Adafruit I2S - 5,51 €
  • Planche à pain - £3-£5 chacun
  • Fils de liaison - 3 £
  • Casque filaire/Système Hi-Fi - £££
  • Embases à pousser ou fer à souder - 2,10 £ / 30 £
  • Câble micro USB - 2,10 £/ 3 £
  • Connecteur 3,5 mm vers RCA/prise 3,5 mm vers prise (ou tout ce dont votre enceinte a besoin) - 2,40 £/ 1,50 £
  • Alimentation USB - 5 £

Étape 1: Construction - la planche à pain

Construction - la planche à pain
Construction - la planche à pain

Si vous avez acheté le ESP32-PICO-KIT, vous n'aurez pas à souder de broches car il est pré-soudé. Placez-le simplement sur la planche à pain.

Étape 2: Construction - Embases à pousser/soudage

Construction - Embases à pousser/soudage
Construction - Embases à pousser/soudage
Construction - Embases à pousser/soudage
Construction - Embases à pousser/soudage

Si vous avez un fer à souder, soudez les broches au décodeur stéréo selon les instructions sur le site Web d'Adafruit. Au moment d'écrire ces lignes, mon fer à souder était au travail et était verrouillé. Je ne voulais pas payer pour un fer à souder temporaire, alors j'ai découpé des en-têtes de poussée de pimoroni. Je les ai découpés pour qu'ils tiennent sur le décodeur stéréo. Ce n'est pas la meilleure solution (et pas la façon dont les en-têtes étaient destinés à être utilisés) mais c'est l'alternative la moins chère à un fer à souder. Insérez l'en-tête découpé sur la planche à pain. Vous ne devriez avoir besoin que d'une ligne de 6 broches pour le décodeur. Vous pouvez en ajouter six autres de l'autre côté pour plus de stabilité, mais ce n'est pas nécessaire pour ce système prototype. Les broches dans lesquelles insérer les en-têtes sont vin, 3vo, gnd, wsel, din et bclk.

Étape 3: Construction - Câblez les broches d'alimentation

Construction - Câblez les broches d'alimentation
Construction - Câblez les broches d'alimentation

Placez le décodeur stéréo sur les en-têtes push (broches vin, 3vo, gnd, wsel, din et bclk) et poussez-les fermement ensemble. Encore une fois, cela devrait idéalement être fait avec un fer à souder mais j'ai dû improviser. Vous remarquerez que tous les fils de cette instructable sont bleus. C'est parce que je n'avais pas de fils de liaison, alors j'ai coupé 1 long fil en plus petits morceaux. De plus, je suis daltonien et je ne me soucie pas vraiment de la couleur du fil. Les broches d'alimentation sont fixées comme suit:

3v3 (ESP32) -> à vin sur décodeur stéréo

gnd (ESP32) -> à gnd sur le décodeur stéréo

Étape 4: Construction - Câblage I2S

Construction - Câblage I2S
Construction - Câblage I2S

Pour envoyer l'audio Bluetooth de l'ESP32 au décodeur stéréo, nous allons utiliser une méthode de communication numérique appelée I2S. Le décodeur stéréo prendra ce signal numérique et le transformera en un signal analogique pouvant être branché sur un haut-parleur ou une chaîne HiFi. I2S ne nécessite que 3 fils et est assez simple à comprendre. La ligne d'horloge binaire (bclk) passe à un niveau haut et bas pour indiquer qu'un nouveau bit est transmis. La ligne de sortie de données (dout) passe à l'état haut ou bas pour indiquer si ce bit a une valeur de 0 ou 1 et la ligne de sélection de mot (wsel) passe à l'état haut ou bas pour indiquer si le canal gauche ou droit est en cours de transmission. Tous les microcontrôleurs ne prennent pas en charge I2S mais l'ESP32 dispose de 2 lignes I2S. Cela en fait un choix évident pour ce projet.

Le câblage est le suivant:

27 (ESP32) -> wsel (décodeur stéréo)

25 (ESP32) -> din (décodeur stéréo)

26 (ESP32) -> bclk (décodeur stéréo)

Étape 5: Installation de la bibliothèque BtAudio

Installation de la bibliothèque BtAudio
Installation de la bibliothèque BtAudio
Installation de la bibliothèque BtAudio
Installation de la bibliothèque BtAudio

Si vous ne les avez pas déjà installés, installez l'IDE Arduino et le noyau Arduino pour ESP32. Une fois que vous les avez installés, visitez ma page Github et téléchargez le référentiel. Dans l'IDE Arduino sous Sketch>>Inclure la bibliothèque>> sélectionnez "Ajouter une bibliothèque. ZIP". Sélectionnez ensuite le fichier zip téléchargé. Cela devrait ajouter ma bibliothèque btAudio à vos bibliothèques Arduino. Pour utiliser la bibliothèque, vous devrez inclure l'en-tête correspondant dans l'esquisse Arduino. Vous verrez cela à l'étape suivante.

Étape 6: Utilisation de la bibliothèque BtAudio

Utilisation de la bibliothèque BtAudio
Utilisation de la bibliothèque BtAudio
Utilisation de la bibliothèque BtAudio
Utilisation de la bibliothèque BtAudio

Une fois installé, connectez votre ESP32 à votre ordinateur via micro USB puis connectez votre décodeur stéréo à votre enceinte avec votre fil 3.5mm. Avant de télécharger le croquis, vous devrez modifier certaines choses dans l'éditeur Arduino. Après avoir sélectionné votre carte, vous devrez modifier le schéma de partition sous Outils >> Schéma de partition et sélectionner "Pas d'OTA (Large APP)" ou "Minimal SPIFFS (Large APPS with OTA)". Cela est nécessaire car ce projet utilise à la fois le WiFi et le Bluetooth, qui sont tous deux des bibliothèques très gourmandes en mémoire. Une fois que vous avez fait cela, téléchargez le croquis suivant sur l'ESP32.

#comprendre

// Définit le nom du périphérique audio btAudio audio = btAudio("ESP_Speaker"); void setup() { // diffuse les données audio vers l'ESP32 audio.begin(); // renvoie les données reçues vers un I2S DAC int bck = 26; entier ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } boucle vide() { }

Le croquis peut être divisé en 3 étapes:

  1. Créez un objet btAudio global qui définit le "nom Bluetooth" de votre ESP32
  2. Configurez l'ESP32 pour recevoir l'audio avec la méthode btAudio::begin
  3. Définissez les broches I2S avec la méthode btAudio::I2S.

C'est tout du côté du logiciel ! Il ne vous reste plus qu'à initier la connexion Bluetooth avec votre ESP32. Recherchez simplement de nouveaux appareils sur votre téléphone/ordinateur portable/lecteur MP3 et "ESP_Speaker" apparaîtra. Une fois que vous êtes satisfait que tout fonctionne (la musique joue), vous pouvez déconnecter l'ESP32 de votre ordinateur. Alimentez-le avec l'alimentation USB et il se souviendra du dernier code que vous y avez téléchargé. De cette façon, vous pouvez laisser votre ESP32 caché derrière votre système HiFi pour toujours.

Étape 7: DSP - Filtrage

Extension du récepteur avec le traitement numérique du signal

Si vous avez suivi toutes les étapes (et je n'ai rien oublié), vous disposez désormais d'un récepteur Bluetooth entièrement fonctionnel pour votre système HiFi. Bien que ce soit cool, cela ne pousse pas vraiment le microcontrôleur à ses limites. L'ESP32 possède deux cœurs fonctionnant à 240 MHz. Cela signifie que ce projet est bien plus qu'un simple récepteur. Il a la capacité d'être un récepteur Bluetooth avec un processeur de signal numérique (DSP). Les DSP effectuent essentiellement des opérations mathématiques sur le signal en temps réel. Une opération utile est appelée filtrage numérique. Ce processus atténue les fréquences d'un signal au-dessous ou au-dessus d'une certaine fréquence de coupure, selon que vous utilisez un filtre passe-haut ou passe-bas.

Filtres passe-haut

Les filtres passe-haut atténuent les fréquences inférieures à une certaine bande. J'ai construit une bibliothèque de filtres pour les systèmes Arduino basée sur le code de earlevel.com. La principale différence est que j'ai modifié la structure des classes pour permettre la construction de filtres d'ordre supérieur plus facilement. Les filtres d'ordre supérieur suppriment plus efficacement les fréquences au-delà de votre coupure, mais ils nécessitent beaucoup plus de calculs. Cependant, avec l'implémentation actuelle, vous pouvez même utiliser des filtres de 6e ordre pour l'audio en temps réel !

Le croquis est le même que celui trouvé à l'étape précédente sauf que nous avons changé la boucle principale. Pour activer les filtres, nous utilisons la méthode btAudio::createFilter. Cette méthode accepte 3 arguments. Le premier est le nombre de cascades de filtres. Le nombre de cascades de filtres est la moitié de l'ordre du filtre. Pour un filtre de 6e ordre, le premier argument devrait être 3. Pour un filtre de 8e ordre, ce serait 4. Le deuxième argument est la coupure du filtre. J'ai réglé cela sur 1000 Hz pour avoir un effet vraiment dramatique sur les données. Enfin, nous spécifions le type de filer avec le troisième argument. Cela devrait être passe-haut pour un filtre passe-haut et passe-bas pour un filtre passe-bas. Le script ci-dessous bascule la coupure de cette fréquence entre 1000 Hz et 2 Hz. Vous devriez entendre un effet dramatique sur les données.

#comprendre

btAudio audio = btAudio("ESP_Speaker"); void setup() { audio.begin(); int arrière = 26; entier ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } boucle vide () { délai (5000); audio.createFilter(3, 1000, passe-haut); retard (5000); audio.createFilter(3, 2, passe-haut); }

Filtres passe-bas

Les filtres passe-bas font le contraire des filtres passe-haut et suppriment les fréquences au-dessus d'une certaine fréquence. Ils peuvent être implémentés de la même manière que les filtres passe-haut, sauf qu'ils nécessitent de changer le troisième argument en passe-bas. Pour le croquis ci-dessous, j'alterne la coupure passe-bas entre 2000Hz et 20000Hz. J'espère que vous entendrez la différence. Cela devrait sembler assez étouffé lorsque le filtre passe-bas est à 2000 Hz.

#comprendre

btAudio audio = btAudio("ESP_Speaker"); void setup() { audio.begin(); int arrière = 26; entier ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } boucle vide () { délai (5000); audio.createFilter(3, 2000, passe-bas); retard (5000); audio.createFilter(3, 20000, passe-bas); }

Étape 8: DSP - Compression de plage dynamique

Fond

La compression de plage dynamique est une méthode de traitement du signal qui essaie d'égaliser le volume de l'audio. Il compresse les sons forts, qui dépassent un certain seuil, au niveau des sons faibles, puis amplifie éventuellement les deux. Le résultat est une expérience d'écoute beaucoup plus uniforme. Cela m'a été très utile pendant que je regardais une émission avec une musique de fond très forte et des voix très calmes. Dans ce cas, le simple fait d'augmenter le volume n'a pas aidé car cela n'a fait qu'amplifier la musique de fond. Avec la compression de la plage dynamique, je pouvais réduire la musique de fond forte au niveau de la voix et tout entendre à nouveau correctement.

Le code

La compression de plage dynamique n'implique pas seulement de baisser le volume ou de seuiller le signal. C'est un peu plus intelligent que ça. Si vous baissez le volume, les sons faibles seront réduits ainsi que les forts. Une façon de contourner ce problème consiste à seuiller le signal, mais cela entraîne une distorsion importante. La compression de la plage dynamique implique une combinaison de seuillage doux et de filtrage pour minimiser la distorsion que l'on obtiendrait si vous deviez seuiller/écrêter le signal. Le résultat est un signal où les sons forts sont "écrêtés" sans distorsion et les sons faibles sont laissés tels quels. Le code ci-dessous bascule entre trois niveaux de compression différents.

  1. Compression avec distorsion
  2. Compression sans distorsion
  3. Pas de compression

#comprendre

btAudio audio = btAudio("ESP_Speaker"); void setup() { audio.begin(); int arrière = 26; entier ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } boucle vide () { délai (5000); audio.compress (30, 0,0001, 0,0001, 10, 10, 0); retard (5000); audio.compress (30, 0,0001, 0,1, 10, 10, 0); retard (5000); audio.decompress(); }

La compression de plage dynamique est compliquée et les méthodes btAudio::compress ont de nombreux paramètres. Je vais essayer de les expliquer (dans l'ordre) ici:

  1. Seuil - Le niveau auquel le son est réduit (mesuré en décibels)
  2. Temps d'attaque - Le temps qu'il faut pour que le compresseur commence à fonctionner une fois le seuil dépassé
  3. Temps de relâchement - Le temps qu'il faut pour que le compresseur cesse de fonctionner.
  4. Taux de réduction - le facteur par lequel l'audio est compressé.
  5. Largeur du genou - La largeur (en décibels) autour du seuil auquel le compresseur fonctionne partiellement (son plus naturel).
  6. Le gain (décibels) ajouté au signal après compression (augmentation/diminution du volume)

La distorsion très audible lors de la première utilisation de la compression est due au fait que le seuil est très bas et que le temps d'attaque et le temps de relâchement sont très courts, ce qui entraîne effectivement un comportement de seuillage dur. Ceci est clairement résolu dans le second cas en augmentant le temps de relâchement. Cela amène essentiellement le compresseur à agir de manière beaucoup plus douce. Ici, j'ai seulement montré comment la modification d'un paramètre peut avoir un effet dramatique sur l'audio. C'est maintenant à votre tour d'expérimenter différents paramètres.

La mise en œuvre (les mathématiques magiques - facultatif)

J'ai trouvé que la mise en œuvre naïve de la compression de la plage dynamique était difficile. L'algorithme nécessite de convertir un entier 16 bits en décibels, puis de le retransformer en entier 16 bits une fois que vous avez traité le signal. J'ai remarqué qu'une ligne de code prenait 10 microsecondes pour traiter les données stéréo. Comme l'audio stéréo échantillonné à 44,1 KHz ne laisse que 11,3 microsecondes au DSP, c'est une lenteur inacceptable… Cependant, en combinant une petite table de correspondance (400 octets) et une procédure d'interpolation basée sur les différences divisées de Netwon, nous pouvons obtenir une précision de près de 17 bits en 0,2 microseconde. J'ai joint un document pdf avec tous les calculs pour les vraiment intéressés. C'est compliqué, vous êtes prévenus !

Étape 9: L'interface Wifi

L'interface Wi-Fi
L'interface Wi-Fi
L'interface Wi-Fi
L'interface Wi-Fi

Vous disposez maintenant d'un récepteur Bluetooth capable d'exécuter un DSP en temps réel. Malheureusement, si vous souhaitez modifier l'un des paramètres DSP, vous devrez vous déconnecter de votre chaîne HiFi, télécharger une nouvelle esquisse, puis vous reconnecter. C'est maladroit. Pour résoudre ce problème, j'ai développé un serveur Web que vous pouvez utiliser pour modifier tous les paramètres du DSP sans vous reconnecter à votre ordinateur. Le croquis pour utiliser le serveur Web est ci-dessous.

#comprendre

#include btAudio audio = btAudio("ESP_Speaker"); webDSP web; void setup() { Serial.begin(115200); audio.begin(); int arrière = 26; entier ws = 27; int dout = 25; audio. I2S(bck, dout, ws); // remplacez par votre identifiant WiFi et votre mot de passe const char* ssid = "SSID"; const char* mot de passe = "MOT DE PASSE"; web.begin(ssid, mot de passe, &audio); } boucle vide() { web._server.handleClient(); }

Le code attribue une adresse IP à votre ESP32 que vous pouvez utiliser pour accéder à la page Web. La première fois que vous exécutez ce code, vous devriez l'avoir connecté à votre ordinateur. De cette façon, vous pouvez voir l'adresse IP attribuée à votre ESP32 sur votre moniteur série. Si vous souhaitez accéder à cette page Web, entrez simplement cette adresse IP dans n'importe quel navigateur Web (testé sur Chrome).

À présent, nous devrions être familiarisés avec la méthode d'activation du Bluetooth et de l'I2S. La principale différence est l'utilisation d'un objet webDSP. Cet objet prend votre SSID Wifi et votre mot de passe comme arguments ainsi qu'un pointeur vers l'objet btAudio. Dans la boucle principale, nous obtenons continuellement l'objet webDSP pour écouter les données entrantes de la page Web, puis mettre à jour les paramètres DSP. En guise de conclusion, il convient de noter que Bluetooth et Wifi utilisent la même radio sur l'ESP32. Cela signifie que vous devrez peut-être attendre jusqu'à 10 secondes entre le moment où vous entrez les paramètres sur la page Web et le moment où les informations atteignent réellement l'ESP32.

Étape 10: Plans futurs

Espérons que vous avez apprécié cette instructable et que vous avez maintenant l'audio Bluetooth et le DSP ajoutés à votre chaîne HiFi. Cependant, je pense qu'il y a beaucoup de place pour la croissance dans ce projet et je voulais juste souligner quelques orientations futures que je pourrais prendre.

  • Activer le streaming audio Wifi (pour la meilleure qualité audio)
  • Utilisez un microphone I2S pour activer les commandes vocales
  • développer un égaliseur contrôlé par WiFi
  • Rendez-le joli (la planche à pain ne crie pas un excellent design de produit)

Quand j'arriverai à mettre en œuvre ces idées, je ferai plus d'instructables. Ou peut-être que quelqu'un d'autre implémentera ces fonctionnalités. C'est la joie de tout rendre open source !

Conseillé: