Exploring the VoIP engine Mediastreamer2. Part 4

The article material is taken from my Zen channel.

Creating a Signal Level Meter

Previously article We clarified the correct termination of programs using the media streamer.

In this article, we will gather the schematic for the signal level meter and learn to read the measurement results from the filter. We will evaluate the measurement accuracy.

In the set of filters provided by the media streamer, there is a filter, MS_VOLUME, which can measure the root mean square level of the signal passing through it, attenuate the signal, and perform many useful and unexpected functions. Later, we will dedicate a whole article to this filter. But for now, we will use it as a meter.

As the signal source, we will use a tone generator, directing the signal into the MS_VOLUME filter, to which a sound card is connected at the output.

In this example, we will use the filter of the generator in a slightly different mode — it will generate a pure tone signal, i.e., a signal containing only a single sinusoidal oscillation.

In addition to frequency and amplitude, we need to specify the time during which the signal will be generated; it should be sufficient to let a sufficient number of samples pass through the MS_VOLUME filter for measurement. The settings are passed to the generator using the structure MSDtmfGenCustomTone:

struct _MSDtmfGenCustomTone{
    char tone_name[8];     /* Text name of the signal up to 8 letters. */
    int duration;          /* Duration of the signal in milliseconds. */
    int frequencies[2];    /* A pair of frequencies that the output signal should consist of. */
    float amplitude;       /* Amplitude of the tones, 1.0 corresponds to 0 dB level from milliwatt at a 600 Ohm load. */
    int interval;          /* Pause in milliseconds before starting to replay the signal. */
    int repeat_count;      /* Number of repeats. */
};
typedef struct _MSDtmfGenCustomTone MSDtmfGenCustomTone;

To start the generator, we will use its method MS_DTMF_GEN_PLAY_CUSTOM.

Structural schematic of the signal processing:

Exploring the VoIP engine Mediastreamer2. Part 4

The program code implementing this schematic is shown below.

/* Файл 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);
}

We compile our example just as we did before, only using the file name mstest3. We run it to execute and get the result:

An amplitude of 1.000000 volts corresponds to a root mean square value of 0.707733 volts.

As you can see, the measurement result matched the theoretical value to three decimal places, which is equal to the square root of two divided by two: sqr(2)/2=0.7071067811865475

The relative deviation of the result from the true value was 0.1%. We estimated the measurement error at the maximum signal level. Consequently, as the signal level decreases, the error should increase. I suggest you assess it for low signal levels on your own.

In the next article, we will assemble a circuit that detects the presence of a tonal signal of a given frequency at the input using a tone detector. We will also learn how to process events generated by filters.

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster