Истраживање Медиастреамер2 ВоИП механизма. Део 2

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

Истраживање Медиастреамер2 ВоИП механизма. Део 2

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

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

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

Истраживање Медиастреамер2 ВоИП механизма. Део 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);   
}

Након иницијализације медијског стримера, креирају се три филтера: воидсоурце, дтмфген, снд_цард_врите. Извор сата је креиран.

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

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

ms_filter_link(src, src_out, dst, dst_in)

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

Сви филтери су повезани и извор такта је последњи (у даљем тексту ћемо га једноставно звати тикер). Након тога наш звучни круг почиње да ради, али се још ништа не чује у звучницима рачунара - генератор звука је искључен и једноставно пролази кроз блокове улазних података са тишином. Да бисте почели да генеришете тон, потребно је да покренете метод филтера генератора.

Генерисаћемо двотонски (ДТМФ) сигнал који одговара притиску на дугме "1" на телефону. Да бисмо то урадили, користимо функцију мс_филтер_цалл_метход() Позивамо метод МС_ДТМФ_ГЕН_ПЛАИ, прослеђујући га као аргумент као показивач на код коме треба да одговара сигнал репродукције.

Остаје само да компајлирате програм:

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

И трчи:

$ ./mstest2

Након покретања програма, чућете кратак звучни сигнал који се састоји од два тона у звучнику рачунара.

Изградили смо и покренули наше прво звучно коло. Видели смо како да креирамо инстанце филтера, како да их повежемо и како да позовемо њихове методе. Иако смо задовољни нашим почетним успехом, ипак морамо да обратимо пажњу на чињеницу да наш програм не ослобађа додељену меморију пре изласка. У наредном Чланак научићемо да чистимо за собом.

Извор: ввв.хабр.цом

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