Android ilbc 語音對話示範之代碼搭建

來源:互聯網
上載者:User

 基於上一篇中提到的google網站的一份代碼(http://code.google.com/p/android-ilbc/)這個需要git下載,我上傳了一份在CSDN,
稍微進行了修改:下載連結:(http://download.csdn.net/detail/ranxiedao/4450917)。
     現在開始講解代碼結構搭建環節:
要求: 
環境:Ubuntu 12.04 (其他Linux環境皆可),Android 2.2 及以上系統 
 
工具:Elicpse 3.7 ,Android NDK r7 ,Android SDK r7 

1. 建立工程:
開啟Eclipse,建立一個Android 程式,名稱為 AndroidILBC,要求SDK 使用2.2及以上版本,因為Android是從2.2開始正式支援NDK 開發。

2. 添加底層代碼:
     將下載的源碼中的 jni 檔案夾複製到建立的工程的根目錄下,此時,代碼結構如下:
                             

 3. jni 目錄下的Android.mk 的內容為:
LOCAL_PATH := $(call my-dir) 
  
 include $(CLEAR_VARS) 
  
 LOCAL_MODULE := libilbc 
  
 codec_dir := iLBC_RFC3951  #ilbc 原始碼的目錄 
  
 LOCAL_SRC_FILES := \ 
     $(codec_dir)/anaFilter.c \ 
     $(codec_dir)/constants.c \ 
     $(codec_dir)/createCB.c \ 
     $(codec_dir)/doCPLC.c \ 
     $(codec_dir)/enhancer.c \ 
     $(codec_dir)/filter.c \ 
     $(codec_dir)/FrameClassify.c \ 
     $(codec_dir)/gainquant.c \ 
     $(codec_dir)/getCBvec.c \ 
     $(codec_dir)/helpfun.c \ 
     $(codec_dir)/hpInput.c \ 
     $(codec_dir)/hpOutput.c \ 
     $(codec_dir)/iCBConstruct.c \ 
     $(codec_dir)/iCBSearch.c \ 
     $(codec_dir)/iLBC_decode.c \ 
     $(codec_dir)/iLBC_encode.c \ 
     $(codec_dir)/LPCdecode.c \ 
     $(codec_dir)/LPCencode.c \ 
     $(codec_dir)/lsf.c \ 
     $(codec_dir)/packing.c \ 
     $(codec_dir)/StateConstructW.c \ 
     $(codec_dir)/StateSearchW.c \ 
     $(codec_dir)/syntFilter.c 
  
 LOCAL_C_INCLUDES += $(common_C_INCLUDES) 
  
 LOCAL_PRELINK_MODULE := false 
  
 include $(BUILD_STATIC_LIBRARY) 
  
 # Build JNI wrapper 
 include $(CLEAR_VARS) 
  
 LOCAL_MODULE := libilbc-codec #產生的 .so庫名,可以自行修改  
 LOCAL_C_INCLUDES += \ 
     $(JNI_H_INCLUDE) \ 
     $(codec_dir) 
  
 LOCAL_SRC_FILES := ilbc-codec.c 
 LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 
  
 LOCAL_STATIC_LIBRARIES := libilbc 
 LOCAL_PRELINK_MODULE := false 
  
 include $(BUILD_SHARED_LIBRARY) 

4. 程式碼分析:
      開啟jni 檔案夾下的 ilbc-codec.c 檔案,裡面總共只有五個函數,負責音訊轉碼器的初始化,以及音訊編碼和解碼。其中的三個方法:
jint Java_com_googlecode_androidilbc_Codec_init( 
        JNIEnv *env, jobject this, jint mode) 
和 
 
jint Java_com_googlecode_androidilbc_Codec_encode( 
        JNIEnv *env, jobject this, 
        jbyteArray sampleArray, jint sampleOffset, jint sampleLength, 
        jbyteArray dataArray, jint dataOffset) 
和 
jint Java_com_googlecode_androidilbc_Codec_decode( 
        JNIEnv *env, jobject this, 
        jbyteArray dataArray, jint dataOffset, jint dataLength, 
        jbyteArray sampleArray, jint sampleOffset) 
根據這三個函數的名稱就可以知道,使用來讓 Java層代碼調用的三個函數,現在我們對這三個函數進行改造(僅僅是換個函數名稱而已)

5. 寫Java層native 方法:
   在程式的Java層代碼中,建立一個包,用於放 NDK 的java層代碼,比如我建一個名為 xmu.swordbearer.audio 的包,裡面建立一個類:
   AudioCodec.java ,在這個類中只負責對底層C函數進行調用,相當於一個工具類。建立三個 public staic native int 方法:
package xmu.swordbearer.audio; 
 
public class AudioCodec { 
    // initialize decoder and encoder 
    public static native int audio_codec_init(int mode); 
 
    // encode 
    public static native int audio_encode(byte[] sample, int sampleOffset, 
            int sampleLength, byte[] data, int dataOffset); 
 
    // decode 
    public static native int audio_decode(byte[] data, int dataOffset, 
            int dataLength, byte[] sample, int sampleLength); 

三個方法分別用於初始化,音頻編碼,音頻解碼,在這裡只需聲明為 native 方法,不用寫任何代碼;
6. 編譯.h 標頭檔:(如果不會,請參考之前的文章)
   開啟終端,定位到第 5步建立的 AudioCodec.java 目錄下,如下:

   這一步很關鍵,進入到src目錄後,就要帶上 AudioCodec 這個類的包名,此例中的包名為: xmu.swordbearer.audio如果上述步
驟正確,就會在該包下產生一個 xmu_swordbearer_audio_AudioCodec.h 的標頭檔,內容如下:
/*
 * Class:     xmu_swordbearer_audio_AudioCodec
 * Method:    audio_codec_init
 * Signature: (I)I
 */ 
JNIEXPORT jint JNICALL Java_xmu_swordbearer_audio_AudioCodec_audio_1codec_1init 
  (JNIEnv *, jclass, jint); 
 
/*
 * Class:     xmu_swordbearer_audio_AudioCodec
 * Method:    audio_encode
 * Signature: ([BII[BI)I
 */ 
JNIEXPORT jint JNICALL Java_xmu_swordbearer_audio_AudioCodec_audio_1encode 
  (JNIEnv *, jclass, jbyteArray, jint, jint, jbyteArray, jint); 
 
/*
 * Class:     xmu_swordbearer_audio_AudioCodec
 * Method:    audio_decode
 * Signature: ([BII[BI)I
 */ 
JNIEXPORT jint JNICALL Java_xmu_swordbearer_audio_AudioCodec_audio_1decode 
  (JNIEnv *, jclass, jbyteArray, jint, jint, jbyteArray, jint); 
第4步中分析的三個方法修改,開啟jni 下的 ilbc-codec.c 檔案,,把那三個名稱分別用剛剛產生的這三個方法名替換,具體對應如下:
Java_com_googlecode_androidilbc_Codec_init 
改為: 
Java_xmu_swordbearer_audio_AudioCodec_audio_1codec_1init 
 
Java_com_googlecode_androidilbc_Codec_encode 
改為: 
Java_xmu_swordbearer_audio_AudioCodec_audio_1encode 
 
Java_com_googlecode_androidilbc_Codec_decode 
改為: 
Java_xmu_swordbearer_audio_AudioCodec_audio_1decode 
僅是一個 複製,粘貼的過程!!!
當然,如果你寫的JAVA代碼的包名或者方法名不一樣,那產生的 .h 檔案中的方法也就不一樣,這就是為什麼編譯好一個.so庫後,不能隨
便修改 native方法所在類的包名,因為方法名會也就改變了.

7. 編譯 .so 庫
    下來就是要編譯產生 .so 庫了,正如上面Android.mk檔案中寫的,最終編譯產生的庫是 libilbc-codec.so,編譯方法如下:
     開啟終端,定位到 jni 檔案夾下面,輸入 ndk-build ,斷行符號,會看到如下情景:
    
   看到倒數第二行了嗎? libs/armeabi/libilbc-codec.so ,說明已經產生了我們需要的動態庫,這時你會發現在工程的根目錄下多了一個libs 的
檔案夾,裡面有個armeabi 目錄,開啟後就有一個 libilbc-codec.so 的檔案:

     
得到這個庫之後,我們所有與底層有關的工作全部完成,被Linux 虐了的人可以馬上轉戰Windows下,後續工作已經不需要在Liunx下進行了。
OK ,庫編譯完成了,後續將會示範音訊採集以及如何通過Java來調用 底層編解碼 函數。

8.總結:
     光這個編譯過程我研究了兩天才跑通,就像上一篇所提到的,開始使用同學給的demo,儘管可以運行,但是程式的擴充性不好,你不可
能寫個程式後,裡面還夾雜一個詭異的包名,而這個包名你連碰都不敢碰,再加上各種代碼的嵌套,總結了一句話----自己動手,豐衣足食!
 經過幾番研究後,對Android.mk 檔案的編寫積累了一些經驗,NDK 編譯過程逐漸順手,現在可以任意修改自己的代碼,如果哪裡需要改
進,就可以直接該代碼,重新編譯一個 .so 庫出來,甚至這個庫隨便用在其他程式中都可以。
   Android NDK 的確提供了一個非常好的平台,從做視頻時的FFMPEG移植,到現在的ILBC庫的移植,用的都是C代碼,以後如果轉戰到
遊戲開發,說不定會有更廣闊的天地.
   整整花了三個小時來寫這片文章,因為自己也是剛剛學會,一邊寫代碼,一邊又去看 ilbc源碼,從頭到尾順了一遍,ilbc真正的代碼就是幾
千行,不多,但是精。要想掌握得花一定的時間。目前這系列教程只是完成了底層的開發,接下來將完善整個系統,文章中有寫的不好的,希
望多多指教,互相學習!

--------------------------------

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.