開源語音格式speex教程(for IOS)

來源:互聯網
上載者:User

這兩天在折騰語音的東西,實作類別似上對講機的功能,做了兩個Demo,一種使用lib-amr庫用amr格式實現的,這個網上有現成的教程,所以還是比較好實現的。另一個是用的speex庫,這個提的人很多,但是出教程的不多,恨透那個愛圖騰的教程了,很多不明所以的地方,讓我們這些新手很困惑呀,網上晃了3天終於可以搞出個像樣的Demo了。Demo中我將一個錄好的.caf格式的PCM音頻
編碼成speex格式 然後將speex格式的再轉回PCM。當然Demo只是實現了音訊編碼解碼,並沒有增加過多的功能。
本人測試了下,60秒的錄音(8khz,單聲道),轉成最小格式的amr大小為39k和一分鐘錄音檔案的大小差不多,speex格式最小18k但是比較模糊,可以接受的大小是30k,所以還是會比amr格式的小點,另外speex庫可以對聲音進行比如降噪,增益,靜音判定等處理。但是考慮到Android支援amr格式的音頻,wp也支援,所以最後還是選了轉成amr格式的方案,可惜apple現在已經不支援amr了,所以才需要轉碼,下面我就和大家一起一步一步做Demo。


編譯靜態庫:
這個著實讓我費解了一天,其實linux下的C/C++程式員搞這個應該很輕鬆,但是我的那些都還給老師了,按照網上的教程愣是折騰了很久。
首先下載你所需要的源檔案,因為speex是依賴ogg庫的,所以先下載ogg庫,這裡我一併打包上傳了,大家也可以去官網上下載。
源檔案:
libogg-1.3.0.zip (496 K) 下載次數:600 speex-1.2rc1.tar
(3890 K) 下載次數:558   
因為編譯是在命令列模式下進行的,開啟終端,首先進入ogg所在的檔案夾,我們先編譯ogg
補充下,我用的是xcode4.4.1,大家根據自己xcode命令也需要略微調整,4.2的編譯教程網上有,這裡我就不重複了。
在終端鍵入以下內容:
1.ogg-i386的庫
./configure -prefix=/Users/你的電腦使用者名稱/Desktop/speexLibrary/libogg-1.3.0/i386 -host=i386-apple-darwin -build=x86_64-apple-darwin11.3.0 CC="/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2
-std=c99 -arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/"


make
make install
make clean (一定要clean,不然後面編譯的都是第一次的編譯的內容)
2、ogg-armv6的庫
./configure -prefix=/Users/你的電腦使用者名稱/Desktop/speexLibrary/libogg-1.3.0/armv6 -host=armv6-apple-darwin -build=x86_64-apple-darwin11.3.0 CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2
-std=c99 -arch armv6 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/"


make
make install
make clean 


3、ogg-armv7的庫
./configure -prefix=/Users/你的電腦使用者名稱/Desktop/speexLibrary/libogg-1.3.0/armv7 -host=armv7-apple-darwin
-build=x86_64-apple-darwin11.3.0 CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2 -std=c99 -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/"


make
make install
make clean


接著編譯speex庫:
1.speex-i386的庫
./configure -prefix=/Users/你的電腦使用者名稱/Desktop/speexLibrary/speex-1.2rc1/i386 -host=i386-apple-darwin
-disable-shared -enable-static -disable-oggtest -disable-fixed-point -enable-float-api -build=x86_64-apple-darwin11.3.0 -with-ogg=/Users/你的電腦使用者名稱/Desktop/speexLibrary/libogg-1.3.0/i386
CC="/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2 -std=c99 -arch i386 -isysroot/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/"


make
make install
make clean 


2.speex-armv6的庫
./configure -prefix=/Users/你的電腦使用者名稱/Desktop/speexLibrary/speex-1.2rc1/armv6 -host=armv6-apple-darwin
-disable-shared -enable-static -disable-oggtest -enable-fixed-point -disable-float-api -build=x86_64-apple-darwin11.3.0 -with-ogg=/Users/你的電腦使用者名稱/Desktop/speexLibrary/libogg-1.3.0/armv6
CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2 -std=c99 -arch armv6 -isysroot/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/"


make
make install
make clean


3.speex-armv7的庫
./configure -prefix=/Users/你的電腦使用者名稱/Desktop/speexLibrary/speex-1.2rc1/armv7 -host=armv7-apple-darwin
-disable-shared -enable-static -disable-oggtest -enable-fixed-point -disable-float-api -build=x86_64-apple-darwin11.3.0 -with-ogg=/Users/你的電腦使用者名稱/Desktop/speexLibrary/libogg-1.3.0/armv7
CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2 -std=c99 -arch armv7 -isysroot/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/"


make
make install
make clean 


最後合并靜態庫,進入speexLibrary檔案夾,終端鍵入:
lipo -create i386/lib/libogg.a armv6/lib/libogg.a armv7/lib/libogg.a -output libogg.a
lipo -create i386/lib/libspeex.a armv6/lib/libspeex.a armv7/lib/libspeex.a -output libspeex.a
lipo -create i386/lib/libspeexdsp.a armv6/lib/libspeexdsp.a armv7/lib/libspeexdsp.a -output libspeexdsp.a 


好了,這裡應該已經編譯完成了。如果合并靜態庫不成功,那麼請檢查上述步驟(我當時就是忘了make clean,導致編譯的都是i386的.a檔案).你可以lipo
-info xxx.a檔案,後面會顯示庫內檔案使用的平台資訊,正常顯示為i386,armv6,armv7那麼就成功了。當然打包好的庫我也一併上傳了,方便大家下載。
打包好的speex庫:
_speex.zip (821 K) 下載次數:524



下面開始我們的工程:
建立一個工程,匯入我們的靜態庫,我是將包直接拖到工程裡面的,記得設定靜態庫的尋找路徑,我當時就是忘了設定路徑,結果就是各種找不到標頭檔。匯入完以後就進入主題了。


為了方便我已經錄好一個60秒的.caf檔案,怎麼錄製的?此處省略一千字…
詳細的Demo解釋我就不說明了,大家看Demo,我這裡講一下步驟
1.我們需要從.caf檔案中將檔案頭去掉得到純的PCM資料
2.將純的PCM資料編碼成純speex格式
3.給純speex格式資料添加檔案頭
4.匯出speex檔案(這步我沒做,因為是程式內轉碼所以也不需要,我直接用的NSData。至於speex檔案的尾碼名我也不知道,是ogg?,有知道的補充下)
---------------分割一下-------------
4.解碼speex格式資料(帶檔案頭的)成純PCM格式
5.添加wav格式檔案頭
6.將wav資料寫入檔案匯出caf檔案(匯出的檔案可以在類比下該工程的tmp檔案夾內找到,一個caf檔案,點擊可以播放出聲音).


下面是我給出的Demo,請結合speex官方的使用者手冊對照,使用者手冊上有編碼解碼的C語言範例程式碼,一定要仔細研究。
我的Demo
TEST_Speex_001.zip (1585 K) 下載次數:1211
希望對大家有協助

----------------------------------------------------------------------------------------------------------------------------2012.12.30----------------------------------------------------------------------------------------------------------
本想好好深入寫下Speex的Demo,不過本人也就研究了一個多禮拜而已,知道可能還不如大家多。現在也抽不出系統的時間再去研究了,很多問題因為實力有限無法回答,請大家見諒。另外網上搜到一本講Core Audio的好書,當然是英文的,分享給大家。
Learn Core Audio.pdf.zip (8034 K) 下載次數:136

----------------------------------------------------------------------------------------------------------------------------提問匯總----------------------------------------------------------------------------------------------------------

1.對於真機下面調試出現的問題

Undefined symbols for architecture armv7:
  "_speex_decode", referenced from:
      _DecodeSpeexToWAVE in SpeexCodec.o
     (maybe you meant: _speex_decode_stereo_int, _speex_decode_native , _speex_decoder_init , _speex_decode_int , _speex_decoder_destroy , _speex_decoder_ctl )
  "_speex_encode", referenced from:
      _EncodePCMToRawSpeex in SpeexCodec.o
     (maybe you meant: _speex_encode_stereo_int, _speex_encoder_init , _speex_encoder_ctl , _speex_encoder_destroy , _speex_encode_native , _speex_encode_int )
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

“由於編譯的時候speex_encode和speex_decode這2個方法找不到,我就使用了speex_encode_int和speex_decode_int這兩個方法來替代了,從而其中的參數也改成了spx_int16_t類型”
此方法是按照本站另外一篇文章提供的方法,laniu的文章


2.關於工程的四個警告,因為重複定義,有人嘗試注掉了,可以編譯通過,在此,謝謝!

3.關於int tmp = 1;// bps?
void*encode_state =
speex_encoder_init(&speex_nb_mode);
    speex_encoder_ctl(encode_state,
SPEEX_SET_QUALITY, &tmp);
這一段tmp = 8的時候音質還原比較好,但是壓縮後的檔案也大
個人統計,60秒的錄音
tmp值為:
0 --> 18K
1 --> 30K
2 --> 45K
3 --> 60K
4 --> 60K
5 --> 84K
6 --> 84K
7 --> 114K
8 --> 114K
9 --> 138K
10--> 186K

其實對應的參數值,對應一定位元速率,這個詳細請參考手冊。

轉自:http://www.cocoachina.com/bbs/read.php?tid=114755

相關文章

聯繫我們

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