Материалът на статията е взет от моя .
Създаваме измерител на нивото на сигнала
В предходната изяснихме правилното приключване на програми, използващи медиастриймер.
В тази статия ще съберем схема на измерителя на нивото на сигнала и ще научим как да четем резултата от измерването от филтъра. Ще оценим точността на измерването.
В комплекта филтри, предоставени от медиастриймера, има филтър MS_VOLUME, който е способен да измерва средноквадратния ниво на преминаващия през него сигнал, да ослабва сигнала и да изпълнява много полезни и неочаквани функции. По-късно ще посветим цяла статия на този филтър. Но сега ще го използваме като измерител.
Като източник на сигнала ще използваме тонален генератор, сигналът от който ще бъде насочен към филтъра 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.
Структурна схема на обработка на сигнала:
![]()
Кодът на програмата, реализиращ тази схема, е показан по-долу.
/* Файл 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%. Направихме оценка на грешката на измерването при максимално ниво на сигнала. Съответно, при намаляване на нивото, грешката трябва да нараства. Предлагам ви сами да оцените нея за ниски нива на сигнала.
В следващата статия ще съберем схема, която открива наличието на тонален сигнал с зададена честота на входа с помощта на детектор на тонове. Също така ще се научим да обработваме събитията, генерирани от филтрите.
Източник: habr.com
