Mediastreamer2 VoIP motorra arakatzen. 4. zatia

Artikuluaren materiala niretik hartua da zen kanala.

Seinale maila-neurgailua sortzea

Azkenean Artikulu Media streamer erabiliz programen amaiera zuzena argitu dugu.

Artikulu honetan seinale-neurgailuaren zirkuitu bat muntatuko dugu eta iragazkiaren neurketaren emaitza nola irakurtzen ikasiko dugu. Ebalua dezagun neurketaren zehaztasuna.

Media streamer-ek eskaintzen duen iragazkien multzoak iragazki bat dauka, MS_VOLUME, bertatik pasatzen den seinalearen RMS maila neurtzeko gai dena, seinalea arintzeko eta funtzio erabilgarria eta ustekabeko asko betetzeko. Artikulu oso bat eskainiko diogu iragazki honi geroago. Baina oraingoz neurgailu gisa erabiliko dugu.

Seinale-iturburu gisa tonu-sorgailu bat erabiliko dugu, eta seinalea MS_VOLUME iragazkira bidaliko da, zeinaren irteerara soinu-txartela konektatuta dagoen.

Adibide honetan, sorgailu-iragazkia modu apur bat ezberdin batean erabiliko dugu - tonu bakarreko seinalea sortuko digu, hau da. oszilazio sinusoidal bakarra duen seinalea.

Maiztasunaz eta anplitudeaz gain, seinalea sortuko den denbora ezarri beharko dugu; nahikoa izan behar da MS_VOLUME iragazkitik lagin kopuru nahikoa igaro dadin neurtzeko. Ezarpenak sorgailura transferitzeko, MSDtmfGenCustomTone egitura erabiltzen da:

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;

Sorgailua abiarazteko, bere MS_DTMF_GEN_PLAY_CUSTOM metodoa erabiliko dugu.

Seinalearen prozesamenduaren bloke-diagrama:

Mediastreamer2 VoIP motorra arakatzen. 4. zatia

Eskema hau inplementatzen duen programa-kodea behean agertzen da.

/* Π€Π°ΠΉΠ» 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);
}

Gure adibidea konpilatzen dugu, lehen egin genuen bezala, fitxategiaren izena soilik erabiliz mstest3. Exekutatu eta lortu dezagun emaitza:

АмплитудС синуса 1.000000 Π²ΠΎΠ»ΡŒΡ‚  соотвСтствуСт срСднСквадратичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0.707733 Π²ΠΎΠ»ΡŒΡ‚.

Ikus dezakezunez, neurketaren emaitza hirugarren hamartarrekin bat egin zuen biren erro karratuaren balio teorikoarekin erditan zatituta: sqr(2)/2=0,7071067811865475

Emaitzaren benetako balioarekiko desbideratze erlatiboa %0.1ekoa izan zen. Neurketa-errorea seinale maila maximoan baloratu dugu. Horren arabera, maila jaisten den heinean, errorea handitu beharko litzateke. Zuk zeuk ebaluatzea gomendatzen dizut seinale maila baxuetarako.

Hurrengo artikuluan sarreran maiztasun jakin bateko tonu-seinale baten presentzia detektatzen duen zirkuitu bat muntatuko dugu tonu-detektagailu baten bidez. Iragazkiek sortutako gertaerak nola prozesatu ere ikasiko dugu.

Iturria: www.habr.com

Gehitu iruzkin berria