Esplorante la Mediastreamer2 VoIP-motoron. Parto 4

La materialo de la artikolo estas prenita el mia zen kanalo.

Kreante signalnivelmezurilon

En la lasta artikolo Ni klarigis la ĝustan ĉesigon de programoj uzante la amaskomunikilaron.

En ĉi tiu artikolo ni kunvenos signalnivelan mezurilan cirkviton kaj lernos kiel legi la mezuran rezulton de la filtrilo. Ni taksu la mezuran precizecon.

La aro de filtriloj provizitaj de la amaskomunikila streamer inkluzivas filtrilon, MS_VOLUME, kiu kapablas mezuri la RMS-nivelon de la signalo trapasanta ĝin, mildigi la signalon kaj plenumi multajn utilajn kaj neatenditajn funkciojn. Ni dediĉos tutan artikolon al ĉi tiu filtrilo poste. Sed nuntempe ni uzos ĝin kiel metron.

Ni uzos tongeneratoron kiel signalfonton, kies signalo estos sendita al la filtrilo MS_VOLUME, al kies eligo estas konektita la sonkarto.

En ĉi tiu ekzemplo, ni uzos la generatoran filtrilon en iomete malsama reĝimo - ĝi generos unutonan signalon por ni, t.e. signalo enhavanta nur unu sinusoidan osciladon.

Krom la frekvenco kaj amplitudo, ni devos agordi la tempon dum kiu la signalo estos generita; ĝi devas esti sufiĉa por ke sufiĉa nombro da specimenoj trapasu la MS_VOLUME-filtrilon por mezurado. Por transdoni agordojn al la generatoro, la strukturo MSDtmfGenCustomTone estas uzata:

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;

Por komenci la generatoron, ni uzos ĝian MS_DTMF_GEN_PLAY_CUSTOM-metodon.

Blokdiagramo de signala prilaborado:

Esplorante la Mediastreamer2 VoIP-motoron. Parto 4

La programkodo kiu efektivigas ĉi tiun skemon estas montrita malsupre.

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

Ni kompilas nian ekzemplon, same kiel ni faris antaŭe, nur uzante la dosiernomon mstest3. Ni rulu ĝin kaj ricevu la rezulton:

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

Kiel vi povas vidi, la mezurrezulto koincidis al la tria decimala loko kun la teoria valoro egala al la kvadrata radiko de du dividita en duono: sqr(2)/2=0,7071067811865475

La relativa devio de la rezulto de la vera valoro estis 0.1%. Ni taksis la mezuran eraron ĉe la maksimuma signalnivelo. Sekve, ĉar la nivelo malpliiĝas, la eraro devus pliiĝi. Mi sugestas, ke vi mem taksu ĝin por malaltaj signalniveloj.

En la sekva artikolo ni kunvenos cirkviton, kiu detektas la ĉeeston de tonsignalo de donita frekvenco ĉe la enigo per tondetektilo. Ni ankaŭ lernos kiel prilabori eventojn generitajn de filtriloj.

fonto: www.habr.com

Aldoni komenton