Ho hlahloba enjene ea Mediastreamer2 VoIP. Karolo ea 9

Thepa ea sehlooho e nkiloe ho ea ka mocha oa zen.

Duplex intercom

Ho hlahloba enjene ea Mediastreamer2 VoIP. Karolo ea 9

Qetellong sehlooho ho phatlalalitsoe intercom ea duplex, 'me ho ena re tla e etsa.

Setšoantšo se bontšitsoe setšoantšong sa sehlooho. Ketane e ka tlase ea li-filters e theha tsela ea phetisetso, e qalang ho tsoa kareteng ea molumo. E fana ka mehlala ea matšoao ho tsoa ho maekrofono. Ka ho sa feleng, sena se etsahala ka sekhahla sa disampole tse 8000 motsotsoana. Botebo ba li-filters tsa audio tsa media streamer ke li-bits tse 16 (sena ha se bohlokoa; haeba u lakatsa, u ka ngola li-filters tse tla sebetsa ka botebo bo phahameng). Lintlha li arotsoe ka li-block tsa disampole tse 160. Kahoo, boloko bo bong le bo bong bo boholo ba li-byte tse 320. Ka mor'a moo, re fepa data ho kenya letsoho la jenereithara, eo, ha e tima, e "bonahalang" ho data. Ke e kentse haeba u ka khathala ke ho bua ka maekrofono nakong ea ho lokisa liphoso - u ka sebelisa jenereithara ho "thunya" tsela ka lets'oao la molumo.

Ka mor'a jenereithara, lets'oao le ea ho encoder, e fetolang lisampole tsa rona tsa 16-bit ho latela µ-law (G.711 standard) ho tse robeli-bit. Ka tlhahiso ea encoder, re se re ntse re e-na le "data block" halofo ea boholo. Ka kakaretso, re ka fetisetsa data ntle le khatello haeba re sa hloke ho boloka sephethephethe. Empa mona ho bohlokoa ho sebelisa encoder, kaha Wireshark e khona ho hlahisa molumo ho tsoa ho RTP ha feela e hatelloa ho latela µ-law kapa a-law.

Ka mor'a encoder, lisebelisoa tse bobebe tsa data li romelloa ho rtpsend filter, e tla li kenya ka har'a pakete ea RTP, e behe lifolakha tse hlokahalang ebe e li fa mecha ea litaba bakeng sa ho fetisoa ka marang-rang ka mokhoa oa pakete ea UDP.

Ketane e kaholimo ea li-filters e theha tsela ea ho amohela; Lipakete tsa RTP tse amoheloang ke media streamer ho tsoa marang-rang li kenya filthara ea rtprecv, moo tlhahiso ea eona e hlahang ka mokhoa oa li-blocks tsa data, e 'ngoe le e' ngoe e lumellanang le pakete e le 'ngoe e amoheloang. Sebaka sena se na le data ea moputso feela; sengolong se fetileng li bonts'itsoe ka botala papisong.

Ka mor'a moo, li-blocks li romelloa ho sefahla sa li-decoder, se fetolang lisampole tsa single-byte tse teng ho tsona hore e be linear, tse 16-bit. E seng e ka sebetsoa ka li-filters tsa media streamer. Tabeng ea rona, re li romella feela kareteng ea molumo bakeng sa ho bapala ho libui tsa li-headset tsa hau.

Joale a re tsoeleng pele ho ts'ebetsong ea software. Ho etsa sena, re tla kopanya lifaele tsa moamoheli le li-transmitter tseo re li arotseng pele. Pele ho sena, re ne re sebelisa litlhophiso tse tsitsitseng bakeng sa likou le liaterese, empa joale re hloka lenaneo hore le khone ho sebelisa litlhophiso tseo re li boletseng ha re qala. Ho etsa sena, re tla eketsa ts'ebetso ea ho sebetsana le mabaka a mola oa taelo. Ka mor'a moo re tla khona ho beha aterese ea IP le koung ea intercom eo re batlang ho theha khokahanyo le eona.

Taba ea pele, a re kenyelletseng sebopeho lenaneong le tla boloka litlhophiso tsa lona:

struct _app_vars
{
  int  local_port;              /* Локальный порт. */
  int  remote_port;             /* Порт переговорного устройства на удаленном компьютере. */
  char remote_addr[128];        /* IP-адрес удаленного компьютера. */
  MSDtmfGenCustomTone dtmf_cfg; /* Настройки тестового сигнала генератора. */
};

typedef struct _app_vars app_vars;

Lenaneo le tla phatlalatsa sebopeho sa mofuta ona se bitsoang vars.
Ka mor'a moo, ha re kenye letsoho ho hlalosa mabaka a mola oa taelo:

/* Функция преобразования аргументов командной строки в
* настройки программы. */
void  scan_args(int argc, char *argv[], app_vars *v)
{
    char i;
    for (i=0; i<argc; i++)
    {
        if (!strcmp(argv[i], "--help"))
        {
            char *p=argv[0]; p=p + 2;
            printf("  %s walkie talkienn", p);
            printf("--help      List of options.n");
            printf("--version   Version of application.n");
            printf("--addr      Remote abonent IP address string.n");
            printf("--port      Remote abonent port number.n");
            printf("--lport     Local port number.n");
            printf("--gen       Generator frequency.n");
            exit(0);
        }

        if (!strcmp(argv[i], "--version"))
        {
            printf("0.1n");
            exit(0);
        }

        if (!strcmp(argv[i], "--addr"))
        {
            strncpy(v->remote_addr, argv[i+1], 16);
            v->remote_addr[16]=0;
            printf("remote addr: %sn", v->remote_addr);
        }

        if (!strcmp(argv[i], "--port"))
        {
            v->remote_port=atoi(argv[i+1]);
            printf("remote port: %in", v->remote_port);
        }

        if (!strcmp(argv[i], "--lport"))
        {
            v->local_port=atoi(argv[i+1]);
            printf("local port : %in", v->local_port);
        }

        if (!strcmp(argv[i], "--gen"))
        {
            v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
                printf("gen freq : %in", v -> dtmf_cfg.frequencies[0]);
        }
    }
}

Ka lebaka la ho arola, likhang tsa mola oa taelo li tla beoa masimong a sebopeho sa vars. Mosebetsi o ka sehloohong oa ts'ebeliso e tla ba ho bokella litsela tsa ho fetisa le ho amohela ho tsoa ho li-filters; ka mor'a ho hokahanya ticker, taolo e tla fetisetsoa ho loop e sa feleng eo, haeba maqhubu a jenereithara a behiloe ho bao e seng zero, a tla qala jenereithara ea teko hape e sebetsa ntle le ho emisa.

Jenereithara e tla hloka li-restarts tsena ka lebaka la moralo oa eona; ka lebaka le itseng e ke ke ea hlahisa lets'oao le tšoarellang ho feta metsotsoana e 16. Hoa lokela ho hlokomeloa hore nako ea eona e hlalosoa ke nomoro ea 32-bit.

Lenaneo lohle le tla shebahala tjena:

/* Файл mstest8.c Имитатор переговорного устройства. */

#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/msrtp.h>

/* Подключаем файл общих функций. */
#include "mstest_common.c"

/*----------------------------------------------------------*/
struct _app_vars
{
    int  local_port;              /* Локальный порт. */
    int  remote_port;             /* Порт переговорного устройства на удаленном компьютере. */
    char remote_addr[128];        /* IP-адрес удаленного компьютера. */
    MSDtmfGenCustomTone dtmf_cfg; /* Настройки тестового сигнала генератора. */
};

typedef struct _app_vars app_vars;

/*----------------------------------------------------------*/
/* Создаем дуплексную RTP-сессию. */
RtpSession* create_duplex_rtp_session(app_vars v)
{
    RtpSession *session = create_rtpsession (v.local_port, v.local_port + 1, FALSE, RTP_SESSION_SENDRECV);
    rtp_session_set_remote_addr_and_port(session, v.remote_addr, v.remote_port, v.remote_port + 1);
    rtp_session_set_send_payload_type(session, PCMU);
    return session;
}

/*----------------------------------------------------------*/
/* Функция преобразования аргументов командной строки в
* настройки программы. */
void  scan_args(int argc, char *argv[], app_vars *v)
{
    char i;
    for (i=0; i<argc; i++)
    {
        if (!strcmp(argv[i], "--help"))
        {
            char *p=argv[0]; p=p + 2;
            printf("  %s walkie talkienn", p);
            printf("--help      List of options.n");
            printf("--version   Version of application.n");
            printf("--addr      Remote abonent IP address string.n");
            printf("--port      Remote abonent port number.n");
            printf("--lport     Local port number.n");
            printf("--gen       Generator frequency.n");
            exit(0);
        }

        if (!strcmp(argv[i], "--version"))
        {
            printf("0.1n");
            exit(0);
        }

        if (!strcmp(argv[i], "--addr"))
        {
            strncpy(v->remote_addr, argv[i+1], 16);
            v->remote_addr[16]=0;
            printf("remote addr: %sn", v->remote_addr);
        }

        if (!strcmp(argv[i], "--port"))
        {
            v->remote_port=atoi(argv[i+1]);
            printf("remote port: %in", v->remote_port);
        }

        if (!strcmp(argv[i], "--lport"))
        {
            v->local_port=atoi(argv[i+1]);
            printf("local port : %in", v->local_port);
        }

        if (!strcmp(argv[i], "--gen"))
        {
            v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
                printf("gen freq : %in", v -> dtmf_cfg.frequencies[0]);
        }
    }
}

/*----------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Устанавливаем настройки по умолчанию. */
    app_vars vars={5004, 7010, "127.0.0.1", {0}};

    /* Устанавливаем настройки настройки программы в
     * соответствии с аргументами командной строки. */
    scan_args(argc, argv, &vars);

    ms_init();

    /* Создаем экземпляры фильтров передающего тракта. */
    MSSndCard *snd_card =
        ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
    MSFilter *snd_card_read = ms_snd_card_create_reader(snd_card);
    MSFilter *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
    MSFilter *rtpsend = ms_filter_new(MS_RTP_SEND_ID);

    /* Создаем фильтр кодера. */
    MSFilter *encoder = ms_filter_create_encoder("PCMU");

    /* Регистрируем типы нагрузки. */
    register_payloads();

    /* Создаем дуплексную RTP-сессию. */
    RtpSession* rtp_session= create_duplex_rtp_session(vars);
    ms_filter_call_method(rtpsend, MS_RTP_SEND_SET_SESSION, rtp_session);

    /* Соединяем фильтры передатчика. */
    ms_filter_link(snd_card_read, 0, dtmfgen, 0);
    ms_filter_link(dtmfgen, 0, encoder, 0);
    ms_filter_link(encoder, 0, rtpsend, 0);

    /* Создаем фильтры приемного тракта. */
    MSFilter *rtprecv = ms_filter_new(MS_RTP_RECV_ID);
    ms_filter_call_method(rtprecv, MS_RTP_RECV_SET_SESSION, rtp_session);

    /* Создаем фильтр декодера, */
    MSFilter *decoder=ms_filter_create_decoder("PCMU");

    /* Создаем фильтр звуковой карты. */
    MSFilter *snd_card_write = ms_snd_card_create_writer(snd_card);

    /* Соединяем фильтры приёмного тракта. */
    ms_filter_link(rtprecv, 0, decoder, 0);
    ms_filter_link(decoder, 0,  snd_card_write, 0);

    /* Создаем источник тактов - тикер. */
    MSTicker *ticker = ms_ticker_new();

    /* Подключаем источник тактов. */
    ms_ticker_attach(ticker, snd_card_read);
    ms_ticker_attach(ticker, rtprecv);

    /* Если настройка частоты генератора отлична от нуля, то запускаем генератор. */   
    if (vars.dtmf_cfg.frequencies[0])
    {
        /* Настраиваем структуру, управляющую выходным сигналом генератора. */
        vars.dtmf_cfg.duration = 10000;
        vars.dtmf_cfg.amplitude = 1.0;
    }

    /* Организуем цикл перезапуска генератора. */
    while(TRUE)
    {
        if(vars.dtmf_cfg.frequencies[0])
        {
            /* Включаем звуковой генератор. */
            ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,
                    (void*)&vars.dtmf_cfg);
        }
        /* Укладываем тред в спячку на 20мс, чтобы другие треды
         * приложения получили время на работу. */
        ms_usleep(20000);
    }
}

Ha re bokelleng. Joale lenaneo le ka tsamaisoa ka lik'homphieutha tse peli. Kapa ho e 'ngoe, joalo ka ha ke tla etsa hona joale. Re qala TShark ka likhang tse latelang:

$ sudo tshark -i lo -f "udp dst port 7010" -P -V -O RTP -o rtp.heuristic_rtp:TRUE -x

Haeba tšimo ea ho qala ho console e bontša feela molaetsa oa ho qala ho hapa, joale sena ke letšoao le letle - ho bolela hore boema-kepe ba rona bo ka 'na ba se ke ba tšoaroa ke mananeo a mang. Sebakeng se seng, re qala mohlala oa lenaneo o tla etsisa "intercom" e hole ka ho hlakisa nomoro ena ea boema-kepe:

$ ./mstest8 --port 9010 --lport 7010

Joalo ka ha ho bonoa sengoloa sa lenaneo, aterese ea kamehla ea IP ke 127.0.0.1 (loopback ea lehae).

Sebakeng se seng, re qala mohlala oa bobeli oa lenaneo, o etsisang sesebelisoa sa lehae. Re sebelisa khang e eketsehileng e lumellang jenereithara ea liteko e hahelletsoeng ho sebetsa:

$ ./mstest8  --port 7010 --lport 9010 --gen 440

Ka nako ena, lipakete tse fetiselitsoeng ho sesebelisoa sa "hole" li lokela ho qala ho bonesa ka har'a khomphutha le TShark, 'me molumo o tsoelang pele o tla utloahala ho tsoa ho sebui sa komporo.

Haeba ntho e 'ngoe le e' ngoe e etsahetse joalokaha e ngotsoe, joale re qala hape kopi ea bobeli ea lenaneo, empa ntle le senotlolo le khang "-gen 440". Joale o tla bapala karolo ea jenereithara. Kamora sena, o ka etsa lerata ka har'a maekrofono; o lokela ho utloa molumo o lumellanang le sebuela-hōle kapa li-headphone. Ho ithabisa ka molumo oa lentsoe ho ka 'na ha etsahala; fokotsa molumo oa sebui 'me phello e tla nyamela.

Haeba u e tsamaisitse ka lik'homphieutha tse peli 'me u sa ferekane ka liaterese tsa IP, joale sephetho se tšoanang se u letetse - puisano ea lentsoe la boleng ba digital ka litsela tse peli.

Sehloohong se latelang re tla ithuta ho ngola li-filters tsa rona - li-plugins, ka lebaka la tsebo ena u tla khona ho sebelisa mecha ea litaba eseng feela bakeng sa molumo le video, empa hape le sebakeng se seng se itseng.

Source: www.habr.com

Eketsa ka tlhaloso