Maqolaning materiali mendan olingan
Ohang detektori
Oxirida
Qadimgi kunlarda, har bir oilada televizor bo'lmagan va ularning yarmi pense yordamida kanallarni almashtirganida, xorijiy texnik matbuot sharhlarida bir televizor ishlab chiqaruvchisi o'z qurilmalarini simsiz masofadan boshqarish pulti bilan jihozlagani haqida qiziqarli yangiliklar paydo bo'ldi. Tafsilotlardan ma'lum bo'lishicha, masofadan boshqarish pulti g'ayrioddiy yondashuv tufayli batareyasiz ishlagan - masofadan boshqarish pulti mexanik bo'lib, musiqa asbobi - metallofon va revolverning gibrididir. Revolver barabanida turli uzunlikdagi metall tsilindrlar boβlgan va oβq otish pimi ulardan biriga tegsa, silindr oβz chastotasida jiringlay boshlagan. Ehtimol, ultratovush tekshiruvida. Televizordagi elektronika bu signalni eshitdi va uning chastotasini aniqlab, tegishli harakatni amalga oshirdi - kanalni o'zgartiring, ovoz balandligini o'zgartiring, televizorni o'chiring.
Bugun biz media-strimer haqidagi bilimlarimizdan foydalanib, ushbu buyruqlar uzatish tizimini qayta qurishga harakat qilamiz.
Masofadan boshqarish pultini taqlid qilish uchun biz ohang generatorining matnidan foydalanamiz. Biz unga generator chastotasini tugmachalarni bosish orqali boshqarishni va qabul qilingan buyruqlarni konsolga chiqaradigan dekoderli qabul qilgichni qo'shamiz. O'zgartirishdan so'ng, generator 6 chastotali ohanglarni ishlab chiqishi kerak, ular yordamida biz ovoz balandligini oshirish / kamaytirish, kanalni o'zgartirish, televizorni yoqish / o'chirish buyruqlarini kodlaymiz. Detektorni sozlash uchun quyidagi tuzilma qo'llaniladi:
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;
Detektorga ushbu tuzilmalardan 10 tasi berilishi mumkin, shuning uchun bitta detektor o'nta ikki rangli signalni aniqlash uchun sozlanishi mumkin. Ammo biz faqat oltita bitta tonli signaldan foydalanamiz. Sozlamalarni detektorga o'tkazish uchun MS_TONE_DETECTOR_ADD_SCAN usuli qo'llaniladi.
Detektor bizga kerakli chastota komponentlari bo'lgan signal kirishiga kelganligi haqida xabar berishi uchun biz uni bu holatda ishga tushiradigan qayta qo'ng'iroq qilish funktsiyasi bilan ta'minlashimiz kerak. Bu funksiya yordamida amalga oshiriladi ms_filter_set_notify_callback(). Argumentlar sifatida u filtrga ko'rsatgichni, qayta qo'ng'iroq qilish funktsiyasiga ko'rsatgichni va biz qayta qo'ng'iroq qilish funktsiyasiga (foydalanuvchi ma'lumotlari) o'tkazmoqchi bo'lgan ma'lumotlarga ko'rsatgichni oladi.
Detektor ishga tushirilganda, qayta qo'ng'iroq qilish funktsiyasi foydalanuvchi ma'lumotlarini, detektor filtriga ko'rsatgichni, hodisa identifikatorini va hodisani tavsiflovchi tuzilmani oladi:
/** * 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;
Signalni qayta ishlashning blok diagrammasi sarlavha rasmida ko'rsatilgan.
Xo'sh, endi dasturning o'zi sharhlar bilan kodlanadi.
/* Π€Π°ΠΉΠ» 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);
}
}
Biz dasturni kompilyatsiya qilamiz va ishga tushiramiz. Agar hamma narsa to'g'ri ishlayotgan bo'lsa, ishga tushirilgandan so'ng biz ushbu dastur xatti-harakati kabi narsalarni olishimiz kerak:
$ ./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" dan "6" gacha bo'lgan istalgan tugmachalarni bosing va "Enter" tugmasi bilan tasdiqlang, siz quyidagi ro'yxatni olishingiz kerak:
2
ΠΡΠΏΡΠ°Π²Π»Π΅Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°: 2
ΠΡΠΈΠ½ΡΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°: V-
1
ΠΡΠΏΡΠ°Π²Π»Π΅Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°: 1
ΠΡΠΈΠ½ΡΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°: V+
3
ΠΡΠΏΡΠ°Π²Π»Π΅Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°: 3
ΠΡΠΈΠ½ΡΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°: C+
4
ΠΡΠΏΡΠ°Π²Π»Π΅Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°: 4
ΠΡΠΈΠ½ΡΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°: C-
0
$
Biz buyruq ohanglari muvaffaqiyatli yuborilganini va detektor ularni aniqlayotganini ko'ramiz.
Keyingi maqolada biz RTP protokoli yordamida Ethernet tarmog'i orqali audio signalni uzatishga o'tamiz va uni darhol masofadan boshqarish pultimizda qo'llaymiz.
Manba: www.habr.com