Ferkenne de Mediastreamer2 VoIP-motor. Diel 5

It materiaal fan it artikel is nommen út myn zen kanaal.

Tone detector

Yn de lêste artikel Wy hawwe in sinjaalnivometer makke. Yn dizze sille wy leare hoe't jo in toansignal kinne detektearje.

Ferkenne de Mediastreamer2 VoIP-motor. Diel 5

Yn 'e âlde dagen, doe't net elke famylje in tv hie, en de helte fan har kanaal wiksele mei in tang, ferskynde yntrigearjend nijs yn resinsjes fan' e bûtenlânske technyske parse dat ien tv-fabrikant har apparaten útrist mei in draadloze ôfstânsbetsjinning. Ut de details waard bekend dat de ôfstânsbetsjinning wurke sûnder batterijen troch it brûken fan in ûngewoane oanpak - de ôfstânsbetsjinning wie meganysk en wie in hybride fan in muzykynstrumint - in metallofoan en in revolver. De revolvertrommel befette metalen silinders fan ferskillende lingten, en doe't de slachpin ien fan har rekke, begûn de silinder op syn eigen frekwinsje te rinkeljen. Nei alle gedachten op echografie. De elektroanika yn 'e TV hearde dit sinjaal en, nei't de frekwinsje bepaald is, de passende aksje útfierd - it kanaal feroarje, it folume feroarje, de TV útsette.

Hjoed sille wy besykje dit kommando-oerdrachtsysteem te rekonstruearjen, mei ús kennis fan 'e mediastreamer.

Om in ôfstânsbetsjinning te simulearjen, sille wy de tekst fan ús foarbyld fan toangenerator brûke. Wy sille tafoegje oan it kontrôle fan de generator frekwinsje fan toetsoanslaggen en in ûntfanger mei in decoder dat sil útfier ûntfongen kommando's nei de konsole. Nei de wiziging moat de generator toanen fan 6 frekwinsjes produsearje, wêrmei wy kommando's sille kodearje om it folume te ferheegjen / te ferminderjen, it kanaal te feroarjen, de TV yn / út te skeakeljen. Om de detektor te konfigurearjen, wurdt de folgjende struktuer brûkt:

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;

In detektor kin wurde jûn 10 fan dizze struktueren, sadat ien detektor kin wurde konfigurearre om tsien twa-tone sinjalen te detektearjen. Mar wy sille mar seis single-tone sinjalen brûke. Om ynstellings oer te bringen nei de detektor, wurdt de metoade MS_TONE_DETECTOR_ADD_SCAN brûkt.

Om de detektor ús te melden dat in sinjaal mei de winske frekwinsjekomponinten by syn ynfier is oankaam, moatte wy it in werombelfunksje leverje dy't it yn dit gefal sil lansearje. Dit wurdt dien mei de funksje ms_filter_set_notify_callback(). As arguminten ûntfangt it in oanwizer nei it filter, in oanwizer nei de werombelfunksje, en in oanwizer nei de gegevens dy't wy wolle trochjaan oan 'e werombelfunksje (brûkersgegevens).

As de detektor wurdt trigger, sil de werombelfunksje brûkersgegevens ûntfange, in oanwizer nei it detektorfilter, in barrensidentifikaasje, en in struktuer dy't it evenemint beskriuwt:


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

It blokdiagram fan sinjaalferwurking wurdt werjûn yn 'e titelôfbylding.

No, no de programmakoade sels mei opmerkings.

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

Wy kompilearje en rinne it programma. As alles goed wurket, dan moatte wy nei lansearring wat krije as dit programmagedrach:

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

Druk op alle toetsen fan "1" oant "6", befêstigje mei de "Enter"-kaai, jo moatte sa'n ding krije as dizze list:


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

Wy sjogge dat de kommando toanen binne mei súkses ferstjoerd en de detektor detektearret se.

Yn it folgjende artikel sille wy keare nei it ferstjoeren fan in audiosinjaal oer in Ethernet-netwurk mei it RTP-protokol en it direkt tapasse op ús ôfstânsbetsjinning.

Boarne: www.habr.com

Add a comment