Истражување на VoIP моторот Mediastreamer2. Дел 2

Материјалот на статијата е преземен од моето зен канал.

Истражување на VoIP моторот Mediastreamer2. Дел 2

Креирање на генератор на тонови

Во претходниот Член Ја инсталиравме библиотеката за медиумски стример, развојните алатки и ја тестиравме нивната функционалност со градење на пробна апликација.

Денес ќе создадеме апликација која може да генерира тонски сигнал на звучна картичка. За да го решиме овој проблем, треба да ги поврземе филтрите во колото на генератор на звук прикажано подолу:

Истражување на VoIP моторот Mediastreamer2. Дел 2

Го читаме дијаграмот од лево кон десно, ова е насоката во која се движи нашиот проток на податоци. Стрелките исто така го навестуваат ова. Правоаголниците означуваат филтри кои обработуваат блокови од податоци и го даваат резултатот. Внатре во правоаголникот, неговата улога е означена, а типот на филтерот е означен со големи букви веднаш подолу. Стрелките што ги поврзуваат правоаголниците се редици за податоци преку кои се доставуваат блокови од податоци од филтер до филтер. Општо земено, филтерот може да има многу влезови и излези.

Сè започнува со изворот на часовникот, кој го поставува темпото со кое се пресметуваат податоците во филтрите. Според неговиот такт, секој филтер ги обработува сите блокови на податоци што се на неговиот влез. И ги става блоковите со резултатот во редот. Прво, филтерот најблиску до изворот на часовникот врши пресметки, потоа филтрите поврзани со неговите излези (може да има многу излези) и така натаму. Откако последниот филтер во синџирот ќе заврши со обработката, извршувањето запира додека не пристигне нов часовник. Отчукувањата, стандардно, следат интервал од 10 милисекунди.

Да се ​​вратиме на нашиот дијаграм. Циклусите на часовникот пристигнуваат на влезот на изворот на тишина; ова е филтер, кој е зафатен со генерирање на блок од податоци што содржи нули на својот излез за секој такт. Ако го сметаме овој блок како блок од примероци на звук, тогаш ова не е ништо повеќе од тишина. На прв поглед, се чини чудно да се генерираат блокови на податоци со тишина - на крајот на краиштата, тоа не може да се слушне, но овие блокови се неопходни за работата на генераторот на звучен сигнал. Генераторот ги користи овие блокови како празен лист хартија, снимајќи примероци од звук во нив. Во својата нормална состојба, генераторот е исклучен и едноставно ги препраќа влезните блокови на излезот. Така, блоковите на тишината минуваат непроменети низ целото коло од лево кон десно, завршувајќи во звучната картичка. Кој тивко зема блокови од редот поврзан со неговиот влез.

Но, сè се менува ако на генераторот му се даде команда да репродуцира звук, тој почнува да генерира примероци на звук и ги заменува со примероци во влезните блокови и ги става променетите блокови на излезот. Звучната картичка започнува да репродуцира звук. Подолу е програма која ја имплементира работната шема опишана погоре:

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

По иницијализирањето на медиумскиот стример, се креираат три филтри: voidsource, dtmfgen, snd_card_write. Се создава извор на часовник.

Потоа треба да ги поврзете филтрите во согласност со нашето коло, а изворот на часовникот мора да биде поврзан последен, бидејќи по ова колото веднаш ќе започне да работи. Ако поврзете извор на часовник на недовршено коло, може да се случи медиумскиот стример да падне ако открие барем еден филтер во ланецот со сите влезови или сите излези „виси во воздух“ (не е поврзан).

Поврзувањето на филтрите се врши со помош на функцијата

ms_filter_link(src, src_out, dst, dst_in)

каде што првиот аргумент е покажувач на изворниот филтер, вториот аргумент е излезниот број на изворот (забележете дека влезовите и излезите се нумерирани почнувајќи од нула). Третиот аргумент е покажувач на филтерот на примачот, четвртиот е влезниот број на примачот.

Сите филтри се поврзани и изворот на часовникот е поврзан последен (во натамошниот текст едноставно ќе го наречеме тикер). После тоа, нашето звучно коло почнува да работи, но сè уште ништо не се слуша во звучниците на компјутерот - генераторот на звук е исклучен и едноставно поминува низ блоковите за влезни податоци со тишина. За да започнете да генерирате тон, треба да го извршите методот на филтер за генератор.

Ќе генерираме двотонски (DTMF) сигнал што одговара на притискање на копчето „1“ на телефонот. За да го направите ова, ја користиме функцијата ms_filter_call_method() Ние го нарекуваме методот MS_DTMF_GEN_PLAY, пренесувајќи го како аргумент покажувач на кодот на кој треба да одговара сигналот за репродукција.

Останува само да се состави програмата:

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

И трчај:

$ ./mstest2

Откако ќе ја стартувате програмата, ќе слушнете краток звучен сигнал кој се состои од два тона во звучникот на компјутерот.

Го изградивме и лансиравме нашето прво звучно коло. Видовме како да креираме филтри, како да ги поврземе и како да ги повикаме нивните методи. Иако сме задоволни со нашиот првичен успех, сепак треба да обрнеме внимание на фактот дека нашата програма не ја ослободува доделената меморија пред да излеземе. Во следниот Член ќе научиме да се чистиме по себе.

Извор: www.habr.com

Додадете коментар