Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 9

ಲೇಖನದ ವಸ್ತುವನ್ನು ನನ್ನಿಂದ ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ ಝೆನ್ ಚಾನೆಲ್.

ಡ್ಯುಪ್ಲೆಕ್ಸ್ ಇಂಟರ್ಕಾಮ್

Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 9

ಕೊನೆಯಲ್ಲಿ ಲೇಖನ ಡ್ಯುಪ್ಲೆಕ್ಸ್ ಇಂಟರ್‌ಕಾಮ್ ಅನ್ನು ಘೋಷಿಸಲಾಗಿದೆ ಮತ್ತು ಇದರಲ್ಲಿ ನಾವು ಅದನ್ನು ಮಾಡುತ್ತೇವೆ.

ರೇಖಾಚಿತ್ರವನ್ನು ಶೀರ್ಷಿಕೆ ಚಿತ್ರದಲ್ಲಿ ತೋರಿಸಲಾಗಿದೆ. ಫಿಲ್ಟರ್ಗಳ ಕೆಳಗಿನ ಸರಪಳಿಯು ಸಂವಹನ ಮಾರ್ಗವನ್ನು ರೂಪಿಸುತ್ತದೆ, ಇದು ಧ್ವನಿ ಕಾರ್ಡ್ನಿಂದ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ. ಇದು ಮೈಕ್ರೊಫೋನ್‌ನಿಂದ ಸಿಗ್ನಲ್ ಮಾದರಿಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ. ಪೂರ್ವನಿಯೋಜಿತವಾಗಿ, ಇದು ಪ್ರತಿ ಸೆಕೆಂಡಿಗೆ 8000 ಮಾದರಿಗಳ ದರದಲ್ಲಿ ಸಂಭವಿಸುತ್ತದೆ. ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್ ಆಡಿಯೊ ಫಿಲ್ಟರ್‌ಗಳು ಬಳಸುವ ಡೇಟಾ ಬಿಟ್ ಆಳವು 16 ಬಿಟ್‌ಗಳು (ಇದು ಮುಖ್ಯವಲ್ಲ; ನೀವು ಬಯಸಿದರೆ, ಹೆಚ್ಚಿನ ಬಿಟ್ ಆಳದೊಂದಿಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ನೀವು ಬರೆಯಬಹುದು). ಡೇಟಾವನ್ನು 160 ಮಾದರಿಗಳ ಬ್ಲಾಕ್ಗಳಾಗಿ ವರ್ಗೀಕರಿಸಲಾಗಿದೆ. ಹೀಗಾಗಿ, ಪ್ರತಿ ಬ್ಲಾಕ್ ಗಾತ್ರದಲ್ಲಿ 320 ಬೈಟ್ಗಳು. ಮುಂದೆ, ನಾವು ಜನರೇಟರ್ನ ಇನ್ಪುಟ್ಗೆ ಡೇಟಾವನ್ನು ಫೀಡ್ ಮಾಡುತ್ತೇವೆ, ಅದು ಆಫ್ ಮಾಡಿದಾಗ, ಡೇಟಾಗೆ "ಪಾರದರ್ಶಕ". ಡೀಬಗ್ ಮಾಡುವ ಸಮಯದಲ್ಲಿ ನೀವು ಮೈಕ್ರೊಫೋನ್‌ನಲ್ಲಿ ಮಾತನಾಡಲು ಆಯಾಸಗೊಂಡರೆ ನಾನು ಅದನ್ನು ಸೇರಿಸಿದ್ದೇನೆ - ಟೋನ್ ಸಿಗ್ನಲ್‌ನೊಂದಿಗೆ ಮಾರ್ಗವನ್ನು "ಶೂಟ್" ಮಾಡಲು ನೀವು ಜನರೇಟರ್ ಅನ್ನು ಬಳಸಬಹುದು.

ಜನರೇಟರ್ ನಂತರ, ಸಂಕೇತವು ಎನ್‌ಕೋಡರ್‌ಗೆ ಹೋಗುತ್ತದೆ, ಇದು ನಮ್ಮ 16-ಬಿಟ್ ಮಾದರಿಗಳನ್ನು µ-ಕಾನೂನು (G.711 ಸ್ಟ್ಯಾಂಡರ್ಡ್) ಪ್ರಕಾರ ಎಂಟು-ಬಿಟ್ ಆಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ. ಎನ್ಕೋಡರ್ನ ಔಟ್ಪುಟ್ನಲ್ಲಿ, ನಾವು ಈಗಾಗಲೇ ಅರ್ಧದಷ್ಟು ಗಾತ್ರದ ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ಹೊಂದಿದ್ದೇವೆ. ಸಾಮಾನ್ಯವಾಗಿ, ನಾವು ದಟ್ಟಣೆಯನ್ನು ಉಳಿಸುವ ಅಗತ್ಯವಿಲ್ಲದಿದ್ದರೆ ನಾವು ಸಂಕೋಚನವಿಲ್ಲದೆ ಡೇಟಾವನ್ನು ರವಾನಿಸಬಹುದು. ಆದರೆ ಇಲ್ಲಿ ಎನ್‌ಕೋಡರ್ ಅನ್ನು ಬಳಸುವುದು ಉಪಯುಕ್ತವಾಗಿದೆ, ಏಕೆಂದರೆ ವೈರ್‌ಶಾರ್ಕ್ ಆರ್‌ಟಿಪಿ ಸ್ಟ್ರೀಮ್‌ನಿಂದ ಆಡಿಯೊವನ್ನು µ-ಕಾನೂನು ಅಥವಾ ಎ-ಕಾನೂನಿಗೆ ಅನುಗುಣವಾಗಿ ಸಂಕುಚಿತಗೊಳಿಸಿದಾಗ ಮಾತ್ರ ಪುನರುತ್ಪಾದಿಸಬಹುದು.

ಎನ್‌ಕೋಡರ್‌ನ ನಂತರ, ಡೇಟಾದ ಹಗುರವಾದ ಬ್ಲಾಕ್‌ಗಳನ್ನು rtpsend ಫಿಲ್ಟರ್‌ಗೆ ಕಳುಹಿಸಲಾಗುತ್ತದೆ, ಅದು ಅವುಗಳನ್ನು RTP ಪ್ಯಾಕೆಟ್‌ನಲ್ಲಿ ಇರಿಸುತ್ತದೆ, ಅಗತ್ಯ ಫ್ಲ್ಯಾಗ್‌ಗಳನ್ನು ಹೊಂದಿಸುತ್ತದೆ ಮತ್ತು UDP ಪ್ಯಾಕೆಟ್‌ನ ರೂಪದಲ್ಲಿ ನೆಟ್‌ವರ್ಕ್ ಮೂಲಕ ಪ್ರಸಾರ ಮಾಡಲು ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್‌ಗೆ ನೀಡುತ್ತದೆ.

ಫಿಲ್ಟರ್‌ಗಳ ಮೇಲಿನ ಸರಪಳಿಯು ಸ್ವೀಕರಿಸುವ ಮಾರ್ಗವನ್ನು ರೂಪಿಸುತ್ತದೆ; ನೆಟ್‌ವರ್ಕ್‌ನಿಂದ ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ ಸ್ವೀಕರಿಸಿದ RTP ಪ್ಯಾಕೆಟ್‌ಗಳು rtprecv ಫಿಲ್ಟರ್‌ಗೆ ಪ್ರವೇಶಿಸುತ್ತವೆ, ಅದರ ಔಟ್‌ಪುಟ್‌ನಲ್ಲಿ ಅವು ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳ ರೂಪದಲ್ಲಿ ಗೋಚರಿಸುತ್ತವೆ, ಪ್ರತಿಯೊಂದೂ ಸ್ವೀಕರಿಸಿದ ಪ್ಯಾಕೆಟ್‌ಗೆ ಅನುರೂಪವಾಗಿದೆ. ಬ್ಲಾಕ್ ಪೇಲೋಡ್ ಡೇಟಾವನ್ನು ಮಾತ್ರ ಒಳಗೊಂಡಿದೆ; ಹಿಂದಿನ ಲೇಖನದಲ್ಲಿ ಅವುಗಳನ್ನು ವಿವರಣೆಯಲ್ಲಿ ಹಸಿರು ಬಣ್ಣದಲ್ಲಿ ತೋರಿಸಲಾಗಿದೆ.

ಮುಂದೆ, ಬ್ಲಾಕ್ಗಳನ್ನು ಡಿಕೋಡರ್ ಫಿಲ್ಟರ್ಗೆ ಕಳುಹಿಸಲಾಗುತ್ತದೆ, ಇದು ಅವುಗಳಲ್ಲಿ ಒಳಗೊಂಡಿರುವ ಏಕ-ಬೈಟ್ ಮಾದರಿಗಳನ್ನು ರೇಖೀಯ, 16-ಬಿಟ್ ಬಿಡಿಗಳಾಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ. ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್ ಫಿಲ್ಟರ್‌ಗಳಿಂದ ಇದನ್ನು ಈಗಾಗಲೇ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬಹುದು. ನಮ್ಮ ಸಂದರ್ಭದಲ್ಲಿ, ನಿಮ್ಮ ಹೆಡ್‌ಸೆಟ್‌ನ ಸ್ಪೀಕರ್‌ಗಳಲ್ಲಿ ಪ್ಲೇಬ್ಯಾಕ್ ಮಾಡಲು ನಾವು ಅವುಗಳನ್ನು ಸೌಂಡ್ ಕಾರ್ಡ್‌ಗೆ ಕಳುಹಿಸುತ್ತೇವೆ.

ಈಗ ನಾವು ಸಾಫ್ಟ್ವೇರ್ ಅನುಷ್ಠಾನಕ್ಕೆ ಹೋಗೋಣ. ಇದನ್ನು ಮಾಡಲು, ನಾವು ಮೊದಲು ಬೇರ್ಪಡಿಸಿದ ರಿಸೀವರ್ ಮತ್ತು ಟ್ರಾನ್ಸ್ಮಿಟರ್ ಫೈಲ್ಗಳನ್ನು ನಾವು ಸಂಯೋಜಿಸುತ್ತೇವೆ. ಇದಕ್ಕೂ ಮೊದಲು, ನಾವು ಪೋರ್ಟ್‌ಗಳು ಮತ್ತು ವಿಳಾಸಗಳಿಗಾಗಿ ಸ್ಥಿರ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಸಿದ್ದೇವೆ, ಆದರೆ ಈಗ ನಾವು ಪ್ರಾರಂಭದಲ್ಲಿ ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಾಗುವಂತೆ ಪ್ರೋಗ್ರಾಂ ಅಗತ್ಯವಿದೆ. ಇದನ್ನು ಮಾಡಲು, ಆಜ್ಞಾ ಸಾಲಿನ ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ನಾವು ಕಾರ್ಯವನ್ನು ಸೇರಿಸುತ್ತೇವೆ. ಅದರ ನಂತರ ನಾವು ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಬಯಸುವ ಇಂಟರ್‌ಕಾಮ್‌ನ IP ವಿಳಾಸ ಮತ್ತು ಪೋರ್ಟ್ ಅನ್ನು ಹೊಂದಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.

ಮೊದಲಿಗೆ, ಅದರ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಸಂಗ್ರಹಿಸುವ ಪ್ರೋಗ್ರಾಂಗೆ ರಚನೆಯನ್ನು ಸೇರಿಸೋಣ:

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

typedef struct _app_vars app_vars;

ಪ್ರೋಗ್ರಾಂ ಈ ಪ್ರಕಾರದ ರಚನೆಯನ್ನು vars ಎಂದು ಘೋಷಿಸುತ್ತದೆ.
ಮುಂದೆ, ಆಜ್ಞಾ ಸಾಲಿನ ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಕಾರ್ಯವನ್ನು ಸೇರಿಸೋಣ:

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

ಪಾರ್ಸಿಂಗ್ ಪರಿಣಾಮವಾಗಿ, ಕಮಾಂಡ್ ಲೈನ್ ಆರ್ಗ್ಯುಮೆಂಟ್ಗಳನ್ನು ವರ್ಸ್ ರಚನೆಯ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ಇರಿಸಲಾಗುತ್ತದೆ. ಫಿಲ್ಟರ್‌ಗಳಿಂದ ರವಾನಿಸುವ ಮತ್ತು ಸ್ವೀಕರಿಸುವ ಮಾರ್ಗಗಳನ್ನು ಸಂಗ್ರಹಿಸುವುದು ಅಪ್ಲಿಕೇಶನ್‌ನ ಮುಖ್ಯ ಕಾರ್ಯವಾಗಿದೆ; ಟಿಕ್ಕರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿದ ನಂತರ, ನಿಯಂತ್ರಣವನ್ನು ಅನಂತ ಲೂಪ್‌ಗೆ ವರ್ಗಾಯಿಸಲಾಗುತ್ತದೆ, ಅದು ಜನರೇಟರ್ ಆವರ್ತನವನ್ನು ಶೂನ್ಯವಲ್ಲದಕ್ಕೆ ಹೊಂದಿಸಿದರೆ, ಪರೀಕ್ಷಾ ಜನರೇಟರ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸುತ್ತದೆ. ಇದು ನಿಲ್ಲದೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ.

ಜನರೇಟರ್‌ಗೆ ಅದರ ವಿನ್ಯಾಸದ ಕಾರಣದಿಂದ ಈ ಮರುಪ್ರಾರಂಭಗಳ ಅಗತ್ಯವಿರುತ್ತದೆ; ಕೆಲವು ಕಾರಣಗಳಿಂದ ಇದು 16 ಸೆಕೆಂಡುಗಳಿಗಿಂತ ಹೆಚ್ಚು ಕಾಲ ಸಿಗ್ನಲ್ ಅನ್ನು ಉತ್ಪಾದಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಅವಧಿಯನ್ನು 32-ಬಿಟ್ ಸಂಖ್ಯೆಯಿಂದ ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿದೆ ಎಂದು ಗಮನಿಸಬೇಕು.

ಸಂಪೂರ್ಣ ಪ್ರೋಗ್ರಾಂ ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:

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

ಕಂಪೈಲ್ ಮಾಡೋಣ. ನಂತರ ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಎರಡು ಕಂಪ್ಯೂಟರ್‌ಗಳಲ್ಲಿ ಚಲಾಯಿಸಬಹುದು. ಅಥವಾ ಒಂದರ ಮೇಲೆ, ನಾನು ಈಗ ಮಾಡುತ್ತೇನೆ. ನಾವು ಈ ಕೆಳಗಿನ ವಾದಗಳೊಂದಿಗೆ TShark ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ:

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

ಕನ್ಸೋಲ್‌ನಲ್ಲಿನ ಉಡಾವಣಾ ಕ್ಷೇತ್ರವು ಸೆರೆಹಿಡಿಯುವಿಕೆಯ ಪ್ರಾರಂಭದ ಬಗ್ಗೆ ಸಂದೇಶವನ್ನು ಮಾತ್ರ ಪ್ರದರ್ಶಿಸಿದರೆ, ಇದು ಉತ್ತಮ ಸಂಕೇತವಾಗಿದೆ - ಇದರರ್ಥ ನಮ್ಮ ಪೋರ್ಟ್ ಹೆಚ್ಚಾಗಿ ಇತರ ಪ್ರೋಗ್ರಾಂಗಳಿಂದ ಆಕ್ರಮಿಸಲ್ಪಟ್ಟಿಲ್ಲ. ಮತ್ತೊಂದು ಟರ್ಮಿನಲ್‌ನಲ್ಲಿ, ಈ ಪೋರ್ಟ್ ಸಂಖ್ಯೆಯನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸುವ ಮೂಲಕ "ರಿಮೋಟ್" ಇಂಟರ್‌ಕಾಮ್ ಅನ್ನು ಅನುಕರಿಸುವ ಪ್ರೋಗ್ರಾಂ ನಿದರ್ಶನವನ್ನು ನಾವು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ:

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

ಪ್ರೋಗ್ರಾಂ ಪಠ್ಯದಿಂದ ನೋಡಬಹುದಾದಂತೆ, ಡೀಫಾಲ್ಟ್ IP ವಿಳಾಸವು 127.0.0.1 (ಸ್ಥಳೀಯ ಲೂಪ್ಬ್ಯಾಕ್) ಆಗಿದೆ.

ಮತ್ತೊಂದು ಟರ್ಮಿನಲ್‌ನಲ್ಲಿ, ನಾವು ಪ್ರೋಗ್ರಾಂನ ಎರಡನೇ ನಿದರ್ಶನವನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ, ಇದು ಸ್ಥಳೀಯ ಸಾಧನವನ್ನು ಅನುಕರಿಸುತ್ತದೆ. ಅಂತರ್ನಿರ್ಮಿತ ಪರೀಕ್ಷಾ ಜನರೇಟರ್ ಕಾರ್ಯನಿರ್ವಹಿಸಲು ಅನುಮತಿಸುವ ಹೆಚ್ಚುವರಿ ವಾದವನ್ನು ನಾವು ಬಳಸುತ್ತೇವೆ:

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

ಈ ಕ್ಷಣದಲ್ಲಿ, "ರಿಮೋಟ್" ಸಾಧನದ ಕಡೆಗೆ ರವಾನೆಯಾಗುವ ಪ್ಯಾಕೆಟ್‌ಗಳು TShark ನೊಂದಿಗೆ ಕನ್ಸೋಲ್‌ನಲ್ಲಿ ಫ್ಲ್ಯಾಷ್ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಬೇಕು ಮತ್ತು ಕಂಪ್ಯೂಟರ್ ಸ್ಪೀಕರ್‌ನಿಂದ ನಿರಂತರ ಧ್ವನಿಯನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.

ಎಲ್ಲವೂ ಬರೆದಂತೆ ಸಂಭವಿಸಿದಲ್ಲಿ, ನಾವು ಪ್ರೋಗ್ರಾಂನ ಎರಡನೇ ನಕಲನ್ನು ಮರುಪ್ರಾರಂಭಿಸುತ್ತೇವೆ, ಆದರೆ ಕೀ ಮತ್ತು ಆರ್ಗ್ಯುಮೆಂಟ್ ಇಲ್ಲದೆ "-gen 440". ನೀವು ಈಗ ಜನರೇಟರ್ ಪಾತ್ರವನ್ನು ನಿರ್ವಹಿಸುತ್ತೀರಿ. ಇದರ ನಂತರ, ನೀವು ಮೈಕ್ರೊಫೋನ್‌ನಲ್ಲಿ ಶಬ್ದ ಮಾಡಬಹುದು; ನೀವು ಸ್ಪೀಕರ್ ಅಥವಾ ಹೆಡ್‌ಫೋನ್‌ಗಳಲ್ಲಿ ಅನುಗುಣವಾದ ಧ್ವನಿಯನ್ನು ಕೇಳಬೇಕು. ಅಕೌಸ್ಟಿಕ್ ಸ್ವಯಂ-ಪ್ರಚೋದನೆ ಸಹ ಸಂಭವಿಸಬಹುದು; ಸ್ಪೀಕರ್ ವಾಲ್ಯೂಮ್ ಅನ್ನು ಕಡಿಮೆ ಮಾಡಿ ಮತ್ತು ಪರಿಣಾಮವು ಕಣ್ಮರೆಯಾಗುತ್ತದೆ.

ನೀವು ಅದನ್ನು ಎರಡು ಕಂಪ್ಯೂಟರ್‌ಗಳಲ್ಲಿ ಚಲಾಯಿಸಿದರೆ ಮತ್ತು IP ವಿಳಾಸಗಳ ಬಗ್ಗೆ ಗೊಂದಲಕ್ಕೀಡಾಗದಿದ್ದರೆ, ಅದೇ ಫಲಿತಾಂಶವು ನಿಮಗೆ ಕಾಯುತ್ತಿದೆ - ದ್ವಿಮುಖ ಡಿಜಿಟಲ್ ಗುಣಮಟ್ಟದ ಧ್ವನಿ ಸಂವಹನ.

ಮುಂದಿನ ಲೇಖನದಲ್ಲಿ ನಾವು ನಮ್ಮ ಸ್ವಂತ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಹೇಗೆ ಬರೆಯಬೇಕೆಂದು ಕಲಿಯುತ್ತೇವೆ - ಪ್ಲಗ್‌ಇನ್‌ಗಳು, ಈ ಕೌಶಲ್ಯಕ್ಕೆ ಧನ್ಯವಾದಗಳು ನೀವು ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ ಅನ್ನು ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊಗಾಗಿ ಮಾತ್ರವಲ್ಲದೆ ಕೆಲವು ನಿರ್ದಿಷ್ಟ ಪ್ರದೇಶದಲ್ಲಿಯೂ ಬಳಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ