Ngajalajah mesin Mediastreamer2 VoIP. Bagian 5

Materi artikel dicokot ti abdi saluran zen.

Detektor nada

Di tempo anu kalangkung artikel Kami parantos nyiptakeun méteran tingkat sinyal. Dina ieu urang bakal diajar kumaha ngadeteksi sinyal nada.

Ngajalajah mesin Mediastreamer2 VoIP. Bagian 5

Baheula, nalika henteu unggal kulawarga ngagaduhan TV, sareng satengahna ngalihkeun saluran nganggo tang, warta anu pikaresepeun muncul dina ulasan pers téknis asing yén produsén TV dilengkepan alat-alatna sareng kadali jauh nirkabel. Tina detil éta dipikanyaho yén kadali jauh dioperasikeun tanpa batré berkat ngagunakeun pendekatan anu teu biasa - kadali jauh mékanis sareng mangrupikeun hibrida alat musik - metallophone sareng revolver. Kendang revolver ngandung silinder logam tina panjangna béda, sarta nalika pin firing pencét salah sahijina, silinder mimiti hurung dina frékuénsi sorangan. Panginten dina ultrasound. Éléktronik dina TV ngadangu sinyal ieu sareng, saatos nangtukeun frékuénsina, ngalaksanakeun tindakan anu pas - pindah saluran, robih polumeu, pareum TV.

Dinten ieu kami bakal nyobian ngarekonstruksikeun sistem transmisi paréntah ieu, ngagunakeun pangaweruh urang ngeunaan streamer média.

Pikeun simulate kadali jauh, urang bakal ngagunakeun téks conto generator nada urang. Urang bakal nambahan kana eta kadali frékuénsi generator ti keystrokes jeung panarima ku decoder nu bakal kaluaran narima paréntah pikeun konsol nu. Saatos parobihan, generator kedah ngahasilkeun nada 6 frekuensi, dimana kami bakal ngodekeun paréntah pikeun ningkatkeun / ngirangan volume, ngarobih saluran, hurungkeun / mareuman TV. Pikeun ngonpigurasikeun detektor, struktur ieu dianggo:

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;

Hiji detektor bisa dibikeun 10 tina struktur ieu, jadi hiji detektor bisa ngonpigurasi pikeun ngadeteksi sapuluh sinyal dua-nada. Tapi urang ngan ukur nganggo genep sinyal nada tunggal. Pikeun mindahkeun setelan ka detektor, metode MS_TONE_DETECTOR_ADD_SCAN dianggo.

Pikeun detektor ngabéjaan yén sinyal sareng komponén frékuénsi anu dipikahoyong parantos sumping kana inputna, urang kedah nyayogikeun fungsi callback anu bakal diluncurkeun dina hal ieu. Hal ieu dilakukeun ngagunakeun fungsi ms_filter_set_notify_callback(). Salaku argumen, éta nampi pointer kana saringan, pointer kana fungsi callback, sareng pointer kana data anu urang hoyong kirimkeun kana fungsi callback (data pangguna).

Nalika detektor dipicu, pungsi callback bakal nampi data pangguna, panunjuk kana saringan detektor, identifier acara, sareng struktur anu ngajelaskeun kajadian:


/** * 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;

Diagram blok pamrosésan sinyal dipidangkeun dina gambar judul.

Muhun, ayeuna kode program sorangan kalawan komentar.

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

Urang compile tur ngajalankeun program. Upami sadayana jalan leres, maka saatos peluncuran urang kedah nampi sapertos kabiasaan program ieu:

$ ./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

Pencét naon waé konci tina "1" dugi ka "6", mastikeun ku konci "Asupkeun", anjeun kedah nampi anu sapertos daptar ieu:


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

Kami ningali yén nada paréntah suksés dikirim sareng detektor ngadeteksi aranjeunna.

Dina artikel salajengna urang bakal balik ka ngirimkeun sinyal audio ngaliwatan jaringan Ethernet ngagunakeun protokol RTP jeung geura nerapkeun dina kadali jauh urang.

sumber: www.habr.com

Tambahkeun komentar