Mediastreamer2 VoIP programmas izpēte. 2. daļa

Raksta materiāls ņemts no mana zen kanāls.

Mediastreamer2 VoIP programmas izpēte. 2. daļa

Toņu ģeneratora izveide

Iepriekšējā raksts Mēs instalējām multivides straumēšanas bibliotēku, izstrādes rīkus un pārbaudījām to funkcionalitāti, izveidojot izmēģinājuma lietojumprogrammu.

Šodien mēs izveidosim lietojumprogrammu, kas var ģenerēt toņa signālu skaņas kartē. Lai atrisinātu šo problēmu, mums ir jāpievieno filtri skaņas ģeneratora ķēdei, kas parādīta zemāk:

Mediastreamer2 VoIP programmas izpēte. 2. daļa

Mēs lasām diagrammu no kreisās uz labo pusi, tas ir virziens, kurā virzās mūsu datu plūsma. Par to liecina arī bultiņas. Taisnstūri norāda filtrus, kas apstrādā datu blokus un izvada rezultātu. Taisnstūra iekšpusē ir norādīta tā loma, un filtra veids ir norādīts ar lielajiem burtiem tieši zemāk. Bultiņas, kas savieno taisnstūrus, ir datu rindas, caur kurām datu bloki tiek piegādāti no filtra uz filtru. Kopumā filtram var būt daudz ieeju un izeju.

Viss sākas ar pulksteņa avotu, kas nosaka tempu, kādā filtros tiek aprēķināti dati. Katrs filtrs atbilstoši pulksteņa ciklam apstrādā visus datu blokus, kas atrodas tā ievadē. Un ieliek blokus ar rezultātu rindā. Vispirms aprēķinus veic pulksteņa avotam vistuvāk esošais filtrs, pēc tam tā izejām pieslēgtie filtri (izvadu var būt daudz) utt. Kad pēdējais ķēdes filtrs ir pabeidzis apstrādi, izpilde tiek apturēta, līdz tiek parādīts jauns pulkstenis. Pēc noklusējuma sitieni seko 10 milisekundes intervālam.

Atgriezīsimies pie mūsu diagrammas. Pulksteņa cikli nonāk pie klusuma avota ieejas; tas ir filtrs, kas ir aizņemts, ģenerējot datu bloku, kura izvadē ir nulles katram pulksteņa ciklam. Ja mēs uzskatām šo bloku par skaņu paraugu bloku, tad tas nav nekas vairāk kā klusums. No pirmā acu uzmetiena šķiet dīvaini ģenerēt datu blokus ar klusumu - galu galā to nevar dzirdēt, bet šie bloki ir nepieciešami skaņas signālu ģeneratora darbībai. Ģenerators izmanto šos blokus kā tukšu papīra lapu, ierakstot tajos skaņas paraugus. Normālā stāvoklī ģenerators ir izslēgts un vienkārši pārsūta ievades blokus uz izeju. Tādējādi klusuma bloki nemainīti iziet cauri visai shēmai no kreisās puses uz labo, nonākot skaņas kartē. Kas klusi ņem blokus no rindas, kas savienota ar tās ieeju.

Bet viss mainās, ja ģeneratoram tiek dota komanda atskaņot skaņu, tas sāk ģenerēt skaņas paraugus un aizvieto tos ar paraugiem ievades blokos un izmainītos blokus liek izejā. Skaņas karte sāk atskaņot skaņu. Zemāk ir programma, kas ievieš iepriekš aprakstīto darba shēmu:

/* Файл 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ēc multivides straumētāja inicializācijas tiek izveidoti trīs filtri: voidsource, dtmfgen, snd_card_write. Tiek izveidots pulksteņa avots.

Tad jums ir jāpievieno filtri saskaņā ar mūsu ķēdi, un pulksteņa avots ir jāpievieno pēdējam, jo ​​pēc tam ķēde nekavējoties sāks darboties. Ja pievienojat pulksteņa avotu nepabeigtai shēmai, var gadīties, ka multivides straumētājs avarē, ja ķēdē konstatē vismaz vienu filtru, kurā visas ieejas vai visas izejas "karājas gaisā" (nav pievienots).

Filtru pievienošana tiek veikta, izmantojot funkciju

ms_filter_link(src, src_out, dst, dst_in)

kur pirmais arguments ir rādītājs uz avota filtru, otrais arguments ir avota izvades numurs (ņemiet vērā, ka ieejas un izejas tiek numurētas, sākot no nulles). Trešais arguments ir rādītājs uztvērēja filtram, ceturtais ir uztvērēja ievades numurs.

Visi filtri ir pievienoti, un pulksteņa avots ir pievienots pēdējais (turpmāk mēs to vienkārši sauksim par svārstiņu). Pēc tam mūsu skaņas ķēde sāk darboties, bet datora skaļruņos vēl nekas nav dzirdams - skaņas ģenerators tiek izslēgts un vienkārši klusē iziet cauri ievades datu blokiem. Lai sāktu ģenerēt signālu, ir jāpalaiž ģeneratora filtra metode.

Mēs ģenerēsim divu toņu (DTMF) signālu, kas atbilst tālruņa pogas "1" nospiešanai. Lai to izdarītu, mēs izmantojam funkciju ms_filter_call_method() Mēs saucam MS_DTMF_GEN_PLAY metodi, nododot to kā argumentu rādītāju uz kodu, kuram jāatbilst atskaņošanas signālam.

Atliek tikai sastādīt programmu:

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

Un palaist:

$ ./mstest2

Pēc programmas palaišanas datora skaļrunī būs dzirdams īss skaņas signāls, kas sastāv no diviem toņiem.

Mēs izveidojām un iedarbinājām savu pirmo skaņas shēmu. Mēs redzējām, kā izveidot filtru gadījumus, kā tos savienot un kā izsaukt to metodes. Lai gan esam apmierināti ar sākotnējiem panākumiem, mums joprojām ir jāpievērš uzmanība tam, ka mūsu programma pirms iziešanas neatbrīvo piešķirto atmiņu. Nākamajā raksts mācīsimies sakopt aiz sevis.

Avots: www.habr.com

Pievieno komentāru