کاوش در موتور VoIP Mediastreamer2. قسمت 4

مطالب مقاله از من گرفته شده است کانال ذن.

ایجاد یک سنج سطح سیگنال

در آخر مقاله ما خاتمه صحیح برنامه ها را با استفاده از پخش کننده رسانه روشن کرده ایم.

در این مقاله یک مدار سطح سیگنال را جمع آوری می کنیم و نحوه خواندن نتیجه اندازه گیری از فیلتر را یاد می گیریم. بیایید دقت اندازه گیری را ارزیابی کنیم.

مجموعه فیلترهای ارائه شده توسط استریمر مدیا شامل یک فیلتر MS_VOLUME است که قادر است سطح RMS سیگنال عبوری از خود را اندازه گیری کند، سیگنال را ضعیف کند و عملکردهای مفید و غیرمنتظره زیادی را انجام دهد. بعداً یک مقاله کامل را به این فیلتر اختصاص خواهیم داد. اما در حال حاضر از آن به عنوان متر استفاده خواهیم کرد.

ما از یک تولید کننده صدا به عنوان منبع سیگنال استفاده خواهیم کرد که سیگنال از آن به فیلتر 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٪ بود. ما خطای اندازه گیری را در حداکثر سطح سیگنال ارزیابی کردیم. بر این اساس، با کاهش سطح، خطا باید افزایش یابد. پیشنهاد می کنم خودتان آن را برای سطوح سیگنال پایین ارزیابی کنید.

در مقاله بعدی مداری را جمع آوری می کنیم که با استفاده از یک آشکارساز تن، وجود یک سیگنال تن با فرکانس معین را در ورودی تشخیص می دهد. همچنین یاد خواهیم گرفت که چگونه رویدادهای تولید شده توسط فیلترها را پردازش کنیم.

منبع: www.habr.com

اضافه کردن نظر