Աստղի նյութերը վերցված են իմ .
Տոնային ազդանշանի հայտնաբերման սարք
Երեկ եղել է հայտարարված դյուրիական զրույցի սարք, իսկ այսում մենք այն կկառուցենք։ Մենք ստեղծեցինք ազդանշանի մակարդակի չափիչ: Այս դասընթացում մենք կսովորենք հայտնաբերել տոնային ազդանշանը:
![]()
Երբևէ, երբ յուրաքանչյուր ընտանիքում հեռուստացույց չէր եղել, և նրանց կեսը ալիքները փոխում էր պլանշետներով, արտասահմանյան տեխնիկական մամուլում հայտնվել էր հետաքրքրաշարժ նորություն, որ հեռուստացույց արտադրողներից մեկը իր սարքերը սարքել է հեռակառավարման առանց մտրակի: Մանրամասներից հայտնի էր, որ հեռակառումը աշխատում է առանց մարտկոցների՝ օգտվելով յուրահատուկ մոտեցումից՝ հեռակառումը մեխանիկական էր և ներկայացնում էր երաժշտական գործիքի՝ մետալոֆոնի ու ռևոլվերի հիբրիդ: Ռևոլվերի պարունակության մեջ կային տարբեր երկարության մետաղական սիլինդրեր, և երբ իրանը միանում էր դրանցից մեկին, սիլինդրը սկսեց ձվաձայներ իր սեփական հաճախությամբ: Արագությամբ ենթադրաբար ուլտրաձայնային: Հեռուստացույցի էլեկտրոնիկան լսում էր այս ազդանշանը և, որոշելով դրա հաճախությունը, կատարում էր համապատասխան գործողություն՝ ալիքը փոխել, բարձրությունը փոխել, հեռուստացույցը անջատել:
Այսօր մենք փորձելու ենք վերարտադրել այս հրահանգների փոխանցման համակարգը, օգտվելով մեր մեդիա ստրիմերների գիտելիքներից:
Հեռակառման մոդելավորելու համար մենք օգտվելու ենք մեր օրինակ տոնային պրոտոտիպի տեքստից: Մենք կավելացնենք տոնային գեներատորի հաճախության վերահսկում ստեղաններից մուտքերի և ընդունիչի հետ դեկոդերով, որը կարտահայտի ընդունված հրամանները կոնսոլում: Փոփոխությունից հետո, գեներովատորը պետք է ապահովի 6 տոնային ազդանշաններ, որոնք մենք կօգտագործենք ձայնի բարձրացման /նվազման, ալիքի փոփոխման, հեռուստացույցի միացման / անջատման հրամանների կոդավորման համար: Ադապտերի համար օգտագործվում է կառուցվածք:
struct _MSToneDetectorDef{
char tone_name[8];
int frequency; 26lt;Expected frequency of the tone* /
int min_duration; 26lt;Min duration of the tone in milliseconds * /
float min_amplitude; 26lt;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() գործառույթով: 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 գրադարան conf.c:4738:(snd_config_expand) Անծանոթ պարամետրեր 0
ALSA գրադարան control.c:954:(snd_ctl_open_noupdate) Անվավեր CTL default:0
ortp-հարգալից-Չհաջողվեց միացնել խառնիչը քարտին: Անվավեր փաստարկ
ALSA գրադարան conf.c:4738:(snd_config_expand) Անծանոթ պարամետրեր 0
ALSA գրադարան pcm.c:2266:(snd_pcm_open_noupdate) Անծանոթ PCM default:0
ALSA գրադարար conf.c:4738:(snd_config_expand) Անծանոթ պարամետրեր 0
ALSA գրադարան pcm.c:2266:(snd_pcm_open_noupdate) Անծանոթ PCM default:0
ortp-հարգալից-Ոչ կարելի է, ձայնային քարտ Intel 82801AA-ICH կարծես ոչինչ չի կարող, կրկին փորձել plughw-ով...
Պահանջեք հրահանգային կոճակը, ապա օրվա մասին:
Ծրագրի ավարտման համար մուտքագրեք 0:
ortp-հարգալից-alsa_set_params: ժամանակահատվածը:256 Օգտագործելով 256
ortp-հարգալից-alsa_set_params: ժամանակահատվածը:8 Օգտագործելով 8
Սեղմեք ցանկացած կոճակ "1" -ից "6", հաստատելով "Enter"-ով, պետք է ստացվի մոտավորապես նման ցուցակ:
2
Ուղարկված հրահանգ: 2
Հրահանգը ընդունվել է: V-
1
Ուղարկված հրահանգ: 1
Հրահանգը ընդունվել է: V+
3
Ուղարկված հրահանգ: 3
Հրահանգը ընդունվել է: C+
4
Ուղարկված հրահանգ: 4
Հրահանգը ընդունվել է: C-
0
$Մենք տեսնում ենք, որ հրահանգները հաջողությամբ ուղարկվել են, և վերահսկիչն դրանք հայտնաբերում է:
Հաջորդ հոդվածում մենք անդրադառնանք ձայնային ազդանշանի փոխանցմանը Ethernet ցանցով RTP արձանագրության միջոցով և միաժամանակ կիրառում ենք այն մեր հեռակառավարմամբ:
Ընտանիք: habr.com
