Mediastreamer2 VoIP එන්ජිම ගවේෂණය කිරීම. 5 කොටස

ලිපියේ ද්‍රව්‍ය මගේ වෙතින් ලබාගෙන ඇත සෙන් නාලිකාව.

නාද අනාවරකය

අන්තිමට ලිපියයි අපි සංඥා මට්ටමේ මීටරයක් ​​නිර්මාණය කර ඇත. මේකෙන් අපි ඉගෙන ගනිමු ටෝන් සිග්නල් එකක් අඳුරගන්නේ කොහොමද කියලා.

Mediastreamer2 VoIP එන්ජිම ගවේෂණය කිරීම. 5 කොටස

පැරණි දිනවල, සෑම පවුලකටම රූපවාහිනියක් නොතිබූ අතර, ඔවුන්ගෙන් අඩක් ප්ලයර්ස් භාවිතයෙන් නාලිකා මාරු කළ විට, එක් රූපවාහිනී නිෂ්පාදකයෙකු තම උපාංග රැහැන් රහිත දුරස්ථ පාලකයකින් සන්නද්ධ කර ඇති බවට විදේශීය තාක්ෂණික පුවත්පත් සමාලෝචනවල කුතුහලය දනවන පුවත් පළ විය. අසාමාන්‍ය ප්‍රවේශයක් භාවිතා කිරීම නිසා දුරස්ථ පාලකය බැටරි නොමැතිව ක්‍රියාත්මක වූ බව විස්තර වලින් දැන සිටියේය - දුරස්ථ පාලකය යාන්ත්‍රික වූ අතර සංගීත භාණ්ඩයක දෙමුහුන් එකක් විය - මෙටලෝෆෝනයක් සහ රිවෝල්වරයක්. රිවෝල්වර බෙරයේ විවිධ දිග ලෝහ සිලින්ඩර අඩංගු වූ අතර වෙඩි තැබීමේ පින් එක ඉන් එකක වැදුණු විට සිලින්ඩරය එහිම සංඛ්‍යාතයෙන් නාද වීමට පටන් ගත්තේය. අනුමාන වශයෙන් අල්ට්රා සවුන්ඩ් මත. රූපවාහිනියේ ඇති ඉලෙක්ට්රොනික උපකරණ මෙම සංඥාව අසා ඇති අතර, එහි සංඛ්යාතය තීරණය කර, සුදුසු ක්රියාවක් සිදු කර ඇත - නාලිකාව මාරු කරන්න, ශබ්දය වෙනස් කරන්න, රූපවාහිනිය නිවා දමන්න.

අද අපි මාධ්‍ය ප්‍රවාහය පිළිබඳ අපගේ දැනුම භාවිතා කරමින් මෙම විධාන සම්ප්‍රේෂණ පද්ධතිය ප්‍රතිනිර්මාණය කිරීමට උත්සාහ කරමු.

දුරස්ථ පාලකයක් අනුකරණය කිරීම සඳහා, අපි අපගේ නාද උත්පාදක උදාහරණයේ පෙළ භාවිතා කරමු. අපි එයට යතුරු පහරවලින් උත්පාදක සංඛ්‍යාතය පාලනය කිරීම සහ ලැබුණු විධානයන් කොන්සෝලයට ප්‍රතිදානය කරන විකේතකයක් සහිත ග්‍රාහකයක් එකතු කරන්නෙමු. වෙනස් කිරීමෙන් පසු, උත්පාදක යන්ත්රය සංඛ්යාත 6 ක නාද නිපදවිය යුතු අතර, ශබ්දය වැඩි කිරීමට / අඩු කිරීමට, නාලිකාව වෙනස් කිරීමට, රූපවාහිනිය සක්රිය / අක්රිය කිරීමට අපි විධාන කේතනය කරන්නෙමු. අනාවරකය වින්‍යාස කිරීම සඳහා, පහත ව්‍යුහය භාවිතා කරයි:

struct _MSToneDetectorDef{  
     char tone_name[8];     
     int frequency; /**<Expected frequency of the tone*/ 
     int min_duration; /**<Min duration of the tone in milliseconds */ 
     float min_amplitude; /**<Minimum amplitude of the tone, 1.0 corresponding to the normalized 0dbm level */
};

typedef struct _MSToneDetectorDef MSToneDetectorDef;

අනාවරකයකට මෙම ව්‍යුහයන් 10 ක් ලබා දිය හැකි අතර, එබැවින් එක් අනාවරකයක් ද්වි-ස්වර සංඥා දහයක් හඳුනා ගැනීමට වින්‍යාසගත කළ හැක. නමුත් අපි තනි ස්වර සංඥා හයක් පමණක් භාවිතා කරමු. අනාවරකයට සිටුවම් මාරු කිරීමට, MS_TONE_DETECTOR_ADD_SCAN ක්‍රමය භාවිතා කරයි.

අනාවරකයට අපේක්ෂිත සංඛ්‍යාත සංරචක සහිත සංඥාවක් එහි ආදානයට පැමිණ ඇති බව අපට දැනුම් දීම සඳහා, අපි එය මෙම අවස්ථාවේදී දියත් කරන ආපසු කැඳවීමේ කාර්යයක් ලබා දිය යුතුය. මෙය ශ්‍රිතය භාවිතයෙන් සිදු කෙරේ ms_filter_set_notify_callback(). තර්කයක් ලෙස, එය පෙරහනට දර්ශකයක්, ආපසු ඇමතුම් ශ්‍රිතයට දර්ශකයක් සහ අපි ආපසු ඇමතුම් ශ්‍රිතයට (පරිශීලක දත්ත) යැවීමට කැමති දත්ත වෙත දර්ශකයක් ලබා ගනී.

අනාවරකය ක්‍රියාත්මක කළ විට, ආපසු ඇමතුම් ශ්‍රිතයට පරිශීලක දත්ත, අනාවරක පෙරහන වෙත දර්ශකයක්, සිදුවීම් හඳුනාගැනීමක් සහ සිදුවීම විස්තර කරන ව්‍යුහයක් ලැබෙනු ඇත:


/** * Structure carried as argument of the MS_TONE_DETECTOR_EVENT**/
struct _MSToneDetectorEvent{ 
      char tone_name[8];       /* Имя тона которое мы ему назначили при настройке детектора. */
      uint64_t tone_start_time;   /* Время в миллисекундах, когда тон был обнаружен. */
};

typedef struct _MSToneDetectorEvent MSToneDetectorEvent;

සංඥා සැකසීමේ බ්ලොක් රූප සටහන මාතෘකා පින්තූරයේ දැක්වේ.

හොඳයි, දැන් අදහස් සහිත වැඩසටහන් කේතයම.

/* Файл mstest4.c Имитатор пульта управления и приемника. */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/msvolume.h>
#include <mediastreamer2/mstonedetector.h>

/* Подключаем заголовочный файл с функциями управления событиями
 * медиастримера. */
#include <mediastreamer2/mseventqueue.h>

/* Функция обратного вызова, она будет вызвана фильтром, как только он
 * обнаружит совпадение характеристик входного сигнала с заданными. */
static void tone_detected_cb(void *data, MSFilter *f, unsigned int event_id,
        MSToneDetectorEvent *ev)
{
    printf("                      Принята команда: %sn", ev->tone_name);
}

int main()
{
    ms_init();

    /* Создаем экземпляры фильтров. */
    MSFilter  *voidsource = ms_filter_new(MS_VOID_SOURCE_ID);
    MSFilter  *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
    MSFilter  *volume = ms_filter_new(MS_VOLUME_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);
    MSFilter  *detector = ms_filter_new(MS_TONE_DETECTOR_ID);

    /* Очищаем массив находящийся внутри детектора тонов, он описывает
     * особые приметы разыскиваемых сигналов.*/
    ms_filter_call_method(detector, MS_TONE_DETECTOR_CLEAR_SCANS, 0);

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

    /* Соединяем фильтры в цепочку. */
    ms_filter_link(voidsource, 0, dtmfgen, 0);
    ms_filter_link(dtmfgen, 0, volume, 0);
    ms_filter_link(volume, 0, detector, 0);
    ms_filter_link(detector, 0, snd_card_write, 0);

    /* Подключаем к фильтру функцию обратного вызова. */
    ms_filter_set_notify_callback(detector,
            (MSFilterNotifyFunc)tone_detected_cb, NULL);

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

    /* Создаем массив, каждый элемент которого описывает характеристику
     * одного из тонов, который требуется обнаруживать: Текстовое имя
     * данного элемента, частота в герцах, длительность в миллисекундах,
     * минимальный уровень относительно 0,775В. */  
    MSToneDetectorDef  scan[6]=
    {
        {"V+",  440, 100, 0.1}, /* Команда "Увеличить громкость". */
        {"V-",  540, 100, 0.1}, /* Команда "Уменьшить громкость". */
        {"C+",  640, 100, 0.1}, /* Команда "Увеличить номер канала". */
        {"C-",  740, 100, 0.1}, /* Команда "Уменьшить номер канала". */
        {"ON",  840, 100, 0.1}, /* Команда "Включить телевизор". */
        {"OFF", 940, 100, 0.1}  /* Команда "Выключить телевизор". */
    };

    /* Передаем в детектор тонов приметы сигналов. */
    int i;
    for (i = 0; i < 6; i++)
    {
        ms_filter_call_method(detector, MS_TONE_DETECTOR_ADD_SCAN,
                &scan[i]);
    }

    /* Настраиваем структуру, управляющую выходным сигналом генератора.*/
    MSDtmfGenCustomTone dtmf_cfg;
    dtmf_cfg.tone_name[0] = 0;
    dtmf_cfg.duration = 1000;
    dtmf_cfg.frequencies[0] = 440;
    /* Будем генерировать один тон, частоту второго тона установим в 0.*/
    dtmf_cfg.frequencies[1] = 0;
    dtmf_cfg.amplitude = 1.0;
    dtmf_cfg.interval = 0.;
    dtmf_cfg.repeat_count = 0.;

    /* Организуем цикл сканирования нажатых клавиш. Ввод нуля завершает
     * цикл и работу программы. */
    char key='9';
    printf("Нажмите клавишу команды, затем ввод.n"
        "Для завершения программы введите 0.n");
    while(key != '0')
    {
        key = getchar();
        if ((key >= 49) && (key <= 54))
        {
                printf("Отправлена команда: %cn", key);
            /* Устанавливаем частоту генератора в соответствии с
             * кодом нажатой клавиши.*/
            dtmf_cfg.frequencies[0] = 440 + 100*(key-49);

            /* Включаем звуковой генератор c обновленной частотой. */
            ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,
                    (void*)&dtmf_cfg);
        }
        ms_usleep(20000);
    }
}

අපි වැඩසටහන සම්පාදනය කර ධාවනය කරමු. සෑම දෙයක්ම නිවැරදිව ක්‍රියාත්මක වන්නේ නම්, දියත් කිරීමෙන් පසු අපට මෙම වැඩසටහනේ හැසිරීම වැනි දෙයක් ලබා ගත යුතුය:

$ ./mstest4
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib control.c:954:(snd_ctl_open_noupdate) Invalid CTL default:0
ortp-warning-Could not attach mixer to card: Invalid argument
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM default:0
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM default:0
ortp-warning-Strange, sound card Intel 82801AA-ICH does not seems to be capable of anything, retrying with plughw...
Нажмите клавишу команды, затем ввод.
Для завершения программы введите 0.
ortp-warning-alsa_set_params: periodsize:256 Using 256
ortp-warning-alsa_set_params: period:8 Using 8

"1" සිට "6" දක්වා ඕනෑම යතුරු ඔබන්න, "Enter" යතුර සමඟ තහවුරු කරන්න, ඔබට මෙවැනි ලැයිස්තුගත කිරීමක් ලබා ගත යුතුය:


2
Отправлена команда: 2
                      Принята команда: V-
1
Отправлена команда: 1
                      Принята команда: V+
3
Отправлена команда: 3
                      Принята команда: C+
4
Отправлена команда: 4
                      Принята команда: C-
0
$

විධාන නාද සාර්ථකව යවා ඇති අතර අනාවරකය ඒවා හඳුනා ගන්නා බව අපට පෙනේ.

මීළඟ ලිපියෙන් අපි RTP ප්‍රොටෝකෝලය භාවිතයෙන් ඊතර්නෙට් ජාලයක් හරහා ශ්‍රව්‍ය සංඥාවක් සම්ප්‍රේෂණය කිරීමට යොමු කර එය වහාම අපගේ දුරස්ථ පාලකයේ යොදන්නෙමු.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න