El material del artículo fue tomado de mi .
Creando un medidor de nivel de señal
En el anterior aclaramos la correcta finalización de programas que utilizan un mediastreamer.
En este artículo vamos a reunir el esquema del medidor de nivel de señal y aprenderemos a leer el resultado de la medición desde el filtro. Evaluaremos la precisión de la medición.
En el conjunto de filtros proporcionados por el mediastreamer hay un filtro, MS_VOLUME, que puede medir el nivel de raíz cuadrática media de la señal que pasa a través de él, atenuar la señal y realizar muchas funciones útiles e inesperadas. Más adelante dedicaremos un artículo entero a este filtro. Pero ahora lo utilizaremos como medidor.
Como fuente de la señal utilizaremos un generador de tonos, cuya señal será dirigida al filtro MS_VOLUME, al cual está conectada una tarjeta de sonido en su salida.
En este ejemplo, utilizaremos el filtro del generador en un modo ligeramente diferente: generará para nosotros una señal monofónica, es decir, una señal que contiene solo una oscilación sinusoidal.
Además de la frecuencia y amplitud, necesitamos establecer el tiempo durante el cual se generará la señal, el cual debe ser suficiente para que a través del filtro MS_VOLUME pase una cantidad adecuada de muestreos para la medición. Para transmitir configuraciones al generador, se utiliza la estructura MSDtmfGenCustomTone:
struct _MSDtmfGenCustomTone{
char tone_name[8]; /* Nombre textual de la señal de 8 letras */
int duration; /* Duración de la señal en milisegundos */
int frequencies[2]; /* Par de frecuencias que debe tener la señal de salida */
float amplitude; /* Amplitud de los tonos, 1.0 corresponde a un nivel de 0 dB desde un milivatio en una carga de 600 Ohm */
int interval; /* Pausa en milisegundos antes de comenzar la reproducción de nuevo de la señal */
int repeat_count; /* Número de repeticiones */
};
typedef struct _MSDtmfGenCustomTone MSDtmfGenCustomTone;Para poner en funcionamiento el generador, utilizaremos su método MS_DTMF_GEN_PLAY_CUSTOM.
Diagrama estructural del procesamiento de la señal:
![]()
El código del programa que implementa este esquema se muestra a continuación.
/* Файл 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);
}Compilamos nuestro ejemplo, como lo hicimos antes, solo utilizando el nombre del archivo mstest3. Ejecutamos y obtendremos el resultado:
A una amplitud de 1.000000 voltios corresponde un valor cuadrático medio de 0.707733 voltios.Como pueden ver, el resultado de la medición coincidió hasta el tercer decimal con el valor teórico que es igual a la raíz cuadrada de dos dividido por dos: sqr(2)/2=0,7071067811865475
La desviación relativa del resultado con respecto al valor verdadero fue del 0.1%. Hicimos una estimación del error de medición en el nivel máximo de señal. Por lo tanto, al disminuir el nivel, el error debería aumentar. Les propongo que evalúen esto por ustedes mismos para niveles bajos de señal.
En el siguiente artículo reuniremos un esquema que detecta la presencia de una señal tonal de frecuencia específica en la entrada mediante un detector de tonos. También aprenderemos a procesar los eventos generados por filtros.
Fuente: habr.com
