📍 Article principal : Asterisk + FreePBX en production pour PME ouest-africaine. Ce tutoriel construit un serveur vocal interactif trilingue français, wolof et bambara, depuis la génération des invites jusqu’au dialplan complet.
Un standard téléphonique qui n’accueille les clients qu’en français passe à côté d’une partie significative de la clientèle au Sénégal et au Mali. Les administrations, les banques, les services de santé et les centres d’appels sérieux proposent désormais le choix de la langue dès la première seconde de l’appel. Asterisk gère cela nativement via son module IVR : la détection passe par un appui DTMF (1 français, 2 wolof, 3 bambara), et le dialplan charge ensuite les invites vocales du bon dossier. Ce tutoriel construit un IVR trilingue de bout en bout, en utilisant la synthèse vocale Coqui TTS pour générer les invites en français et des enregistrements de voix humaines pour le wolof et le bambara.
Prérequis
- FreePBX 17 ou Asterisk 21+ déjà installé et configuré
- Trunk SIP fonctionnel (voir tutoriel SIP trunk Sonatel/Orange CI) et serveur sécurisé (voir tutoriel sécurisation Asterisk)
- Outil de synthèse vocale : Coqui TTS (open source) ou Amazon Polly (commercial, voix Léa pour le français)
- Pour wolof et bambara : prévoir un locuteur natif pour enregistrer les invites en studio amateur (téléphone Android + Voice Recorder Pro suffit)
- Niveau : intermédiaire
- Temps estimé : 4 à 6 heures
Étape 1 — Préparer la structure des dossiers d’invites
Asterisk attend les invites vocales dans /var/lib/asterisk/sounds/ avec un sous-dossier par langue. Le format préféré est .wav mono 16-bit 8 kHz pour la compatibilité G.711, ou .gsm pour économiser le stockage. Créer la structure :
cd /var/lib/asterisk/sounds/ mkdir -p fr wo bm chown -R asterisk:asterisk fr wo bm ls -la # fr/ → invites en français # wo/ → invites en wolof (ISO 639-1) # bm/ → invites en bambara (ISO 639-1)
Les codes ISO utilisés (fr, wo, bm) correspondent à la norme ISO 639-1. Asterisk utilise la variable de canal CHANNEL(language) pour basculer automatiquement vers le sous-dossier correspondant. Si une invite n’existe pas dans la langue active, Asterisk retombe sur le dossier en/ par défaut — penser à dupliquer au minimum les invites système critiques.
Étape 2 — Générer les invites françaises avec Coqui TTS
Coqui TTS est un projet open source de synthèse vocale qui produit une qualité audio comparable aux solutions commerciales pour le français. L’installation se fait via pip :
apt install python3-pip python3-venv ffmpeg python3 -m venv /opt/coqui-tts source /opt/coqui-tts/bin/activate pip install TTS # Lister les modèles français disponibles tts --list_models | grep -i french # Choisir tts_models/fr/css10/vits ou tts_models/fr/mai/tacotron2-DDC
Le premier appel télécharge le modèle (300 à 600 Mo). Pour générer une invite :
tts --model_name "tts_models/fr/css10/vits" \
--text "Bienvenue chez ITSkillsCenter. Pour le français, tapez 1." \
--out_path /tmp/welcome_fr_raw.wav
# Convertir au format Asterisk : mono 16-bit 8kHz
ffmpeg -i /tmp/welcome_fr_raw.wav -ar 8000 -ac 1 -sample_fmt s16 \
/var/lib/asterisk/sounds/fr/welcome.wav
chown asterisk:asterisk /var/lib/asterisk/sounds/fr/welcome.wav
Tester immédiatement depuis le CLI Asterisk avec asterisk -rx "channel originate Local/100@from-internal application Playback /var/lib/asterisk/sounds/fr/welcome". Le poste 100 doit recevoir l’appel et entendre l’invite. Si la qualité paraît saccadée, augmenter à 16 kHz mais en utilisant un codec wideband (G.722 ou Opus) bout-en-bout.
Construire un script bash qui itère sur un fichier invites_fr.txt contenant le code d’invite et le texte :
#!/bin/bash
# generate_fr.sh
while IFS='|' read -r code texte; do
tts --model_name "tts_models/fr/css10/vits" \
--text "$texte" --out_path /tmp/${code}_raw.wav
ffmpeg -i /tmp/${code}_raw.wav -ar 8000 -ac 1 -sample_fmt s16 \
/var/lib/asterisk/sounds/fr/${code}.wav -y
done < invites_fr.txt
Le fichier invites_fr.txt contient une ligne par invite : welcome|Bienvenue chez ITSkillsCenter. Pour le français, tapez 1. Pour le wolof, tapez 2. Pour le bambara, tapez 3. Cette approche permet de régénérer toutes les invites d’un coup quand le script évolue.
Étape 3 — Enregistrer les invites en wolof et bambara
Les modèles open source de synthèse vocale en wolof et bambara existent (projets Masakhane, AfriSpeech-200) mais leur qualité reste en deçà du français pour un contexte professionnel en 2026. La solution pratique consiste à enregistrer un locuteur natif. Un téléphone Android avec une application comme Easy Voice Recorder en mode WAV non compressé suffit largement. Privilégier une pièce calme avec rideaux et tapis pour réduire la réverbération.
Une fois les fichiers récupérés, les normaliser au format Asterisk :
# Pour chaque enregistrement source
ffmpeg -i welcome_wo_source.wav \
-ar 8000 -ac 1 -sample_fmt s16 \
-af "loudnorm=I=-23:TP=-2:LRA=7" \
/var/lib/asterisk/sounds/wo/welcome.wav
# Le filtre loudnorm aligne le volume sur le standard EBU R128
# évitant les invites trop fortes ou trop faibles dans l'IVR
Reproduire le même travail pour le bambara dans /var/lib/asterisk/sounds/bm/. À la fin de cette étape, chaque dossier contient au minimum : welcome.wav, menu_principal.wav, service_indisponible.wav, au_revoir.wav, patientez.wav.
Étape 4 — Construire l’IVR de sélection de langue dans FreePBX
Dans l’interface FreePBX 17, naviguer dans Applications → IVR → Add IVR. Donner un nom (ivr_langue), définir le délai de saisie à 5 secondes, le nombre de tentatives à 3. Dans le champ Announcement, sélectionner l’invite welcome (qui annoncera dans les trois langues le choix possible).
Définir trois entrées DTMF : la touche 1 redirige vers un IVR ivr_fr, la touche 2 vers ivr_wo, la touche 3 vers ivr_bm. Avant chaque redirection, on positionne la variable de canal CHANNEL(language) pour qu’Asterisk utilise automatiquement le bon dossier de sons. Cela passe par un Custom Destination ou par un dialplan custom dans extensions_custom.conf :
[set-language-fr] exten => s,1,Set(CHANNEL(language)=fr) exten => s,n,Goto(ivr-2,s,1) [set-language-wo] exten => s,1,Set(CHANNEL(language)=wo) exten => s,n,Goto(ivr-3,s,1) [set-language-bm] exten => s,1,Set(CHANNEL(language)=bm) exten => s,n,Goto(ivr-4,s,1)
Les numéros ivr-2, ivr-3, ivr-4 correspondent aux IDs internes attribués par FreePBX aux IVR ivr_fr, ivr_wo et ivr_bm respectivement. Ces IDs sont visibles dans la liste des IVR. Créer un Custom Destination par langue qui pointe vers set-language-fr,s,1 et l’utiliser comme cible des trois entrées du menu de sélection.
Étape 5 — Construire chaque IVR de langue
Pour chaque langue, créer un IVR dédié avec le menu principal : 1 pour le service commercial, 2 pour le support technique, 3 pour la comptabilité, 0 pour parler à une personne. L’invite Announcement de chaque IVR pointe vers le fichier dans le dossier de la bonne langue : fr/menu_principal pour ivr_fr, wo/menu_principal pour ivr_wo, etc.
Chaque entrée DTMF dirige vers une queue, une extension ou une autre destination. Penser à configurer une destination par défaut en cas de saisie invalide (réessayer le menu) et une destination de timeout (transférer vers le standard humain).
Étape 6 — Tester et ajuster
Brancher l’IVR de sélection de langue à la route entrante du SDA principal : Connectivity → Inbound Routes → DID principal → Set Destination → IVR → ivr_langue. Appliquer la configuration et tester depuis un mobile externe.
Surveiller en parallèle la console Asterisk pour confirmer le bon enchaînement :
asterisk -rvvvv
# Lors de l'appel, observer :
# Executing [s@ivr-1:1] Background("PJSIP/...", "custom/welcome")
# Executing [s@set-language-wo:1] Set(CHANNEL(language)=wo)
# Executing [s@ivr-3:1] Background("PJSIP/...", "custom/menu_principal")
# Le path résolu doit pointer vers /var/lib/asterisk/sounds/wo/menu_principal.wav
Si l’invite jouée reste en français malgré le choix wolof, vérifier deux choses : le Custom Destination est bien configuré pour Set CHANNEL(language) avant le Goto, et le fichier wo/menu_principal.wav existe avec les bonnes permissions asterisk:asterisk.
Heures ouvrées et jours fériés CEDEAO
Un IVR professionnel doit basculer automatiquement en mode nuit après les heures ouvrables et fermer pendant les jours fériés. FreePBX gère cela via les modules Time Conditions et Time Groups. Créer un Time Group heures_ouvrees qui couvre du lundi au vendredi de 8h à 18h et le samedi de 9h à 13h. Créer un Time Condition standard_principal qui pointe vers l’IVR de sélection de langue pendant les heures ouvrées et vers une boîte vocale d’accueil hors heures.
Pour les jours fériés, deux approches possibles. La première, manuelle : créer un Time Group jours_feries_2026 avec les dates précises de l’année (Korité, Tabaski, Maouloud, fête nationale, Tamkharit, Indépendance). L’inconvénient : les fêtes musulmanes mobiles (Korité, Tabaski, Maouloud) glissent chaque année selon le calendrier hégirien et il faut mettre à jour la liste annuellement. La seconde approche, plus robuste : un script Python AGI qui consulte une API publique de calendrier ouest-africain et bascule automatiquement le canal sur la branche « férié » du dialplan. Quelques fournisseurs proposent un flux JSON gratuit (par exemple Calendar API de Nager.Date pour les fêtes civiles), à compléter manuellement avec les fêtes religieuses.
Mesurer la qualité de la synthèse vocale
Une synthèse vocale médiocre ruine immédiatement l’image professionnelle d’une PME. Trois métriques permettent de juger objectivement la qualité : le naturel perçu (subjectif, à valider par un panel de 5 à 10 personnes), l’intelligibilité (pourcentage de mots correctement compris à la première écoute) et la cohérence prosodique (rythme et intonation adaptés au sens). Pour le français, les modèles VITS de Coqui TTS atteignent un naturel de 4,1/5 en moyenne sur des phrases neutres — comparable à Polly ou Azure Neural en 2026. Les modèles plus anciens type Tacotron2-DDC plafonnent autour de 3,5/5.
Pour les langues africaines, la situation est plus nuancée. Les datasets d’entraînement pour le wolof, le bambara ou le pular restent limités à quelques dizaines d’heures de parole, contre des milliers d’heures pour le français. La qualité des modèles open source actuels (projets Masakhane, AfriSpeech) atteint 3,2 à 3,5/5 sur le wolof — utilisable pour des messages courts mais perçu comme robotique sur les phrases longues. La voix humaine enregistrée reste donc la meilleure option pour les invites longues ou émotionnellement chargées (excuses pour un retard, condoléances dans un service funéraire, etc.).
Statistiques d’utilisation par langue
Mesurer la répartition réelle des choix de langue par les appelants permet d’investir intelligemment dans les ressources humaines (recrutement d’agents bilingues) et dans la qualité des invites. Asterisk journalise dans le CDR la variable userfield qui peut être positionnée par le dialplan : Set(CDR(userfield)=lang_wo). Un dashboard SQL simple compte ensuite les choix sur 30 jours : SELECT userfield, COUNT(*) FROM cdr WHERE calldate > NOW() - INTERVAL 30 DAY GROUP BY userfield.
Sur un standard sénégalais grand public, les statistiques observées tournent typiquement autour de 55 % de wolof, 35 % de français, 8 % de pular et 2 % d’autres choix. Pour une PME B2B avec une clientèle entreprise, le ratio s’inverse : 70 % de français, 25 % de wolof, 5 % d’autres. Ces chiffres orientent les priorités de qualité — investir d’abord sur la langue majoritaire de la cible commerciale, puis sur la deuxième.
DTMF avancé et reconnaissance vocale
Pour les déploiements ambitieux, l’IVR DTMF peut être complété par une reconnaissance vocale qui accepte le nom du service en langage naturel (« commercial », « support », « comptabilité », etc.). Asterisk peut faire dialoguer son dialplan avec un service de reconnaissance via AGI — le module app_speech intégré ou un connecteur vers Whisper en local. Whisper en mode tiny (39M paramètres) tourne sur le même CPU que FreePBX avec une latence de 200 ms pour un échantillon de 3 secondes, suffisant pour un IVR fluide.
L’avantage : l’appelant ne dépend plus du clavier de son téléphone (parfois absent sur les vieux postes Nokia 105 utilisés en zone rurale) et l’expérience est plus naturelle. L’inconvénient : la reconnaissance dégrade fortement avec le bruit ambiant — un appel passé depuis un marché de Sandaga ne fonctionne pas. Toujours conserver le DTMF en parallèle comme fallback.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| Invite jouée saccadée ou hachée | Format incompatible avec le codec négocié | Convertir en 8 kHz mono 16-bit, ou utiliser .gsm si l’opérateur impose ce codec |
| Asterisk joue toujours la version anglaise | Variable language non positionnée ou fichier manquant | Vérifier core show channel pendant l’appel, confirmer la présence du fichier dans le dossier de langue |
| Coqui TTS très lent à générer | Premier appel télécharge le modèle, ou pas de GPU disponible | Pré-télécharger les modèles, ou utiliser un VPS GPU pour les générations massives |
| Volume des invites wolof/bambara très différent du français | Pas de normalisation du loudness | Appliquer le filtre ffmpeg loudnorm systématiquement |
Adaptation au contexte ouest-africain
Le wolof reste la langue véhiculaire la plus parlée au Sénégal (environ 80 % des locuteurs en compréhension), suivi du français comme langue officielle. Au Mali, le bambara est compris par plus de 80 % de la population. En Côte d’Ivoire, le dioula joue un rôle similaire dans le nord. Une PME ivoirienne peut donc adapter ce tutoriel en remplaçant bm/ par dyu/ (dioula). Pour les centres d’appels qui couvrent toute la sous-région, ajouter le pular et le soninké élargit encore l’audience accessible. Penser aussi à l’arabe pour la diaspora subsaharienne et les zones du Sahel — code ISO ar.
Synchroniser les invites avec un dépôt Git
Maintenir les invites vocales à jour devient vite ingérable quand la PME en accumule plusieurs centaines. La bonne pratique consiste à versionner le dossier /var/lib/asterisk/sounds/custom/ dans un dépôt Git privé (Gitea, Forgejo ou GitLab self-hosted). Chaque modification d’invite passe par un commit nominatif, avec message précisant la raison du changement (correction orthographique, mise à jour tarifaire, nouveau service annoncé).
Un hook post-receive sur le serveur Git déploie automatiquement les invites mises à jour vers le serveur Asterisk via rsync chiffré, puis recharge le module. L’opération devient ainsi traçable, réversible (rollback Git en cas d’erreur) et auditable — précieux pour les services réglementés où la moindre invite financière peut faire l’objet d’un contentieux client. Le dépôt sert aussi de back-up automatique : en cas de perte du serveur principal, les invites sont reconstruites en quelques minutes à partir du repo.
Pour parfaire l’expérience appelant, ajouter une option zéro qui transfère immédiatement vers un agent humain à tout moment dans l’arborescence de l’IVR. Beaucoup d’appelants ouest-africains préfèrent contourner le menu vocal et parler directement à une personne, surtout quand l’appel est passé depuis un mobile en mouvement où l’interaction DTMF est compliquée. Configurer dans chaque IVR la touche 0 comme raccourci vers la queue commerciale ou le standard humain. Mesurer ensuite le pourcentage d’appelants qui empruntent ce raccourci : au-dessus de 30 %, c’est le signe que l’arborescence est trop complexe ou que les invites sont mal formulées et qu’il faut simplifier.
Pour aller plus loin
🔝 Retour à l’article principal : Asterisk + FreePBX en production pour PME ouest-africaine. Tutoriels précédents : configurer le SIP trunk Sonatel/Orange CI et sécuriser Asterisk contre le toll-fraud.
Documentation Coqui TTS sur docs.coqui.ai, gestion multilingue dans Asterisk sur docs.asterisk.org, projet Masakhane pour les langues africaines sur masakhane.io.