Explorando el motor VoIP de Mediastreamer2. Parte 4

El material del artículo está tomado de mi canal zen.

Crear un medidor de nivel de señal

En el pasado статье Hemos aclarado la finalización correcta de los programas que utilizan el transmisor de medios.

En este artículo ensamblaremos un circuito medidor de nivel de señal y aprenderemos cómo leer el resultado de la medición del filtro. Evaluemos la precisión de la medición.

El conjunto de filtros proporcionado por el transmisor de medios incluye un filtro, MS_VOLUME, que es capaz de medir el nivel RMS de la señal que pasa a través de él, atenuando la señal y realizando muchas funciones útiles e inesperadas. Más adelante dedicaremos un artículo completo a este filtro. Pero por ahora lo usaremos como medidor.

Utilizaremos un generador de tonos como fuente de señal, cuya señal se enviará al filtro MS_VOLUME, a cuya salida está conectada la tarjeta de sonido.

En este ejemplo, usaremos el filtro generador en un modo ligeramente diferente: generará una señal de un solo tono para nosotros, es decir. una señal que contiene sólo una oscilación sinusoidal.

Además de la frecuencia y amplitud, necesitaremos establecer el tiempo durante el cual se generará la señal; debe ser suficiente para que un número suficiente de muestras pasen por el filtro MS_VOLUME para su medición. Para transferir configuraciones al generador, se utiliza la estructura 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;

Para iniciar el generador, usaremos su método MS_DTMF_GEN_PLAY_CUSTOM.

Diagrama de bloques de procesamiento de señales:

Explorando el motor VoIP de Mediastreamer2. Parte 4

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, tal como lo hicimos antes, solo usando el nombre del archivo mstest3. Ejecutémoslo y obtengamos el resultado:

Амплитуде синуса 1.000000 вольт  соответствует среднеквадратическое значение 0.707733 вольт.

Como puede ver, el resultado de la medición coincidió hasta el tercer decimal con el valor teórico igual a la raíz cuadrada de dos dividido por la mitad: sqr(2)/2=0,7071067811865475

La desviación relativa del resultado del valor real fue del 0.1%. Evaluamos el error de medición en el nivel máximo de señal. En consecuencia, a medida que disminuye el nivel, el error debería aumentar. Le sugiero que lo evalúe usted mismo para detectar niveles de señal bajos.

En el próximo artículo montaremos un circuito que detecta la presencia de una señal de tono de una frecuencia determinada en la entrada mediante un detector de tonos. También aprenderemos a procesar eventos generados por filtros.

Fuente: habr.com

Añadir un comentario