Vekolîna motora VoIP ya Mediastreamer2. Beş 5

Madeya gotarê ji min hatiye girtin kanala zen.

Detektorê Tone

Di ya paşîn de gotara Me metreyek asta sînyalê çêkiriye. Di vê yekê de em ê fêr bibin ka meriv çawa îşaretek tone kifş dike.

Vekolîna motora VoIP ya Mediastreamer2. Beş 5

Di rojên berê de, dema ku ne her malbatek televîzyonek hebû, û nîvê wan kanalan bi karanîna pêlavan diguherand, di nirxandinên çapameniya teknîkî ya biyanî de nûçeyên balkêş derketin ku çêkerek TV-yê cîhazên xwe bi kontrolek dûr a bêtêlê vekir. Ji hûragahiyan hate zanîn ku bi saya karanîna nêzîkatiyek neasayî-kontrola ji dûr ve mekanîkî bû û hevberek amûrek muzîkê bû - metallofon û revolver. Tembûra revolverê sîlindirên metal ên bi dirêjiyên cihê dihewand, û dema ku pêla gulebaranê li yek ji wan ket, silindirê bi frekansa xwe dest bi lêdana zengilê kir. Dibe ku li ser ultrasound. Elektronîkên di TV-yê de ev sînyala bihîstin û, piştî ku frekansa wê diyar kir, çalakiya guncan pêk anî - kanalê biguhezîne, deng biguhezîne, TV-yê qut bike.

Îro em ê hewl bidin ku vê pergala veguheztina fermanê ji nû ve ava bikin, bi karanîna zanîna xwe ya li ser weşana medyayê.

Ji bo simulasyona kontrolek ji dûr ve, em ê nivîsa mînaka hilberînerê tone bikar bînin. Em ê kontrolkirina frekansa jeneratorê ji lêdana bişkojan û wergirek bi dekoderek ku dê fermanên wergirtî derxe konsolê lê zêde bikin. Piştî guheztinê, jenerator divê tonên 6 frekansan hilberîne, bi wan re em ê fermanan ji bo zêdekirin/kêmkirina deng, kanalê biguherînin, TV-yê vekin/vekin. Ji bo mîhengkirina dedektorê, strukturên jêrîn têne bikar anîn:

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;

Detektorek dikare 10 ji van avahiyan were dayîn, ji ber vê yekê yek detektor dikare were mîheng kirin ku deh îşaretên du-tonî tespît bike. Lê em ê tenê şeş ​​sînyalên yek-ton bikar bînin. Ji bo veguheztina mîhengan li dedektorê, rêbaza MS_TONE_DETECTOR_ADD_SCAN tê bikar anîn.

Ji bo ku dedektor me agahdar bike ku sînyalek bi hêmanên frekansa xwestî gihîştiye têketina wê, divê em jê re fonksiyonek vegerê peyda bikin ku ew ê di vê rewşê de dest pê bike. Ev bi karanîna fonksiyonê tête kirin ms_filter_set_notify_callback(). Wekî argûman, ew nîşanek ji parzûnê re, nîşanek ji fonksiyona vegerê re, û nîşanek daneya ku em dixwazin ji fonksiyona vegerê (daneyên bikarhêner) re derbas bikin, distîne.

Dema ku dedektor tê dest pê kirin, fonksiyona vegerandina bangê dê daneyên bikarhêner, nîşanek ji parzûna dedektorê, nasnameyek bûyerê, û avahiyek ku bûyerê diyar dike bistîne:


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

Di wêneya sernavê de diyagrama blokê ya hilberîna sînyalê tê xuyang kirin.

Welê, naha koda bernameyê bixwe bi şîroveyan re.

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

Em bernameyê berhev dikin û dimeşînin. Ger her tişt rast dixebite, wê hingê piştî destpêkirinê divê em tiştek mîna vê tevgerê bernameyê bistînin:

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

Bişkojka ji "1" heya "6" bikirtînin, bi bişkoja "Enter" piştrast bikin, divê hûn tiştek mîna vê navnîşê bistînin:


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

Em dibînin ku awazên fermanê bi serfirazî têne şandin û dedektor wan tespît dike.

Di gotara din de em ê bi protokola RTP veguhezînin îşaretek dengî li ser tora Ethernetê û tavilê wê di kontrola xweya dûr de bicîh bikin.

Source: www.habr.com

Add a comment