Uurime VoIP-mootorit Mediastreamer2. Osa 2

Artikli sisu on pärit minu zen-kanalist.

Uurime VoIP-mootorit Mediastreamer2. Osa 2

Loome toonigeneraatori

Eelmises osas artiklis teostasime mediastreameri teegi paigaldamise, arendustööriistade installimise ja kontrollisime nende toimimist, koostades proovirakenduse.

Täna loome rakenduse, mis suudab helikaardil genereerida toonisignaali. Selle ülesande täitmiseks peame ühendama filtrid allolevas heligeneraatori skeemis:

Uurime VoIP-mootorit Mediastreamer2. Osa 2

Lugedes skeemi vasakult paremale, liigub meie andmevoog just selles suunas. Nooled viitavad sellele. Joonisega tähistatud ristkülikud on filtrid, mis töötlevad andmeplokke ja esitavad tulemuse väljundis. Ristküliku sees on märgitud selle roll ja veidi allpool suurtähtedega filtri tüüp. Nooled, mis ühendavad ristkülikud, on andmejärjekorrad, mille kaudu andmeplokid edastatakse filtrist filtri juurde. Üldiselt võib filtril olla mitmeid sisendeid ja väljundeid.

Kõik algab takti allikast, mis määrab rütmi, milles andmeid filtrites töödeldakse. Selle takti järgi töötleb iga filter kõik andmeplokid, mis on sellele sisendiks. Ja saadab tulemused välja - järjekorda. Esmalt teostab arvutuse filter, mis on takti allikaga kõige lähemal, seejärel filtrid, mis on ühendatud tema väljunditega (väljundeid võib olla palju) ja nii edasi. Pärast seda, kui viimane filter ahelas lõpetab arvutamise, peatutakse, kuni saabub uus takt. Takti, vaikimisi, järgivad 10 millisekundi intervalliga.

Naas tagasi meie skeemile. Takti tuleb vaikuse allikasse, see on filter, mis iga takti jooksul genereerib oma väljundis nullide ploki. Kui vaadata seda plokki kui helimõõtmiste plokki, siis ei ole see midagi muud kui vaikus. Esialgu võib tunduda kummaline genereerida andmeplokke vaikuse jaoks — sest seda ei saa kuulda, aga need plokid on vajalikud heligeneraatori tööks. Generaator kasutab neid plokke nagu puhast paberilehte, kirjutades sinna helimõõtmised. Oma tavapärases olekus on generaator välja lülitatud ja laseb lihtsalt sisende plokid väljundisse läbi. Nii läbivad vaikuse plokid muutumatult kogu skeemi vasakult paremale, sattudes helikaardile, mis vaikselt võtab plokid oma sisendisse järjekorrast.

Kuid kõik muutub, kui generaatorile antakse käsk helimängimiseks, ta hakkab genereerima helimõõtmisi ja asendab nendega sisendplokkide mõõtmed ning paneb muudetud plokid väljundisse. Helkaart hakkab heli taasesitama. Allpool on toodud programm, mis rakendab eespool kirjeldatud tööskeemi:

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

Pärast meediastreameri initsialiseerimist luuakse kolm filtrit: voidsource, dtmfgen, snd_card_write. Luuakse taktsignaali allikas.

Seejärel tuleb filtrite ühendamine vastavalt meie skeemile teostada, kusjuures taktsignaal tuleb ühendada viimaseena, kuna pärast seda algab kohe skeemi töö. Kui ühendada taktsignaal lõpetamata skeemiga, võib juhtuda, et meediastreamer lõpetab töö ootamatult, kui tuvastab ahelas vähemalt ühe filtri, mille kõik sisse- või väljundid "ripuvad õhus" (pole ühendatud).

Filtrite ühendamine toimub funktsiooni abil

ms_filter_link(src, src_out, dst, dst_in)

, kus esimene argument on viide allika filtrile, teine argument — allika väljundi number (pange tähele, et sisse- ja väljundid on nummerdatud alates nullist). Kolmas argument on viide sihtfiltri jaoks, neljas — vastuvõtja sisendi number.

Kõik filtrid on ühendatud ja viimaseks ühendatakse takti allikas (edaspidi nimetame seda lihtsalt tikkeriks). Pärast seda käivitub meie heliskeem, kuid arvuti kõlaritest ei ole hetkel midagi kuulda - heligeneraator on välja lülitatud ja lihtsalt edastab andmeblokke vaikuses. Helisignaali genereerimiseks peab olema aktiveeritud generaatori filtri meetod.

Me genereerime kaheetapilise (DTMF) signaali, mis vastab telefoni nupule "1" vajutamisel. Selleks kasutame funktsiooni ms_filter_call_method() kutsume välja meetodi MS_DTMF_GEN_PLAY, edastades sellele argumentidena viite koodile, millele vastab mängitav signaal.

Seejärel tuleb programm kompileerida:

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

Ja käivitada:

$ ./mstest2

Programmi käivitamisel kuulete arvuti kõlarites lühikest helisignaali, mis koosneb kahest toonist.

Meie esimese heliskeemi loomisest ja töölepanemisest. Nägime, kuidas filtreid luua, ühendada ja kuidas nende meetodeid kutsuda. Kuigi esimesest edust rõõmustasime, peame siiski tähelepanu pöörama sellele, et meie programm ei vabasta enne lõpetamist eraldatud mälu. Järgmises artiklis õpime enda järel koristama.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster