探索 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

為具有 DDoS 保護、VPS VDS 服務器的站點購買可靠的主機 🔥 購買具備 DDoS 防護的可靠網站寄存服務,包括 VPS 和 VDS 伺服器 | ProHoster