Istraživanje Mediastreamer2 VoIP motora. Dio 2

Materijal članka je preuzet sa mog zen kanal.

Istraživanje Mediastreamer2 VoIP motora. Dio 2

Kreiranje generatora tona

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

Danas ćemo kreirati aplikaciju koja može generirati tonski signal na zvučnoj kartici. Da bismo riješili ovaj problem, moramo spojiti filtere u kolo generatora zvuka prikazano u nastavku:

Istraživanje Mediastreamer2 VoIP motora. Dio 2

Čitamo dijagram s lijeva na desno, to je smjer u kojem se kreće naš tok podataka. Strelice takođe nagoveštavaju ovo. Pravokutnici označavaju filtere koji obrađuju blokove podataka i izlaze rezultat. Unutar pravougaonika, njegova uloga je naznačena, a tip filtera je naveden velikim slovima odmah ispod. Strelice koje povezuju pravokutnike su redovi podataka kroz koje se blokovi podataka isporučuju od filtera do filtera. Općenito, filter može imati mnogo ulaza i izlaza.

Sve počinje sa izvorom takta, koji postavlja tempo kojim se podaci računaju u filterima. Prema svom ciklusu takta, svaki filter obrađuje sve blokove podataka koji se nalaze na njegovom ulazu. I stavlja blokove s rezultatom u red čekanja. Prvo, filter koji je najbliži izvoru takta izvodi proračune, zatim filteri povezani na njegove izlaze (može biti mnogo izlaza) i tako dalje. Nakon što posljednji filter u lancu završi obradu, izvršenje se zaustavlja dok ne stigne novi sat. Otkucaji, prema zadanim postavkama, prate interval od 10 milisekundi.

Vratimo se na naš dijagram. Ciklusi takta stižu na ulaz izvora tišine; ovo je filter, koji je zauzet generiranjem bloka podataka koji sadrži nule na svom izlazu za svaki ciklus takta. Ako ovaj blok smatramo blokom zvučnih uzoraka, onda ovo nije ništa drugo do tišina. Na prvi pogled izgleda čudno generirati blokove podataka uz tišinu - uostalom, to se ne čuje, ali ti su blokovi neophodni 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 s lijeva na desno, završavajući u zvučnoj kartici. Koji tiho uzima blokove iz reda koji je povezan na njegov ulaz.

Ali sve se mijenja ako se generatoru da naredba za reprodukciju zvuka, on počinje generirati zvučne uzorke i zamjenjuje ih uzorcima u ulaznim blokovima i stavlja promijenjene blokove na izlaz. Zvučna kartica počinje da reprodukuje zvuk. Ispod je program koji implementira gore opisanu šemu 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 media streamera, kreiraju se tri filtera: voidsource, dtmfgen, snd_card_write. Kreiran je izvor sata.

Zatim trebate spojiti filtere u skladu s našim krugom, a izvor sata mora biti spojen posljednji, jer će nakon toga krug odmah početi s radom. Ako povežete izvor takta na nedovršeno kolo, može se dogoditi da se medijski streamer sruši ako otkrije barem jedan filter u lancu sa svim ulazima ili svim izlazima koji "vise u zraku" (nije povezani).

Povezivanje filtera se vrši pomoću funkcije

ms_filter_link(src, src_out, dst, dst_in)

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

Svi filteri su povezani i izvor takta je poslednji (u daljem tekstu ćemo ga jednostavno zvati tiker). Nakon toga naš zvučni krug počinje da radi, ali se još ništa ne čuje u zvučnicima kompjutera - generator zvuka je isključen i jednostavno prolazi kroz blokove ulaznih podataka u tišini. Da biste započeli generiranje tona, morate pokrenuti metod filtera generatora.

Generisaćemo dvotonski (DTMF) signal koji odgovara pritisku na dugme "1" na telefonu. Da bismo to učinili, koristimo funkciju ms_filter_call_method() Pozivamo metodu MS_DTMF_GEN_PLAY, prosljeđujući je kao argument kao pokazivač na kod kojem signal reprodukcije treba da odgovara.

Sve što ostaje je kompajlirati program:

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

I pokrenite:

$ ./mstest2

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

Izgradili smo i lansirali naše prvo zvučno kolo. 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 pažnju na činjenicu da naš program ne oslobađa dodijeljenu memoriju prije izlaska. U sljedećem članak naučićemo da čistimo za sobom.

izvor: www.habr.com

Dodajte komentar