Article material taken from my zen channel .

Create a signal level meter
In a previous article, we clarified the correct termination of programs using a media streamer.
In this article we will assemble the circuit of a signal level meter and learn how to read the measurement result from a filter. Estimate the accuracy of the measurement.
In the set of filters provided by the media streamer there is a filter, MS_VOLUME, which is able to measure the rms level of the signal passing through it, attenuate the signal and perform a lot of useful and unexpected functions. Weβll cover the whole article with this filter later. But now we will use it as a meter.
As a signal source we will use a tone generator, the signal from which will be sent to the MS_VOLUME filter, to the output of which a sound card is connected.
In this example, we will use the generator filter in a slightly different mode - it will generate a single-tone signal for us, i.e. a signal containing only one sinusoidal oscillation.
, , , MS_VOLUME . MSDtmfGenCustomTone:
struct _MSDtmfGenCustomTone{
char tone_name[8];
int duration;
int frequencies[2];
float amplitude;
int interval;
int repeat_count;
};
typedef struct _MSDtmfGenCustomTone MSDtmfGenCustomTone;
, MS_DTMF_GEN_PLAY_CUSTOM.
:

, .
#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;
dtmf_cfg.frequencies[1]=0;
dtmf_cfg.amplitude=1.0;
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. :
1.000000 0.707733 .
, : sqr(2)/2=0,7071067811865475
The relative deviation of the result from the true value was 0.1%. We made an estimation of the measurement error at the maximum signal level. Accordingly, with a decrease in the level, the error should increase. I suggest you independently evaluate it for small signal levels.
In the next article, we will assemble a circuit that detects the presence of a given frequency input at the input of a tone using a tone detector. And also learn how to handle events generated by filters.