Artikelmaterialet är hämtat från min .
Vi skapar en signalnivåmätare
Tidigare Vi har klargjort korrekt avslutning av program som använder medieströmmaren.
I denna artikel kommer vi att sammanställa en schema för signalnivåmätaren och lära oss att läsa av mätresultatet från filtret. Vi kommer att utvärdera mätprecisionen.
I uppsättningen av filter som tillhandahålls av medieströmmaren finns det ett filter, MS_VOLUME, som kan mäta den genomsnittliga kvadratiska nivån av signalen som passerar genom det, dämpa signalen och utföra många användbara och oväntade funktioner. Senare kommer vi att ägna en hel artikel åt detta filter. Men just nu kommer vi att använda det som en mätare.
Vi kommer att använda en tongenerator som signalkälla, vars signal vi skickar till filtret MS_VOLUME, vars utgång är ansluten till ljudkortet.
I detta exempel kommer vi att använda generatorfilteret i en något annan läge — det kommer att generera en enstämig signal för oss, dvs. en signal som endast innehåller en sinusoidal svängning.
Förutom frekvens och amplitud behöver vi ange den tid under vilken signalen ska genereras, och den bör vara tillräcklig för att tillräckligt många mätvärden ska passera genom filtret MS_VOLUME. För att överföra inställningar till generatorn används strukturen MSDtmfGenCustomTone:
struct _MSDtmfGenCustomTone{
char tone_name[8]; /* Textnamn på signalen bestående av 8 bokstäver. */
int duration; /* Signalens varaktighet i millisekunder. */
int frequencies[2]; /* Par av frekvenser som den utgående signalen ska bestå av. */
float amplitude; /* Amplituden av tonerna, 1.0 motsvarar 0 dB nivå från milliwatt vid 600 Ohm belastning. */
int interval; /* Paus i millisekunder innan signalen börjar spelas om. */
int repeat_count; /* Antal upprepningar. */
};
typedef struct _MSDtmfGenCustomTone MSDtmfGenCustomTone;För att starta generatorn kommer vi att använda dess metod MS_DTMF_GEN_PLAY_CUSTOM.
Strukturell schema för signalbehandling:
![]()
Programkoden som implementerar detta schema visas nedan.
/* Файл 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);
}Vi kompilerar vårt exempel, precis som vi gjorde tidigare, men använder filnamnet mstest3. Vi startar det och får resultatet:
En amplitud av sinus på 1.000000 volt motsvarar RMS-värdet 0.707733 volt.Som ni kan se, överensstämmer mätresultatet till tredje decimalen med det teoretiska värdet som är kvadratroten av två delat med två: sqr(2)/2=0,7071067811865475
Det relativa avvikelsen från det verkliga värdet var 0,1 %. Vi gjorde en felvärdering vid maximal signalnivå. Följaktligen bör felet öka vid minskad nivå. Jag föreslår att ni själva värderar detta för låga signalnivåer.
I nästa artikel ska vi sammanställa ett schema som upptäcker närvaron av en ton signal av en angiven frekvens vid ingången med hjälp av en ton-detektor. Vi kommer även att lära oss att bearbeta de händelser som genereras av filtren.
Källa: habr.com
