前言
本文介绍如何将htk工具包中HCopy和HDecode工具部署到android手机,从而实现手机端离线语言识别的功能。htk是开源的c语言工具包,在android中 通过NDK来集成该工具包。
NDK环境搭建可参照Andye的博客史上最易懂的Android jni开发资料–NDK环境搭建.讲得很全面。这里就不再重复
HCopy工具包
查看HTK中MakeFile文件可知道 HCopy依赖于下列文件
HCopy.c esig_asc.c esignal.c esig_edr.c esig_nat.c HAdapt.c HArc.c HAudio.c HDict.c HExactMPE.c HFB.c HFBLat.c HLabel.c HLat.c HLM.c HMap.c HMath.c HMem.c HModel.c HNet.c HParm.c HRec.c HShell.c HSigP.c HTrain.c HUtil.c HVQ.c HWave.c strarr.c
将这些文件拷贝到jni目录中。并且修改Android.mk文件:
1 |
LOCAL_PATH := $(call my-dir) |
Build一下即可完成对HCopy源码的编译并在obj/local/armeabi/目录下生成 libTestNdk.so文件 在需要调用该动态库的类中添加如下代码即可:
1 |
static { |
当然HCopy适合在linux终端环境下使用,在实际工程中,需要修改HCopy源码。使他能够对多个文件连续提取特征而只执行一次初始化工作。
首先将HCopy中 main 函数初始化部分全部移动到 HCopyInit 函数中,并将OpenSpeechFile和PutTargetFile等提取特征函数移动到HCopyWhile 函数中。
然后再jni接口函数中调用他即可。
1 |
int argc=5; |
HDecode工具包
通过查看HDecode中的Makefile文件可知道HDecode的依赖文件,同时编译HDecode需要携带参数-DNO_LAT_LM,基于此在Android.mk文件中添加如下内容:
1 |
include $(CLEAR_VARS) |
并将相应文件拷贝到jni文件夹中。Build一下即可完成对HDecode源码的编译并在obj/local/armeabi/目录下生成 libTestHDNdk.so文件 在需要调用该动态库的类中添加如下代码即可:
1 |
static { |
同样HDecode适合在linux终端环境下使用,在实际工程中,需要修改HDecode源码。参照HCopy修改方法即可完成。
1 |
int argc=27; |
识别结果
在实际工程中,将手机录制的音频保存到/hucd/a.wav中,并依次调用HCopyDoFile和HDecodeDoFile函数即可在生成的/hucd/out文件中找到识别结果。
由于android 环境中一般并不存在gunzip等工具,因此不要尝试在hdecode.hlda.cfg使用Fillter,如有 HLANGMODFILTER = ‘gunzip -c $.gz’类似配置 请去掉,并使用未压缩的语言模型。