Mediastreamer2 VoIP programmas izpēte. 4. daļa

Raksta materiāls ņemts no mana zen kanāls.

Signāla līmeņa mērītāja izveide

Pagātnē raksts Mēs esam noskaidrojuši pareizu programmu pārtraukšanu, izmantojot multivides straumētāju.

Šajā rakstā mēs apkoposim signāla līmeņa mērītāja ķēdi un uzzināsim, kā no filtra nolasīt mērījumu rezultātu. Novērtēsim mērījumu precizitāti.

Mediju straumētāja nodrošinātajā filtru komplektā ietilpst filtrs MS_VOLUME, kas spēj izmērīt caur to ejošā signāla RMS līmeni, vājināt signālu un veikt daudz noderīgu un negaidītu funkciju. Vēlāk šim filtram veltīsim visu rakstu. Bet pagaidām mēs to izmantosim kā skaitītāju.

Kā signāla avotu izmantosim toņu ģeneratoru, no kura signāls tiks nosūtīts uz MS_VOLUME filtru, kura izejai pieslēgta skaņas karte.

Šajā piemērā mēs izmantosim ģeneratora filtru nedaudz citā režīmā - tas mums ģenerēs viena toņa signālu, t.i. signāls, kas satur tikai vienu sinusoidālu svārstību.

Papildus frekvencei un amplitūdai mums būs jāiestata laiks, kurā signāls tiks ģenerēts; tam jābūt pietiekamam, lai mērīšanai caur MS_VOLUME filtru izietu pietiekams skaits paraugu. Lai pārsūtītu iestatījumus uz ģeneratoru, tiek izmantota MSDtmfGenCustomTone struktūra:

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;

Lai palaistu ģeneratoru, mēs izmantosim tā metodi MS_DTMF_GEN_PLAY_CUSTOM.

Signāla apstrādes blokshēma:

Mediastreamer2 VoIP programmas izpēte. 4. daļa

Programmas kods, kas ievieš šo shēmu, ir parādīts zemāk.

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

Mēs apkopojam savu piemēru tāpat kā iepriekš, izmantojot tikai faila nosaukumu mstest3. Palaidīsim to un iegūsim rezultātu:

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

Kā redzat, mērījuma rezultāts sakrita līdz trešajai zīmei aiz komata ar teorētisko vērtību, kas vienāda ar kvadrātsakni no diviem, kas dalīti uz pusēm: sqr(2)/2=0,7071067811865475

Rezultāta relatīvā novirze no patiesās vērtības bija 0.1%. Mēs novērtējām mērījumu kļūdu maksimālā signāla līmenī. Attiecīgi, līmenim samazinoties, kļūdai vajadzētu palielināties. Es iesaku jums pašiem novērtēt zemu signāla līmeni.

Nākamajā rakstā mēs saliksim ķēdi, kas, izmantojot toņu detektoru, nosaka noteiktas frekvences toņa signāla klātbūtni ieejā. Mēs arī iemācīsimies apstrādāt filtru ģenerētos notikumus.

Avots: www.habr.com

Pievieno komentāru