Mediastreamer2 VoIP motorunu keşfetme. 4. Bölüm

Makalenin materyali benim zenci kanalı.

Sinyal seviyesi ölçer oluşturma

Geçmişte Makale Medya aktarıcıyı kullanarak programların doğru şekilde sonlandırılmasına açıklık getirdik.

Bu yazımızda bir sinyal seviye ölçer devresi kuracağız ve ölçüm sonucunu filtreden nasıl okuyacağımızı öğreneceğiz. Ölçüm doğruluğunu değerlendirelim.

Medya aktarıcı tarafından sağlanan filtre seti, içinden geçen sinyalin RMS seviyesini ölçebilen, sinyali zayıflatabilen ve birçok yararlı ve beklenmedik işlevi gerçekleştirebilen MS_VOLUME adlı bir filtre içerir. Daha sonra bir makalenin tamamını bu filtreye ayıracağız. Ama şimdilik onu metre olarak kullanacağız.

Sinyal kaynağı olarak, ses kartının bağlı olduğu çıkışa MS_VOLUME filtresine sinyal gönderilecek olan bir ton üreteci kullanacağız.

Bu örnekte, jeneratör filtresini biraz farklı bir modda kullanacağız - bizim için tek tonlu bir sinyal üretecektir; yalnızca bir sinüzoidal salınım içeren bir sinyal.

Frekans ve genliğin yanı sıra sinyalin üretileceği süreyi de ayarlamamız gerekecek; ölçüm için yeterli sayıda numunenin MS_VOLUME filtresinden geçmesini sağlayacak şekilde yeterli olmalıdır. Ayarları jeneratöre aktarmak için MSDtmfGenCustomTone yapısı kullanılır:

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;

Jeneratörü başlatmak için MS_DTMF_GEN_PLAY_CUSTOM yöntemini kullanacağız.

Sinyal işlemenin blok şeması:

Mediastreamer2 VoIP motorunu keşfetme. 4. Bölüm

Bu şemayı uygulayan program kodu aşağıda gösterilmiştir.

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

Örneğimizi, daha önce yaptığımız gibi, yalnızca dosya adını kullanarak derliyoruz. mstest3. Çalıştıralım ve sonucu alalım:

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

Gördüğünüz gibi ölçüm sonucu üçüncü ondalık basamağa denk geldi ve teorik değeri ikiye bölünen kareköke eşitti: sqr(2)/2=0,7071067811865475

Sonucun gerçek değerden bağıl sapması %0.1 idi. Ölçüm hatasını maksimum sinyal seviyesinde değerlendirdik. Buna göre seviye azaldıkça hatanın artması gerekir. Düşük sinyal seviyelerini kendiniz değerlendirmenizi öneririm.

Bir sonraki makalede, bir ton dedektörü kullanarak girişte belirli bir frekansta bir ton sinyalinin varlığını tespit eden bir devre kuracağız. Ayrıca filtreler tarafından oluşturulan olayların nasıl işleneceğini de öğreneceğiz.

Kaynak: habr.com

Yorum ekle