Istraživanje Mediastreamer2 VoIP mehanizma. dio 2

Materijal članka preuzet je iz mog zen kanal.

Istraživanje Mediastreamer2 VoIP mehanizma. dio 2

Stvaranje ton generatora

U prethodnom članak Instalirali smo biblioteku media streamera, razvojne alate i testirali njihovu funkcionalnost izgradnjom probne aplikacije.

Danas ćemo izraditi aplikaciju koja može generirati tonski signal na zvučnoj kartici. Kako bismo riješili ovaj problem, moramo spojiti filtre u krug generatora zvuka prikazan ispod:

Istraživanje Mediastreamer2 VoIP mehanizma. dio 2

Dijagram čitamo s lijeva na desno, to je smjer u kojem se kreće naš protok podataka. Na to upućuju i strelice. Pravokutnici označavaju filtre koji obrađuju blokove podataka i ispisuju rezultat. Unutar pravokutnika navedena je njegova uloga, a ispod velikim slovima navedena je vrsta filtra. Strelice koje povezuju pravokutnike su redovi podataka kroz koje se blokovi podataka isporučuju od filtra do filtra. Općenito, filtar može imati mnogo ulaza i izlaza.

Sve počinje s izvorom takta, koji postavlja tempo po kojem se podaci izračunavaju u filtrima. Svaki filtar prema svom ciklusu takta obrađuje sve blokove podataka koji su na njegovom ulazu. I stavlja blokove s rezultatom u red čekanja. Prvo, filtar najbliži izvoru takta izvodi izračune, zatim filtri spojeni na njegove izlaze (može biti mnogo izlaza), i tako dalje. Nakon što posljednji filtar u lancu završi obradu, izvršenje se zaustavlja dok ne stigne novi sat. Otkucaji prema zadanim postavkama slijede interval od 10 milisekundi.

Vratimo se našem dijagramu. Ciklusi takta dolaze na ulaz izvora tišine; ovo je filtar, koji je zauzet generiranjem bloka podataka koji sadrži nule na svom izlazu za svaki ciklus takta. Ako ovaj blok promatramo kao blok zvučnih uzoraka, onda to nije ništa više od tišine. Na prvi pogled čini se čudno generirati podatkovne blokove s tišinom - uostalom, ne čuje se, ali ti su blokovi nužni za rad generatora zvučnog signala. Generator koristi ove blokove kao prazan list papira, snimajući u njih uzorke zvuka. U svom normalnom stanju, generator je isključen i jednostavno prosljeđuje ulazne blokove na izlaz. Dakle, blokovi tišine prolaze nepromijenjeni kroz cijeli krug slijeva nadesno, završavajući u zvučnoj kartici. Koji tiho uzima blokove iz reda čekanja spojenog na njegov ulaz.

Ali sve se mijenja ako se generatoru da naredba za reprodukciju zvuka, on počinje generirati uzorke zvuka i zamjenjuje ih uzorcima u ulaznim blokovima i stavlja promijenjene blokove na izlaz. Zvučna kartica počinje reproducirati zvuk. Ispod je program koji implementira gore opisanu shemu rada:

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

Nakon inicijalizacije medijskog streamera stvaraju se tri filtra: voidsource, dtmfgen, snd_card_write. Stvoren je izvor takta.

Zatim trebate spojiti filtre u skladu s našim krugom, a izvor takta mora biti spojen posljednji, jer će nakon toga krug odmah početi raditi. Ako spojite izvor takta na nedovršeni krug, može se dogoditi da se media streamer sruši ako detektira barem jedan filter u lancu sa svim ulazima ili svim izlazima koji "vise u zraku" (nisu spojeni).

Spajanje filtara vrši se pomoću funkcije

ms_filter_link(src, src_out, dst, dst_in)

gdje je prvi argument pokazivač na izvorni filtar, drugi argument je izlazni broj izvora (imajte na umu da su ulazi i izlazi numerirani počevši od nule). Treći argument je pokazivač na filtar prijemnika, četvrti je ulazni broj prijemnika.

Svi filtri su spojeni, a posljednji je spojen izvor takta (u daljnjem tekstu ćemo ga jednostavno zvati ticker). Nakon čega naš zvučni krug počinje raditi, ali se još ništa ne čuje u zvučnicima računala - generator zvuka je isključen i jednostavno prolazi kroz blokove ulaznih podataka uz tišinu. Za početak generiranja tona morate pokrenuti metodu filtra generatora.

Generirat ćemo dvotonski (DTMF) signal koji odgovara pritisku tipke "1" na telefonu. Da bismo to učinili, koristimo funkciju ms_filter_call_method() Pozivamo metodu MS_DTMF_GEN_PLAY, prosljeđujući joj kao argument pokazivač na kod kojem bi trebao odgovarati signal reprodukcije.

Ostaje samo kompajlirati program:

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

I trči:

$ ./mstest2

Nakon pokretanja programa, u zvučniku računala čut ćete kratki zvučni signal koji se sastoji od dva tona.

Izgradili smo i pokrenuli naš prvi zvučni krug. Vidjeli smo kako kreirati instance filtera, kako ih povezati i kako pozvati njihove metode. Iako smo zadovoljni našim početnim uspjehom, ipak moramo obratiti pozornost na činjenicu da naš program ne oslobađa dodijeljenu memoriju prije izlaska. U sljedećem članak naučit ćemo pospremati za sobom.

Izvor: www.habr.com

Dodajte komentar