De Mediastreamer2 VoIP-engine verkennen. Deel 2

Het materiaal van het artikel is afkomstig uit mijn zen-kanaal.

De Mediastreamer2 VoIP-engine verkennen. Deel 2

Een toongenerator creëren

In de vorige статье We hebben de mediastreamerbibliotheek en ontwikkeltools geïnstalleerd en hun functionaliteit getest door een proefapplicatie te bouwen.

Vandaag gaan we een applicatie maken die een toonsignaal op een geluidskaart kan genereren. Om dit probleem op te lossen, moeten we de filters aansluiten op het hieronder weergegeven geluidsgeneratorcircuit:

De Mediastreamer2 VoIP-engine verkennen. Deel 2

We lezen het diagram van links naar rechts, dit is de richting waarin onze datastroom beweegt. De pijlen wijzen hier ook op. Rechthoeken geven filters aan die gegevensblokken verwerken en het resultaat weergeven. Binnen de rechthoek wordt de rol ervan aangegeven en het filtertype wordt net daaronder in hoofdletters aangegeven. De pijlen die de rechthoeken verbinden, zijn gegevenswachtrijen waardoor gegevensblokken van filter naar filter worden afgeleverd. Over het algemeen kan een filter veel in- en uitgangen hebben.

Het begint allemaal met de klokbron, die het tempo bepaalt waarmee gegevens in de filters worden berekend. Volgens zijn klokcyclus verwerkt elk filter alle datablokken die aan zijn ingang staan. En plaatst blokken met het resultaat in de wachtrij. Eerst voert het filter dat zich het dichtst bij de klokbron bevindt berekeningen uit, vervolgens de filters die op de uitgangen zijn aangesloten (er kunnen veel uitgangen zijn), enzovoort. Nadat het laatste filter in de keten de verwerking heeft voltooid, stopt de uitvoering totdat er een nieuwe klok arriveert. Beats volgen standaard een interval van 10 milliseconden.

Laten we terugkeren naar ons diagram. De klokcycli arriveren bij de ingang van de stiltebron; dit is een filter, dat bezig is met het genereren van een datablok met nullen aan de uitgang voor elke klokcyclus. Als we dit blok beschouwen als een blok geluidssamples, dan is dit niets anders dan stilte. Op het eerste gezicht lijkt het vreemd om datablokken met stilte te genereren - het is immers niet hoorbaar, maar deze blokken zijn nodig voor de werking van de geluidssignaalgenerator. De generator gebruikt deze blokken als een blanco vel papier en neemt er geluidssamples in op. In de normale toestand is de generator uitgeschakeld en stuurt hij eenvoudigweg invoerblokken door naar de uitvoer. Blokken stilte gaan dus onveranderd door het hele circuit van links naar rechts en komen terecht in de geluidskaart. Die stilletjes blokken uit de wachtrij haalt die op de invoer zijn aangesloten.

Maar alles verandert als de generator een opdracht krijgt om geluid af te spelen, hij begint geluidssamples te genereren en vervangt deze door samples in de invoerblokken en plaatst de gewijzigde blokken aan de uitvoer. De geluidskaart begint geluid af te spelen. Hieronder vindt u een programma dat het hierboven beschreven werkschema implementeert:

/* Файл 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);   
}

Na het initialiseren van de mediastreamer worden er drie filters aangemaakt: voidsource, dtmfgen, snd_card_write. Er wordt een klokbron gemaakt.

Vervolgens moet u de filters aansluiten in overeenstemming met ons circuit, en de klokbron moet als laatste worden aangesloten, omdat hierna het circuit onmiddellijk begint te werken. Als je een klokbron aansluit op een onafgewerkt circuit, kan het gebeuren dat de mediastreamer crasht als deze minimaal één filter in de keten detecteert waarbij alle ingangen of alle uitgangen ‘in de lucht hangen’ (niet aangesloten).

Het aansluiten van filters gebeurt met behulp van de functie

ms_filter_link(src, src_out, dst, dst_in)

waarbij het eerste argument een verwijzing naar het bronfilter is, is het tweede argument het bronuitvoernummer (merk op dat invoer en uitvoer genummerd zijn vanaf nul). Het derde argument is een verwijzing naar het ontvangerfilter, het vierde is het invoernummer van de ontvanger.

Alle filters zijn aangesloten en de klokbron is als laatste aangesloten (hierna noemen we dit eenvoudigweg een ticker). Daarna begint ons geluidscircuit te werken, maar er is nog niets te horen in de computerluidsprekers - de geluidsgenerator wordt uitgeschakeld en gaat eenvoudigweg in stilte door de invoergegevensblokken. Om een ​​toon te genereren, moet u de generatorfiltermethode uitvoeren.

We genereren een tweetonig (DTMF) signaal dat overeenkomt met het indrukken van de "1"-knop op de telefoon. Om dit te doen, gebruiken we de functie ms_filter_call_method() We noemen de methode MS_DTMF_GEN_PLAY, waarbij we deze als argument doorgeven aan een verwijzing naar de code waarmee het afspeelsignaal moet corresponderen.

Het enige dat overblijft is het compileren van het programma:

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

En loop:

$ ./mstest2

Na het starten van het programma hoort u in de computerluidspreker een kort geluidssignaal bestaande uit twee tonen.

We bouwden en lanceerden ons eerste geluidscircuit. We hebben gezien hoe u filterinstanties kunt maken, hoe u deze kunt verbinden en hoe u hun methoden kunt aanroepen. Hoewel we blij zijn met ons aanvankelijke succes, moeten we er nog steeds op letten dat ons programma het toegewezen geheugen niet vrijmaakt voordat het wordt afgesloten. In de volgende статье we zullen leren onszelf op te ruimen.

Bron: www.habr.com

Voeg een reactie