Skúmanie enginu Mediastreamer2 VoIP. Časť 2

Materiál článku je prevzatý z môjho zenový kanál.

Skúmanie enginu Mediastreamer2 VoIP. Časť 2

Vytvorenie tónového generátora

V predošlom článok Nainštalovali sme knižnicu media streamer, vývojové nástroje a otestovali ich funkčnosť vytvorením skúšobnej aplikácie.

Dnes si vytvoríme aplikáciu, ktorá dokáže generovať tónový signál na zvukovej karte. Na vyriešenie tohto problému musíme pripojiť filtre do obvodu zvukového generátora zobrazeného nižšie:

Skúmanie enginu Mediastreamer2 VoIP. Časť 2

Diagram čítame zľava doprava, to je smer, ktorým sa pohybuje náš dátový tok. Naznačujú to aj šípky. Obdĺžniky označujú filtre, ktoré spracúvajú bloky údajov a vydávajú výsledok. Vo vnútri obdĺžnika je označená jeho úloha a pod ním je veľkými písmenami označený typ filtra. Šípky spájajúce obdĺžniky sú dátové fronty, cez ktoré sa doručujú bloky dát z filtra do filtra. Vo všeobecnosti môže mať filter veľa vstupov a výstupov.

Všetko to začína zdrojom hodín, ktorý nastavuje tempo, akým sa údaje počítajú vo filtroch. Každý filter podľa svojho hodinového cyklu spracováva všetky dátové bloky, ktoré sú na jeho vstupe. A zaradí bloky s výsledkom do frontu. Najprv vykoná výpočty filter najbližšie k zdroju hodín, potom filtre pripojené k jeho výstupom (výstupov môže byť veľa) atď. Po dokončení spracovania posledného filtra v reťazci sa vykonávanie zastaví, kým neprídu nové hodiny. Údery v predvolenom nastavení sledujú interval 10 milisekúnd.

Vráťme sa k nášmu diagramu. Hodinové cykly prichádzajú na vstup zdroja ticha; toto je filter, ktorý je zaneprázdnený generovaním bloku dát obsahujúcich nuly na svojom výstupe pre každý hodinový cyklus. Ak tento blok považujeme za blok zvukových vzoriek, potom to nie je nič iné ako ticho. Na prvý pohľad sa zdá zvláštne generovať dátové bloky s tichom – koniec koncov, nie je to počuť, ale tieto bloky sú nevyhnutné pre činnosť generátora zvukového signálu. Generátor používa tieto bloky ako prázdny list papiera a zaznamenáva do nich zvukové vzorky. V normálnom stave je generátor vypnutý a jednoducho posiela vstupné bloky na výstup. Bloky ticha tak prechádzajú nezmenené celým obvodom zľava doprava a končia v zvukovej karte. Ktorý potichu odoberá bloky z frontu pripojeného k jeho vstupu.

Všetko sa však zmení, ak generátor dostane príkaz na prehrávanie zvuku, začne generovať zvukové vzorky a nahradí ich vzorkami vo vstupných blokoch a zmenené bloky umiestni na výstup. Zvuková karta začne prehrávať zvuk. Nižšie je uvedený program, ktorý implementuje pracovnú schému opísanú vyššie:

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

Po inicializácii mediálneho streamera sa vytvoria tri filtre: voidsource, dtmfgen, snd_card_write. Vytvorí sa zdroj hodín.

Potom musíte pripojiť filtre v súlade s naším obvodom a zdroj hodín musí byť pripojený ako posledný, pretože potom obvod okamžite začne fungovať. Ak pripojíte zdroj hodín na nedokončený obvod, môže sa stať, že media streamer zlyhá, ak zaznamená aspoň jeden filter v reťazci so všetkými vstupmi alebo všetkými výstupmi „visiacimi vo vzduchu“ (nezapojené).

Pripojenie filtrov sa vykonáva pomocou funkcie

ms_filter_link(src, src_out, dst, dst_in)

kde prvý argument je ukazovateľ na zdrojový filter, druhý argument je číslo výstupu zdroja (všimnite si, že vstupy a výstupy sú číslované od nuly). Tretí argument je ukazovateľ na filter prijímača, štvrtý je číslo vstupu prijímača.

Všetky filtre sú pripojené a zdroj hodín sa pripája ako posledný (ďalej to budeme nazývať ticker). Potom náš zvukový obvod začne fungovať, ale v reproduktoroch počítača ešte nič nepočuť - generátor zvuku je vypnutý a jednoducho ticho prechádza cez vstupné dátové bloky. Ak chcete začať generovať tón, musíte spustiť metódu filtrovania generátora.

Vygenerujeme dvojtónový (DTMF) signál zodpovedajúci stlačeniu tlačidla „1“ na telefóne. Na to používame funkciu ms_filter_call_method() Zavoláme metódu MS_DTMF_GEN_PLAY, pričom jej ako argument odovzdávame ukazovateľ na kód, ktorému by mal zodpovedať signál prehrávania.

Zostáva len skompilovať program:

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

A bež:

$ ./mstest2

Po spustení programu sa v reproduktore počítača ozve krátky zvukový signál pozostávajúci z dvoch tónov.

Postavili sme a spustili náš prvý zvukový okruh. Videli sme, ako vytvoriť inštancie filtra, ako ich prepojiť a ako volať ich metódy. Aj keď sme spokojní s naším počiatočným úspechom, stále musíme venovať pozornosť skutočnosti, že náš program neuvoľňuje pridelenú pamäť pred ukončením. V ďalšom článok naučíme sa po sebe upratovať.

Zdroj: hab.com

Pridať komentár