Mediastreamer2 VoIP хөдөлгүүртэй танилцаж байна. 5-р хэсэг

Нийтлэлийн материалыг миний нийтлэлээс авсан болно zen суваг.

Дуу мэдрэгч

Хамгийн сүүлд нийтлэл Бид дохионы түвшний хэмжигчийг бүтээсэн. Эндээс бид дууны дохиог хэрхэн илрүүлэх талаар сурах болно.

Mediastreamer2 VoIP хөдөлгүүртэй танилцаж байна. 5-р хэсэг

Эрт дээр үед айл болгон зурагтгүй, тал хувь нь бахө ашиглан суваг сольдог байсан тэр үед нэг телевизор үйлдвэрлэгч төхөөрөмжөө утасгүй алсын удирдлагаар тоноглосон тухай гадаадын техникийн хэвлэлүүдийн тоймд сонирхолтой мэдээ гарч байв. Нарийвчилсан мэдээллээс харахад алсын удирдлага нь механик бөгөөд хөгжмийн зэмсэг - металлофон, буу хоёрын эрлийз байсан ер бусын аргыг ашигласны үр дүнд алсын удирдлага нь батерейгүй ажилладаг болохыг олж мэдсэн. Револверын бөмбөрт нь янз бүрийн урттай металл цилиндрүүд байсан бөгөөд галын гол нь нэгийг нь оноход цилиндр өөрийн давтамжаараа дуугарч эхлэв. Магадгүй хэт авиан шинжилгээгээр. Телевизийн электроникууд энэ дохиог сонссон бөгөөд түүний давтамжийг тодорхойлсны дараа зохих үйлдлийг гүйцэтгэсэн - суваг солих, дууны хэмжээг өөрчлөх, ТВ-г унтраа.

Өнөөдөр бид медиа дамжуулагчийн талаарх мэдлэгээ ашиглан энэхүү тушаал дамжуулах системийг дахин бүтээхийг хичээх болно.

Алсын удирдлагыг дуурайхын тулд бид дууны генераторын жишээний текстийг ашиглана. Бид түүнд товчлуурын цохилтоос генераторын давтамжийн хяналт, хүлээн авсан командуудыг консол руу гаргах декодлогчтой хүлээн авагчийг нэмнэ. Өөрчлөлтийн дараа генератор нь 6 давтамжийн аяыг гаргах ёстой бөгөөд бид дууны хэмжээг нэмэгдүүлэх/багасгах, сувгийг өөрчлөх, ТВ-г асаах/унтраах командуудыг кодлох болно. Илрүүлэгчийг тохируулахын тулд дараах бүтцийг ашиглана.

struct _MSToneDetectorDef{  
     char tone_name[8];     
     int frequency; /**<Expected frequency of the tone*/ 
     int min_duration; /**<Min duration of the tone in milliseconds */ 
     float min_amplitude; /**<Minimum amplitude of the tone, 1.0 corresponding to the normalized 0dbm level */
};

typedef struct _MSToneDetectorDef MSToneDetectorDef;

Илрүүлэгчид эдгээр бүтцийн 10-ыг өгч болох тул нэг детекторыг арван хоёр өнгийн дохиог илрүүлэхээр тохируулж болно. Гэхдээ бид зөвхөн зургаан нэг авиа дохиог ашиглах болно. Тохиргоог илрүүлэгч рүү шилжүүлэхийн тулд MS_TONE_DETECTOR_ADD_SCAN аргыг ашиглана.

Илрүүлэгч нь хүссэн давтамжийн бүрэлдэхүүн хэсэг бүхий дохио оролтод ирсэн тухай бидэнд мэдэгдэхийн тулд бид үүнийг энэ тохиолдолд эхлүүлэх буцах дуудлагын функцээр хангах ёстой. Энэ нь функцийг ашиглан хийгддэг ms_filter_set_notify_callback(). Аргумент болгон энэ нь шүүлтүүрийн заагч, буцаан дуудах функцийн заагч, бидний буцаан дуудах функц (хэрэглэгчийн өгөгдөл) руу дамжуулахыг хүсэж буй өгөгдөлд заагчийг хүлээн авдаг.

Илрүүлэгчийг асаах үед буцаан дуудлагын функц нь хэрэглэгчийн өгөгдөл, илрүүлэгч шүүлтүүрийн заагч, үйл явдлын тодорхойлогч, үйл явдлыг дүрсэлсэн бүтцийг хүлээн авна.


/** * Structure carried as argument of the MS_TONE_DETECTOR_EVENT**/
struct _MSToneDetectorEvent{ 
      char tone_name[8];       /* Имя тона которое мы ему назначили при настройке детектора. */
      uint64_t tone_start_time;   /* Время в миллисекундах, когда тон был обнаружен. */
};

typedef struct _MSToneDetectorEvent MSToneDetectorEvent;

Дохио боловсруулах блок диаграммыг гарчгийн зурагт үзүүлэв.

За, одоо програмын код нь өөрөө тайлбартай.

/* Файл mstest4.c Имитатор пульта управления и приемника. */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/msvolume.h>
#include <mediastreamer2/mstonedetector.h>

/* Подключаем заголовочный файл с функциями управления событиями
 * медиастримера. */
#include <mediastreamer2/mseventqueue.h>

/* Функция обратного вызова, она будет вызвана фильтром, как только он
 * обнаружит совпадение характеристик входного сигнала с заданными. */
static void tone_detected_cb(void *data, MSFilter *f, unsigned int event_id,
        MSToneDetectorEvent *ev)
{
    printf("                      Принята команда: %sn", ev->tone_name);
}

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);
    MSFilter  *detector = ms_filter_new(MS_TONE_DETECTOR_ID);

    /* Очищаем массив находящийся внутри детектора тонов, он описывает
     * особые приметы разыскиваемых сигналов.*/
    ms_filter_call_method(detector, MS_TONE_DETECTOR_CLEAR_SCANS, 0);

    /* Создаем источник тактов - тикер. */
    MSTicker *ticker=ms_ticker_new();

    /* Соединяем фильтры в цепочку. */
    ms_filter_link(voidsource, 0, dtmfgen, 0);
    ms_filter_link(dtmfgen, 0, volume, 0);
    ms_filter_link(volume, 0, detector, 0);
    ms_filter_link(detector, 0, snd_card_write, 0);

    /* Подключаем к фильтру функцию обратного вызова. */
    ms_filter_set_notify_callback(detector,
            (MSFilterNotifyFunc)tone_detected_cb, NULL);

    /* Подключаем источник тактов. */
    ms_ticker_attach(ticker,voidsource);

    /* Создаем массив, каждый элемент которого описывает характеристику
     * одного из тонов, который требуется обнаруживать: Текстовое имя
     * данного элемента, частота в герцах, длительность в миллисекундах,
     * минимальный уровень относительно 0,775В. */  
    MSToneDetectorDef  scan[6]=
    {
        {"V+",  440, 100, 0.1}, /* Команда "Увеличить громкость". */
        {"V-",  540, 100, 0.1}, /* Команда "Уменьшить громкость". */
        {"C+",  640, 100, 0.1}, /* Команда "Увеличить номер канала". */
        {"C-",  740, 100, 0.1}, /* Команда "Уменьшить номер канала". */
        {"ON",  840, 100, 0.1}, /* Команда "Включить телевизор". */
        {"OFF", 940, 100, 0.1}  /* Команда "Выключить телевизор". */
    };

    /* Передаем в детектор тонов приметы сигналов. */
    int i;
    for (i = 0; i < 6; i++)
    {
        ms_filter_call_method(detector, MS_TONE_DETECTOR_ADD_SCAN,
                &scan[i]);
    }

    /* Настраиваем структуру, управляющую выходным сигналом генератора.*/
    MSDtmfGenCustomTone dtmf_cfg;
    dtmf_cfg.tone_name[0] = 0;
    dtmf_cfg.duration = 1000;
    dtmf_cfg.frequencies[0] = 440;
    /* Будем генерировать один тон, частоту второго тона установим в 0.*/
    dtmf_cfg.frequencies[1] = 0;
    dtmf_cfg.amplitude = 1.0;
    dtmf_cfg.interval = 0.;
    dtmf_cfg.repeat_count = 0.;

    /* Организуем цикл сканирования нажатых клавиш. Ввод нуля завершает
     * цикл и работу программы. */
    char key='9';
    printf("Нажмите клавишу команды, затем ввод.n"
        "Для завершения программы введите 0.n");
    while(key != '0')
    {
        key = getchar();
        if ((key >= 49) && (key <= 54))
        {
                printf("Отправлена команда: %cn", key);
            /* Устанавливаем частоту генератора в соответствии с
             * кодом нажатой клавиши.*/
            dtmf_cfg.frequencies[0] = 440 + 100*(key-49);

            /* Включаем звуковой генератор c обновленной частотой. */
            ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,
                    (void*)&dtmf_cfg);
        }
        ms_usleep(20000);
    }
}

Бид програмыг эмхэтгэж ажиллуулдаг. Хэрэв бүх зүйл зөв ажиллаж байвал програмыг ажиллуулсны дараа бид дараах үйлдлийн шинж чанарыг олж авах ёстой.

$ ./mstest4
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib control.c:954:(snd_ctl_open_noupdate) Invalid CTL default:0
ortp-warning-Could not attach mixer to card: Invalid argument
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM default:0
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM default:0
ortp-warning-Strange, sound card Intel 82801AA-ICH does not seems to be capable of anything, retrying with plughw...
Нажмите клавишу команды, затем ввод.
Для завершения программы введите 0.
ortp-warning-alsa_set_params: periodsize:256 Using 256
ortp-warning-alsa_set_params: period:8 Using 8

"1"-ээс "6" хүртэлх дурын товчлуурыг дарж, "Enter" товчлуураар баталгаажуулснаар дараах жагсаалт гарч ирнэ.


2
Отправлена команда: 2
                      Принята команда: V-
1
Отправлена команда: 1
                      Принята команда: V+
3
Отправлена команда: 3
                      Принята команда: C+
4
Отправлена команда: 4
                      Принята команда: C-
0
$

Бид командын аяыг амжилттай илгээж, илрүүлэгч тэдгээрийг илрүүлж байгааг харж байна.

Дараагийн өгүүллээр бид RTP протоколыг ашиглан Ethernet сүлжээгээр аудио дохиог дамжуулж, алсын удирдлагадаа шууд ашиглах болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх