نحن ندرس محرك Mediastreamer2 VoIP. الجزء 5

مادة المقالة مأخوذة من قناة zen الخاصة بي .



كاشف النغمة


في المقالة الأخيرة ، أنشأنا مقياس مستوى الإشارة. في هذا سنتعلم كيفية اكتشاف النغمة.



في الأيام الخوالي ، عندما لم يكن لدى كل أسرة جهاز تلفزيون ، وقام نصفهم بتبديل القنوات بمساعدة الكماشة ، في مراجعات الصحافة التقنية الأجنبية ، كانت هناك أخبار مثيرة للفضول مفادها أن أحد مصنعي التلفزيون جهزوا أجهزتهم بجهاز تحكم عن بعد لاسلكي. من التفاصيل كان من المعروف أن جهاز التحكم عن بعد يعمل بدون بطاريات بسبب استخدام نهج غير عادي - كان جهاز التحكم عن بعد ميكانيكيًا وكان عبارة عن مزيج من آلة موسيقية - ميتالوفون ومسدس. احتوت أسطوانة المسدس على أسطوانات معدنية بأطوال مختلفة ، وعندما ضرب المهاجم أحدها ، بدأت الأسطوانة في الطوق على ترددها. يفترض في الموجات فوق الصوتية. سمعت الإلكترونيات في التلفزيون هذه الإشارة ، وبعد تحديد ترددها ، نفذت الإجراء المقابل - قم بتبديل القناة ، وتغيير مستوى الصوت ،أطفئ التلفاز.


, .


, . , . , 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("                       : %s\n", 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(" : %c\n", 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
$

نرى أن نغمات الأوامر يتم إرسالها بنجاح ويكتشفها الكاشف.


في المقالة التالية ، سوف ننتقل إلى إرسال إشارة صوتية عبر شبكة Ethernet باستخدام بروتوكول RTP وتطبيقها على الفور في جهاز التحكم عن بُعد.


All Articles