Mediastreamer2 VoIP 엔진 탐색. 4 부

글의 소재는 제 글에서 가져왔습니다. 젠 채널.

신호 레벨 미터 만들기

과거에 기사 미디어 스트리머를 사용하는 프로그램의 올바른 종료를 명확히 했습니다.

이 기사에서는 신호 레벨 미터 회로를 조립하고 필터에서 측정 결과를 읽는 방법을 배웁니다. 측정 정확도를 평가해 보겠습니다.

미디어 스트리머가 제공하는 필터 세트에는 필터를 통과하는 신호의 RMS 레벨을 측정하고 신호를 감쇠하며 많은 유용하고 예상치 못한 기능을 수행할 수 있는 필터 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 메서드를 사용합니다.

신호 처리의 블록 다이어그램:

Mediastreamer2 VoIP 엔진 탐색. 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 вольт.

보시다시피, 측정 결과는 2를 반으로 나눈 제곱근과 동일한 이론값으로 소수점 세 번째 자리와 일치했습니다. sqr(2)/0,7071067811865475=XNUMX

결과와 실제 값의 상대편차는 0.1%였습니다. 우리는 최대 신호 레벨에서 측정 오류를 평가했습니다. 따라서 레벨이 감소할수록 오류는 증가해야 합니다. 낮은 신호 수준에 대해서는 직접 평가해 보시기 바랍니다.

다음 기사에서는 톤 감지기를 사용하여 입력에서 주어진 주파수의 톤 신호의 존재를 감지하는 회로를 조립할 것입니다. 또한 필터에 의해 생성된 이벤트를 처리하는 방법도 알아봅니다.

출처 : habr.com

코멘트를 추가