Prozkoumání enginu Mediastreamer2 VoIP. Část 2

Materiál článku je převzat z mého zenový kanál.

Prozkoumání enginu Mediastreamer2 VoIP. Část 2

Vytvoření tónového generátoru

V předchozím článek Nainstalovali jsme knihovnu media streamerů, vývojové nástroje a otestovali jejich funkčnost vytvořením zkušební aplikace.

Dnes si vytvoříme aplikaci, která umí generovat tónový signál na zvukové kartě. K vyřešení tohoto problému musíme zapojit filtry do obvodu zvukového generátoru zobrazeného níže:

Prozkoumání enginu Mediastreamer2 VoIP. Část 2

Diagram čteme zleva doprava, to je směr, kterým se ubírá náš datový tok. Naznačují to i šipky. Obdélníky označují filtry, které zpracovávají bloky dat a vydávají výsledek. Uvnitř obdélníku je uvedena jeho role a pod ním je velkými písmeny označen typ filtru. Šipky spojující obdélníky jsou datové fronty, přes které jsou bloky dat doručovány z filtru do filtru. Obecně může mít filtr mnoho vstupů a výstupů.

Vše začíná u zdroje hodin, který nastavuje tempo, jakým se data ve filtrech počítají. Každý filtr podle svého hodinového cyklu zpracovává všechny datové bloky, které jsou na jeho vstupu. A zařadí bloky s výsledkem do fronty. Nejprve provede výpočty filtr nejblíže ke zdroji hodin, poté filtry připojené k jeho výstupům (výstupů může být mnoho) a tak dále. Po dokončení zpracování posledního filtru v řetězci se provádění zastaví, dokud nepřijdou nové hodiny. Údery ve výchozím nastavení sledují interval 10 milisekund.

Vraťme se k našemu schématu. Hodinové cykly přicházejí na vstup zdroje ticha, což je filtr, který je zaneprázdněn generováním bloku dat obsahujících nuly na svém výstupu pro každý hodinový cyklus. Pokud tento blok považujeme za blok zvukových vzorků, pak to není nic jiného než ticho. Na první pohled se zdá divné generovat datové bloky s tichem – přeci jen to není slyšet, ale tyto bloky jsou pro chod generátoru zvukového signálu nezbytné. Generátor používá tyto bloky jako prázdný list papíru a zaznamenává do nich zvukové vzorky. V normálním stavu je generátor vypnutý a jednoduše předává vstupní bloky na výstup. Bloky ticha tak procházejí beze změny celým obvodem zleva doprava a končí ve zvukové kartě. Který tiše odebírá bloky z fronty připojené k jeho vstupu.

Vše se ale změní, pokud generátor dostane příkaz k přehrávání zvuku, začne generovat zvukové vzorky a nahradí je vzorky ve vstupních blocích a změněné bloky umístí na výstup. Zvuková karta začne přehrávat zvuk. Níže je uveden program, který implementuje pracovní schéma popsané výše:

/* Файл 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 inicializaci streamování médií se vytvoří tři filtry: voidsource, dtmfgen, snd_card_write. Je vytvořen zdroj hodin.

Poté musíte připojit filtry v souladu s naším obvodem a zdroj hodin musí být připojen jako poslední, protože poté obvod okamžitě začne fungovat. Pokud připojíte zdroj hodin k nedokončenému obvodu, může se stát, že media streamer zkolabuje, pokud detekuje alespoň jeden filtr v řetězci se všemi vstupy nebo všemi výstupy „visícími ve vzduchu“ (nezapojené).

Připojení filtrů se provádí pomocí funkce

ms_filter_link(src, src_out, dst, dst_in)

kde první argument je ukazatel na zdrojový filtr, druhý argument je číslo výstupu zdroje (všimněte si, že vstupy a výstupy jsou číslovány od nuly). Třetí argument je ukazatel na filtr přijímače, čtvrtý je číslo vstupu přijímače.

Všechny filtry jsou zapojeny a zdroj hodin se připojuje jako poslední (dále tomu budeme říkat jednoduše ticker). Poté náš zvukový obvod začne fungovat, ale v reproduktorech počítače zatím není nic slyšet - zvukový generátor je vypnutý a jednoduše tiše prochází vstupními datovými bloky. Chcete-li začít generovat tón, musíte spustit metodu filtrování generátoru.

Vygenerujeme dvoutónový (DTMF) signál odpovídající stisknutí tlačítka „1“ na telefonu. K tomu použijeme funkci ms_filter_call_method() Zavoláme metodu MS_DTMF_GEN_PLAY a předáme ji jako argument ukazatel na kód, kterému by měl odpovídat signál přehrávání.

Zbývá pouze zkompilovat program:

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

A běž:

$ ./mstest2

Po spuštění programu uslyšíte v reproduktoru počítače krátký zvukový signál sestávající ze dvou tónů.

Postavili jsme a spustili náš první zvukový okruh. Viděli jsme, jak vytvářet instance filtrů, jak je propojovat a jak volat jejich metody. I když jsme spokojeni s naším počátečním úspěchem, stále musíme věnovat pozornost skutečnosti, že náš program neuvolňuje přidělenou paměť před ukončením. V dalším článek naučíme se po sobě uklízet.

Zdroj: www.habr.com

Přidat komentář