Kuwunika injini ya Mediastreamer2 VoIP. Gawo 9

Zomwe zili m'nkhaniyi zatengedwa kuchokera ku wanga zene channel.

Duplex intercom

Kuwunika injini ya Mediastreamer2 VoIP. Gawo 9

Pomaliza nkhani duplex intercom idalengezedwa, ndipo mu iyi tipanga.

Chithunzicho chikuwonetsedwa mu chithunzi chamutu. Unyolo wapansi wa zosefera umapanga njira yopatsira, yomwe imayambira pa khadi lamawu. Amapereka zitsanzo zazizindikiro kuchokera pa maikolofoni. Mwachikhazikitso, izi zimachitika pamlingo wa zitsanzo 8000 pamphindikati. Kuzama kwa data komwe zosefera zomvera za media streamer zimagwiritsa ntchito 16 bits (izi sizofunikira; ngati mukufuna, mutha kulemba zosefera zomwe zingagwire ntchito mozama kwambiri). Detayo imagawidwa m'magulu a zitsanzo za 160. Chifukwa chake, chipika chilichonse ndi 320 byte kukula kwake. Kenaka, timadyetsa deta kuzinthu za jenereta, zomwe, zitazimitsidwa, zimakhala "zowonekera" ku deta. Ndidawonjezeranso ngati mutatopa kuyankhula ndi maikolofoni pakuwongolera zolakwika - mutha kugwiritsa ntchito jenereta "kuwombera" njira ndi siginecha yamtundu.

Pambuyo pa jenereta, chizindikirocho chimapita ku encoder, yomwe imasintha zitsanzo zathu za 16-bit molingana ndi µ-law (G.711 standard) kukhala zisanu ndi zitatu. Pakutulutsa kwa encoder, tili ndi block block ya theka la kukula kwake. Kawirikawiri, tikhoza kutumiza deta popanda kukakamiza ngati sitiyenera kusunga magalimoto. Koma apa ndizothandiza kugwiritsa ntchito encoder, popeza Wireshark imatha kupanganso mawu kuchokera pamtsinje wa RTP pokhapokha ikakanikizidwa molingana ndi µ-lamulo kapena lamulo.

Pambuyo pa encoder, midadada yopepuka ya data imatumizidwa ku fyuluta ya rtpsend, yomwe idzayike mu paketi ya RTP, ikani mbendera zofunika ndikuzipereka kwa media streamer kuti zitumizidwe pa intaneti mu mawonekedwe a paketi ya UDP.

Zosefera zapamwamba zimapanga njira yolandirira; Mapaketi a RTP olandilidwa ndi media media streamer kuchokera pa netiweki amalowetsa fyuluta ya rtprecv, pakutulutsa kwake komwe amawoneka ngati midadada ya data, iliyonse yomwe imagwirizana ndi paketi imodzi yolandilidwa. Chotchingacho chimakhala ndi zolipira zokha; m'nkhani yapitayi adawonetsedwa zobiriwira m'fanizoli.

Kenako, midadada imatumizidwa ku decoder fyuluta, yomwe imatembenuza zitsanzo za single-byte zomwe zili mmenemo kukhala mzere, 16-bit. Zomwe zitha kukonzedwa kale ndi zosefera za media streamer. Kwa ife, timangowatumiza ku khadi lamawu kuti abwerezenso pama speaker amutu wanu.

Tsopano tiyeni tipite ku kukhazikitsa mapulogalamu. Kuti tichite izi, tidzaphatikiza mafayilo olandila ndi ma transmitter omwe tidawalekanitsa kale. Izi zisanachitike, tidagwiritsa ntchito makonda okhazikika a madoko ndi ma adilesi, koma tsopano tikufunika pulogalamuyo kuti igwiritse ntchito makonda omwe timawafotokozera poyambira. Kuti tichite izi, titha kuwonjezera magwiridwe antchito pokonza mfundo za mzere wamalamulo. Pambuyo pake tidzatha kukhazikitsa adilesi ya IP ndi doko la intercom yomwe tikufuna kukhazikitsa nayo kulumikizana.

Choyamba, tiyeni tiwonjezere dongosolo ku pulogalamu yomwe idzasungira zokonda zake:

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

typedef struct _app_vars app_vars;

Pulogalamuyi idzalengeza zamtundu wamtunduwu wotchedwa vars.
Kenako, tiyeni tiwonjezere ntchito kuti tigawane mfundo za mzere wa lamulo:

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

Chifukwa cha kugawa, mikangano ya mzere wolamula idzayikidwa m'magawo a ma vars. Ntchito yayikulu yogwiritsira ntchito idzakhala kusonkhanitsa njira zotumizira ndi kulandira kuchokera ku zosefera; mutalumikiza ticker, chiwongolero chidzasamutsidwa ku loop yopanda malire yomwe, ngati ma frequency a jenereta adayikidwa kuti akhale osakhala zero, adzayambitsanso jenereta yoyesa kuti zimagwira ntchito popanda kuyimitsa.

Jenereta idzafunika kuyambiranso izi chifukwa cha mapangidwe ake; pazifukwa zina sizingapange chizindikiro chopitilira masekondi 16. Tiyenera kukumbukira kuti nthawi yake imatchulidwa ndi nambala ya 32-bit.

Pulogalamu yonse idzawoneka motere:

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

Tiyeni tipange. Ndiye pulogalamu akhoza kuthamanga pa makompyuta awiri. Kapena pa chimodzi, monga ndichitira tsopano. Timayambitsa TShark ndi zifukwa zotsatirazi:

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

Ngati gawo lotsegulira mu kontrakitala limangowonetsa uthenga wokhudza kuyamba kugwidwa, ndiye kuti ichi ndi chizindikiro chabwino - zikutanthauza kuti doko lathu silikhala ndi mapulogalamu ena. Mu terminal ina, tikuyambitsa pulogalamu yomwe ingafanane ndi "kutali" intercom pofotokoza nambala yadoko iyi:

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

Monga momwe tikuwonera palemba la pulogalamuyo, adilesi ya IP yokhazikika ndi 127.0.0.1 (loopback yakomweko).

Mu terminal ina, timayambitsa pulogalamu yachiwiri, yomwe imatengera chipangizo chapafupi. Timagwiritsa ntchito mkangano wowonjezera womwe umalola jenereta yoyeserera kuti igwire ntchito:

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

Pakadali pano, mapaketi omwe amatumizidwa ku chipangizo cha "kutali" ayenera kuyamba kuwunikira mu kontrakitala ndi TShark, ndipo kamvekedwe kopitilira kadzamveka kuchokera kwa wokamba kompyuta.

Ngati zonse zidachitika monga momwe zidalembedwera, ndiye kuti timayambiranso pulogalamu yachiwiri, koma popanda fungulo ndi mkangano "-Gen 440". Tsopano mukhala ngati jenereta. Pambuyo pa izi, mutha kupanga phokoso mu maikolofoni; muyenera kumva mawu ofanana mu speaker kapena mahedifoni. Kudzisangalatsa kwamphamvu kumatha kuchitika; tsitsani voliyumu yolankhula ndipo zotsatira zake zitha.

Ngati mudayendetsa pamakompyuta awiri ndipo simunasokonezeke ndi ma adilesi a IP, ndiye kuti zotsatira zomwezo zikukuyembekezerani - kulumikizana kwamawu a digito kwanjira ziwiri.

M'nkhani yotsatira tidzaphunzira kulemba zosefera zathu - mapulagini, chifukwa cha luso mudzatha kugwiritsa ntchito TV streamer osati zomvetsera ndi kanema, komanso ena enieni m'dera.

Source: www.habr.com

Kuwonjezera ndemanga