开源语音格式speex教程(for IOS)

翻译 2013年12月04日 11:36:29

原文地址:http://www.cocoachina.com/bbs/read.php?tid=114755&keyword=speex

这两天在折腾语音的东西,实现类似微信上对讲机的功能,做了两个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) 下载次数:841  speex-1.2rc1.tar (3890 K) 下载次数:767   

因为编译是在命令行模式下进行的,打开终端,首先进入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) 下载次数:737 



下面开始我们的工程:

新建一个工程,导入我们的静态库,我是将包直接拖到工程里面的,记得设置静态库的查找路径,我当时就是忘了设置路径,结果就是各种找不到头文件。导入完以后就进入主题了。



为了方便我已经录好一个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) 下载次数:1763 希望对大家有帮助




----------------------------------------------------------------------------------------------------------------------------2012.12.30----------------------------------------------------------------------------------------------------------

本想好好深入写下Speex的Demo,不过本人也就研究了一个多礼拜而已,知道可能还不如大家多。现在也抽不出系统的时间再去研究了,很多问题因为实力有限无法回答,请大家见谅。另外网上搜到一本讲Core Audio的好书,当然是英文的,分享给大家。  Learn Core Audio.pdf.zip (8034 K) 下载次数:212 


----------------------------------------------------------------------------------------------------------------------------2013.06.28----------------------------------------------------------------------------------------------------------

没想到这篇帖子的点击量突破2万了,实感意外,最近在赶项目所以很少再更新了,后续也许也不会再更新了。现在项目用的AMR格式的音频,和Android兼容的比较好,而Speex版本的本人也做了一份。因为涉及到公司的保密问题,这里就不共享代码了。如果想实现实录实转的话,用偏底层的音频队列在回调函数中对数据进行转换就可以了。其实理解了原理的话,也不是很难的事情。官方代码推荐SpeakHere,音频队列用的很好。



----------------------------------------------------------------------------------------------------------------------------提问汇总----------------------------------------------------------------------------------------------------------


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

其实对应的参数值,对应一定比特率,这个详细请参考手册。

开源语音格式speex教程-IOS

这两天在折腾语音的东西,实现类似微信上对讲机的功能,做了两个Demo,一种使用lib-amr库用amr格式实现的,这个网上有现成的教程,所以还是比较好实现的。另一个是用的speex库,这个提的人很多,...
  • gyley2
  • gyley2
  • 2013年01月05日 17:25
  • 1261

IOS开发之使用Speex格式实现简单的语音聊天功能(一)

语音技术近来可是出bian'l
  • shenjie12345678
  • shenjie12345678
  • 2014年10月10日 14:25
  • 22193

Speex语音压缩与解压在Android上的实现

由于项目需要做语音降噪处理,最近做了这方面的研究。但结果却没有达到,反而却学得了基于Speex的语音压缩和解压,也算没有白白浪费时间(300K的语音文件经过Speex压缩后文件大小变为了30K左右,对...
  • wangjiang_qianmo
  • wangjiang_qianmo
  • 2015年09月06日 17:48
  • 4368

开源语音格式speex教程(for IOS)

这两天在折腾语音的东西,实现类似微信上对讲机的功能,做了两个Demo,一种使用lib-amr库用amr格式实现的,这个网上有现成的教程,所以还是比较好实现的。另一个是用的speex库,这个提的人很多,...
  • logcabin
  • logcabin
  • 2013年01月16日 13:58
  • 549

开源语音格式speex教程(for IOS)

转自:http://www.cocoachina.com/bbs/read.php?tid=114755 这两天在折腾语音的东西,实现类似微信上对讲机的功能,做了两个Demo,一种使用lib...
  • leonpengweicn
  • leonpengweicn
  • 2012年09月06日 09:54
  • 726

开源语音格式speex教程(for iOS)

为实现类似微信上的对讲机功能,做了两个Demo。一种使用lib-amr库,用amr格式实现。另一个用的是speex库,这个提的人很多,但是出教程的不多,大家有很多不明所以的地方,新手对此较 ...
  • billfanggs
  • billfanggs
  • 2012年11月06日 13:32
  • 395

开源语音格式speex教程(for IOS)

这两天在折腾语音的东西,实现类似微信上对讲机的功能,做了两个Demo,一种使用lib-amr库用amr格式实现的,这个网上有现成的教程,所以还是比较好实现的。另一个是用的speex库,这个提的人很多,...
  • l241002209
  • l241002209
  • 2013年05月29日 17:33
  • 755

开源语音格式speex教程

本文由社区会员cxjwin分享 这两天在折腾语音的东西,实现类似微信上对讲机的功能,做了两个Demo,一种使用lib-amr库用amr格式实现的,这个网上有现成的教程,所以还是比较好实现的。另一...
  • meegomeego
  • meegomeego
  • 2012年09月28日 22:37
  • 688

IOS开发之使用Speex格式实现简单的语音聊天功能(二)

今天我们继续上一篇博客“IOS开发之使用Speex格式实现简单的语音聊天功能(一)”继续往下讲,主要是讲述一下PlayManager与RecorderManager两个类的功能。 首先要讲的是Rec...
  • shenjie12345678
  • shenjie12345678
  • 2014年10月15日 14:39
  • 6384

IOS开发之使用Speex格式实现简单的语音聊天功能(一)

分类: IOS开发 语音 仿聊天2014-10-10 14:25 4301人阅读 评论(2) 收藏 举报 聊天speexios语音聊天ogg [objc] view p...
  • zlyapple
  • zlyapple
  • 2015年09月11日 13:22
  • 861
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:开源语音格式speex教程(for IOS)
举报原因:
原因补充:

(最多只允许输入30个字)