Paggalugad sa Mediastreamer2 VoIP engine. Bahagi 2

Ang materyal ng artikulo ay kinuha mula sa aking zen channel.

Paggalugad sa Mediastreamer2 VoIP engine. Bahagi 2

Paglikha ng Tone Generator

Sa nakaraan Artikulo Nag-install kami ng media streamer library, mga tool sa pag-develop at sinubukan ang kanilang functionality sa pamamagitan ng pagbuo ng trial na application.

Ngayon ay gagawa kami ng isang application na maaaring makabuo ng signal ng tono sa isang sound card. Upang malutas ang problemang ito kailangan naming ikonekta ang mga filter sa sound generator circuit na ipinapakita sa ibaba:

Paggalugad sa Mediastreamer2 VoIP engine. Bahagi 2

Binabasa namin ang diagram mula kaliwa hanggang kanan, ito ang direksyon kung saan gumagalaw ang aming daloy ng data. Ang mga arrow ay nagpapahiwatig din nito. Ang mga parihaba ay nagpapahiwatig ng mga filter na nagpoproseso ng mga bloke ng data at naglalabas ng resulta. Sa loob ng parihaba, ang papel nito ay ipinahiwatig at ang uri ng filter ay ipinahiwatig sa malalaking titik sa ibaba lamang. Ang mga arrow na nagkokonekta sa mga parihaba ay mga queue ng data kung saan ang mga bloke ng data ay inihahatid mula sa filter hanggang sa filter. Sa pangkalahatan, maaaring magkaroon ng maraming input at output ang isang filter.

Nagsisimula ang lahat sa pinagmulan ng orasan, na nagtatakda ng tempo kung saan kinakalkula ang data sa mga filter. Ayon sa ikot ng orasan nito, pinoproseso ng bawat filter ang lahat ng mga bloke ng data na nasa input nito. At naglalagay ng mga bloke na may resulta sa pila. Una, ang filter na pinakamalapit sa pinagmulan ng orasan ay nagsasagawa ng mga kalkulasyon, pagkatapos ay ang mga filter na konektado sa mga output nito (maaaring maraming mga output), at iba pa. Matapos maproseso ang huling filter sa chain, hihinto ang pagpapatupad hanggang sa dumating ang isang bagong orasan. Ang mga beats, bilang default, ay sumusunod sa pagitan ng 10 millisecond.

Bumalik tayo sa aming diagram. Dumating ang mga cycle ng orasan sa input ng pinagmulan ng katahimikan; ito ay isang filter, na abala sa pagbuo ng isang bloke ng data na naglalaman ng mga zero sa output nito para sa bawat ikot ng orasan. Kung isasaalang-alang namin ang bloke na ito bilang isang bloke ng mga sample ng tunog, ito ay walang iba kundi katahimikan. Sa unang sulyap, tila kakaiba ang pagbuo ng mga bloke ng data na may katahimikan - pagkatapos ng lahat, hindi ito maririnig, ngunit ang mga bloke na ito ay kinakailangan para sa pagpapatakbo ng sound signal generator. Ginagamit ng generator ang mga bloke na ito tulad ng isang blangkong papel, na nagre-record ng mga sound sample sa mga ito. Sa normal nitong estado, ang generator ay naka-off at ipinapasa lamang ang mga bloke ng input sa output. Kaya, ang mga bloke ng katahimikan ay hindi nagbabago sa buong circuit mula kaliwa hanggang kanan, na nagtatapos sa sound card. Na tahimik na kumukuha ng mga bloke mula sa pila na konektado sa input nito.

Ngunit lahat ng bagay ay nagbabago kung ang generator ay bibigyan ng isang utos upang i-play ang tunog, ito ay nagsisimula upang makabuo ng mga sample ng tunog at pinapalitan ang mga ito ng mga sample sa mga bloke ng input at inilalagay ang mga binagong bloke sa output. Nagsisimulang mag-play ng sound ang sound card. Nasa ibaba ang isang programa na nagpapatupad ng scheme ng trabaho na inilarawan sa itaas:

/* Π€Π°ΠΉΠ» 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);   
}

Pagkatapos masimulan ang media streamer, tatlong filter ang gagawin: voidsource, dtmfgen, snd_card_write. Ang isang mapagkukunan ng orasan ay nilikha.

Pagkatapos ay kailangan mong ikonekta ang mga filter alinsunod sa aming circuit, at ang pinagmulan ng orasan ay dapat na huling konektado, dahil pagkatapos nito ang circuit ay agad na magsisimulang gumana. Kung ikinonekta mo ang isang source ng orasan sa isang hindi natapos na circuit, maaaring mangyari na ang media streamer ay nag-crash kung ito ay nakakita ng hindi bababa sa isang filter sa chain na may lahat ng mga input o lahat ng mga output ay "nakabitin sa hangin" (hindi konektado).

Ang pagkonekta ng mga filter ay ginagawa gamit ang function

ms_filter_link(src, src_out, dst, dst_in)

kung saan ang unang argument ay isang pointer sa source filter, ang pangalawang argument ay ang source output number (tandaan na ang mga input at output ay binibilang simula sa zero). Ang ikatlong argumento ay isang pointer sa receiver filter, ang ikaapat ay ang receiver input number.

Ang lahat ng mga filter ay konektado at ang pinagmulan ng orasan ay huling konektado (pagkatapos nito ay tatawagin na lang natin itong isang ticker). Pagkatapos nito, ang aming sound circuit ay nagsimulang gumana, ngunit wala pa ring maririnig sa mga speaker ng computer - ang sound generator ay naka-off at pumasa lamang sa mga bloke ng data ng input nang may katahimikan. Upang simulan ang pagbuo ng isang tono, kailangan mong patakbuhin ang paraan ng filter ng generator.

Bubuo kami ng two-tone (DTMF) signal na naaayon sa pagpindot sa "1" na button sa telepono. Upang gawin ito, ginagamit namin ang function ms_filter_call_method() Tinatawag namin ang paraan ng MS_DTMF_GEN_PLAY, na ipinapasa ito bilang argumento bilang isang pointer sa code na dapat tumutugma sa signal ng playback.

Ang natitira na lang ay i-compile ang program:

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

At tumakbo:

$ ./mstest2

Pagkatapos simulan ang programa, makakarinig ka ng maikling sound signal na binubuo ng dalawang tono sa speaker ng computer.

Binuo at inilunsad namin ang aming unang sound circuit. Nakita namin kung paano gumawa ng mga instance ng filter, kung paano ikonekta ang mga ito at kung paano tawagan ang kanilang mga pamamaraan. Bagama't kami ay masaya sa aming unang tagumpay, kailangan pa rin naming bigyang pansin ang katotohanan na ang aming programa ay hindi nagpapalaya sa inilalaan na memorya bago lumabas. Sa susunod Artikulo matututo tayong maglinis pagkatapos ng ating sarili.

Pinagmulan: www.habr.com

Magdagdag ng komento