Il materiale dell'articolo è tratto dal mio .
Creiamo un misuratore di livello del segnale
Nel passato Abbiamo chiarito come terminare correttamente i programmi che utilizzano lo stream media.
In questo articolo costruiremo uno schema del misuratore di livello del segnale e impareremo a leggere il risultato della misurazione dal filtro. Valuteremo la precisione della misurazione.
Nel set di filtri forniti dallo stream media c'è un filtro, MS_VOLUME, che è in grado di misurare il livello quadratico medio del segnale che lo attraversa, attenuare il segnale ed eseguire una serie di funzioni utili e sorprendenti. In seguito, dedicheremo a questo filtro un intero articolo. Ma ora lo utilizzeremo come misuratore.
Utilizzeremo un generatore di tono come sorgente del segnale, il cui segnale verrà inviato al filtro MS_VOLUME, la cui uscita è collegata a una scheda audio.
In questo esempio utilizzeremo il filtro del generatore in una modalità leggermente diversa — genererà per noi un segnale monofonico, cioè un segnale contenente solo un'oscillazione sinusoidale.
Oltre alla frequenza e all'ampiezza, dovremo specificare il tempo durante il quale verrà generato il segnale; questo deve essere sufficiente affinché attraverso il filtro MS_VOLUME passi un numero adeguato di campioni per la misurazione. Per trasmettere al generatore le impostazioni, si utilizza la struttura MSDtmfGenCustomTone:
struct _MSDtmfGenCustomTone{
char tone_name[8]; /* Nome testuale del segnale di 8 caratteri. */
int duration; /* Durata del segnale in millisecondi. */
int frequencies[2]; /* Coppia di frequenze da cui deve essere composto il segnale di uscita. */
float amplitude; /* Ampiezza dei toni, 1.0 corrisponde a un livello di 0 dB da un milliwatt su un carico di 600 Ohm. */
int interval; /* Pausa in millisecondi prima dell'inizio della riproduzione del segnale. */
int repeat_count; /* Numero di ripetizioni. */
};
typedef struct _MSDtmfGenCustomTone MSDtmfGenCustomTone;Per avviare il generatore, utilizzeremo il suo metodo MS_DTMF_GEN_PLAY_CUSTOM.
Schema strutturale di elaborazione del segnale:
![]()
Il codice del programma che implementa questo schema è mostrato di seguito.
/* Файл 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);
}Compiliamo il nostro esempio come abbiamo fatto prima, utilizzando solo il nome del file mstest3. Eseguiamo e otterremo il risultato:
Per un'ampiezza di seno di 1.000000 volt, il valore efficace corrisponde a 0.707733 volt.Come potete vedere, il risultato della misurazione coincide fino al terzo decimale con il valore teorico pari alla radice quadrata di due divisa per due: sqr(2)/2=0,7071067811865475.
La deviazione relativa del risultato dal valore reale è stata dello 0,1%. Abbiamo effettuato una stima dell'errore di misura al livello massimo del segnale. Pertanto, all'abbassamento del livello, l'errore dovrebbe aumentare. Vi propongo di valutarlo autonomamente per i livelli di segnale ridotti.
Nell'articolo successivo, raccoglieremo uno schema che rileva la presenza di un segnale tonale a una frequenza specificata utilizzando un rilevatore di toni. Inoltre, impareremo a gestire gli eventi generati dai filtri.
Fonte: habr.com
