Explorans machinam Mediastreamer2 VoIP. Pars I

Materia articuli sumitur ex my rhoncus channel.

duplex intercom

Explorans machinam Mediastreamer2 VoIP. Pars I

In novissimis articulus duplex interca indicto et in hoc uno faciemus.

Tabula in titulo figurae ostenditur. Inferior filorum catena format iter transmissionis, quod incipit a card sono. Signum praebet exempla e tortor ligula. Defalta, hoc fit ad 8000 speciminum pro secundo. Notitia aliquantulum profunditatis quae media ad streaming audio filters usus est 16 frusta (hoc non est magni momenti; si vis, Filtra scribere potes quae cum altiori aliqua profunditate laborabit). Notitia in caudices 160 exempla condensatur. Uterque ergo clausus est 320 bytes in magnitudine. Deinde notitias input generantis pascimus, quae cum submoveretur, "transparens" in notitia est. Hoc adieci si loqui in tortor ligula per debugging gravere - generans uti potes ad "iaculationem" viam sono signo.

Post generante signum accedit ad encoder, quod nostra 16 bis exempla secundum generum (G.711 vexillum) in octingentos suos convertit. Ad output encoder, iam nos in medium datae molis scandalum habemus. In genere, notitias sine compressione transmittere possumus, si mercaturam servare non indigemus. Sed hic utile est uti encoder, quandoquidem Wireshark ex RTP rivo solum sonum referre potest cum comprimitur secundum legem vel legem.

Post encoder, leviores caudices notitiarum ad colum mittuntur ad rtpsend, qui eas in fasciculum RTP pones, vexilla necessaria pones et trades instrumentis streamer tradendis super reticulum in modum UDP fasciculi.

Superior catena filorum iter accipit, RTP fasciculae receptae a instrumentis confluentibus e retis intra colum rtprecv intrant, ad quorum output apparent in forma stipitorum notitiarum, quarum singulae uni receptaculo lecti respondent. Stipes tantum continet datas payload, in articulo praecedente monstratum est in illustratione viridi.

Deinceps caudices mittuntur ad colum decoder, quod singula exempla in eis contenta in lineares, 16 frenum convertit. Quae iam per filtras medias streaming discursum possunt. In casu nostro, simpliciter eos mittimus ad sonum chartae pro playback super oratores capitis vestri.

Nunc ad exsequendam software transeamus. Ad hoc faciendum, receptatorem ac transmissorem lima componemus, quae ante nos separavimus. Ante hoc certa loca pro portubus et inscriptionibus usi sumus, nunc programmata indigemus ut uncinis uti possimus quos incipimus nominamus. Ad hoc faciendum, functionality ad componendas lineas argumentorum mandatum addere volumus. Post quam IP inscriptionem portumque intercom ponere poterimus quo nexum constituere volumus.

Primum addamus structuram programmatis quae sua loca condet;

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

typedef struct _app_vars app_vars;

Propositum declarabit structuram huius generis vars appellatam.
Deinde, munus ad parse lineae rationes addamus;

/* Функция преобразования аргументов командной строки в
* настройки программы. */
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]);
        }
    }
}

Ex parsing, rationes lineae mandatum in agris vars structuram collocabuntur. Praecipuum munus applicationis erit ut semitas ex filtra transmittendo et recipiendo colligas, post connexum ticker, imperium transferetur ad ansam infinitam quae, si frequentia generans in non-nulla posita erat, testem generantis sileo ut sine intermissione operatur.

Generator his restarts ex consilio suo indigebit, nam aliqua de causa signum plusquam XVI secundis perennes producere non potest. Notandum est, quod eius duratio per numerum XXXII frenum specificatur.

Propositum totum sic erit:

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

Let's compilare. Propositum deinde duobus computatris currere potest. Aut ex una, ut nunc faciam. TShark demittimus cum his argumentis:

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

Si campus immissus in console solum nuntium exhibet de incepto captivitatis, tunc bonum signum est - significat portum nostrum ab aliis programmatis non occupatum esse verisimile est. Alio terminali instantia programma iniciemus, quod intercom "remotum" simulat, numerum hunc portum denotans:

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

Ut ex textu programmatis videri potest, default IP oratio est 127.0.0.1 (locus loopback).

In alio termino secundo instantia progressionis, quae localem fabricam simulat. Addito argumento utimur quod constructum-in test generantis ad operandum permittit;

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

Hoc momento, fasciculi ad "desertam" fabricam transmissae in consolatione cum TShark fulgere debent, et continuus tonus audietur ab oratore computatorio.

Si omnia ut scripta sunt, secundo programmatis exemplar sileo, sed sine clave et argumento "-gen 440". tu nunc genitoris ludas. Postea, in tortor ligula, sonum facere potes, audias sonum respondentem in loquentis vel in headphones. Acoustic auto-excitationem etiam fieri potest, oratorium volumen descendet et effectus evanescet.

Si in duobus computers currebas et de IP inscriptionibus non confundebas, idem eventus te exspectat - duo-modo digitalis qualitas vocis communicationis.

In proximo articulo discemus scribere filtra nostra - plugins, propter hanc peritiam, instrumentis streamer non solum in audio et video, sed etiam in aliqua alia regione specifica uti poteris.

Source: www.habr.com

Add a comment