android 语音识别 语音手电(一)

一,语音识别库 cmu-pocketsphinx

        当然要用现成的语音识别库了,自己的水平离开发语音识别库还远的很呢。网上搜索找到卡内基梅龙大学的开源语音项目,好象是李开复创办的项目。有JAVA实现,有C语言实现,pocketsphinx是专为嵌入式开发的轻便型C语言实现版本。而且已经有Android版本,所以语音识别库就选它了。


要做语音识别需要几样东西:

1.  程序代码。
2.  声学模型文件。应该是声音与音素的对应关系。为一个文件夹。
3.  词典文件。音素与字词的对应关系。是一个文件 。
4.  语言模型。词与句子的对应关系。一个文件 。我只是想用来做简单命令词的识别,应该没用,不过好象不加载语言模型文件不能运行。

        程序用官网上的pocketsphine_continuous.exe,声学模型文件与用官网的中文声学模型,词典和语言模型先用网上搜的某博客下载的一个很小词汇量的,在命令行指定声学模型字典和语言模型后可以运行了,但识别出来的是乱码,说不同的话显示不同的乱码,相同的话显示相同的乱码,猜想可能是编码不对,把字典和语言模型文件都改成GB2312的,就可以正确识别与显示了.

      自己的词典和语言模型用在线生成方法生成,但是中文的词典不能生成,要手工从官网的某个中文词典中复制音素,还要注意词典和语言模型文件 的编码,在windows 下都用GB2312可以显示中文,估计Andriod下要转成UTF8。在windows下测试成功,识别率感觉还不错。

        现在只是依葫芦画漂,还没有深入学习。比如上面的文件中,对于小词汇量,文件都很小,但声学模型比较大,不知道有什么方法减小没有,也不知道自己训练声学模型会不会小点,再说训练好象比较麻烦,自己不定能精力有能力训练声学模型。再有就是以上数据是以文件形式加载的,Android APK中打包文件在NDK中使用好象也不是太方便,将来不知道能不能直接人内存加载,这样就少方便些了。


        语音识别模块开发,先在PC环境把语音模块的代码完成,调试好,再到NDK环境下编译,在NDK用要用的模块文件中除了pocketsphinx库关相的别的东西都不使用,减少依赖。本模块直接用pocketsphinx的语音识别程序pocketsphine_continuous.exe的源码continuous.c修改,这个程序在命令行指定声学模型、字典和语言模型后就可以进行语音识别。

我们把涉及到语音识别的代码提取出来到一个单独文件speech.c中,做成三个函数,

一个初始化函数speech_init(const char * model_path);

一个反初始化函数speech_uninit();

一个不停提供音频数据的函数speech_feed(short * data,int len);

        语音识别就在speech_feed这个函数中完成,将来这个函数再去回调JAVA,把识别出来的语音反回到JAVA代码。基本就是代码复制,没什么技术含量。音频读取代码还在原来的文件中。这样就实现了和原来pocketsphine_continuous.exe功能一样的程序。整个程序开发在VS Express 2013 for Desktop中完成,用自己改写的代码测试,可以正确识别,和原来的官网程序一模一样.

    然后到NDK是编译speech.c基本上没什么问题,很容易就成功了。

基本代码如下:

static ps_decoder_t *ps;
static cmd_ln_t *config;
static inited = 0;

int speech_init(const char * data_path)
{
	char hmm[256] = "";
	char lm[256] = "";
	char dict[256] = "";
	strcat(hmm, data_path);
	strcat(hmm, "/tdt_sc_8k");
	strcat(lm, data_path);
	strcat(lm, "/light.lm");
	strcat(dict, data_path);
	strcat(dict, "/light.dic");
	config = cmd_ln_init(NULL, ps_args(), TRUE,"-hmm", hmm,"-lm",lm,"-dict", dict,NULL);
	LOGI("speech_init hmm--->%s", (const char *)hmm);
	LOGI("speech_init lm--->%s", (const char *)lm);
	LOGI("speech_init dict--->%s", (const char *)dict);
	ps_default_search_args(config);
	ps = ps_init(config);
	if (ps == NULL) {
		cmd_ln_free_r(config);
		return -1;
	}
	if (ps_start_utt(ps) < 0)
	{
		printf("Failed to start utterance\n");
		return -1;
	}
	inited = 1;
	return 0;
}

int speech_uninit()
{
	if (ps!=NULL)
		ps_free(ps);
	cmd_ln_free_r(config);
	return 0;
}

int speech_feed(const short * buf, int len)
{
	static char utt_started = FALSE;
	char in_speech = 0;
	char const *hyp;
	if (inited != 1)
		return -1;
	ps_process_raw(ps, buf, len, FALSE, FALSE);
	in_speech = ps_get_in_speech(ps);
	if (in_speech && !utt_started) {
		utt_started = TRUE;
		//printf("Listening...\n");
	}
	if (!in_speech && utt_started) {
		/* speech -> silence transition, time to start new utterance  */
		ps_end_utt(ps);
		hyp = ps_get_hyp(ps, NULL);
		if (hyp != NULL)
		{
			//LOGI("speech:%s", (const char *)hyp);
			CallBack_Java(hyp); //printf("%s\n", hyp);
		}
		ps_start_utt(ps);

		utt_started = FALSE;
		//printf("READY....\n");
	}

	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值