STM32F7-Discovery上的SIP電話

大家好。

前段時間我們 писали 關於我們如何在具有 32 MB ROM 和 4 KB RAM 的 STM1F192-Discovery 上成功啟動 SIP 電話 恩博克斯。 這裡必須說的是,該版本是最小的,直接連接兩部電話,無需服務器,並且僅在一個方向上進行語音傳輸。 因此,我們決定推出一款更完整的電話,通過服務器進行通話,雙向傳輸語音,但同時保持盡可能小的內存大小。


對於手機,決定選擇一個應用程序 簡單_pjsua 作為 PJSIP 庫的一部分。 這是一個最小的應用程序,可以在服務器上註冊、接聽和應答呼叫。 下面我將立即介紹如何在STM32F7-Discovery上運行它。

如何跑

  1. 配置 Embox
    make confload-platform/pjsip/stm32f7cube
  2. 在conf/mods.config 文件中設置所需的SIP 帳戶。
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    哪裡 服務器 是 SIP 服務器(例如 sip.linphone.org), 用戶名 и 密碼 - 帳戶用戶名和密碼。

  3. 將 Embox 組建為一個團隊 使。 關於我們擁有的主板固件 維基百科文章.
  4. 在 Embox 控制台中運行“simple_pjsua_imported”命令
    
    00:00:12.870    pjsua_acc.c  ....SIP outbound status for acc 0 is not active
    00:00:12.884    pjsua_acc.c  ....sip:[email protected]: registration success, status=200 (Registration succes
    00:00:12.911    pjsua_acc.c  ....Keep-alive timer started for acc 0, destination:91.121.209.194:5060, interval:15s
    

  5. 最後,還需要將揚聲器或耳機插入音頻輸出,並對顯示屏旁邊的兩個小型 MEMS 麥克風講話。 我們通過應用程序 simple_pjsua、pjsua 從 Linux 進行調用。 好吧,或者您可以使用任何其他類型的 linphone。

所有這些都在我們的 維基百科.

我們是如何到達那裡的

因此,最初出現了選擇硬件平台的問題。 由於內存顯然不適合 STM32F4-Discovery,因此選擇了 STM32F7-Discovery。 她有一個 1 MB 閃存驅動器和 256 KB RAM(+ 64 個特殊快速內存,我們也將使用它)。 通過服務器進行的呼叫也不是很多,但我們決定嘗試適應。

有條件為自己,任務分為幾個階段:

  • 在 QEMU 上運行 PJSIP。 它方便調試,而且我們已經支持 AC97 編解碼器。
  • 在 QEMU 和 STM32 上進行語音錄製和播放。
  • 移植應用程序 簡單_pjsua 來自 PJSIP。 它允許您在 SIP 服務器上註冊並撥打電話。
  • 部署您自己的基於 Asterisk 的服務器並對其進行測試,然後嘗試外部服務器,例如 sip.linphone.org

Embox 中的聲音通過 Portaudio 工作,PISIP 中也使用了 Portaudio。 第一個問題出現在 QEMU 上 - WAV 在 44100 Hz 時播放良好,但在 8000 Hz 時明顯出現問題。 事實證明,這是設置頻率的問題 - 默認情況下,設備中的頻率為 44100,並且這不會以編程方式更改。

在這裡,也許值得解釋一下聲音的一般播放方式。 聲卡可以設置為指向您想要以預定頻率播放或錄製的內存的某個指針。 緩衝區結束後,會生成中斷並繼續執行下一個緩衝區。 事實上,這些緩衝區需要在播​​放前一個緩衝區時提前填充。 我們將在STM32F7上進一步面對這個問題。

接下來,我們租了一台服務器並在其上部署了Asterisk。 由於需要調試很多,但又不想對著麥克風說話太多,所以需要進行自動播放和錄音。 為此,我們修補了 simple_pjsua,以便您可以滑動文件而不是音頻設備。 在 PJSIP 中,這很簡單,因為它們有端口的概念,端口可以是設備也可以是文件。 並且這些端口可以靈活地與其他端口連接。 你可以在我們的pjsip中看到代碼 儲存庫。 結果,方案如下。 在 Asterisk 服務器上,我啟動了兩個帳戶 - 用於 Linux 和 Embox。 接下來在 Embox 上執行命令 simple_pjsua_imported, Embox 註冊到服務器上,之後我們從 Linux 中調用 Embox。 連接時,我們檢查 Asterisk 服務器是否已建立連接,過了一會兒我們應該在 Embox 中聽到 Linux 發出的聲音,並且在 Linux 中我們保存從 Embox 播放的文件。

在 QEMU 上運行後,我們開始移植到 STM32F7-Discovery。 第一個問題是,如果沒有針對映像大小啟用編譯器優化“-Os”,它們就無法裝入 1 MB 的 ROM。 這就是我們添加“-Os”的原因。 此外,該補丁禁用了對C++的支持,因此僅pjsua需要它,我們使用simple_pjsua。

放置後 簡單_pjsua,決定現在有機會推出它。 但首先需要處理語音的錄製和播放。 問題是寫到哪裡呢? 我們選擇外部存儲器 - SDRAM (128 MB)。 你可以自己嘗試一下:

創建頻率為 16000 Hz、持續時間為 10 秒的立體聲 WAV:


record -r 16000 -c 2 -d 10000 -m C0000000

我們輸了:


play -m C0000000

這裡有兩個問題。 第一個使用編解碼器 - WM8994,它有一個插槽這樣的東西,並且有 4 個插槽。因此,默認情況下,如果未配置此選項,則在播放音頻時,會在所有四個插槽中進行播放。 因此,在 16000 Hz 的頻率下,我們收到了 8000 Hz,但對於 8000 Hz,播放根本不起作用。 當僅選擇插槽 0 和 2 時,它可以正常工作。 另一個問題是STM32Cube中的音頻接口,其中音頻輸出通過SAI(串行音頻接口)與音頻輸入同步工作(我不明白細節,但事實證明它們共享一個公共時鐘,當音頻輸出已初始化,音頻以某種方式附加到其入口)。 也就是說,你不能單獨運行它們,所以我們做了以下操作——音頻輸入和音頻輸出始終工作(包括生成中斷)。 但是,當系統中沒有播放任何內容時,我們只需將一個空緩衝區滑入音頻輸出,當播放開始時,我們就開始填充它。

此外,我們還發現錄音時的聲音非常小。 這是因為 STM32F7-Discovery 上的 MEMS 麥克風在低於 16000 Hz 的頻率下無法正常工作。 因此,即使16000 Hz到來,我們也設置8000 Hz。 然而,要做到這一點,有必要添加一種頻率到另一種頻率的軟件轉換。

接下來,我必須增加位於 RAM 中的堆的大小。 根據我們的計算,pjsip 需要大約 190 KB,而我們只剩下大約 100 KB。 這裡我不得不使用一些外部存儲器——SDRAM(大約128 KB)。

經過所有這些編輯後,我看到了 Linux 和 Embox 之間的第一個軟件包,並且我聽到了聲音! 但聲音很糟糕,和QEMU上的完全不一樣,根本聽不清任何東西。 然後我們思考可能出了什麼問題。 調試表明 Embox 根本沒有時間填充/卸載音頻緩衝區。 當pjsip處理一幀的時候,有2次中斷來得及完成緩衝區處理,這太多了。 對於速度的第一個想法是編譯器優化,但它已經包含在 PJSIP 中。 第二個是硬件浮點,我們在 文章。 但實踐表明,FPU 並沒有給速度帶來顯著的提升。 下一步是確定線程的優先級。 Embox 有不同的調度策略,我添加了一種支持優先級並將音頻流設置為最高優先級的策略。 這也沒有幫助。

下一個想法是,我們正在使用外部存儲器,最好將經常訪問的結構移動到那裡。 我初步分析了何時何地 簡單_pjsua 分配內存。 事實證明,在 190 Kb 中,前 90 Kb 分配用於 PJSIP 的內部需求,並且訪問頻率不高。 此外,在傳入呼叫期間,將調用 pjsua_call_answer 函數,然後在其中分配緩衝區以處理傳入和傳出幀。 仍然是 100 Kb 左右。 然後我們做了以下事情。 直到調用的那一刻,我們將數據放置在外部存儲器中。 一旦調用,我們立即用 RAM 中的另一個堆替換該堆。 因此,所有“熱”數據都被轉移到更快、更可預測的內存中。

結果,所有這些共同使得啟動成為可能 簡單_pjsua 並通過您的服務器調用。 然後通過其他服務器,例如 sip.linphone.org。

發現

結果,可以啟動 簡單_pjsua 通過服務器進行雙向語音傳輸。 額外花費128 KB SDRAM的問題可以通過使用稍微強大的Cortex-M7(例如具有32 KB RAM的STM769F512NI)來解決,但同時我們仍然沒有放棄進入256的希望KB 🙂 如果有人感興趣,我們會很高興,或者更好的是,嘗試一下。 像往常一樣,所有來源都在我們的 儲存庫.

來源: www.habr.com

添加評論