La bibliothèque dynakit.cpp de studyvox

Je décris dans cette page, les principales fonctions de la bibliothèque dynakit.cpp

J'explique ensuite comment utiliser ce kit dynamique, pour créer des applications personnelles.

Ces explications sont illustrées par la construction d'un synthétiseur vocal, ainsi que la construction d'un synthétiseur musical.

Le modèle winmain.cpp

Il est toujours pénible, de se familiariser avec les fonctions d'une bibliothèque, car les explications destinées aux programmeurs sont plus ou moins claires !

Le plus simple est de proposer un moule, dans lequel il suffira d'ajouter quelques lignes de code, pour constater l'action produite, après la compilation de la source ainsi modifiée.

J'ai placé tous les fichiers indispensables pour cela, dans le sous-répertoire source du répertoire dyna. Le modèle que vous utiliserez pour créer vos applications pour windows, s'appelle winmain.cpp, que vous compilerez avec compwinm.bat La compilation est faite avec bcc32 de la version 5.0 de borland. Si vous possèdez un autre compilateur, vous devrez vraisemblablement effectuer des changements dans les sources .cpp, car toutes les fonctions utilisées, ne seront pas portables pour tout compilateur c++. C'est en particulier le cas, pour le compilateur vcc de visualstudio, de microsoft !

Dans le modèle winmain.cpp, j'ai placé les instruction #include "dynakit.cpp" et #include "kitinit.cpp" Elles vous évitent d'avoir à vous plonger dans la description des variables globales, et de leur initialisation.

Le fichier kitinit.cpp n'est indispensable, que si vous utilisez des fonctions de la bibliothèque dynakit.cpp, qui utilisent des variables globales, pour lesquelles on doit imposer des valeurs initiales. On y déclare en particuliers, des tableaux de caractères assez volumineux, qui sont indispensables pour la création dynamique des données, utilisées par la fonction dynaplay. Vous pouvez vous passer de ce fichier dans certaines applications, mais pour cela, vous devez être sûr de n'utiliser aucune de ces variables ! La présence des tableaux de grande taille, necessite la compilation de winmain.cpp avec bcc32.exe et non bcc.exe

Vous ne modifierez ces fichiers, que pour personnaliser la bibliothèque dynakit, dans une étape ultérieure.

winmain.cpp est une source pour windows, qui ne possède pas de fenêtre propre, car l'objectif recherché ici, est de traiter des données chargées à partir de la mémoire morte, avec les outils sonores de mmsystem.h Si vous voulez incorporer dynakit dans une application windows standard, qui possède sa boucle GetMessage, son environnement sdi ou mci... il vous suffira d'introduire les instructions précédantes, dans la source de son winmain. Remarque : j'ai utilisé des instructions propres au c++, dans la bibliothèque, ce qui vous oblige de compiler votre projet en c++ et non en c. La démarche suivante consiste à appeler une fonction de la bibliothèque, en écrivant une ligne de code dans winmain.cpp

Le fichier dyna.h pour le prototype des fonctions de la bibliothèque dynakit

Vous trouverez le prototype de ces fonctions dans dyna.h Consultez le lien suivant, pour prendre connaissance de ces prototypes.

dyna.h : prototype des fonctions de dynakit.cpp

On y trouve des fonctions pour l'initialisation du fabriquant, comme init, lonliste, ficlonliste. Elles sont utilisées dans kitinit.cpp

On trouve des fonctions pour les entrées/sorties comme :

entrer, sortir, entrerpage, donnerligne, charger, copier, saisir, saisirmuet

Nous verrons que ces fonctions permettent de modifier des paramètres d'environnement, à partir d'instructions simples, que l'on peut placer dans des fichiers texte.

D'autres fonctions facilitent le traitement des chaînes de caractère, comme mid, lmid, coder, coderphr, couper, hdrdata...

Enfin, le traitement sonore des données est facilité par les fonctions :

formuler, epeler, dynaplay,mciplay, mciplaymot, analyse, synthese, executer...

Parmi ces fonctions, on distingue les fonctions diredyna, lire et gram La fonction lire est une lecture sonore moins sophistiquée que diredyna. diredyna permet de lire successivement des sources sonores contenues dans des .wav, ou d'ajouter ces sources les unes aux autres, pour en faire une donnée .wav qui est ensuite envoyée à la carte sonore. La lecture peut être synchrone ou asynchrone. En mode asynchrone, le son est en arrière plan, et le programme continue son exécution, tandis qu'en mode synchrone, l'exécution est stoppée pendant la lecture sonore, puis reprend quand celle-ci est terminée. Le mode asynchrone est utile pour interrompre la lecture sonore, en envoyant par exemple une nouvelle donnée à la carte sonore. On utilise cette remarque pour la lecture des ligne d'unfichier, pour la valeur iparle=2 ou iparle=3 (voir plus loin)

diredyna permet d'utiliser 9 modes de lecture, que l'on peut choisir avec la variable globale imode (entre 0 et 8) Les modes 0 1 et 2 sont plus particulièrement adaptés à une synthèse, qui peut être réalisée par un moteur de synthèse que l'on place dans la fonction gram

Vous trouverez plus loin un exemple de moteur avec la fonction gram00, pour la langue française.

Les autres modes permettent la lecture par caractère ou symbole, par mot... La lecture peut se faire dans plusieurs langues, en recherchant les données sonores dans des répertoires de langue, définis par la variable globale ilang et par la fonction chemin.

Les chemins des répertoires de langue, sont associés aux nom suivants, pour ilang entre 0 et 8 : 0=studyvox, 1=espavox, 2=italivox, 3=anglavox

4=musivox, 5=germavox, 6=mathvox

7=arabivox, 8=vox

Le nom studyvox est associé au français, et le nom vox sert pour une langue personnelle. Les autres noms désignent clairement la langue concernée.

On remarque que la musique et les mathématiques sont considérées comme des langues, ce qui permet de leur associer des données sonores personnalisées.

La fonction chemin définit la variable globale chemlang, qui contient le nom du répertoire de langue.

Les sources sonores placées dans les répertoires de langues sont des.wav, qui permettent la lecture sonore dans les différents modes. Les caractères ou synboles ont pour nom leur code ASCII On peut y ajouter tout .wav de nom quelconque, qui sera lu en mode mot, pour imode=7

En plus des répertoires de langues, qui sont tous des sous-répertoire du répertoire de base, défini par la variable globale chembase, on trouve le répertoire de nom wav, qui contient des .wav nécessaires pour la lecture en mode formule, pour imode=4.

Le fichier kitpho.ini et les paramètres d'environnement

Le nom du répertoire de base (ou mieux, son chemin) peut être choisi librement. Cette souplesse est intéressante, pour permettre de développer autant de données sonores que l'on veut. Toutes les variables globales, que nous appelerons paramètres d'environnement, peuvent être définis très simplement dans des fichiers de lecture.

Le fichier kitpho.ini en est un exemple. La syntaxe, pour l'affectation d'une valeur à un paramètre est :

para=valeur où para est le nom d'un paramètre d'environnement, et valeur est la valeur que l'on désire lui affecter.

Par exemple : chembase=\sv3\ Cette affectation définira comme répertoire de base, le répertoire de nom sv3 de l'unité courante.

Les variables d'environnement sont des chaînes de caractères ou des entiers. Les chaînes permettent de définir des chemin, des listes de séparateurs... On trouve les chaînes suivantes :

chembase chemlang ficlec listeind listesep

Les paramètres dont les valeurs sont des nombres entiers, ont des noms qui commencent par la lettre i :

isel imode ivoix ilang iparle ipage iligne ipos

Les paramètres définis dans les fichiers de lectures, sont traités dynamiquement par les applications, grâce aux fonctions saisir para et saisirparamuet. Comme son nom l'indique, la fonction saisirparamuet permet une saisie muette, sans que l'utilisateur n'entende la valeur de la modification. Cela permet de traiter tous les modes sonores, qui mélangeront les formules, les langues... dans un même fichier de lecture !

La liste des séparateurs écrite dans listesep, sert pour reconnaître le début et la fin des mots, pour la lecture des formules. De plus, ces séparateurs sont prononcés, s'ils ont leur echo sonore dans un .wav de la langue courante. La liste des séparateurs d'indications, contenue dans listeind, sert pour l'analyse et la synthèse des données sonores. En effet, on peut faire plus que lire des fichiers de lecture, car il est très facile de construire des .wav (ou des .mid) en leur affectant des indications variées pour leur analyse et leur synthèse.

La chaîne fic sert pour définir le fichier de lecture.

la variable isel permet de sélectionner le clavier, pour isel=0 ou le fichier de lecture courant, pour isel=1. On peut envisager d'affecter d'autres valeurs à isel, pour lire l'écran, ou un fichier particuliers, comme celui qui contiendrait les sorties DOS...

Le paramètre ivoix permet de choisir la hauteur de la voix (entre 30 et 50 de préférence)

La fonction diredyna utilise le paramètre iparle, pour la lecture sonore synchrone successive, pour iparle=1. Pour iparle=2 ou 3, diredyna construit le .wav qui contient l'ensemble des données sonores rencontrées dans le traitement de la chaêne phr entrée. Le .wav correspondant est copié sur le disque dur, puis il est lu en mode asynchrone, ce qui permet une interruption de la lecture si on le désire. Comme on connaît toutes les sources sonores qui ont permis de construire ce .wav, on en profite pour copier sur le disque dur, un fichier .ind, qui contient toutes les indications nécessaires pour l'analyse et la synthèse du .wav Pour iparle=2, les fichiers sont copiés dans le répertoire de base, avec les noms prv.wav et prv.ind Pour iparle=3, les fichiers sont copiés dans le répertoire ou se trouve winmain.exe, avec les noms prvi_j.wav et prvi_j.ind, où i et j sont les numéros de page et de ligne du fichier de lecture

Tous ces fichiers peuvent être utilisés pour des cours ou des aides sonores, et ils peuvent être effacés simplement par la commande erase prv*.*

Développement des outils d'analyse et de synthèse

Je vais maintenant décrire comment on peut développer des outils d'analyse et de synthèse, qui utilisent des sources sonores et des fichiers d'indications.

Je commence par décrire les applications analmci.exe et syntmci.exe, que vous obtenez en compilant analmci.cpp et syntmci.cpp, par : bcc32 -W analmci ou bcc32 -W syntmci N'oubliez pas l'option -W pour le compilateur, car les sources contiennent des instructions comme WinMain, PlaySound... qui nécessitent windows.

Les données nécessaires pour l'analyse ou pour la synthèse, sont saisies par la fonction entrer, ou par la fonction entrerpage. On peut ainsi disposer des données de prv.txt, prv1_1.ind et de prv.mci

L'analyse d'une source mci, dont le nom est dans prv.mci, consiste à rechercher les indications successives, qui sont contenues dans prv1_1.ind. Le fichier prv.txt peut contenir une description générale de la source mci, qui précise l'intérêt des indications qui sont associées à cette source mci.

La synthèse des données associées à la source mci, consiste à utiliser les indications pour traiter une chaîne de caractère. Pour cela, il suffit de rechercher la suite des portions de données, associée aux mots, ou aux caractères de la chaîne.

Les instructions que vous lirez dans les sources analmci.cpp et syntmci.cpp s'expliquent d'elles-mêmes, et ne nécessitent pas d'explications détaillées. Vous pouvez vous en inspirer, pour construire des synthèses plus élaborées, pour lesquelles vous développerez des règles grammaticales, qui transformeront les chaînes à traiter, avant de rechercher l'indication souhaitée.

Indications pour la construction d'un synthétiseur musical

Par exemple, vous pouvez facilement construire un synthétiseur musical, en plaçant dans musipho.wav la suite des notes, qui correspond à la tessiture d'un instrument, puis dans prv1_1.ind, vous écrirez les indications pour le nom des notes de musique et de leur début et de fin, correspondant à des rondes.

Les règles grammaticales reconnaîtront dans une chaîne de caractère, la durée des notes, leur altération... Le synthétiseur permettra d'écouter la tablature associée à cette chaîne, en la jouant note par note, ou mesure par mesure... Inversement, l'analise de la tablature que l'on entendra, permettra de retrouver le nom des notes jouées, ainsi que leur durée... Mieux encore, vous pourrez changer d'instrument, en remplaçant simplement musipho.wav, par un autre fichier de banque sonore, sans avoir à modifier votre programme.

Vous pouvez consulter l'exemple que j'ai placé dans le répertoire dynakit. J'ai choisi dans prv.mci, le fichier musipho.wav qui contient 5 notes de guitare. Le fichier prv1_1.ind contient les indications 30 31 32 33 et 34, qui correspondent à ces notes. Le fichier prv.txt explique ce que l'on peut faire avec ces données. analmci.exe fait jouer les notes de la banque musicale. syntmci joue la tablature 32 31 30 note par note. Cet exemple simpliste n'a aucun intérêt musical, mais je l'ai choisi pour illustrer la facilité avec laquelle vous pourrez développer par vous-même des synthèses variées.

Indications pour la construction d'un synthètiseur vocal

Dans ce qui suit, j'envisage des applications plus complexes, qui nécessitent de modifier la bibliothèque dynakit.cpp, et les paramètres d'environnement déclarés dans kitinit.cpp

Voici les modifications que j'ai effectuées, pour construire à partir des fichiers du répertoire dyna, le sous-répertoire source du répertoire gramdyna, qui contient un synthétiseur vocal pour la langue française.

Pour cela, j'ai copié intégralement le répertoire dyna\source, dans un répertoire appelé gramdyna\source. J'ai modifié kitinit.cpp et dynakit.cpp, c'est pourquoi j'ai changé leur nom en graminit.cpp et dynagram.cpp, pour éviter les confusions, par la suite. Pour que la synthèse vocale soit entièrement dynamique, j'ai placé l'ensemble des 32 phonèmes retenus, dans le fichier grampho.wav

Pour optimiser la recherche des données associées à chacun de ces phonèmes, j'ai opté pour un traitement des indications, qui diffère légèrement de ce qui a été décrit précédemment.

Ici, j'ai choisi d'utiliser un tableau d'indice, qui contient les longueurs en octets, des phonèmes placés dans la banque de phonème grampho.wav

Vous trouverez des explications sur le synthétiseur vocal, dans le répertoire gramdyna. On y trouve aussi la commande winmain.exe, qui donne une démonstration des possibilités offertes, pour la lecture des textes français, qui peuvent contenir des formules, des symboles ou des caractères isolés, des nombres, des indications pour les paramètres d'environnement... Toutes les sources pour la compilation de winmain, sont dans le sous-répertoire source de gramdyna. Elles ont été copiées à partir de dynakit\source, et la principale modification concerne dynakit.cpp Plus précisément, on a ajouté dans la fonction diredyna de dynakit.cpp, l'appel à la fonction gram, qui transforme un texte écrit en français, en une suite de phonèmes.

La bibliothèque bibli.c de studyvox

Pour que le programmeur ait le moins de travail à effectuer, j'ai regroupé toutes les instructions nécessaires au moteur grammatical, dans la bibliothèque bibli.c, qui doit être ajoutée au projet, par une instruction #include "bibli.c"

Cette bibliothèque utilise des variables globales et des fonctions, dont les prototypes sont dans var.h var_ext.h et fn_ext.h, que l'on inclue au même titre que bibli.c On dispose alors de la fonction gram00, que l'on appelle dans la fonction gram.

Un autre exemple d'utilisation de la bibliothèque dynakit, est donnée dans le répertoire musidyna\source. Cette application ressemble à celle de gramdyna\source, mais on à choisi dans musipho.wav, des données sonores qui correspondent aux notes d'une gamme chromatique, jouées sur une guitare. Vous trouverez des explications sur cette application dans musidyna. Vous pouvez vous inspirer de toutes les sources .cpp, que vous trouverez dans les sous-répertoires de dynakit, gramdyna, musidyna. Ces sources utilisent largement les fonctions de la bibliothèque dynakit.cpp

Pour une description complète de ces fonctions, consultez le lien suivant.

description détaillée des fonctions de la bibliothèque dynakit

retour au sommaire de la rubrique dynakit