2016-10-07 21:18:45 sac761 阅读数 20573
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4709 人正在学习 去看看 Frank Lee

本项目做出的产品是一个Windows下的增强现实系统,系统很庞大,产品功能已经基本完善,考虑到给用户带来更好的体验,故综合评估后采用讯飞语音识别方案进行嫁接。

项目介绍:

1)打开系统时启动语音识别,检测到用户说出关键词(如:上一步,下一步,结束等)时,系统自动进行相应的操作;

2)不需要按任何按键进行连续的语音识别控制,延迟为2秒左右;

3)可以识别词语,句子,中文,英文数字字母通吃,不限语速。并且语句结束判断机制很智能;

3)离线!离线!现在做一个基于windows的离线的语音识别系统在网络上还真没谁,讯飞自己也还没有推出这款SDK,我是在讯飞的离线命令词识别SDK开发包上开发出的介于两者之间功能的系统。

为什么用讯飞:

之前使用过语音识别开发版,用驻极体采集声音,通过串口传输信号来进行识别,只能讲开发版只适合用来做个课程设计啥的玩玩,做产品还是太LOW,识别率地下并且识别范围窄,貌似只能识别数字字母;之后调查过汉语语音识别库如Sphinx,Julius,百度语音等。去网上问,很多人推荐这些方案的,我没试过,不过一个SDK也只有自己正真开发过才知道好不好用强不强大,说的再牛逼也是在别人手上玩的转,到你这就不一定了。我用讯飞就是看上它的鲁棒,免费,毕竟是久经考验的平台,讯飞有一个开发者论坛,开发别人的SDK有个社区很重要,不然有问题没地方问。


项目开发经验与源码如下:

一、跑通讯飞离线命令词识别SDK

首先去讯飞官网下载相应SDK,要注册登录,绑定产品才能下载,下载后跑一跑给的demo,跑不通的话去讯飞的论坛找答案。

我用的demo是asr_record_demo,这个demo可以实现的功能是按下R键从mic中录制缓冲音频并按下S键后进行识别。

稍微看一看这个demo中的东西吧,把该删的东西删了,该修整的修整,玩转了demo才能进一步做移植。

二、文件分析与移植

把SDK包中的需要的.lib  .h  .c和所需要的其余文件拷贝到项目相应的文件夹去,最好是分个类,看起来比较清楚。它比较重要的几个文件有以下几个:

msc.lib   讯飞语音离线命令词识别所依赖的库(X64版本为msc_x64.lib)才15KB就能有如此强大的功能。

call.bnf    采用巴科斯范式语法规则的自定义语法库(call是根据自己需要命名的),用来编写语音识别过程中的语法规则,这个语法写的好语音识别更智能。

speech_recognizer.c  基于录音接口和MSC接口封装一个MIC录音识别的模块,SDK的主要文件

winrec.c  封装windows录音,Windows平台下SDK的主要文件


好了,既然demo已经知道怎么用了,把demo所依赖的所有文件和库照搬进自己的项目去,就可以在自己的项目中调用讯飞的函数了(注意头文件和库文件的路径问题)。

三、使用讲解

先看看我的语法文件

call.bnf:


巴科斯范式语法语法文件怎么写在讯飞的论坛里有很多资源自己去看吧,我写的比较简单,写得好的语法可以更加智能。


大致讲讲源码:

为了看起来简洁,我在speech_recognizer.h中做了一个类SR,把主文件中的一些函数定义和一些宏搬进去。

speech_recognizer.h:

class SR {
public:

	const char * ASR_RES_PATH = "fo|res/asr/common.jet";  //离线语法识别资源路径
#ifdef _WIN64
	const char * GRM_BUILD_PATH = "res/asr/GrmBuilld_x64";  //构建离线语法识别网络生成数据保存路径
#else
	const char * GRM_BUILD_PATH = "res/asr/GrmBuilld";  //构建离线语法识别网络生成数据保存路径
#endif
	const char * GRM_FILE = "call.bnf"; //构建离线识别语法网络所用的语法文件

	int build_grammar(UserData *udata);//构建语法
	int run_asr(UserData *udata);//启动引擎

};
speech_recognizer.c:

#pragma comment(lib,"../../lib/msc_x64.lib") //x64
#else
#pragma comment(lib,"XXXXXX/lib/msc.lib") //x86
#endif
这里的库目录要注意,用相对路径可能找不到文件,可以使用绝对路径

#ifdef _WIN64
<pre name="code" class="cpp">static int update_format_from_sessionparam(const char * session_para, WAVEFORMATEX *wavefmt)
{
	char *s;
	/*if ((s = strstr(session_para, "sample_rate"))) {
		if (s = strstr(s, "=")) {
			s = skip_space(s);
			if (s && *s) {
				wavefmt->nSamplesPerSec = atoi(s);
				wavefmt->nAvgBytesPerSec = wavefmt->nBlockAlign * wavefmt->nSamplesPerSec;
			}
		}
		else
			return -1;
	}
	else {
		return -1;
	}*/

	return 0;
}


如果加到讯飞提供的demo使用的是VS2010如果放到VS2015中就会出一些语法上的错,自己看着改一改,比如上面这个函数,是更新用户词典用的,我不需要但是又存在语法错误,就把它的内容直接注释掉得了。

我的项目的主文件中:

首先定义几个宏:

UserData asr_data;//语音识别用户配置
speech_rec asr;//麦克风输入存储结构体
SR sr;//语音识别实体
string SPEAKER="";//用于缓存语音识别内容
在程序初始化处配置如下:

openVoiceRecognizer = true;//语音识别开关
	if (openVoiceRecognizer)
	{
		const char *login_config = "appid = XXXXX"; //登录参数
		int ret = 0;


		ret = MSPLogin(NULL, NULL, login_config); //第一个参数为用户名,第二个参数为密码,传NULL即可,第三个参数是登录参数
		if (MSP_SUCCESS != ret) {
			printf("登录失败:%d\n", ret);
			openVoiceRecognizer = false;
		}


		memset(&asr_data, 0, sizeof(UserData));
		printf("构建离线识别语法网络...\n");
		ret = sr.build_grammar(&asr_data);  //第一次使用某语法进行识别,需要先构建语法网络,获取语法ID,之后使用此语法进行识别,无需再次构建
		if (MSP_SUCCESS != ret) {
			printf("构建语法调用失败!\n");
			openVoiceRecognizer = false;
		}


		while (1 != asr_data.build_fini)
			_sleep(300);
		if (MSP_SUCCESS != asr_data.errcode)
			_sleep(300);
		printf("离线识别语法网络构建完成,开始识别...\n");
		ret = sr.run_asr(&asr_data);//预启动语音识别引擎
	}
在初始化这里我修改了 sr.run_asr(&asr_data);这个函数,我把它调用的sr_start_listening(&asr);函数抽离出来,不让它启动识别引擎而只让它预启动,把所有结构体,变量先初始化待命。

void recognize_mic(const char* session_begin_params)  //根据自己项目需要写的语音识别预热函数
{
	int errcode;
	HANDLE helper_thread = NULL;

	struct speech_rec_notifier recnotifier = {
		on_result,
		on_speech_begin,
		on_speech_end
	};
	errcode = sr_init(&asr, session_begin_params, SR_MIC, DEFAULT_INPUT_DEVID, &recnotifier);
	if (errcode) {
		printf("speech recognizer init failed\n");
		return;
	}

	/*	while (1) {
			errcode = sr_start_listening(&asr);//我把它调用的sr_start_listening(&asr);函数抽离出来,不让它启动识别引擎而只让它预启动,把所有结构体,变量先初始化待命。
		}

	exit:
		sr_uninit(&asr);*/
}

int SR::run_asr(UserData *udata)
{
	char asr_params[MAX_PARAMS_LEN] = { NULL };
	const char *rec_rslt = NULL;
	const char *session_id = NULL;
	const char *asr_audiof = NULL;
	FILE *f_pcm = NULL;
	char *pcm_data = NULL;
	long pcm_count = 0;
	long pcm_size = 0;
	int last_audio = 0;
	int aud_stat = MSP_AUDIO_SAMPLE_CONTINUE;
	int ep_status = MSP_EP_LOOKING_FOR_SPEECH;
	int rec_status = MSP_REC_STATUS_INCOMPLETE;
	int rss_status = MSP_REC_STATUS_INCOMPLETE;
	int errcode = -1;
	int aud_src = 0;

	//离线语法识别参数设置
	_snprintf(asr_params, MAX_PARAMS_LEN - 1,         //<span style="font-family: Arial, Helvetica, sans-serif;">离线语法识别参数根据自己的需要进行更改</span>

		"engine_type = local, \
		asr_res_path = %s, sample_rate = %d, \
		grm_build_path = %s, local_grammar = %s, ",
		sr.ASR_RES_PATH,
		SAMPLE_RATE_16K,
		sr.GRM_BUILD_PATH,
		udata->grammar_id
		);

	recognize_mic(asr_params);
	return 0;
}
而后是三个语音识别的中间过程和结果处理的函数:

void on_result(const char *result, char is_last)   //根据自己的需要写结果处理
{
	char *p = "上一步";
	char *pq = "下一步";
	char *q = "扫频仪操作演示";
	char *end1 = "结束";
	char *end2 = "退出";
	if (strstr(result, p)) {
		SPEAKER = "上一步";	
	}
	else if (strstr(result, pq)) {
		SPEAKER = "下一步";
	}
	else if (strstr(result, q)) {
		SPEAKER = "扫频仪操作演示";
	}
	else if (strstr(result,end1)|| strstr(result, end2)) {
		SPEAKER = "退出";
	}
	cout << SPEAKER << endl;
}
void on_speech_begin()
{
	if (g_result)
	{
		free(g_result);
	}
	g_result = (char*)malloc(BUFFER_SIZE);
	g_buffersize = BUFFER_SIZE;
	memset(g_result, 0, g_buffersize);

	printf("Start Listening...\n");
}
void on_speech_end(int reason)
{
	if (reason == END_REASON_VAD_DETECT)
		printf("\nSpeaking done \n");
	else
		printf("\nRecognizer error %d\n", reason);
}
最后就是在自己项目哪里需要语音识别就在哪里抛出缓冲线程启动识别引擎:

if (openVoiceRecognizer) {
		
		sr_start_listening(&asr);//抛出缓冲线程进行语音识别

		if (SPEAKER=="下一步") {
			keyPressed(' ');
		}
		else if (SPEAKER == "上一步") {
			keyPressed('b');
		}
		else if (SPEAKER == "扫频仪操作演示") {
			keyPressed('1');
		}
		else if (SPEAKER=="退出") {
			std::exit(0);
		}
		SPEAKER = "";
	}

上面代码中的关键就是sr_start_listening(&asr);这个函数,前面也说了这是从run_asr()调用的方法中抽离出来的,抽离出来后run_asr()就变成了预热函数,只需在程序初始化的时候调用它后面的语音识别就不要重复调用了,节省资源。

必须要说说这个关键函数sr_start_listening(&asr);

这是讯飞这款SDK中不需要动的最后一个封装好的函数,里面的东西不要动,前面的东西配置好一调用它就可以进行语音识别了,这个函数中的东西是这款SDK的精华,实现过程很复杂不需要管,但是要记住它的几个特性:

1)一调用它就相当于抛出了一个带缓冲的新线程,这个线程独立进行语音的识别可以不干扰项目的主循环的进行。

2)这个线程寿命是自动的,程序一开始启动到这里调用这个函数后启动线程,当程序的主循环又回来这里不会重复启动这个线程,而是该线程识别完用户的语音判断语句结束机制触发后才待命,等待下一次循环的启动。这句话有些费解,用我的项目解释下:我的项目在update()函数中调用sr_start_listening(&asr); 我的update()函数每100毫秒循环一次,第一次循环启动这个函数,抛出线程进行语音识别,语音识别用了10秒结束,在这10秒过程中update()循环了100次,但是只启动该函数一次,第101次循环的时候就可以第二次启动该函数了,同时在上面代码片中我用SPEAKER转存的字符串的判断条件已经成立,就可以进行相应的操作了,在这里我触发了不同的按键来代替各种操作。

3)举个栗子,我在update()中可以在每一次循环时画一帧图片的方式实现一个视频的播放,而在这里面调用语音引擎sr_start_listening(&asr);,在引擎识别的过程中会不会中断视频的播放或者视频出现卡帧或迟滞呢?答案是不会,上面也解释了,这个函数抛出一个独立的线程,不影响主函数的循环。所以可以用这种方法实现用语音控制视频的播放:快进、后退、暂停、截屏、全屏、音量加大、切换到高清......是不是很酷!

上面的几个源码文件我打了个包,下载看可能更清楚:

http://download.csdn.net/detail/sac761/9647029

四、总结

我用这个方案实现了离线的语音控制系统,语音识别率达到百分之九十以上,而且词语句子中英文通吃,实时性强,系统鲁棒。

畅想一下用这个方法加方案开发这几个产品:

语音控制的媒体播放器,功能在上面也讲了,很酷的!

语音控制的PPT遥控器

语音控制的AR/VR系统

语音交互智能眼镜

.............





2018-03-15 16:55:57 u012375207 阅读数 460
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4709 人正在学习 去看看 Frank Lee

写在前面

时隔一年没有写博客了,最近的一篇博客是2017年4月17日,怎么说呢,一个字,懒。哈哈,当然实际上是从去年四月开始接到做语音识别的项目去了,一直到现在也没什么空(其实有空,但是还是懒)。被各种bug折磨了一整年之后,终于也算是熬出头了,这里就写一个关于语音框架构建的博客,不过因为公司项目,肯定不能说得太详细了,说个大概吧,具体代码之类的可以去看看百度的那个duros,虽然我觉得它写得很烂。

关于语音识别

语音识别是一个很庞大的东西,当然对于我们这样的客户端选手来说,需要了解的也不多,这里简单的说一下,因为很庞大,所以篇幅原因,我就不说太详细(其实还是因为懒)。

云端识别

语音识别因为需要很大的数据量作为支持,所以要得到很好的体验,只能通过服务器跑神经网络来实现,所以大部分的识别是放在云端的,这里本地只需要做好网络和录放音即可。然后语音识别分两种,一种叫做听写机,还有一种叫做JSGF。他们两个的区别就在于听写机是你随便说什么,他都能给你识别出来,对错就不知道,也没有一个固定的值,JSGF就只能够识别固定的词语,你设置了他就能识别,没有设置他就不能识别。这里你就可以看看Siri的实现,当你对Siri说打电话给张三的时候,“打电话给”这四个字就是云端听写机实现的识别,“张三”这两个字就是JSGF识别的,因为张三在当前情况下一定是一个人名,那么它就会拿这个语音到你的通讯录,通过JSGF来识别。JSGF简单的说就是在一个固定的结果集里面,一定会识别出一个结果给你。如果这里我没解释清楚的,自己去百度看看,记住,就是两种东西:听写机和JSGF。

本地识别

由于刚才说了识别就分两种,一种是听写机,还有一种是JSGF,因为听写机需要很庞大的数据支撑,所以本地只能使用JSGF,当然这也至少有二三十兆。JSGF放在本地一般用作唤醒,比如类似hey Siri这种操作,当然Siri还做了声纹识别。还用作识别第一个、第二个这种类似选择的命令词。

端点检测

这个用作检测当前是否有人说话。

回声消除

回声消除主要用在当设备在播放音频的同时还要录音识别的时候,因为这种时候mic会把播放出来的音频一起录制回去,所以需要做一个消除的算法,由于android手机的AudioTrack和AudioRecord中都存在一个环形缓冲区,而每一个厂家的缓冲区大小不同,所以会造成录制的音频和当前播放的音频不一致,音频起点无法对齐,而出现消除效果很差的情况,所以这个功能在Android手机上是一个难以突破的瓶颈,不过可以勉强使用系统自带的communication来实现,不过很多厂家可能是由于技术原因吧,这个communication的参数根本没用,这里点名小米,小米垃圾,哈哈哈。

TTS

TTS就是把文字生成为音频的一个东西,也分为云端和本地,当然是云端效果好,不过本地也有它的作用,比如说没有网络的时候。

SILK

这是一个音频压缩库,主要用于本地和服务器通信的时候对数据做压缩处理。

正文开始咯

思路

怎么说呢,这个东西是一个很庞大的,一时半儿说不清楚,这里涉及太多东西了,我先挨个说怎么做,至于为什么这样做,能解释的就解释,不能解释的,就先挨个去了解这些知识,最后就知道为什么了。

分包

一共分4个包:

  1. SILK音频压缩
  2. TTS+音频播放
  3. 本地识别+端点检测+回声消除+音频录制
  4. 云端识别

本地识别包的实现

一个录音数据同步队列
一个识别结果同步队列
一个录音线程
一个识别线程
内部流程:录音线程录制音频放入录音队列,识别线程从录音线程取出数据识别后放入结果队列
外部调用:从结果队列取出结果进行操作
结果数据包括:识别内容、音频原始数据、端点数据

TTS包的实现

一个生成同步队列
一个结果同步队列
一个生成线程
一个播放线程
内部流程:生成线程从生成队列中取出文字进行生成,生成的音频放进结果队列,播放线程从结果队列中取出音频进行播放
外部调用:需要传入interface从内部回调播放状态

云端识别的实现

云端识别需要依赖本地识别库,然后从本地识别库中取数据往云端发,这里需要一个网络队列即可。

具体业务实现

架构

采用MVP架构,能够做到多个子流程解耦,比如说在Siri中,播放音乐和拨打电话,这能够分为两个子流程,他们和主流程(对话流程)是毫不相干的,但是他们却是操作的同一个页面,那么这里我们能够联想到MVP架构,我只需要在切换流程的时候切换不同的presenter即可,页面不用进行其他操作,而且每个presenter中的业务也毫不相干,可以多人共同协助开发。这里的业务分发根据云端识别后进行语义分析返回的业务标签来判断,这里我们可以考虑做成注解的方式,子流程在类名上注解自己处理的业务标签,主流程在得到业务标签后进行遍历,反射调用子流程,这样的话完完全全能够模仿Spring的操作了。

然后我感觉好像也没什么可说的了,因为涉及到太多不能说的东西,而且还有很多单独拿出来都很庞大的东西,不是三言两语能说清楚的,比如说JSGF,这里只是提供一个思路,提供一个方向,按照这个放下往下走,是可以构建出一个语音识别的开发框架的。你们可以找一下各种语音开放平台,下载这些库,来根据我这个大概的思路进行实现。

2017-09-14 22:11:08 ckzhouzhe 阅读数 2426
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4709 人正在学习 去看看 Frank Lee
微信小程序 语音识别开发
2018-10-25 15:18:53 Soumns_Kris 阅读数 859
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4709 人正在学习 去看看 Frank Lee

1.调用Google原生语音识别

 Intent intent = new Intent(
                RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); //设置识别模式
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Please start your voice");//开始说话描述
        try {
            startActivityForResult(intent, RESULT_SPEECH); //RESULT_SPEECH为Activity回调时的code值
        } catch (ActivityNotFoundException a) { //当前设备无法支持google语音识别
            Toast t = Toast.makeText(getApplicationContext(),
                    "Opps! Your device doesn't support Speech to Text",
                    Toast.LENGTH_SHORT);
            t.show();
        }

2.Activity回调结果

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case RESULT_SPEECH: {
                if (resultCode == RESULT_OK && data != null) {
                    ArrayList<String> text = data
                            .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                    //此集合列表第一个值为匹配度最高的值
                    tv_open.setText(text.get(0));
                }
                break;
            }

        }
    }

3.由于Google语音识别有一定的限制,所以很多设备可能不支持。但又无法提取获取是否支持此功能,因此提供一个判断此Intent是否可用的方法

 public static boolean isIntentAvailable(Context context) {
        final PackageManager packageManager = context.getPackageManager();
        final Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);//参数为需要启动Google识别的action,也可动态传递
        List<ResolveInfo> list =
                packageManager.queryIntentActivities(intent,
                        PackageManager.MATCH_DEFAULT_ONLY);
        return list.size() > 0;
    }

——————————-

三样东西有助于缓解生命的辛劳:希望,睡眠和微笑

2016-12-26 15:19:50 cwfjimogudan 阅读数 4348
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4709 人正在学习 去看看 Frank Lee

语音识别第三步:了解语音识别的相关背景

1.语音识别的发展历史
作为智能计算机研究的主导方向和人机语音通信的关键技术,语音识别技术一直受到各国科学界的广泛关注。以语音识别开发出的产品应用领域非常广泛,有声控电话交换、语音拨号系统、信息网络查询、家庭服务、宾馆服务、旅行社服务系统、订票系统、声控智能玩具、医疗服务、银行服务、股票查询服务、计算机控制、工业控制、语音通信系统、军事监听、信息检索、应急服务、翻译系统等,几乎深入到社会的每个行业、每个方面,其应用和经济社会效益前景非常广泛。因此语音识别技术既是国际竞争的一项重要技术,也是每一个国家经济发展不可缺少的重要技术支撑。研究语音识别,开发相应的产品有着广泛的社会意义和经济意义。
语音识别中的说话人辨认的研究始于20世纪30年代。早期的工作主要集中在人耳听辨试验和探讨听音识别的可能性方面。Bell实验室的L.G.Kesta目视观察语谱图进行识别,提出了“声纹(Voiceprint)”的概念。Bell实验室的S.Pruzansky提出了模版匹配和概率统计方差分析的声纹识别方法,形成了声纹识别研究的一个高潮。60年代末和70年代初语音识别最重要的发展是语音信号线性预测编码(LPC)技术和动态时间规整(DTW)技术,有效地解决了语音的特征提取和时间不等长匹配问题,对特定人的语音识别十分有效。研究特点是以孤立字语音识别为主,通常把孤立字作为一个整体来建立模板。80年代,语音识别研究的重点之一是连接词语音识别,开发了各种连接词语音识别和关键词识别算法,如多级动态规划语音识别算法。另一个重要发展是语音识别算法从模板匹配技术转向基于统计模型技术。

2.语音识别研究现状
20世纪90年代后,在细化模型的设计、参数提取和优化,以及系统的自适应技术上取得了一些关键进展。语音识别技术进一步成熟,并开始向市场提供产品。由于中国的国际地位不断提高,以及在经济和市场方面所处的重要地位,汉语语音识别也越来越受到重视。IBM、Microsoft、L&H等公司相继投入到汉语语音识别系统的开发中,其投资也逐年增加。IBM开发的Viavoice和Microsoft开发的中文识别引擎代表了当前汉语语音识别的最高水平。台湾的一些大学和研究所也开发出大词汇量非特定人连续语音识别演示系统。日本也先
后在语音识别领域大展头角,还有如Philips公司开发的Speech—Media和Speech Pearl两套软件,涵盖了自然语音识别与理解的对话系统。
我国语音识别研究工作近年来发展很快,同时也从实验室逐步走向实用。从1987年开始执行863计划后,国家863《智能计算机主题》专家组为语音识别研究立项。每两年滚动一次,从1991年开始,专家组每一至二年举行一次全国性的语音识别系统测试。汉语语音识别研究已经走上组织化的道路。目前我国大词汇量连续语音识别系统的研究已经接近国外最高水平。
语音识别发展到一定阶段,世界各国都加快了语音识别引用系统的研究开发,通常连续语音是含有较完整语法信息的连续语句,最接近于人的自然讲话方式,从非连续语音到连续语音的研究面临着很多完全不同的技术难点,非连续语音的识别是一些孤立的声波片段,连续语音则面临着如何切分声波的问题。诸如此类的新问题使连续语音识别率的提高比非连续语音更加困难。
经过几十年的发展和摸索,人们终于在实验室突破了大词汇量、连续语音和非特定人这三大障碍,第一次把这三个特性一起集中于一个系统中,并以此确定了统计方法和模型在语音识别和语音处理中的主流地位。在声学识别层次,以多个说话人发音的大规模语音数据为基础,以马尔可夫链为基础的语音序列建模方法HMM(隐含马尔可夫模型)比较有效的解决了语音信号短时稳定、长时时变的特性,并且能根据一些基本建模单元构造成连续语音的句子模型,达到了比较高的建模精度和建模灵活性。
目前在语音识别研究领域非常活跃的课题为稳健语音识别、说话人自适应技术、大词汇量关键词识别算法、语音识别的可信度评测算法、基于类的语言模型和自适应语言模型,以及深层次的自然语音的理解。研究的方向也越来越侧重于口语对话系统。

3. 语音识别系统的分类
语音识别是近年来十分活跃的一个研究领域。在不远的将来,语音识别技术有可能作为一种重要的人机交互手段,辅助甚至取代传统的键盘、鼠标等输入设备,在个人计算机上进行文字录入和操作控制。本文介绍了语音识别的基本流程、所用到的语音参数算法、语音识别的训练算法和识别算法做初步的探究,主要运用了特定人孤立词识别的DTW算法和非特定人识别的连续HMM算法的Matlab识别系统。
语音识别按说话人的讲话方式可分为孤立词(Isolated Word)识别、连接词(Connected Word)识别和连续语音(Continuous Speech)识别。孤立词识别是指说话人每次只说一个词或短语,每个词或短语在词汇表中都算作一个词条,一般用在语音电话拨号系统中。连接词语音识别支持一个小的语法网络,其内部形成一个状态机,可以实现简单的家用电器的控制,而复杂的连接词语音识别系统可以用于电话语音查询、航空定票等系统。连续语音识别是指对说话人以日常自然的方式发音,通常特指用于语音录入的听写机。显然,连续非特定人语音识别的难度要大得多,因为不仅有说话人口音的问题,还有协同发音、断字断句、搜索等问题,除了考虑语音的声学模型外还要涉及到语言模型,如构词法、文法等。
从识别对象的类型来看,语音识别可以分为特定人(Speaker Dependent)语音识别和非特定人(Speaker Independent)语音识别。特定人是指只针对一个用户的语音识别,非特定人则可用于不同的用户。实际上,非特定人语音识别的初始识别率往往都比较低,一般都要求用户花一定的时间对系统进行训练,将系统的参数进行一定的自适应调整,才能使识别率达到满意的程度。
非特定人大词表连续语音识别是近几年研究的重点,也是研究的难点。目前的连续语音识别大多是基于HMM(隐马尔可夫模型)框架,并将声学、语言学的知识统一引入来改善这个框架,其硬件平台通常是功能强大的工作站或PC机。

4. 语音识别系统的基本构成
语音识别系统的典型实现方案为:输入的模拟语音信号首先要进行预处理,包括预滤波、采样和量化、加窗、端点检测、预加重等。语音信号经预处理后,接下来很重要的一环就是特征参数提取。对特征参数的要求是:1,提取的特征参数能有效地代表语音特征,具有很好的区分性。2,各阶参数之间有良好的独立性。3,特征参数要计算方便,最好有高效的计算方法,以保证语音识别的实时实现。
在训练阶段,将特征参数进行一定的处理之后,为每个词条得到一个模型,保存为模版库。在识别阶段,语音喜好经过相同的通道得到语音参数,生成测试模版,与参考模版进行匹配,将匹配分数最高的参考模版作为识别结果。同时还可以在很多先验知识的帮助下,提高识别的准确率。

5. 语音识别技术难点
虽然语音识别已突破了最初对技术的检验阶段,而进入通过对话及系统形象的设计,建立用户喜爱的应用系统时期。然而语音技术本身仍在不断进步,为市场提供更新更好的应用模式和技术。目前,技术及应用的焦点主要集中在三个方面。
首先,带口音(Dialect)语音的识别。首先要明确的是,口音是指同一种语言在不同地区的发音有所不同,与同一地区(例如中国)的不同方言是有区别的。例如,中国的八大方言多属于与普通话(北方语系)不同的语系。也就是说是有别于普通话的不同的语言,应该用不同的声学模型来描述。而对于口音的适应性首先是由声学模型本身的品质决定的。对某一种口音,语言的声学模型的适应性决定了基础识别率,而在此基础上的优化和模型适应方案则提供了很好的解决方案。例如Nuance公司,作为拥有最大市场和最多用户的公司,也拥有最多的用户语音数据,保证了它极高的基础识别率。此外,该公司的系统优化工具为所有系统提供一个实用、有效的优化方法。优化过程对所有系统的表现都会有提高,也可以解决小范围的口音问题。而针对严重的口音问题,它的声学模型适应机制提供了很好的解决方案,可以使系统的识别率有很大改善。
焦点之二是背景噪音。人多的公共场所巨大的噪音对语音识别的影响自不用说,早期即使在实验室环境下,敲击键盘、挪动麦克风都会成为背景噪音。它将破坏原始语音的频谱,或者把原始语音部分或全部掩盖掉,造成识别率下降。实际应用中,噪音是无法避免的。研究将要解决的问题就是如何把原始语音从背景噪音中分离出来,即所谓提高音质(speech enhancement)或减噪(noise reduction)的预处理。这将会使识别系统具有很强的适应性。在这方面,Nuance优化的语音参数、灵活的模型结构、新的建模方法以及独有的噪音抑制功能,使得系统在背景环境噪声、手机、车载免提等高噪音环境下能保持良好的工作状况。
第三个就是“口语”的问题。这就是用户说话的自由度问题。它既涉及到自然语言理解,又与声学有关。语音识别技术的最终目的是要让用户在“人机对话”的时候,能够像进行“人人对话”一样自然。而一旦用户以跟人交谈的方式来进行语音输入时,口语的语法不规范和语序不正常的特点会给语义的分析和理解带来困难。你也许接触到一些语音软件声称是可以做到自然语言识别,而在这方面真正有实用商业系统的只有Nuance公司。Nuance的最新版识别软件所提供的“随意说(Say anything)”技术,使用户可以以自然的语言说出自己的需求。例如,“我对我的手机上的一些功能不太明白,想问一下”,或者“嗯,我的账单应该到期了,请帮我查一下要交多少钱”。它为用户提供了一种像“人人对话”的自然语音交互界面,这种更加友善的界面允许一般对话时的一些行为,如停顿及不完全的语句等。

语音识别之Python开发

阅读数 14270

语音识别入门

阅读数 6968

没有更多推荐了,返回首页