Kami mempelajari mesin VoIP Mediastreamer2. Bagian 5

Materi artikel diambil dari saluran zen saya .



Pendeteksi Nada


Pada artikel terakhir , kami membuat pengukur level sinyal. Dalam hal ini kita akan belajar cara mendeteksi nada.



Di masa lalu, ketika tidak setiap keluarga memiliki TV, dan setengah dari mereka mengganti saluran dengan bantuan tang, dalam ulasan dari pers teknis asing ada berita menarik bahwa salah satu produsen TV melengkapi perangkat mereka dengan remote control nirkabel. Dari perincian diketahui bahwa kendali jarak jauh bekerja tanpa baterai karena penggunaan pendekatan yang tidak biasa - kendali jarak jauh bersifat mekanis dan merupakan hibrida dari alat musik - metalofon dan revolver. Drum revolver berisi silinder logam dengan panjang yang berbeda, dan ketika striker menabrak salah satu dari mereka, silinder mulai berdering pada frekuensi sendiri. Agaknya dalam USG. Elektronik di TV mendengar sinyal ini dan, setelah menentukan frekuensinya, melakukan tindakan yang sesuai - mengganti saluran, ubah volumenyaMatikan tvnya.


, .


, . , . , 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);
    }
}

Kami mengkompilasi dan menjalankan program. Jika semuanya bekerja dengan benar, maka setelah memulai kita harus mendapatkan sesuatu seperti ini:


$ ./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

Tekan sembarang tombol dari "1" hingga "6", yang mengonfirmasi dengan tombol "Enter", Anda akan mendapatkan sesuatu seperti daftar ini:



2
 : 2
                       : V-
1
 : 1
                       : V+
3
 : 3
                       : C+
4
 : 4
                       : C-
0
$

Kita melihat bahwa nada perintah berhasil dikirim dan detektor mendeteksinya.


Pada artikel selanjutnya, kita akan beralih untuk mentransmisikan sinyal suara melalui jaringan Ethernet menggunakan protokol RTP dan segera menerapkannya dalam kendali jarak jauh kami.


All Articles