Studiamo il motore VoIP Mediastreamer2. Parte 4

Il materiale dell'articolo è tratto dal mio canale zen.

Creiamo un misuratore di livello del segnale

Nell'articolo precedente abbiamo chiarito il corretto completamento dei programmi che utilizzano il mediastreamer. 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.

Studiamo il motore VoIP Mediastreamer2. Parte 4

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

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster