Проучване на VoIP двигателя на Mediastreamer2. част 4

Материалът на статията е взет от моя дзен канал.

Създаване на измервател на нивото на сигнала

В последния Статия Изяснихме правилното прекратяване на програми с помощта на медийния стример.

В тази статия ще сглобим верига за измерване на нивото на сигнала и ще научим как да четем резултата от измерването от филтъра. Нека да оценим точността на измерването.

Наборът от филтри, осигурен от медийния стример, включва филтър MS_VOLUME, който е способен да измерва RMS нивото на преминаващия през него сигнал, да отслабва сигнала и да изпълнява много полезни и неочаквани функции. По-късно ще посветим цяла статия на този филтър. Но засега ще го използваме като метър.

Като източник на сигнал ще използваме тон генератор, сигналът от който ще бъде изпратен към филтъра MS_VOLUME, към изхода на който е свързана звуковата карта.

В този пример ще използваме филтъра на генератора в малко по-различен режим - той ще генерира еднотонален сигнал за нас, т.е. сигнал, съдържащ само едно синусоидално трептене.

В допълнение към честотата и амплитудата ще трябва да зададем времето, през което ще се генерира сигналът; то трябва да е достатъчно, за да може достатъчен брой проби да преминат през филтъра MS_VOLUME за измерване. За прехвърляне на настройки към генератора се използва структурата MSDtmfGenCustomTone:

struct _MSDtmfGenCustomTone{
    char tone_name[8];     /* Текстовое название сигнала из 8 букв.*/
    int duration;          /* Длительность сигнала в миллисекундах.*/
    int frequencies[2];    /* Пара частот из которых должен состоять выходной сигнал. */
    float amplitude;       /* Амплитуда тонов, 1.0 соответствует уровню 0 дБ от милливатта на нагрузке 600 Ом.*/
    int interval;          /* Пауза в миллисекундах перед началом повторного проигрывания сигнала.*/
    int repeat_count;      /* Количество повторов.*/
};
typedef struct _MSDtmfGenCustomTone MSDtmfGenCustomTone;

За да стартираме генератора, ще използваме неговия метод MS_DTMF_GEN_PLAY_CUSTOM.

Блокова схема на обработка на сигнала:

Проучване на VoIP двигателя на Mediastreamer2. част 4

Програмният код, който изпълнява тази схема, е показан по-долу.

/* Файл mstest3.c */

#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/msvolume.h>

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);

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

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

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

    MSDtmfGenCustomTone dtmf_cfg;

   /* Устанавливаем имя нашего сигнала, помня о том, что в массиве мы должны
    оставить место для нуля, который обозначает конец строки. */
    strncpy(dtmf_cfg.tone_name, "busy", sizeof(dtmf_cfg.tone_name));
    dtmf_cfg.duration=1000;
    dtmf_cfg.frequencies[0]=440; /* Будем генерировать один тон, частоту второго тона установим в 0.*/
    dtmf_cfg.frequencies[1]=0;
    dtmf_cfg.amplitude=1.0; /* Такой амплитуде синуса должен соответствовать результат измерения 0.707.*/
    dtmf_cfg.interval=0.;
    dtmf_cfg.repeat_count=0.;

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

   /* Даем, время половину секунды, чтобы измеритель накопил данные. */
   ms_usleep(500000);

   /* Читаем результат измерения. */
  float level=0;
   ms_filter_call_method(volume, MS_VOLUME_GET_LINEAR,&level);
   printf("Амплитуде синуса %f вольт  соответствует среднеквадратическое значение %f вольт.n", dtmf_cfg.amplitude, level);
}

Компилираме нашия пример, точно както правехме преди, използвайки само името на файла mstest3. Нека да го стартираме и да получим резултата:

Амплитуде синуса 1.000000 вольт  соответствует среднеквадратическое значение 0.707733 вольт.

Както можете да видите, резултатът от измерването съвпада до третия знак след десетичната запетая с теоретичната стойност, равна на корен квадратен от две, разделено наполовина: sqr(2)/2=0,7071067811865475

Относителното отклонение на резултата от истинската стойност е 0.1%. Ние оценихме грешката на измерване при максимално ниво на сигнала. Съответно, когато нивото намалява, грешката трябва да се увеличи. Предлагам ви да го оцените сами за ниски нива на сигнала.

В следващата статия ще сглобим схема, която открива наличието на тонален сигнал с дадена честота на входа с помощта на тонален детектор. Ще научим също как да обработваме събития, генерирани от филтри.

Източник: www.habr.com

Добавяне на нов коментар