Uurime VoIP-mootorit Mediastreamer2. Osa 2

Artikli materjal on saadud minu Dzen-kanalist.

Uurime VoIP-mootorit Mediastreamer2. Osa 2

Loome toonigeneraatori

Eelnevas artiklis Oleme installinud meedia voogedastuse teegi, arendusvahendid ja kontrollinud nende toimimist, koostades proovitalituse.

Täna loome rakenduse, mis suudab heli kaardil toota toonisignaali. Selle ülesande lahendamiseks peame ühendama filtrid allpool näidatud heligeneraatori skeemiga:

Uurime VoIP-mootorit Mediastreamer2. Osa 2

Kasutame skeemi lugemiseks vasakult paremale, just selles suunas liigub meie andmevoog. Nooled viitavad ka sellele. Ristkülikud tähistavad filtre, mis töötlevad andmeblokke 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 andmebloke tarnitakse filtrist filtrisse. Üldjuhul võib filtril olla palju sisenemis- ja väljundpunkte.

Kõik algab takti allikast, mis määrab tempo, mille aeg need andmed filtrites töödeldakse. Iga filtri jaoks, mis on kõige lähemal takti allikale, töötleb filtri kõik andmeblokid, mis asuvad selle sisendis. Seejärel esitab see tulemuse blokid väljundisse – järjekorda. Alguses käivitub töödeldud esimene filter, mis on takti allika lähedal, seejärel filtrid, mis on ühendatud selle väljundite juurde (väljundeid võib olla palju) ja nii edasi. Kui ahelas viimane filter lõpetab töötlemise, lõpetatakse täitmine kuni uue takti saabumiseni. Taktid järgivad vaikimisi 10 millisekundi intervalli.

Naasime tagasi meie skeemi. Takti andmed lähevad sisse vaigistamise allikasse, see filter tegeleb sellega, et genereerida iga takti jaoks andmeplokki, mis sisaldab nulli. Kui vaadata seda plokki kui helide proovide plokki, siis see ei ole midagi muud kui vaikus. Esmapilgul tundub kummaline genereerida andmeplokke vaikusest — sest seda ei saa kuulda, kuid need plokid on vajalikud heligeneraatori tööks. Generaator kasutab neid plokke nagu puhta paberilehe, salvestades neisse heliproovid. Oma tavalisel olekul on generaator väljas ja lihtsalt edastab sisemusblokeeringud välja. Seega, vaikuseplokid lähevad muutumatult läbi kogu skeemi vasakult paremale, jõudes heli kaardile. Mis vaikselt võtab plokid oma sisenemise järjekorrast.

Kuid kõik muutub, kui generaatorile antakse käsk heli esitamiseks, ta hakkab genereerima heliproove ja asendab nendega sisenemise plokkide proovid ning kuvab muudetud plokid väljundis. Helikaart hakkab heli esitama. Allpool on 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 meediumitootja initsialiseerimist luuakse kolm filtrit: voidsource, dtmfgen, snd_card_write. Loob taktsignaali allika.

Seejärel tuleb filtreid ühendada vastavalt meie skeemile, kusjuures taktsignaali allikas tuleb ühendada viimase asjana, kuna pärast seda algab skeemi töö kohe. Kui ühendada taktsignaali allikas lõpetamata skeemi, siis võib juhtuda, et meediumitootja lõpetab tegevuse, kui tuvastab ahelas vähemalt ühe filtri, mille kõik sisenemised või kõik väljundid "ripuvad õhus" (ei ole ühendatud).

Filtrite ühendamine toimub funktsiooni kaudu

ms_filter_link(src, src_out, dst, dst_in)

kus esimene argument on viide allika filtrile, teine argument — allika väljundi number (tähelepanu, et sisenemised ja väljundid on nummerdatud nullist alates). Kolmas argument on viide vastuvõtva filtri, neljas — vastuvõtva sisenemise number.

Kõik filtrid on ühendatud ja viimasena ühendatakse taktgeneraator (edaspidi nimetame seda lihtsalt tikkeriks). Pärast seda käivitatakse meie heliskeem, kuid arvuti kõlarites ei ole veel midagi kuulda — heligeneraator on välja lülitatud ja edastab lihtsalt andmepakette, mis koosnevad vaikusest. Tonaalse signaali genereerimiseks tuleb käivitada generaatori filtri meetod.

Me genereerime kahetoonilise (DTMF) signaali, mis vastab telefoni nupu "1" vajutamisele. Selleks kasutame funktsiooni ms_filter_call_method() kutsume välja MS_DTMF_GEN_PLAY meetodi, edastades selle argumentidena viite koodile, millele mängitav signaal peab vastama.

Jääb üle programm kompileerida:

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

Ja käivitada:

$ ./mstest2

Pärast programmi käivitamist kuulete arvuti kõlarites lühikest helisignaali, mis koosneb kahest toonist.

Oleme loonud ja käivitanud meie esimese heliskeemi. Nägime, kuidas luua filtreid, neid ühendada ja nende meetodeid kutsuda. Esimese edu üle rõõmustades peame siiski tähelepanu pöörama sellele, et meie programm ei vabasta eraldatud mälu enne lõpetamist. Järgmises artiklis õpime koristama pärast iseennast.

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster