正文php
然而本次優化仍然沒能用上整套VoE,由於VoE不只僅包含音頻預處理,它將音頻編碼模塊、傳輸模塊一併融入了引擎,而bill的項目須要使用既有的編碼、傳輸層,所以使用整個VoE對我來講顯得冗餘且不可操做。天無絕人之路,拋開VoE不談,bill找到了僅次於VoE層級的模塊 —— APM(Audio Preprocessing Module)—— 一個整合了前文全部模塊且純粹的音頻預處理單元。html
Step 1 - 下載Google WebRTC源碼linux
Google WebRTC的開發進度仍是可觀的,本文將以WebRTC的最新trunk revision 5125爲例進行講解。請自行使用SVN同步如下目錄(至於同步的方法,請自行google):android
http://webrtc.googlecode.com/svn/trunk/ios
Step 2 - 提取編譯APM所需資源c++
APM的總體編譯須要WebRTC源碼目錄下的以下資源:git
1)common_audio 整個目錄github
2)modules 目錄(不包含 video 部分)web
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 文件,編輯以下:
1
2
3
4
5
6
7
8
9
10
11
12
|
# 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_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-9
|
其中 APP_STL 的官方說明以下:
1
2
3
4
5
6
7
8
9
10
11
|
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 文件便可:
1
2
3
4
5
6
7
8
9
|
# 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 文件以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
# 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
)
#
# voice
include $(MY_WEBRTC_ROOT_PATH)
/common_audio/signal_processing/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/common_audio/vad/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/audio_processing/aec/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/audio_processing/aecm/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/audio_processing/agc/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/audio_processing/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/audio_processing/ns/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/audio_processing/utility/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/utility/source/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/modules/audio_device/Android
.mk
include $(MY_WEBRTC_ROOT_PATH)
/system_wrappers/source/Android
.mk
#
# build .so
LOCAL_PATH := $(call my-
dir
)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE := lib
lu
_audio_preprocessing
LOCAL_MODULE_TAGS := optional
LOCAL_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_neon
endif
LOCAL_STATIC_LIBRARIES := \
libprotobuf-cpp-2.3.0-lite
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdl \
libstlport
LOCAL_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
.a
LOCAL_LDLIBS += -lOpenSLES
ifndef NDK_ROOT
include external
/stlport/libstlport
.mk
endif
include $(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,那麼在加載這兩個庫時應該參照以下順序:
1
2
3
4
5
|
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等模塊了。如何使用他們,如何融進本身的項目,到時候就知道了。
出處http://billhoo.blog.51cto.com/2337751/1325273