Il materiale dell'articolo è tratto dal mio .
Creiamo un misuratore di livello del segnale
Nell'articolo precedente In questo articolo, costruiremo uno schema del misuratore di livello del segnale e impareremo a leggere il risultato della misurazione dal filtro. Valuteremo l'accuratezza della misurazione.
Nel set di filtri forniti dal mediastreamer, c'è un filtro, MS_VOLUME, che è in grado di misurare il livello medio quadratico del segnale che lo attraversa, attenuare il segnale e svolgere una serie di funzioni utili e inaspettate. Più tardi dedicheremo un intero articolo a questo filtro. Ma ora lo utilizzeremo come misuratore.
Come sorgente del segnale utilizzeremo un generatore di toni, il cui segnale sarà inviato al filtro MS_VOLUME, al quale è collegata una scheda audio.
In questo esempio utilizzeremo il filtro del generatore in una modalità leggermente diversa: genererà per noi un segnale monofonico, ossia un segnale contenente solo un'oscillazione sinusoidale.
Oltre alla frequenza e all'ampiezza, dobbiamo specificare il tempo durante il quale sarà generato il segnale; questo deve essere sufficiente affinché attraverso il filtro MS_VOLUME passi un numero sufficiente di campioni per la misurazione. Per trasmettere le impostazioni al generatore si utilizza la struttura MSDtmfGenCustomTone:
struct _MSDtmfGenCustomTone{ char tone_name[8]; /* Nome del segnale di testo di 8 lettere.*/ int duration; /* Durata del segnale in millisecondi.*/ int frequencies[2]; /* Coppia di frequenze da cui deve consistere il segnale in uscita. */ float amplitude; /* Ampiezza dei toni, 1.0 corrisponde a un livello di 0 dB da milliwatt su un carico di 600 Ohm.*/ int interval; /* Pausa in millisecondi prima di iniziare a riprodurre nuovamente il 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.
![]()
Compiliamo il nostro esempio, proprio come abbiamo fatto in precedenza, utilizzando solo il nome del file
/* Файл 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 . Avviamo l'esecuzione e otterremo il risultato:Un'ampiezza del seno di 1.000000 volt corrisponde a un valore medio quadratico di 0.707733 volt.
L'ampiezza del seno di 1,000000 volt corrisponde a un valore quadratico medio di 0,707733 volt.Come potete vedere, il risultato della misurazione è coinciso fino al terzo decimale con il valore teorico equivalente 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. Di conseguenza, riducendo il livello, l'errore dovrebbe aumentare. Vi invitiamo a valutare autonomamente ciò per i livelli di segnale ridotti.
Nel prossimo articolo assembleremo un circuito che rileva la presenza di un segnale tonale di una determinata frequenza all'ingresso utilizzando un rilevatore di toni. Inoltre, impareremo a gestire gli eventi generati dai filtri.
Fonte: habr.com
