Mediastreamer2 VoIP motorunu keşfetme. 2. Bölüm

Makalenin materyali benim zenci kanalı.

Mediastreamer2 VoIP motorunu keşfetme. 2. Bölüm

Ton Oluşturucu Oluşturma

Önceki Makale Medya aktarıcı kitaplığını, geliştirme araçlarını kurduk ve bir deneme uygulaması oluşturarak işlevlerini test ettik.

Bugün ses kartı üzerinde ton sinyali üretebilecek bir uygulama oluşturacağız. Bu sorunu çözmek için filtreleri aşağıda gösterilen ses üreteci devresine bağlamamız gerekir:

Mediastreamer2 VoIP motorunu keşfetme. 2. Bölüm

Diyagramı soldan sağa okuyoruz, veri akışımız bu yönde ilerliyor. Oklar da buna işaret ediyor. Dikdörtgenler, veri bloklarını işleyen ve sonucu çıkaran filtreleri belirtir. Dikdörtgenin içinde rolü belirtilmiş ve filtre tipi hemen altında büyük harflerle belirtilmiştir. Dikdörtgenleri birbirine bağlayan oklar, veri bloklarının filtreden filtreye iletildiği veri kuyruklarıdır. Genel olarak bir filtrenin birçok girdisi ve çıktısı olabilir.

Her şey, filtrelerde verilerin hesaplanacağı tempoyu ayarlayan saat kaynağıyla başlar. Her filtre kendi saat döngüsüne göre girişindeki tüm veri bloklarını işler. Ve sonucu içeren blokları sıraya koyar. Önce saat kaynağına en yakın filtre hesaplamaları yapar, ardından çıkışlarına bağlanan filtreler (çok sayıda çıkış olabilir) vb. Zincirdeki son filtrenin işlenmesi tamamlandıktan sonra, yeni bir saat gelene kadar yürütme durdurulur. Vuruşlar varsayılan olarak 10 milisaniyelik bir aralığı takip eder.

Diyagramımıza geri dönelim. Saat döngüleri sessizlik kaynağının girişine ulaşır; bu, her saat döngüsü için çıkışında sıfırlar içeren bir veri bloğu oluşturmakla meşgul olan bir filtredir. Bu bloğu bir ses örnekleri bloğu olarak düşünürsek, bu sessizlikten başka bir şey değildir. İlk bakışta sessiz veri blokları oluşturmak garip görünüyor - sonuçta duyulamıyor, ancak bu bloklar ses sinyali üretecinin çalışması için gereklidir. Jeneratör bu blokları boş bir kağıt parçası gibi kullanarak ses örneklerini bunlara kaydediyor. Normal durumda jeneratör kapalıdır ve giriş bloklarını çıkışa iletir. Böylece sessizlik blokları soldan sağa tüm devre boyunca değişmeden geçerek ses kartında son bulur. Bu, girişine bağlı sıradan blokları sessizce alır.

Ancak jeneratöre ses çalma komutu verilirse her şey değişir, ses örnekleri oluşturmaya başlar ve bunları giriş bloklarındaki örneklerle değiştirir ve değiştirilen blokları çıkışa koyar. Ses kartı ses çalmaya başlar. Yukarıda açıklanan çalışma şemasını uygulayan bir program aşağıdadır:

/* Файл 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);   
}

Medya aktarıcıyı başlattıktan sonra üç filtre oluşturulur: voidsource, dtmfgen, snd_card_write. Bir saat kaynağı oluşturulur.

Daha sonra filtreleri devremize uygun olarak bağlamanız gerekir ve saat kaynağı en son bağlanmalıdır, çünkü bundan sonra devre hemen çalışmaya başlayacaktır. Bir saat kaynağını tamamlanmamış bir devreye bağlarsanız, medya aktarıcı, zincirde tüm girişlerin veya tüm çıkışların "havada asılı" (bağlı değil) olduğu en az bir filtre tespit ederse çökebilir.

Filtrelerin bağlanması fonksiyon kullanılarak yapılır

ms_filter_link(src, src_out, dst, dst_in)

burada ilk argüman kaynak filtresini gösteren bir işaretçidir, ikinci argüman ise kaynak çıkış numarasıdır (giriş ve çıkışların sıfırdan başlayarak numaralandırıldığını unutmayın). Üçüncü argüman alıcı filtresine yönelik bir işaretçidir, dördüncüsü ise alıcı giriş numarasıdır.

Tüm filtreler bağlanır ve saat kaynağı en son bağlanır (bundan sonra ona sadece kayan yazı işareti diyeceğiz). Bundan sonra ses devremiz çalışmaya başlar, ancak bilgisayar hoparlörlerinde henüz hiçbir şey duyulamaz - ses üreteci kapatılır ve giriş veri bloklarından sessizce geçer. Bir ton oluşturmaya başlamak için jeneratör filtre yöntemini çalıştırmanız gerekir.

Telefondaki "1" tuşuna basmaya karşılık gelen iki tonlu (DTMF) bir sinyal üreteceğiz. Bunu yapmak için fonksiyonu kullanıyoruz ms_filter_call_method() MS_DTMF_GEN_PLAY yöntemini çağırıyoruz ve bunu, oynatma sinyalinin karşılık gelmesi gereken koda yönelik bir işaretçi olarak argüman olarak iletiyoruz.

Geriye kalan tek şey programı derlemek:

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

Ve koş:

$ ./mstest2

Programı başlattıktan sonra bilgisayar hoparlöründe iki tondan oluşan kısa bir ses sinyali duyacaksınız.

İlk ses devremizi kurup devreye aldık. Filtre örneklerinin nasıl oluşturulacağını, bunların nasıl bağlanacağını ve yöntemlerinin nasıl çağrılacağını gördük. Başlangıçtaki başarımızdan memnun olsak da, programımızın çıkmadan önce ayrılan hafızayı boşaltmamasına yine de dikkat etmemiz gerekiyor. Gelecek Makale arkamızı temizlemeyi öğreneceğiz.

Kaynak: habr.com

Yorum ekle