Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 2

ಲೇಖನದ ವಸ್ತುವನ್ನು ನನ್ನಿಂದ ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ ಝೆನ್ ಚಾನೆಲ್.

Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 2

ಟೋನ್ ಜನರೇಟರ್ ರಚಿಸಲಾಗುತ್ತಿದೆ

ಹಿಂದಿನದರಲ್ಲಿ ಲೇಖನ ನಾವು ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್ ಲೈಬ್ರರಿ, ಅಭಿವೃದ್ಧಿ ಪರಿಕರಗಳನ್ನು ಸ್ಥಾಪಿಸಿದ್ದೇವೆ ಮತ್ತು ಪ್ರಾಯೋಗಿಕ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ನಿರ್ಮಿಸುವ ಮೂಲಕ ಅವುಗಳ ಕಾರ್ಯವನ್ನು ಪರೀಕ್ಷಿಸಿದ್ದೇವೆ.

ಇಂದು ನಾವು ಸೌಂಡ್ ಕಾರ್ಡ್‌ನಲ್ಲಿ ಟೋನ್ ಸಿಗ್ನಲ್ ಅನ್ನು ರಚಿಸಬಹುದಾದ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ. ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ನಾವು ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಕೆಳಗೆ ತೋರಿಸಿರುವ ಸೌಂಡ್ ಜನರೇಟರ್ ಸರ್ಕ್ಯೂಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಬೇಕು:

Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 2

ನಾವು ರೇಖಾಚಿತ್ರವನ್ನು ಎಡದಿಂದ ಬಲಕ್ಕೆ ಓದುತ್ತೇವೆ, ಇದು ನಮ್ಮ ಡೇಟಾ ಹರಿವು ಚಲಿಸುವ ದಿಕ್ಕಿನಲ್ಲಿದೆ. ಬಾಣಗಳೂ ಇದರ ಬಗ್ಗೆ ಸುಳಿವು ನೀಡುತ್ತವೆ. ಆಯತಗಳು ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವ ಮತ್ತು ಫಲಿತಾಂಶವನ್ನು ಔಟ್‌ಪುಟ್ ಮಾಡುವ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಸೂಚಿಸುತ್ತವೆ. ಆಯತದ ಒಳಗೆ, ಅದರ ಪಾತ್ರವನ್ನು ಸೂಚಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಫಿಲ್ಟರ್ ಪ್ರಕಾರವನ್ನು ಸ್ವಲ್ಪ ಕೆಳಗೆ ದೊಡ್ಡ ಅಕ್ಷರಗಳಲ್ಲಿ ಸೂಚಿಸಲಾಗುತ್ತದೆ. ಆಯತಗಳನ್ನು ಸಂಪರ್ಕಿಸುವ ಬಾಣಗಳು ಡೇಟಾ ಕ್ಯೂಗಳಾಗಿವೆ, ಅದರ ಮೂಲಕ ಡೇಟಾದ ಬ್ಲಾಕ್‌ಗಳನ್ನು ಫಿಲ್ಟರ್‌ನಿಂದ ಫಿಲ್ಟರ್‌ಗೆ ತಲುಪಿಸಲಾಗುತ್ತದೆ. ಸಾಮಾನ್ಯವಾಗಿ, ಫಿಲ್ಟರ್ ಅನೇಕ ಇನ್‌ಪುಟ್‌ಗಳು ಮತ್ತು ಔಟ್‌ಪುಟ್‌ಗಳನ್ನು ಹೊಂದಿರಬಹುದು.

ಇದು ಎಲ್ಲಾ ಗಡಿಯಾರದ ಮೂಲದಿಂದ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ, ಇದು ಫಿಲ್ಟರ್‌ಗಳಲ್ಲಿ ಡೇಟಾವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡುವ ಗತಿಯನ್ನು ಹೊಂದಿಸುತ್ತದೆ. ಅದರ ಗಡಿಯಾರದ ಚಕ್ರದ ಪ್ರಕಾರ, ಪ್ರತಿ ಫಿಲ್ಟರ್ ತನ್ನ ಇನ್ಪುಟ್ನಲ್ಲಿರುವ ಎಲ್ಲಾ ಡೇಟಾ ಬ್ಲಾಕ್ಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುತ್ತದೆ. ಮತ್ತು ಫಲಿತಾಂಶದೊಂದಿಗೆ ಬ್ಲಾಕ್‌ಗಳನ್ನು ಸರದಿಯಲ್ಲಿ ಇರಿಸುತ್ತದೆ. ಮೊದಲನೆಯದಾಗಿ, ಗಡಿಯಾರದ ಮೂಲಕ್ಕೆ ಹತ್ತಿರವಿರುವ ಫಿಲ್ಟರ್ ಲೆಕ್ಕಾಚಾರಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ, ನಂತರ ಅದರ ಔಟ್ಪುಟ್ಗಳಿಗೆ ಸಂಪರ್ಕ ಹೊಂದಿದ ಫಿಲ್ಟರ್ಗಳು (ಅನೇಕ ಔಟ್ಪುಟ್ಗಳು ಇರಬಹುದು), ಇತ್ಯಾದಿ. ಸರಪಳಿಯಲ್ಲಿನ ಕೊನೆಯ ಫಿಲ್ಟರ್ ಪ್ರಕ್ರಿಯೆ ಮುಗಿದ ನಂತರ, ಹೊಸ ಗಡಿಯಾರ ಬರುವವರೆಗೆ ಎಕ್ಸಿಕ್ಯೂಶನ್ ನಿಲ್ಲುತ್ತದೆ. ಬೀಟ್ಸ್, ಪೂರ್ವನಿಯೋಜಿತವಾಗಿ, 10 ಮಿಲಿಸೆಕೆಂಡುಗಳ ಮಧ್ಯಂತರವನ್ನು ಅನುಸರಿಸಿ.

ನಮ್ಮ ರೇಖಾಚಿತ್ರಕ್ಕೆ ಹಿಂತಿರುಗಿ ನೋಡೋಣ. ಗಡಿಯಾರದ ಚಕ್ರಗಳು ಮೌನ ಮೂಲದ ಇನ್‌ಪುಟ್‌ಗೆ ಆಗಮಿಸುತ್ತವೆ; ಇದು ಫಿಲ್ಟರ್ ಆಗಿದೆ, ಇದು ಪ್ರತಿ ಗಡಿಯಾರ ಚಕ್ರಕ್ಕೆ ಅದರ ಔಟ್‌ಪುಟ್‌ನಲ್ಲಿ ಸೊನ್ನೆಗಳನ್ನು ಹೊಂದಿರುವ ಡೇಟಾದ ಬ್ಲಾಕ್ ಅನ್ನು ಉತ್ಪಾದಿಸುವಲ್ಲಿ ನಿರತವಾಗಿದೆ. ನಾವು ಈ ಬ್ಲಾಕ್ ಅನ್ನು ಧ್ವನಿ ಮಾದರಿಗಳ ಬ್ಲಾಕ್ ಎಂದು ಪರಿಗಣಿಸಿದರೆ, ಇದು ಮೌನಕ್ಕಿಂತ ಹೆಚ್ಚೇನೂ ಅಲ್ಲ. ಮೊದಲ ನೋಟದಲ್ಲಿ, ಮೌನದೊಂದಿಗೆ ಡೇಟಾ ಬ್ಲಾಕ್ಗಳನ್ನು ಉತ್ಪಾದಿಸಲು ವಿಚಿತ್ರವಾಗಿ ತೋರುತ್ತದೆ - ಎಲ್ಲಾ ನಂತರ, ಅದನ್ನು ಕೇಳಲಾಗುವುದಿಲ್ಲ, ಆದರೆ ಧ್ವನಿ ಸಿಗ್ನಲ್ ಜನರೇಟರ್ನ ಕಾರ್ಯಾಚರಣೆಗೆ ಈ ಬ್ಲಾಕ್ಗಳು ​​ಅವಶ್ಯಕ. ಜನರೇಟರ್ ಈ ಬ್ಲಾಕ್ಗಳನ್ನು ಖಾಲಿ ಹಾಳೆಯಂತೆ ಬಳಸುತ್ತದೆ, ಅವುಗಳಲ್ಲಿ ಧ್ವನಿ ಮಾದರಿಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತದೆ. ಅದರ ಸಾಮಾನ್ಯ ಸ್ಥಿತಿಯಲ್ಲಿ, ಜನರೇಟರ್ ಅನ್ನು ಆಫ್ ಮಾಡಲಾಗಿದೆ ಮತ್ತು ಔಟ್ಪುಟ್ಗೆ ಇನ್ಪುಟ್ ಬ್ಲಾಕ್ಗಳನ್ನು ಸರಳವಾಗಿ ಫಾರ್ವರ್ಡ್ ಮಾಡುತ್ತದೆ. ಹೀಗಾಗಿ, ಮೌನದ ಬ್ಲಾಕ್ಗಳು ​​ಸಂಪೂರ್ಣ ಸರ್ಕ್ಯೂಟ್ ಮೂಲಕ ಎಡದಿಂದ ಬಲಕ್ಕೆ ಬದಲಾಗದೆ, ಧ್ವನಿ ಕಾರ್ಡ್ನಲ್ಲಿ ಕೊನೆಗೊಳ್ಳುತ್ತವೆ. ಇದು ತನ್ನ ಇನ್‌ಪುಟ್‌ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸರದಿಯಿಂದ ಬ್ಲಾಕ್‌ಗಳನ್ನು ಮೌನವಾಗಿ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ.

ಆದರೆ ಜನರೇಟರ್‌ಗೆ ಧ್ವನಿಯನ್ನು ಪ್ಲೇ ಮಾಡಲು ಆಜ್ಞೆಯನ್ನು ನೀಡಿದರೆ ಎಲ್ಲವೂ ಬದಲಾಗುತ್ತದೆ, ಅದು ಧ್ವನಿ ಮಾದರಿಗಳನ್ನು ಉತ್ಪಾದಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ ಮತ್ತು ಅವುಗಳನ್ನು ಇನ್‌ಪುಟ್ ಬ್ಲಾಕ್‌ಗಳಲ್ಲಿ ಮಾದರಿಗಳೊಂದಿಗೆ ಬದಲಾಯಿಸುತ್ತದೆ ಮತ್ತು ಬದಲಾದ ಬ್ಲಾಕ್‌ಗಳನ್ನು ಔಟ್‌ಪುಟ್‌ನಲ್ಲಿ ಇರಿಸುತ್ತದೆ. ಧ್ವನಿ ಕಾರ್ಡ್ ಧ್ವನಿಯನ್ನು ಪ್ಲೇ ಮಾಡಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ. ಮೇಲೆ ವಿವರಿಸಿದ ಕೆಲಸದ ಯೋಜನೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಪ್ರೋಗ್ರಾಂ ಕೆಳಗೆ ಇದೆ:

/* Файл mstest2.c */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/mssndcard.h>
int main()
{
    ms_init();

    /* Создаем экземпляры фильтров. */
    MSFilter  *voidsource = ms_filter_new(MS_VOID_SOURCE_ID);
    MSFilter  *dtmfgen = ms_filter_new(MS_DTMF_GEN_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);

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

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

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

   /* Включаем звуковой генератор. */
   char key='1';
   ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY, (void*)&key);

   /* Даем, время, чтобы все блоки данных были получены звуковой картой.*/
   ms_sleep(2);   
}

ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿದ ನಂತರ, ಮೂರು ಫಿಲ್ಟರ್‌ಗಳನ್ನು ರಚಿಸಲಾಗಿದೆ: voidsource, dtmfgen, snd_card_write. ಗಡಿಯಾರದ ಮೂಲವನ್ನು ರಚಿಸಲಾಗಿದೆ.

ನಂತರ ನೀವು ನಮ್ಮ ಸರ್ಕ್ಯೂಟ್‌ಗೆ ಅನುಗುಣವಾಗಿ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಸಂಪರ್ಕಿಸಬೇಕು ಮತ್ತು ಗಡಿಯಾರದ ಮೂಲವನ್ನು ಕೊನೆಯದಾಗಿ ಸಂಪರ್ಕಿಸಬೇಕು, ಏಕೆಂದರೆ ಇದರ ನಂತರ ಸರ್ಕ್ಯೂಟ್ ತಕ್ಷಣವೇ ಕಾರ್ಯನಿರ್ವಹಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ. ನೀವು ಗಡಿಯಾರದ ಮೂಲವನ್ನು ಪೂರ್ಣಗೊಳಿಸದ ಸರ್ಕ್ಯೂಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಿದರೆ, ಎಲ್ಲಾ ಇನ್‌ಪುಟ್‌ಗಳು ಅಥವಾ ಎಲ್ಲಾ ಔಟ್‌ಪುಟ್‌ಗಳೊಂದಿಗೆ "ಗಾಳಿಯಲ್ಲಿ ನೇತಾಡುವ" (ಸಂಪರ್ಕವಾಗಿಲ್ಲ) ಸರಪಳಿಯಲ್ಲಿ ಕನಿಷ್ಠ ಒಂದು ಫಿಲ್ಟರ್ ಅನ್ನು ಪತ್ತೆ ಮಾಡಿದರೆ ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ ಕ್ರ್ಯಾಶ್ ಆಗಬಹುದು.

ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಸಂಪರ್ಕಿಸುವುದು ಕಾರ್ಯವನ್ನು ಬಳಸಿಕೊಂಡು ಮಾಡಲಾಗುತ್ತದೆ

ms_filter_link(src, src_out, dst, dst_in)

ಮೊದಲ ಆರ್ಗ್ಯುಮೆಂಟ್ ಮೂಲ ಫಿಲ್ಟರ್‌ಗೆ ಪಾಯಿಂಟರ್ ಆಗಿದ್ದರೆ, ಎರಡನೇ ಆರ್ಗ್ಯುಮೆಂಟ್ ಮೂಲ ಔಟ್‌ಪುಟ್ ಸಂಖ್ಯೆಯಾಗಿದೆ (ಇನ್‌ಪುಟ್‌ಗಳು ಮತ್ತು ಔಟ್‌ಪುಟ್‌ಗಳನ್ನು ಶೂನ್ಯದಿಂದ ಪ್ರಾರಂಭಿಸಿ ಸಂಖ್ಯೆ ಮಾಡಲಾಗಿದೆ ಎಂಬುದನ್ನು ಗಮನಿಸಿ). ಮೂರನೇ ಆರ್ಗ್ಯುಮೆಂಟ್ ರಿಸೀವರ್ ಫಿಲ್ಟರ್‌ಗೆ ಪಾಯಿಂಟರ್ ಆಗಿದೆ, ನಾಲ್ಕನೆಯದು ರಿಸೀವರ್ ಇನ್‌ಪುಟ್ ಸಂಖ್ಯೆ.

ಎಲ್ಲಾ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಸಂಪರ್ಕಿಸಲಾಗಿದೆ ಮತ್ತು ಗಡಿಯಾರದ ಮೂಲವನ್ನು ಕೊನೆಯದಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ (ಇನ್ನು ಮುಂದೆ ನಾವು ಅದನ್ನು ಟಿಕ್ಕರ್ ಎಂದು ಕರೆಯುತ್ತೇವೆ). ಅದರ ನಂತರ ನಮ್ಮ ಧ್ವನಿ ಸರ್ಕ್ಯೂಟ್ ಕಾರ್ಯನಿರ್ವಹಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ, ಆದರೆ ಕಂಪ್ಯೂಟರ್ ಸ್ಪೀಕರ್‌ಗಳಲ್ಲಿ ಇನ್ನೂ ಏನನ್ನೂ ಕೇಳಲಾಗುವುದಿಲ್ಲ - ಧ್ವನಿ ಜನರೇಟರ್ ಅನ್ನು ಆಫ್ ಮಾಡಲಾಗಿದೆ ಮತ್ತು ಇನ್‌ಪುಟ್ ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳ ಮೂಲಕ ಮೌನವಾಗಿ ಹಾದುಹೋಗುತ್ತದೆ. ಟೋನ್ ಉತ್ಪಾದಿಸಲು ಪ್ರಾರಂಭಿಸಲು, ನೀವು ಜನರೇಟರ್ ಫಿಲ್ಟರ್ ವಿಧಾನವನ್ನು ರನ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.

ಫೋನ್‌ನಲ್ಲಿ "1" ಗುಂಡಿಯನ್ನು ಒತ್ತುವುದಕ್ಕೆ ಅನುಗುಣವಾಗಿ ನಾವು ಎರಡು-ಟೋನ್ (DTMF) ಸಿಗ್ನಲ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ. ಇದನ್ನು ಮಾಡಲು, ನಾವು ಕಾರ್ಯವನ್ನು ಬಳಸುತ್ತೇವೆ ms_filter_call_method() ನಾವು MS_DTMF_GEN_PLAY ವಿಧಾನವನ್ನು ಕರೆಯುತ್ತೇವೆ, ಪ್ಲೇಬ್ಯಾಕ್ ಸಿಗ್ನಲ್ ಹೊಂದಿಕೆಯಾಗಬೇಕಾದ ಕೋಡ್‌ಗೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ರವಾನಿಸುತ್ತೇವೆ.

ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಕಂಪೈಲ್ ಮಾಡುವುದು ಮಾತ್ರ ಉಳಿದಿದೆ:

$ gcc mstest2.c -o mstest2 `pkg-config mediastreamer --libs --cflags`

ಮತ್ತು ಓಡಿ:

$ ./mstest2

ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿದ ನಂತರ, ಕಂಪ್ಯೂಟರ್ ಸ್ಪೀಕರ್ನಲ್ಲಿ ಎರಡು ಟೋನ್ಗಳನ್ನು ಒಳಗೊಂಡಿರುವ ಸಣ್ಣ ಧ್ವನಿ ಸಂಕೇತವನ್ನು ನೀವು ಕೇಳುತ್ತೀರಿ.

ನಾವು ನಮ್ಮ ಮೊದಲ ಧ್ವನಿ ಸರ್ಕ್ಯೂಟ್ ಅನ್ನು ನಿರ್ಮಿಸಿದ್ದೇವೆ ಮತ್ತು ಪ್ರಾರಂಭಿಸಿದ್ದೇವೆ. ಫಿಲ್ಟರ್ ನಿದರ್ಶನಗಳನ್ನು ಹೇಗೆ ರಚಿಸುವುದು, ಅವುಗಳನ್ನು ಹೇಗೆ ಸಂಪರ್ಕಿಸುವುದು ಮತ್ತು ಅವುಗಳ ವಿಧಾನಗಳನ್ನು ಹೇಗೆ ಕರೆಯುವುದು ಎಂದು ನಾವು ನೋಡಿದ್ದೇವೆ. ನಮ್ಮ ಆರಂಭಿಕ ಯಶಸ್ಸಿನಿಂದ ನಾವು ಸಂತೋಷವಾಗಿರುವಾಗ, ನಮ್ಮ ಪ್ರೋಗ್ರಾಂ ನಿರ್ಗಮಿಸುವ ಮೊದಲು ನಿಗದಿಪಡಿಸಿದ ಮೆಮೊರಿಯನ್ನು ಮುಕ್ತಗೊಳಿಸುವುದಿಲ್ಲ ಎಂಬ ಅಂಶಕ್ಕೆ ನಾವು ಇನ್ನೂ ಗಮನ ಹರಿಸಬೇಕಾಗಿದೆ. ಮುಂದಿನದರಲ್ಲಿ ಲೇಖನ ನಮ್ಮ ನಂತರ ನಾವು ಸ್ವಚ್ಛಗೊಳಿಸಲು ಕಲಿಯುತ್ತೇವೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ