AEC et réduction de bruit avec le ReSpeaker Mic Array v2.0

La pratique

Le matériel nécessaire pour jouer

Alors il nous faut :

  • Un raspberry (étonnant non ? 🙂 ) . Celui du TP est un 3B+
  • Un respeaker mic array v2
  • Un écran avec connectique HDMI (et donc HP intégré)
  • Un haut parleur que l’on branchera en jack 3.5mm sur le respeaker
  • un câble jack mâle – mâle 3.5 mm
  • Un câble USB A mâle / micro USB mâle
  • un câble HDMI de très bonne qualité
  • Un ordinateur à côté pour le SSH/VNC
  • Un cerveau en état de marche

La préparation du TP

Alors on commence par brancher tout comme il faut :

On aura donc la possibilité de faire sortir du son par l’enceinte connectée au respeaker mais aussi par l’écran HDMI.

Pitié, évite d’utiliser la sortie Jack du raspberry qui est une plaie vivante à elle toute seule…

Installatation de raspbian

Comme le but de tout ça est un TP, on va partir d’un truc propre et si tu veux le faire, il faudra en faire de même. Pour l’installation, si tu ne sais pas le faire, tu peux aller lire ce TP : https://www.coxprod.org/domotique/installation-du-raspberry/

De plus, je te conseille aussi d’appliquer ceci pour avoir accès directement en SSH depuis ton ordinateur. Ça t’évitera d’avoir à brancher un clavier et une souris au raspberry : https://www.coxprod.org/domotique/activer-ssh-et-wifi-sans-ecran-sur-le-raspberry

Lors de la configuration, je te conseille d’activer VNC. Pour savoir comment faire la config : https://www.coxprod.org/domotique/chapitre-4-la-configuration-du-raspberry/

Yopla ! Et voilà, on est presque prêt. Il nous reste un dernier truc à faire. Une fois connecté en SSH à ton raspberry, tu vas editer ce fichier :

sudo nano /boot/cmdline.txt

Et là il va y avoir déjà du contenu. SURTOUT, tu ne fais pas de retour à la ligne !!! Tu tapes un espace et tu viens coller ça :

snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_compat_alsa=0

En fait, cela va permettre de voir la sortie son HDMI comme une carte son à part entière et non comme un sous périphérique d’une même carte avec la prise Jack. Cela va être plus pratique pour notre TP.

Tu redémarres, et vérifie qu’avec aplay -l , tu obtiens bien ça :

pi@raspberrypi:~ $ aplay -l
**** Liste des Périphériques Matériels PLAYBACK ****
carte 0: b1 [bcm2835 HDMI 1], périphérique 0: bcm2835 HDMI 1 [bcm2835 HDMI 1]
  Sous-périphériques: 3/4
  Sous-périphérique #0: subdevice #0
  Sous-périphérique #1: subdevice #1
  Sous-périphérique #2: subdevice #2
  Sous-périphérique #3: subdevice #3
carte 1: Headphones [bcm2835 Headphones], périphérique 0: bcm2835 Headphones [bcm2835 Headphones]
  Sous-périphériques: 3/4
  Sous-périphérique #0: subdevice #0
  Sous-périphérique #1: subdevice #1
  Sous-périphérique #2: subdevice #2
  Sous-périphérique #3: subdevice #3
carte 2: ArrayUAC10 [ReSpeaker 4 Mic Array (UAC1.0)], périphérique 0: USB Audio [USB Audio]
  Sous-périphériques: 0/1
  Sous-périphérique #0: subdevice #0
pi@raspberrypi:~ $

installation des outils

Maintenant, on va installer quelques outils dont on va avoir besoin.

Le premier, c’est audacity. C’est un logiciel de traitement de son. Il va nous permettre d’enregistrer les différentes pistes qui proviennent du micro ainsi que la piste “voix” une fois traitée.

sudo apt-get install audacity

Ensuite, nous allons installer pyusb. C’est un outil qui va permettre de discuter avec le respeaker mic array v2.

Attention ! Ce respeaker est en USB et n’a absolument pas besoin de driver. On le branche, et il est directement reconnu comme carte son à contrario des autres respeaker.

sudo pip install pyusb

Maintenant, on va aller chercher les firmwares disponibles pour notre respeaker ainsi que l’outil tuning.py qui va nous permettre de configurer l’AEC et la réduction de bruit.

git clone https://github.com/respeaker/usb_4_mic_array.git

Mise à jour du firmware respeaker

Comme le but de cet article est de faire un TP, nous allons installer un firmware qui va nous permettre de faire des tests et mieux voir ce qui se passe.

Pour ça, on va aller dans le répertoire usb_4_mic_array qu’on vient juste de télécharger

cd usb_4_mic_array

Regardons maintenant ce que nous avons à notre disposition

pi@raspberrypi:~/usb_4_mic_array $ ls -l *.bin
-rw-r--r-- 1 pi pi 148992 avril 11 17:03 1_channel_firmware_12.06dB.bin
-rw-r--r-- 1 pi pi 148992 avril 11 17:03 1_channel_firmware_6.02dB.bin
-rw-r--r-- 1 pi pi 148992 avril 11 17:03 1_channel_firmware.bin
-rw-r--r-- 1 pi pi 150016 avril 11 17:03 48k_1_channel_firmware_6.02dB.bin
-rw-r--r-- 1 pi pi 149760 avril 11 17:03 48k_1_channel_firmware.bin
-rw-r--r-- 1 pi pi 150016 avril 11 17:03 48k_6_channels_firmware_6.02dB.bin
-rw-r--r-- 1 pi pi 150016 avril 11 17:03 48k_6_channels_firmware.bin
-rw-r--r-- 1 pi pi 148992 avril 11 17:03 6_channels_firmware_12.06dB.bin
-rw-r--r-- 1 pi pi 148992 avril 11 17:03 6_channels_firmware_6.02dB.bin
-rw-r--r-- 1 pi pi 148992 avril 11 17:03 6_channels_firmware.bin
pi@raspberrypi:~/usb_4_mic_array $

Déjà, on voit qu’on a des firmwares avec 1 ou 6 canaux. En fait, les firmwares 6 canaux nous permettent d’avoir 6 canaux en entrée :

  • Canal 0 : le canal “Voix optimisée”
  • Canal 1 : Ce qui est capté par le micro 1
  • Canal 2 : Ce qui est capté par le micro 2
  • Canal 3 : Ce qui est capté par le micro 3
  • Canal 4 : Ce qui est capté par le micro 4
  • Canal 5 : Ce qui sort du haut parleur et qui va être utilisé pour l’AEC

Les firmwares 1 canal ne sont en fait composés que du canal 0, c’est à dire le canal que j’appelle “Voix optimisée”. C’est à dire après application de tous les algorithmes pour n’obtenir que la voix (où ce qu’il en reste…)

Ensuite, on voit des firmwares 48k et d’autres non. En fait, par défaut le respeaker mic array v2 est en 16k en qualité audio. Seeed a sorti des firmwares pour de la qualité 48k. Problème, les 48k à 6 canaux, je n’ai pas réussi à faire le TP avec. Ça déconne à mort.

Et pour finir, on voit des firmwares avec 6.02dB et 12.06dB. Ce sont des firmwares qui intègrent directement un gain au niveau des micros.

Donc, si on réfléchit 2 secondes, on va avoir besoin d’un firmware 6 canaux parce qu’on veut voir ce qui se passe, comme c’est du test, pas besoin de gain supplémentaire, et le 48k, j’ai testé pour vous, ça ne marche pas 🙂

Donc ce sera le firmware 6_channels_firmware.bin

N’oublie pas que mettre à jour un firmware n’est pas une opération anodine. Si tu n’as pas une source d’alimentation solide et fiable pour ton raspberry, ou si quoique ce soit se passe de travers, ton respeaker va se retrouver en outil pour caler une table dans le garage….

sudo python dfu.py --download 6_channels_firmware.bin

Ce qui devrait te donner quelque chose comme ça :

pi@raspberrypi:~/usb_4_mic_array $ sudo python dfu.py --download 6_channels_firmware.bin
entering dfu mode
found dfu device
downloading
149056 bytes
done
pi@raspberrypi:~/usb_4_mic_array $

Réglage du respeaker mic array v2

Alors, j’en ai parlé un peu tout à l’heure, nous avons la possibilité de toucher aux réglages concernant les algorithmes AEC et NR.

Pour ça on va utiliser l’outil tuning.py qui est arrivé quand on a cloné le git tout à l’heure.

Pour avoir la liste complète des paramètres à notre disposition :

sudo python tuning.py -p

ce qui nous donne ceci :

name                    type    max     min     r/w     info
-------------------------------
AECFREEZEONOFF          int     1       0       rw      Adaptive Echo Canceler updates inhibit.
                                                            0 = Adaptation enabled
                                                            1 = Freeze adaptation, filter only
AECNORM                 float   16      0.25    rw      Limit on norm of AEC filter coefficients
AECPATHCHANGE           int     1       0       ro      AEC Path Change Detection.
                                                            0 = false (no path change detected)
                                                            1 = true (path change detected)
AECSILENCELEVEL         float   1       1e-09   rw      Threshold for signal detection in AEC [-inf .. 0] dBov (Default: -80dBov = 10log10(1x10-8))
AECSILENCEMODE          int     1       0       ro      AEC far-end silence detection status.
                                                            0 = false (signal detected)
                                                            1 = true (silence detected)
AGCDESIREDLEVEL         float   0.99    1e-08   rw      Target power level of the output signal.
                                                            [−inf .. 0] dBov (default: −23dBov = 10log10(0.005))
AGCGAIN                 float   1000    1       rw      Current AGC gain factor.
                                                            [0 .. 60] dB (default: 0.0dB = 20log10(1.0))
AGCMAXGAIN              float   1000    1       rw      Maximum AGC gain factor.
                                                            [0 .. 60] dB (default 30dB = 20log10(31.6))
AGCONOFF                int     1       0       rw      Automatic Gain Control.
                                                            0 = OFF
                                                            1 = ON
AGCTIME                 float   1       0.1     rw      Ramps-up / down time-constant in seconds.
CNIONOFF                int     1       0       rw      Comfort Noise Insertion.
                                                            0 = OFF
                                                            1 = ON
DOAANGLE                int     359     0       ro      DOA angle. Current value. Orientation depends on build configuration.
ECHOONOFF               int     1       0       rw      Echo suppression.
                                                            0 = OFF
                                                            1 = ON
FREEZEONOFF             int     1       0       rw      Adaptive beamformer updates.
                                                            0 = Adaptation enabled
                                                            1 = Freeze adaptation, filter only
FSBPATHCHANGE           int     1       0       ro      FSB Path Change Detection.
                                                            0 = false (no path change detected)
                                                            1 = true (path change detected)
FSBUPDATED              int     1       0       ro      FSB Update Decision.
                                                            0 = false (FSB was not updated)
                                                            1 = true (FSB was updated)
GAMMAVAD_SR             float   1000    0       rw      Set the threshold for voice activity detection.
                                                            [−inf .. 60] dB (default: 3.5dB 20log10(1.5))
GAMMA_E                 float   3       0       rw      Over-subtraction factor of echo (direct and early components). min .. max attenuation
GAMMA_ENL               float   5       0       rw      Over-subtraction factor of non-linear echo. min .. max attenuation
GAMMA_ETAIL             float   3       0       rw      Over-subtraction factor of echo (tail components). min .. max attenuation
GAMMA_NN                float   3       0       rw      Over-subtraction factor of non- stationary noise. min .. max attenuation
GAMMA_NN_SR             float   3       0       rw      Over-subtraction factor of non-stationary noise for ASR.
                                                            [0.0 .. 3.0] (default: 1.1)
GAMMA_NS                float   3       0       rw      Over-subtraction factor of stationary noise. min .. max attenuation
GAMMA_NS_SR             float   3       0       rw      Over-subtraction factor of stationary noise for ASR.
                                                            [0.0 .. 3.0] (default: 1.0)
HPFONOFF                int     3       0       rw      High-pass Filter on microphone signals.
                                                            0 = OFF
                                                            1 = ON - 70 Hz cut-off
                                                            2 = ON - 125 Hz cut-off
                                                            3 = ON - 180 Hz cut-off
MIN_NN                  float   1       0       rw      Gain-floor for non-stationary noise suppression.
                                                            [−inf .. 0] dB (default: −10dB = 20log10(0.3))
MIN_NN_SR               float   1       0       rw      Gain-floor for non-stationary noise suppression for ASR.
                                                            [−inf .. 0] dB (default: −10dB = 20log10(0.3))
MIN_NS                  float   1       0       rw      Gain-floor for stationary noise suppression.
                                                            [−inf .. 0] dB (default: −16dB = 20log10(0.15))
MIN_NS_SR               float   1       0       rw      Gain-floor for stationary noise suppression for ASR.
                                                            [−inf .. 0] dB (default: −16dB = 20log10(0.15))
NLAEC_MODE              int     2       0       rw      Non-Linear AEC training mode.
                                                            0 = OFF
                                                            1 = ON - phase 1
                                                            2 = ON - phase 2
NLATTENONOFF            int     1       0       rw      Non-Linear echo attenuation.
                                                            0 = OFF
                                                            1 = ON
NONSTATNOISEONOFF       int     1       0       rw      Non-stationary noise suppression.
                                                            0 = OFF
                                                            1 = ON
NONSTATNOISEONOFF_SR    int     1       0       rw      Non-stationary noise suppression for ASR.
                                                            0 = OFF
                                                            1 = ON
RT60                    float   0.9     0.25    ro      Current RT60 estimate in seconds
RT60ONOFF               int     1       0       rw      RT60 Estimation for AES. 0 = OFF 1 = ON
SPEECHDETECTED          int     1       0       ro      Speech detection status.
                                                            0 = false (no speech detected)
                                                            1 = true (speech detected)
STATNOISEONOFF          int     1       0       rw      Stationary noise suppression.
                                                            0 = OFF
                                                            1 = ON
STATNOISEONOFF_SR       int     1       0       rw      Stationary noise suppression for ASR.
                                                            0 = OFF
                                                            1 = ON
TRANSIENTONOFF          int     1       0       rw      Transient echo suppression.
                                                            0 = OFF
                                                            1 = ON
VOICEACTIVITY           int     1       0       ro      VAD voice activity status.
                                                            0 = false (no voice activity)
                                                            1 = true (voice activity)

Si on souhaite la valeur actuellement configurée pour un paramètre, par exemple si l’AEC est activé ou non :

sudo python tuning.py ECHOONOFF

Ce qui nous donne :

pi@raspberrypi:~/usb_4_mic_array $ sudo python tuning.py ECHOONOFF
ECHOONOFF: 1
pi@raspberrypi:~/usb_4_mic_array $

Il est donc activé. si je souhaite le désactiver :

sudo python tuning.py ECHOONOFF 0

Le problème c’est qu’il perd les réglages après redémarrage… Donc, il va falloir faire un script qui sera exécuté à chaque redémarrage du pi, si on souhaite rendre persistent nos modifs.

pi@raspberrypi:~/usb_4_mic_array $ nano myconfig.sh

Comme je suis un gars sympa, tu as juste à recopier le script ci dessous

sudo python tuning.py MIN_NS
sudo python tuning.py MIN_NS_SR
sudo python tuning.py MIN_NN
sudo python tuning.py MIN_NN_SR
sudo python tuning.py HPFONOFF
sudo python tuning.py AECNORM
sudo python tuning.py GAMMA_NN
sudo python tuning.py GAMMA_NN_SR
sudo python tuning.py GAMMA_NS
sudo python tuning.py GAMMA_NS_SR
sudo python tuning.py NLAEC_MODE
sudo python tuning.py ECHOONOFF
sudo python tuning.py NLATTENONOFF
sudo python tuning.py NONSTATNOISEONOFF
sudo python tuning.py NONSTATNOISEONOFF_SR
sudo python tuning.py STATNOISEONOFF
sudo python tuning.py STATNOISEONOFF_SR
sudo python tuning.py TRANSIENTONOFF

On oublie pas de rendre exécutable le script et on peut le lancer pour voir le résultat.

pi@raspberrypi:~/usb_4_mic_array $ chmod +x myconfig.sh
pi@raspberrypi:~/usb_4_mic_array $ ./myconfig.sh

tel qu’il est là, il ne fait que t’afficher la config en cours. Mais si tu souhaites modifier une valeur, tu l’ajoutes au bout de la ligne.

Et là, je vois arriver la question tel le la météorite qui a mis fin aux dinosaures… Quels sont les meilleurs réglages ? Hé bien de la même façon, tu vois arriver la réponse…

Ça dépend ! Ce qui fonctionnera chez moi, ne fonctionnera pas obligatoirement chez toi. En gros, il va falloir que tu fasses des tests. Tu as les valeurs minimales et maximales pour chaque paramètre dans le tableau un peu plus haut. quand c’est 0 ou 1, ça veut 0 désactiver et 1 activer.

Ah, et j’ai oublié de dire. Attention, les paramètres qui sont “ro“, ça veut dire Read Only. Ca veut dire qu’elle donne une info à un instant T. Ce n’est pas un paramètre réglable. Alors que “rw“, qui veut dire Read Write, ça, ce sont bien des paramètres.

Pour le TP, laisse les réglages par défaut, tu pourras jouer avec ensuite !

Récupérer un morceau de musique

il va bien falloir pour tester l’AEC qu’on joue un morceau de musique. Alors, je vais donner une solution ici mais sinon, je te laisserai le soin de chercher une autre si celle-ci ne te convient pas 🙂

Sachant que j’ai un NAS avec un partage sur lequel j’ai de la musique, je vais monter vite fait ce parage dans un répertoire et aller y récupérer un morceau de musique

sudo mkdir /mnt/music
sudo mount -t cifs -o username=utilisateur,password=motdepasse //nas/music /mnt/music

Évidemment, tu remplaces utilisateur et motdepasse par un utilisateur qui a accès à ton partage…

Et voilà, tu peux aller naviguer dans /mnt/music et aller récupérer le morceau de ton choix 🙂

Pour démonter proprement :

sudo umount /mnt/music

perso, j’ai mis le morceau à la racine de mon home, c’est à dire /home/pi

La suite ?

Alors comme il y a 2 moyens de gérer le son sous linux, ALSA et PulseAudio, ce TP fera les mêmes exercices pour les 2 !

2 Comments

  1. Bonjour cedcox,
    Merci beaucoup pour tes guides très détaillés et qui plus est : écrits de manière sympa et ludique !
    Tu parles de temps en temps du respeaker core v2. J’en ai un en ma possession et je ne demandais si je pouvais avoir un avis dessus ?
    Il semble déjà plus musclé que le respeaker mic array, mais aussi équipe de plus de places dédiées au traitement de la voix (aec, doa, ns, wakeword, etc…)
    Que penses-tu de la bestiole ?
    J’aimerai tirer meilleur parti de ses capacités mais je ne sais pas trop par où commencer.
    Installer rhasspy dessus ou bien se baser sur respeakerd et dialoguer avec l’api rhasspy ?
    Comme tu le vois c’est un peu flou pour moi ^^

    En ce moment je l’utilise comme satellite rhasspy mais j’ai l’impression qu’on peut mieux faire

    Une idée ?
    Merci d’avance et merci pour tes guides !

    Jérôme

    • Bonjour Jerôme,

      Le respeaker core v2 est plus complet parce qu’il contient déjà de quoi faire tourner le système d’exploitation. C’est un “tout-en-un” qui regroupe un raspberry et un mic array v2 qui n’est qu’une carte son en quelque sorte.
      Après, je ne connais pas les caractéristiques techniques exactes du core v2, mais je pense que ça doit se rapprocher des mêmes composants que le mic array.
      Donc pour tes questions, je n’ai pas d’idées ou de piste pour un cas qui marchera mieux qu’un autre. Certainement les essayer 🙂

      Ced

Poster un Commentaire

Votre adresse de messagerie ne sera pas publiée.


*


Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.