Exploration du moteur VoIP Mediastreamer2. Partie 2

Le matériel de l'article est tiré de mon canal zen.

Exploration du moteur VoIP Mediastreamer2. Partie 2

Création d'un générateur de sons

Dans le précédent article Nous avons installé la bibliothèque Media Streamer, les outils de développement et testé leurs fonctionnalités en créant une application d'essai.

Aujourd'hui, nous allons créer une application capable de générer un signal sonore sur une carte son. Pour résoudre ce problème, nous devons connecter les filtres au circuit générateur de son illustré ci-dessous :

Exploration du moteur VoIP Mediastreamer2. Partie 2

Nous lisons le schéma de gauche à droite, c'est la direction dans laquelle se déplace notre flux de données. Les flèches le font également allusion. Les rectangles indiquent les filtres qui traitent les blocs de données et génèrent le résultat. A l'intérieur du rectangle, son rôle est indiqué et le type de filtre est indiqué en majuscules juste en dessous. Les flèches reliant les rectangles sont des files d'attente de données à travers lesquelles des blocs de données sont transmis de filtre en filtre. En général, un filtre peut avoir de nombreuses entrées et sorties.

Tout commence par la source d'horloge, qui définit le tempo auquel les données sont calculées dans les filtres. Selon son cycle d'horloge, chaque filtre traite tous les blocs de données qui se trouvent à son entrée. Et met les blocs avec le résultat dans la file d'attente. Tout d'abord, le filtre le plus proche de la source d'horloge effectue les calculs, puis les filtres connectés à ses sorties (il peut y avoir plusieurs sorties), et ainsi de suite. Une fois le traitement du dernier filtre de la chaîne terminé, l'exécution s'arrête jusqu'à l'arrivée d'une nouvelle horloge. Les battements, par défaut, suivent un intervalle de 10 millisecondes.

Revenons à notre schéma. Les cycles d'horloge arrivent à l'entrée de la source de silence, c'est un filtre qui est occupé à générer à sa sortie un bloc de données contenant des zéros pour chaque cycle d'horloge. Si l'on considère ce bloc comme un bloc d'échantillons sonores, alors ce n'est rien d'autre que du silence. À première vue, il semble étrange de générer des blocs de données avec du silence - après tout, cela ne peut pas être entendu, mais ces blocs sont nécessaires au fonctionnement du générateur de signaux sonores. Le générateur utilise ces blocs comme une feuille de papier vierge, en y enregistrant des échantillons sonores. Dans son état normal, le générateur est éteint et transmet simplement les blocs d'entrée à la sortie. Ainsi, des blocs de silence parcourent inchangés tout le circuit de gauche à droite pour aboutir dans la carte son. Ce qui prend silencieusement des blocs de la file d'attente connectée à son entrée.

Mais tout change si le générateur reçoit l'ordre de jouer du son, il commence à générer des échantillons sonores et les remplace par des échantillons dans les blocs d'entrée et met les blocs modifiés à la sortie. La carte son commence à jouer du son. Vous trouverez ci-dessous un programme qui met en œuvre le plan de travail décrit ci-dessus :

/* Файл mstest2.c */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/mssndcard.h>
int main()
{
    ms_init();

    /* Создаем экземпляры фильтров. */
    MSFilter  *voidsource = ms_filter_new(MS_VOID_SOURCE_ID);
    MSFilter  *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
    MSSndCard *card_playback = ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
    MSFilter  *snd_card_write = ms_snd_card_create_writer(card_playback);

    /* Создаем тикер. */
    MSTicker *ticker = ms_ticker_new();

    /* Соединяем фильтры в цепочку. */
    ms_filter_link(voidsource, 0, dtmfgen, 0);
    ms_filter_link(dtmfgen, 0, snd_card_write, 0);

   /* Подключаем источник тактов. */
   ms_ticker_attach(ticker, voidsource);

   /* Включаем звуковой генератор. */
   char key='1';
   ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY, (void*)&key);

   /* Даем, время, чтобы все блоки данных были получены звуковой картой.*/
   ms_sleep(2);   
}

Après avoir initialisé le streamer multimédia, trois filtres sont créés : source vide, dtmfgen, snd_card_write. Une source d'horloge est créée.

Ensuite, vous devez connecter les filtres conformément à notre circuit, et la source d'horloge doit être connectée en dernier, car après cela, le circuit commencera immédiatement à fonctionner. Si vous connectez une source d'horloge à un circuit inachevé, il peut arriver que le streamer multimédia plante s'il détecte au moins un filtre dans la chaîne avec toutes les entrées ou toutes les sorties « suspendues en l'air » (non connectées).

La connexion des filtres se fait à l'aide de la fonction

ms_filter_link(src, src_out, dst, dst_in)

où le premier argument est un pointeur vers le filtre source, le deuxième argument est le numéro de sortie source (notez que les entrées et sorties sont numérotées à partir de zéro). Le troisième argument est un pointeur vers le filtre du récepteur, le quatrième est le numéro d'entrée du récepteur.

Tous les filtres sont connectés et la source d'horloge est connectée en dernier (ci-après, nous l'appellerons simplement un ticker). Après quoi notre circuit sonore commence à fonctionner, mais rien n'est encore entendu dans les haut-parleurs de l'ordinateur - le générateur de son est éteint et traverse simplement les blocs de données d'entrée avec silence. Pour commencer à générer une tonalité, vous devez exécuter la méthode de filtrage du générateur.

Nous générerons un signal bicolore (DTMF) correspondant à l'appui sur le bouton "1" du téléphone. Pour ce faire, nous utilisons la fonction ms_filter_call_method() Nous appelons la méthode MS_DTMF_GEN_PLAY, en lui passant comme argument un pointeur vers le code auquel doit correspondre le signal de lecture.

Il ne reste plus qu'à compiler le programme :

$ gcc mstest2.c -o mstest2 `pkg-config mediastreamer --libs --cflags`

Et courir:

$ ./mstest2

Après avoir démarré le programme, vous entendrez un court signal sonore composé de deux tonalités dans le haut-parleur de l'ordinateur.

Nous avons construit et lancé notre premier circuit sonore. Nous avons vu comment créer des instances de filtre, comment les connecter et comment appeler leurs méthodes. Même si nous sommes satisfaits de notre succès initial, nous devons néanmoins faire attention au fait que notre programme ne libère pas la mémoire allouée avant de se terminer. Ensuite article nous apprendrons à nettoyer après nous.

Source: habr.com

Ajouter un commentaire