【WebRTC音頻預先處理單元APM的整體編譯及使用 - android】

來源:互聯網
上載者:User

標籤:預先處理   win7   als   無法   根據   code   前言   tin   3.0   

前言

在寫【單獨編譯使用WebRTC的音頻處理模組 - android】一文之前,就一直想直接把WebRTC的音頻處理引擎VoE整個兒編譯出來供自己的項目使用,但限於技術拙劣、時間緊迫,所以沒能成功。只得挨個挨個把引擎中的Aecm、Agc、Ns以及Vad模組單獨編譯出來湊合著用。雖能達到一定效果,但始終不甚理想。5個月後,bill需要最佳化之前的項目,於是就下了狠心,定要將整個音頻處理模組用上 ...

 

本文

然而本次最佳化仍然沒能用上整套VoE,因為VoE不僅僅包含音頻預先處理,它將音頻編碼模組、傳輸模組一併融入了引擎,而bill的項目需要使用既有的編碼、傳輸層,因此使用整個VoE對我來說顯得冗餘且不可操作。天無絕人之路,拋開VoE不談,bill找到了僅次於VoE層級的模組 —— APM(Audio Preprocessing Module) —— 一個整合了前文所有模組且純粹的音頻預先處理單元。

 

Step 1 - 下載Google WebRTC源碼

Google WebRTC的開發進度還是可觀的,本文將以WebRTC的最新trunk revision 5125為例進行講解。請自行使用SVN同步以下目錄(至於同步的方法,請自行google):

http://webrtc.googlecode.com/svn/trunk/

 

Step 2 - 提取編譯APM所需資源

APM的整體編譯需要WebRTC源碼目錄下的如下資源:

1)common_audio 整個目錄

2)modules 目錄(不包含 video 部分)

3)system_wrappers 整個目錄

4)位於 WebRTC 源碼根目錄下的 common_types.h | common.h | typedefs.h 三個標頭檔。

5)位於 WebRTC 主目錄下的 android-webrtc.mk 檔案。

 

Step 3 - 在Eclipse中編譯APM基礎步驟及部分要點

對於Eclipse中jni的編譯及使用請參見上篇文章所述,在此不再贅述。

此節僅按照自己的jni目錄組織圖進行講解,讀者可根據自己需要進行調整。

在Eclipse中的jni組織圖如下:

Step-2中的所有檔案夾及標頭檔均位於 webrtc 子目錄下。android-webrtc.mk 位於 jni 根目錄下。

下面我們逐步進行分解:

 

step 3.1

首先我們需要對整個 android 工程進行描述和設定,開啟 jni 根目錄下的 Application.mk 檔案,編輯如下:

 

 

123456789101112 # Copyright (c) 2013 BillHoo. All Rights Reserved.# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.## Use of this source code is governed by a BSD-style license# that can be found in the LICENSE file in the root of the source# tree. An additional intellectual property rights grant can be found# in the file PATENTS.  All contributing project authors may# be found in the AUTHORS file in the root of the source tree.APP_STL := gnustl_staticAPP_CPPFLAGS := -frtti -fexceptionsAPP_ABI := armeabi armeabi-v7aAPP_PLATFORM := android-9

其中 APP_STL 的官方說明如下:

 

1234567891011 APP_STL    By default, the NDK build system provides C++ headers for the minimal    C++ runtime library (/system/lib/libstdc++.so) provided by the Android    system.    However, the NDK comes with alternative C++ implementations that you can    use or link to in your own applications. Define APP_STL to select one of    them. Examples are:       APP_STL := stlport_static    --> static STLport library       APP_STL := stlport_shared    --> shared STLport library       APP_STL := system            --> default C++ runtime library    For more information on the subject, please read docs/CPLUSPLUS-SUPPORT.html

由於 NDK 預設使用最小 C++ 執行階段程式庫進行項目的編譯,導致無法編譯 WebRTC 中使用諸如 std::map 等 STL 容器的源碼。因此我們需要自行設定適合本項目的 C++ 執行階段程式庫 gnustl_static。

 

step 3.2

開啟並編輯 jni 根目錄下的 Android.mk 檔案如下,本檔案只需告訴 NDK 去調用所有子目錄下的 Android.mk 檔案即可:

 

123456789 # Copyright (c) 2013 BillHoo. All Rights Reserved.# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.## Use of this source code is governed by a BSD-style license# that can be found in the LICENSE file in the root of the source# tree. An additional intellectual property rights grant can be found# in the file PATENTS.  All contributing project authors may# be found in the AUTHORS file in the root of the source tree.include $(call all-subdir-makefiles)

 

 

step 3.3

準備工作就緒,下面就可以開始著手編譯整個 APM 單元了,首先開啟 jni/webrtc 目錄,建立 Android.mk 檔案如下:

 

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 # Copyright (c) 2013 BillHoo. All Rights Reserved.# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.## Use of this source code is governed by a BSD-style license# that can be found in the LICENSE file in the root of the source# tree. An additional intellectual property rights grant can be found# in the file PATENTS.  All contributing project authors may# be found in the AUTHORS file in the root of the source tree.#MY_WEBRTC_ROOT_PATH := $(call my-dir)## voiceinclude $(MY_WEBRTC_ROOT_PATH)/common_audio/signal_processing/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/common_audio/vad/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/audio_processing/aec/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/audio_processing/aecm/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/audio_processing/agc/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/audio_processing/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/audio_processing/ns/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/audio_processing/utility/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/utility/source/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/modules/audio_device/Android.mkinclude $(MY_WEBRTC_ROOT_PATH)/system_wrappers/source/Android.mk## build .soLOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_ARM_MODE := armLOCAL_MODULE := liblu_audio_preprocessingLOCAL_MODULE_TAGS := optionalLOCAL_WHOLE_STATIC_LIBRARIES := \    libwebrtc_spl \    libwebrtc_apm \    libwebrtc_apm_utility \    libwebrtc_vad \    libwebrtc_ns \    libwebrtc_agc \    libwebrtc_aec \    libwebrtc_aecm \    libwebrtc_system_wrappers \    libwebrtc_audio_device \    libwebrtc_utility## Add Neon libraries.ifeq ($(WEBRTC_BUILD_NEON_LIBS),true)LOCAL_WHOLE_STATIC_LIBRARIES += \    libwebrtc_aecm_neon \    libwebrtc_ns_neon \    libwebrtc_spl_neonendifLOCAL_STATIC_LIBRARIES := \    libprotobuf-cpp-2.3.0-liteLOCAL_SHARED_LIBRARIES := \    libcutils \    libdl \    libstlportLOCAL_PRELINK_MODULE := false##TODO(billhoo) find a properway to do this.LOCAL_LDLIBS += $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/libgnustl_static.aLOCAL_LDLIBS += -lOpenSLESifndef NDK_ROOTinclude external/stlport/libstlport.mkendifinclude $(BUILD_SHARED_LIBRARY)

需要注意的幾點:

1)在編譯時間如提示找不到 ../../../Android.mk 檔案等錯誤,請檢查並修正你的相對路徑。

2)位於第60行的gnu靜態庫連結路徑是針對NDK版本 r8d 的,如讀者版本不匹配,請自行找到 libgnustl_static.a 靜態庫的路徑進行替換。

3)本樣本並不打算編譯 WebRTC 的測試工程,請使用 Eclipse 搜尋檔案功能,找到 Android.mk 檔案中的 -DWEBRTC_AUDIOPROC_DEBUG_DUMP 並注釋掉。

 

step 3.4

萬事俱備,我們可以開始編譯 APM 了,不過在編譯過程中肯定還會有很多小問題出現(比如相對路徑不正確、找不到某某函數的符號等等),這些問題就留給讀者自行google、SO解決了,bill就不再贅述。

 

Step 4 - 在android應用中使用APM的注意事項

經過上述步驟,讀者便能夠得到 libwebrtc_audio_preprocessing.so 這個動態連結程式庫。我們需要做的僅僅是編寫自己的 jni 封裝函數向 android 應用程式層提供 APM 的介面。具體做法bill之前的文章已經詳細介紹過。這裡需要注意的是,如果讀者打算在自己的動態庫中引用已經編譯好的 APM 庫,那麼在 android 類載入這兩個庫時的順序是敏感的。

假設讀者將自己的 JNI 介面封裝成單獨的庫 libmy_jni_wrapper.so,而該庫引用了 libwebrtc_audio_preprocessing.so,那麼在載入這兩個庫時應該參照如下順序:

 

12345 static {    // Ordering of loading these shared libraries is significant.    System.loadLibrary("webrtc_audio_preprocessing");    System.loadLibrary("my_jni_wrapper");}

若順序寫反,在運行時將得到找不到 webrtc_audio_preprocessing 庫中符號的異常。

 

總結

整個編譯工作在現在看來非常簡單,但需要很多的耐心和搜尋,不過結果還是令人比較滿意的,APM出來的效果比之前自己單獨使用各個音頻模組要好很多。不過對於抖動等因素的影響,APM就力不從心了。也許bill接下來該花時間去看看NetEq、Jitter Buffer等模組了。如何使用他們,如何融進自己的項目,到時候就知道了。

【WebRTC音頻預先處理單元APM的整體編譯及使用 - android】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.