一. 语音库及SWIG
安装
从
http://sourceforge.net/projects/cmusphinx/files/
,
下载sphinxbase-0.8
.tar.gz和
pocketsphinx-0.8.tar.gz放在同一个目录下,开始安装。
1. 安装sphinxbase
安装,
tar -xzf sphinxbase-0.8
.tar.gz
cd sphinxbase-0.8
./configure
make
sudo make install
默认安装在/usr/local/bin下面。
2.安装pocketsphinx
安装,
tar -xzf
pocketsphinx-0.8.tar.gz
cd pocketsphinx-0.8
./configure
make
sudo make install
安装得到的库信息文件*.pc默认在/usr/local/lib/pkgconfig下,共享库*.so默认在/usr/local/lib下,因此要配置环境,
sudo gedit /etc/bash.bashrc
在文件尾添加export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
sudo gedit /etc/ld.so.conf.d/sphinx.conf
在文件尾添加/usr/local/lib,再执行,
sudo ldconfig
3. 验证语音库
安装完
sphinxbase
和
pocketsphinx后
,在/usr/local/bin下面可以看到以下三个文件,
pocketsphinx_batch
pocketsphinx_continuous
pocketsphinx_mdef_convert
测试下安装结果,
./pocketsphinx_continuous
如果运行没有error,则表示成功。
为了后面Android离线语音demo的编译,需要把解压出来的文件夹
sphinxbase-0.8
和
pocketsphinx-0.8的版本号去掉,变成
sphinxbase
和
pocketsphinx。
4. 安装SWIG
需要安装swig软件,
据说
不支持2.0以上的版本,所以下载swig-1.3.34.tar.gz到~/temp,解压,进入解压目录,
./configure
make
sudo make install
实际上,我用sudo apt-get install swig安装了2.0版本,好像也在后面的编译成功过。
二. 编译Demo
1.
先到
sphinxbase
和
pocketsphinx的父目录,检查/
pocketsphinx/swig目录下是否有libpocketsphinx_jni.so文件,如果没有则需要编译。在该文件夹下直接make即可,但make一般不会通过,会出现如下错误,
fatal error: jni.h: No such file or directory 或
fatal error: jni_md.h: No such file or directory
你需要修改该目录下的Makefile,将其中CPPFLAGS对应的内容改为,
-I$YouJavaHome/include/ -I$YouJavaHome/include/linux/
才可以make通过,生成
libpocketsphinx_jni.so共享库文件(
$YouJavaHome指的是你的JDK安装路径
)。
2.
下载PocketSpinxAndroiDemo, http://ucla.jamesyxu.com/custom_uploads/PocketSphinxAndroidDemo.zip
。解压到
sphinxbase
和
pocketsphinx的父目录下(这三个文件夹现在同一目录了),然后,
cp -r ./pocketsphinx/swig/edu ./PocketSphinxAndroidDemo/jni/
cd ./PocketSphinxAndroidDemo/jni/
修改
Android.mk,将文件中
SPHINX_PATH修改为
sphinxbase
和
pocketsphinx的父目录(注意,一定要用绝对路径!),
将LOCAL_STATIC_LIBRARIES的内容改成pocketsphinx sphinxlm sphinxfeat sphinxfe sphinxutil(据说这样可以解决stack overflow问题)。
为了生成适应多个平台的.so文件,在/PocketSphinxAndroidDemo/
jni目录下添加一个Application.mk文件,在文件中添加以下语句,
APP_ABI := armeabi armeabi-v7a x86
然后,在当前目录下执行,
ndk-build
这样就生成了3个不同平台下的.so文件。
3.
打开eclipse,导入
PocketSpinxAndroiDemo,然后修改
Project -> Properties -> Builders:
3.1 Select SWIG -> Edit -> for Working Directory, select Browse Workspace and pick the jni directory, In the Refresh tab, select The folder containing the selected resource, in Build Options, untick Specify working set of relevant resources (This option may be hidden in the dialog, if you dont see it, maximize the Configuration window).
3.2
Select NDK build -> Edit -> Set the correct location for ndk-build, select the correct Working directory (Browse workspace and then select the jni directory). In the Refresh tab, select The project containing the selected resource, in Build Options, untick Specify working set of relevant resources (This option may be hidden in the dialog, if you dont see it, maximize the Configuration window).
以上设置后,还会出现找不到AVD设备等错误,这个只要去
Project -> Properties ->
Android下设置一下Android API level(设置成你用的API level)就可以了
。
之后,是一个困扰我时间最长的错误——
Nbest.java在
Build Project时一直报错说什么什么没定义,尝试了很久都没法解决。最后,直接把
PocketSphinxAndroidDemo/jni/edu
下
Nbest.java
这个文件删除掉,再
Build Project,
没想到竟然可以了!这样编译在Console下会有红色的警告,但这个貌似影响不大~
三. 真机调试Demo
打开手机的USB调试功能,用USB连接至电脑。
先看
RecognizerTask.java文件的代码,
public RecognizerTask() {
pocketsphinx
.setLogfile(
"/sdcard/Android/data/edu.cmu.pocketsphinx/pocketsphinx.log")
;
Config c = new Config()
;
/*
* In 2.2 and above we can use getExternalFilesDir() or whatever it's
* called
*/
c.setString(
"-hmm",
"/sdcard/Android/data/edu.cmu.pocketsphinx/hmm/en_US/hub4wsj_sc_8k")
;
c.setString(
"-dict",
"/sdcard/Android/data/edu.cmu.pocketsphinx/lm/en_US/hub4.5000.dic")
;
c.setString(
"-lm",
"/sdcard/Android/data/edu.cmu.pocketsphinx/lm/en_US/hub4.5000.DMP")
;
/*
c.setString("-hmm",
"/sdcard/Android/data/edu.cmu.pocketsphinx/hmm/zh/tdt_sc_8k");
c.setString("-dict",
"/sdcard/Android/data/edu.cmu.pocketsphinx/lm/zh_TW/mandarin_notone.dic");
c.setString("-lm",
"/sdcard/Android/data/edu.cmu.pocketsphinx/lm/zh_TW/gigatdt.5000.DMP");
*/
c.setString(
"-rawlogdir",
"/sdcard/Android/data/edu.cmu.pocketsphinx")
;
c.setFloat(
"-samprate",
8000.
0)
;
c.setInt(
"-maxhmmpf",
2000)
;
c.setInt(
"-maxwpf",
10)
;
c.setInt(
"-pl_window",
2)
;
c.setBoolean(
"-backtrace",
true)
;
c.setBoolean(
"-bestpath",
false)
;
this.ps = new Decoder(c)
;
this.audio = null
;
this.audioq = new LinkedBlockingQueue<short[]>()
;
this.use_partials =
false
;
this.mailbox = Event.NONE
;
}
代码中说得很清楚,需要在手机的/sdcard/Android/data/下添加文件夹edu.cmu.pocketsphinx,并在该文件夹下创建两个文件夹lm和hmm,将pocketsphinx/model/hmm下的en_US文件夹放进hmm,pocketsphinx/model/lm下的en_US文件夹放进lm。接下来,在eclipse界面下点击运行,选择手机设备,便能在真机上运行了,
如果不改声学模型、语言模型以及字典,识别率是很低的;提高准确率需要该模型,可以参考下面的第4、5条链接的信息,这个需要在下一步去做。
参考:
http://ucla.jamesyxu.com/?p=118(主要参考)
http://blog.csdn.net/aaaeee2011/article/details/12884117
(windows下比较好的参考)
http://www.javaworld.com.tw/jute/post/view?bid=11&id=288677&sty=3
(jni编译头文件找不到的问题)
http://www.cnblogs.com/huanghuang/archive/2011/07/14/2106579.html
(
Sphinx参考
)
http://blog.csdn.net/songgeabc/article/details/8570026
(资料整合)