Вивчаємо VoIP-движок Mediastreamer2. Частина 4

Матеріал статті взято з мого дзен-каналу.

Створюємо вимірювач рівня сигналу

У минулій статті ми внесли ясність у коректне завершення програм, що використовують медіастрімер.

У цій статті ми зберемо схему вимірювача рівня сигналу та навчимося читати результат вимірювання з фільтра. Оцінимо точність виміру.

У наборі фільтрів, що надаються медіастримером є фільтр, MS_VOLUME, який здатний вимірювати середньоквадратичний рівень сигналу, що проходить через нього, послаблювати сигнал і виконувати масу корисних і несподіваних функцій. Пізніше ми присвятимо цьому фільтру статтю. Але зараз ми використовуватимемо його як вимірювач.

Як джерело сигналу використовуватимемо тональний генератор, сигнал з якого направимо на фільтр MS_VOLUME, до виходу якого підключена звукова карта.

У цьому прикладі фільтр генератора ми використовуватимемо дещо іншому режимі — він буде генерувати нам однотональний сигнал, тобто. сигнал, що містить тільки одне синусоїдальне коливання.

Крім частоти та амплітуди нам знадобиться задати час, протягом якого буде генеруватися сигнал, він повинен бути достатнім, щоб через фільтр MS_VOLUME пройшло достатню для вимірювання кількість відліків. Для передачі генератору налаштувань використовується структура 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;

Щоб запустити генератор у роботу, будемо використовувати його метод MS_DTMF_GEN_PLAY_CUSTOM.

Структурна схема обробки сигналу:

Вивчаємо VoIP-движок Mediastreamer2. Частина 4

Код програми, що реалізує цю схему, показаний нижче.

/* Файл 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. Запускаємо на виконання та отримаємо результат:

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

Як бачите, результат вимірювання збігся до третього знака після коми з теоретичним значенням рівним квадратному кореню з поділеної двійки навпіл: sqr(2)/2=0,7071067811865475

Відносне відхилення результату від справжнього значення становило 0.1%. Ми зробили оцінку похибки вимірювання за максимального рівня сигналу. Відповідно, при зниженні рівня похибка має зростати. Пропоную вам самостійно оцінити її для невеликих рівнів сигналу.

У наступній статті ми зберемо схему, що виявляє присутність на вході тонального сигналу заданої частоти за допомогою детектора тонів. А також навчимося обробляти події, що генеруються фільтрами.

Джерело: habr.com

Додати коментар або відгук