Meneroka enjin Mediastreamer2 VoIP. Bahagian 2

Bahan artikel diambil dari saya saluran zen.

Meneroka enjin Mediastreamer2 VoIP. Bahagian 2

Mencipta Penjana Nada

Dalam sebelumnya artikel Kami memasang pustaka penstrim media, alat pembangunan dan menguji kefungsiannya dengan membina aplikasi percubaan.

Hari ini kami akan mencipta aplikasi yang boleh menjana isyarat nada pada kad bunyi. Untuk menyelesaikan masalah ini kita perlu menyambungkan penapis ke dalam litar penjana bunyi yang ditunjukkan di bawah:

Meneroka enjin Mediastreamer2 VoIP. Bahagian 2

Kami membaca rajah dari kiri ke kanan, ini adalah arah aliran data kami bergerak. Anak panah juga membayangkan perkara ini. Segi empat tepat menunjukkan penapis yang memproses blok data dan mengeluarkan hasilnya. Di dalam segi empat tepat, peranannya ditunjukkan dan jenis penapis ditunjukkan dalam huruf besar tepat di bawah. Anak panah yang menyambungkan segi empat tepat ialah baris gilir data yang melaluinya blok data dihantar dari penapis ke penapis. Secara umum, penapis boleh mempunyai banyak input dan output.

Semuanya bermula dengan sumber jam, yang menetapkan tempo di mana data dikira dalam penapis. Mengikut kitaran jamnya, setiap penapis memproses semua blok data yang berada pada inputnya. Dan meletakkan blok dengan hasilnya ke dalam baris gilir. Pertama, penapis yang paling hampir dengan sumber jam melakukan pengiraan, kemudian penapis disambungkan ke outputnya (boleh terdapat banyak output), dan seterusnya. Selepas penapis terakhir dalam rantai selesai diproses, pelaksanaan dihentikan sehingga jam baharu tiba. Pukulan, secara lalai, mengikut selang 10 milisaat.

Mari kita kembali kepada rajah kita. Kitaran jam tiba pada input sumber senyap; ini ialah penapis, yang sibuk menjana blok data yang mengandungi sifar pada outputnya untuk setiap kitaran jam. Jika kita menganggap blok ini sebagai blok sampel bunyi, maka ini tidak lebih daripada senyap. Pada pandangan pertama, nampaknya pelik untuk menjana blok data dengan senyap - lagipun, ia tidak dapat didengari, tetapi blok ini diperlukan untuk operasi penjana isyarat bunyi. Penjana menggunakan blok ini seperti helaian kertas kosong, merakam sampel bunyi ke dalamnya. Dalam keadaan biasa, penjana dimatikan dan hanya memajukan blok input ke output. Oleh itu, blok senyap tidak berubah melalui keseluruhan litar dari kiri ke kanan, berakhir dalam kad bunyi. Yang secara senyap mengambil blok dari baris gilir yang disambungkan ke inputnya.

Tetapi segala-galanya berubah jika penjana diberi arahan untuk memainkan bunyi, ia mula menghasilkan sampel bunyi dan menggantikannya dengan sampel dalam blok input dan meletakkan blok yang diubah pada output. Kad bunyi mula memainkan bunyi. Di bawah ialah program yang melaksanakan skema kerja yang diterangkan di atas:

/* Π€Π°ΠΉΠ» 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);   
}

Selepas memulakan penstrim media, tiga penapis dibuat: voidsource, dtmfgen, snd_card_write. Sumber jam dicipta.

Kemudian anda perlu menyambungkan penapis mengikut litar kami, dan sumber jam mesti disambungkan terakhir, kerana selepas ini litar akan segera mula beroperasi. Jika anda menyambungkan sumber jam ke litar yang belum selesai, ia mungkin berlaku bahawa penstrim media ranap jika ia mengesan sekurang-kurangnya satu penapis dalam rantai dengan semua input atau semua output "bergantung di udara" (tidak disambungkan).

Menyambung penapis dilakukan menggunakan fungsi

ms_filter_link(src, src_out, dst, dst_in)

di mana argumen pertama adalah penunjuk kepada penapis sumber, argumen kedua ialah nombor output sumber (perhatikan bahawa input dan output dinomborkan bermula dari sifar). Hujah ketiga ialah penunjuk kepada penapis penerima, yang keempat ialah nombor input penerima.

Semua penapis disambungkan dan sumber jam disambungkan terakhir (selepas ini kami hanya akan memanggilnya sebagai ticker). Selepas itu litar bunyi kami mula berfungsi, tetapi tiada apa yang boleh didengari dalam pembesar suara komputer - penjana bunyi dimatikan dan hanya melalui blok data input dengan senyap. Untuk mula menjana nada, anda perlu menjalankan kaedah penapis penjana.

Kami akan menjana isyarat dua nada (DTMF) sepadan dengan menekan butang "1" pada telefon. Untuk melakukan ini, kami menggunakan fungsi ms_filter_call_method() Kami memanggil kaedah MS_DTMF_GEN_PLAY, menghantarnya sebagai hujah sebagai penunjuk kepada kod yang sepatutnya sepadan dengan isyarat main balik.

Apa yang tinggal ialah menyusun atur cara:

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

Dan jalankan:

$ ./mstest2

Selepas memulakan program, anda akan mendengar isyarat bunyi pendek yang terdiri daripada dua nada dalam pembesar suara komputer.

Kami membina dan melancarkan litar bunyi pertama kami. Kami melihat cara membuat tika penapis, cara menyambungkannya dan cara memanggil kaedahnya. Walaupun kami gembira dengan kejayaan awal kami, kami masih perlu memberi perhatian kepada fakta bahawa program kami tidak membebaskan memori yang diperuntukkan sebelum keluar. Dalam seterusnya artikel kita akan belajar untuk membersihkan diri sendiri.

Sumber: www.habr.com

Tambah komen