2019-08-20 22:57:48 zhangyuandilove 阅读数 267
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

百度语音权限token获取地址:https://openapi.baidu.com/oauth/2.0/token

百度语音识别接口地址:http://vop.baidu.com/server_api

按照官方Api指导,第一步获取token,采用post请求方式,js代码如下:

var token;
function getToken() {
	$.post("https://openapi.baidu.com/oauth/2.0/token", {
		grant_type: 'client_credentials',
		client_id: '个人应用的clientid',//需要替换
		client_secret: '对应应用的加密串'//需要替换
	}, function(result) {
		token = result.access_token;
	}, "json")
}

token获取后,先放一边,我们进行页面语音的录制并播放。

var mediaRecorder;
	var voiceMsg = $("#voice-rec");//按钮,按住说话,放开进行语音识别
		voiceMsg.on('touchstart', function(ev) {
			$(this).html('松开 结束');
			$(this).addClass("activeBtn");
			$('#voiceInputLoading').show();
			setTimeout(function() {
				mediaRecorder.stop();
			}, 10000)
			mediaRecorder.record({
				samplerate: "16000",
				format: "amr",
				filename: "_doc/audio/"
			}, function(e) {
				plus.io.resolveLocalFileSystemURL(e, function(entry) {
					entry.file(function(file) {
						let reader = null;
						let size = file.size;
						reader = new plus.io.FileReader();
						reader.onload = function(e) {};
						reader.readAsDataURL(file);
						reader.onloadend = function(e) {
							var urlStr = e.target.result;
                            //注意以下字符截取,关键部分
							urlArr = urlStr.split(",")[1];
							//调用百度API进行语音识别
							getVoice2Text(urlArr, size, function(msg) {
								console.log(msg);
							});
						}
					})
				});
			}, function(e) {
				alert("Audio record failed: " + e.message);
			});
		});
		voiceMsg.on('touchend', function(ev) {
			$(this).html('按下 说话');
			$(this).removeClass("activeBtn");
			$('#voiceInputLoading').hide();
			mediaRecorder.stop();
		});

以上代码中getVoice2Text这个方法就是调用百度语音识别Api

function getVoice2Text(base64, urlSize,callback) {
	$.ajax({
		type: "post",
		url: "http://vop.baidu.com/server_api",
		async: true,
		contentType: "application/json",
		processData: false,
		data: JSON.stringify({
			"format": "amr", 
			"rate": 16000, 
			"dev_pid": 1536, 
			"channel": 1, 
			"cuid": "862245234377502,862989243244150", //设备的唯一id
			"speech": base64, 
			"len": urlSize, 
			"token": token//第一步获取到的token
		}),
		success: function(data) {
			console.log(data.result[0]);
			callback(data.result[0]);
		}
	});

}

这里需要注意一下的地方就是以下两点:

1:音频采用的是plus.audio提供的api;

2:音频文件转换采用的是plus.io提供的api

感兴趣的朋友可以参考:http://www.html5plus.org/doc/zh_cn/webview.html

2019-03-21 13:26:18 active2489595970 阅读数 133
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

https://blog.csdn.net/michaelliang12/article/details/51317531#c语音识别接口快速入门microsoft-speech-sdk

 

C++语音识别接口快速入门(Microsoft Speech SDK)
最近毕业设计用到了微软的C++语音识别接口,查找了很多资料,也碰到了很多问题,走了很多弯路。现在把我自己的经验写下来,一是提升自己,二是回报社会。希望大家看了这篇blog之后,5min就学会C++语音识别接口的实现。(采用的平台为win8+VS2013)

目录
C语音识别接口快速入门Microsoft Speech SDK
目录
一安装SDK
二新建工程配置环境
三语音识别代码
1文字转语音
2语音转文字
源代码下载
参考网站
一、安装SDK
安装MicrosoftSpeechPlatformSDK.msi,默认路径安装即可。 
下载路径: 
http://download.csdn.net/detail/michaelliang12/9510691

二、新建工程,配置环境
设置: 
1,属性–配置属性–C/C++–常规–附加包含目录:C:\Program Files\Microsoft SDKs\Speech\v11.0\Include(具体路径与安装路径有关) 
2,属性–配置属性–链接器–输入–附加依赖项:sapi.lib;

三、语音识别代码
语音识别接口可分为文字转语音和语音转文字

1、文字转语音
需要添加的头文件:

#include <sapi.h> //导入语音头文件
#pragma comment(lib,"sapi.lib") //导入语音头文件库
1
2
3
函数:

void  CBodyBasics::MSSSpeak(LPCTSTR speakContent)// speakContent为LPCTSTR型的字符串,调用此函数即可将文字转为语音
{
    ISpVoice *pVoice = NULL;

    //初始化COM接口

    if (FAILED(::CoInitialize(NULL)))
        MessageBox(NULL, (LPCWSTR)L"COM接口初始化失败!", (LPCWSTR)L"提示", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);

    //获取SpVoice接口

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);


    if (SUCCEEDED(hr))
    {
        pVoice->SetVolume((USHORT)100); //设置音量,范围是 0 -100
        pVoice->SetRate(2); //设置速度,范围是 -10 - 10
        hr = pVoice->Speak(speakContent, 0, NULL);

        pVoice->Release();

        pVoice = NULL;
    }

    //释放com资源
    ::CoUninitialize();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2、语音转文字
这个稍微麻烦一点,因为需要实时监控麦克风,涉及到windows的消息机制。 
(1)首先设置工程属性: 
属性–配置属性–C/C++–预处理器–预处理器定义:_WIN32_DCOM;

(2)需要添加的头文件:

#include <sapi.h> //导入语音头文件
#pragma comment(lib,"sapi.lib") //导入语音头文件库
#include <sphelper.h>//语音识别头文件
#include <atlstr.h>//要用到CString

#pragma once
const int WM_RECORD = WM_USER + 100;//定义消息
1
2
3
4
5
6
7
(3)在程序的.h头文件中定义变量

//定义变量
CComPtr<ISpRecognizer>m_cpRecoEngine;// 语音识别引擎(recognition)的接口。
CComPtr<ISpRecoContext>m_cpRecoCtxt;// 识别引擎上下文(context)的接口。
CComPtr<ISpRecoGrammar>m_cpCmdGrammar;// 识别文法(grammar)的接口。
CComPtr<ISpStream>m_cpInputStream;// 流()的接口。
CComPtr<ISpObjectToken>m_cpToken;// 语音特征的(token)接口。
CComPtr<ISpAudio>m_cpAudio;// 音频(Audio)的接口。(用来保存原来默认的输入流)
ULONGLONG  ullGrammerID;
1
2
3
4
5
6
7
8
9
(4)创建语音识别初始化函数(程序刚开始执行的时候调用,例如文末示例代码中,将此初始化函数放在对话框初始化消息WM_INITDIALOG的响应代码里)

//语音识别初始化函数
void  CBodyBasics::MSSListen()
{

    //初始化COM接口

    if (FAILED(::CoInitialize(NULL)))
        MessageBox(NULL, (LPCWSTR)L"COM接口初始化失败!", (LPCWSTR)L"提示", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);


    HRESULT hr = m_cpRecoEngine.CoCreateInstance(CLSID_SpSharedRecognizer);//创建Share型识别引擎
    if (SUCCEEDED(hr))
    {


        hr = m_cpRecoEngine->CreateRecoContext(&m_cpRecoCtxt);//创建识别上下文接口

        hr = m_cpRecoCtxt->SetNotifyWindowMessage(m_hWnd, WM_RECORD, 0, 0);//设置识别消息

        const ULONGLONG ullInterest = SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_SOUND_END) | SPFEI(SPEI_RECOGNITION);//设置我们感兴趣的事件
        hr = m_cpRecoCtxt->SetInterest(ullInterest, ullInterest);

        hr = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &m_cpAudio);
        m_cpRecoEngine->SetInput(m_cpAudio, true);

        //创建语法规则
        //dictation听说式
        //hr = m_cpRecoCtxt->CreateGrammar(GIDDICTATION, &m_cpDictationGrammar);
        //if (SUCCEEDED(hr))
        //{
        //  hr = m_cpDictationGrammar->LoadDictation(NULL, SPLO_STATIC);//加载词典
        //}

        //C&C命令式,此时语法文件使用xml格式
        ullGrammerID = 1000;
        hr = m_cpRecoCtxt->CreateGrammar(ullGrammerID, &m_cpCmdGrammar);

        WCHAR wszXMLFile[20] = L"";//加载语法
        MultiByteToWideChar(CP_ACP, 0, (LPCSTR)"CmdCtrl.xml", -1, wszXMLFile, 256);//ANSI转UNINCODE
        hr = m_cpCmdGrammar->LoadCmdFromFile(wszXMLFile, SPLO_DYNAMIC);


        //MessageBox(NULL, (LPCWSTR)L"语音识别已启动!", (LPCWSTR)L"提示", MB_CANCELTRYCONTINUE );
        //激活语法进行识别
        //hr = m_cpDictationGrammar->SetDictationState(SPRS_ACTIVE);//dictation
        hr = m_cpCmdGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE);//C&C
        hr = m_cpRecoEngine->SetRecoState(SPRST_ACTIVE);

    }

    else
    {
        MessageBox(NULL, (LPCWSTR)L"语音识别引擎启动出错!", (LPCWSTR)L"警告", MB_OK);
        exit(0);
    }


    //释放com资源
    ::CoUninitialize();
    //hr = m_cpCmdGrammar->SetRuleState(NULL, NULL, SPRS_INACTIVE);//C&C


}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
(5)定义消息处理函数 
需要和其他的消息处理代码放在一起,如本文代码中,放在文末示例代码的DlgProc()函数尾部。本文整个其他的代码块都可以直接照搬,只需要更改如下的消息反应模块即可

//消息处理函数
USES_CONVERSION;
    CSpEvent event;

    if (m_cpRecoCtxt)
    {
        while (event.GetFrom(m_cpRecoCtxt) == S_OK){

            switch (event.eEventId)
            {
            case SPEI_RECOGNITION:
            {
                                     //识别出了语音
                                     m_bGotReco = TRUE; 

                                     static const WCHAR wszUnrecognized[] = L"<Unrecognized>";

                                     CSpDynamicString dstrText;

                                     ////取得识别结果 
                                     if (FAILED(event.RecoResult()->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL)))
                                     {
                                         dstrText = wszUnrecognized;
                                     }

                                     BSTR SRout;
                                     dstrText.CopyToBSTR(&SRout);
                                     CString Recstring;
                                     Recstring.Empty();
                                     Recstring = SRout;

                                    //做出反应(*****消息反应模块*****)
                                    if (Recstring == "发短信")
                                     {
                                         //MessageBox(NULL, (LPCWSTR)L"好的", (LPCWSTR)L"提示", MB_OK);
                                         MSSSpeak(LPCTSTR(_T("好,马上发短信!")));

                                     }

                                     else if (Recstring == "李雷")
                                     {
                                         MSSSpeak(LPCTSTR(_T("好久没看见他了,真是 long time no see")));
                                     }   

            }
                break;
            }
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
(6)修改语法文件 
修改CmdCtrl.xml文件,可以提高某些词汇的识别度,对里面的词识别效果会很好多,如人名等。(此外,单独运行exe时也需要将此文件和exe放在同一文件夹内,不放也不会报错,只是语法文件里的词汇识别效果变差)

<?xml version="1.0" encoding="utf-8"?>
<GRAMMAR LANGID="804">
  <DEFINE>
    <ID NAME="VID_SubName1" VAL="4001"/>
    <ID NAME="VID_SubName2" VAL="4002"/>
    <ID NAME="VID_SubName3" VAL="4003"/>
    <ID NAME="VID_SubName4" VAL="4004"/>
    <ID NAME="VID_SubName5" VAL="4005"/>
    <ID NAME="VID_SubName6" VAL="4006"/>
    <ID NAME="VID_SubName7" VAL="4007"/>
    <ID NAME="VID_SubName8" VAL="4008"/>
    <ID NAME="VID_SubName9" VAL="4009"/>
    <ID NAME="VID_SubNameRule" VAL="3001"/>
    <ID NAME="VID_TopLevelRule" VAL="3000"/>
  </DEFINE>
  <RULE ID="VID_TopLevelRule" TOPLEVEL="ACTIVE">
    <O>
      <L>
        <P>我要</P>
        <P>运行</P>
        <P>执行</P>
      </L>
    </O>
    <RULEREF REFID="VID_SubNameRule" />
  </RULE>
  <RULE ID="VID_SubNameRule" >
    <L PROPID="VID_SubNameRule">
      <P VAL="VID_SubName1">发短信</P>
      <P VAL="VID_SubName2">是的</P>
      <P VAL="VID_SubName3">好的</P>
      <P VAL="VID_SubName4">不用</P>
      <P VAL="VID_SubName5">李雷</P>
      <P VAL="VID_SubName6">韩梅梅</P>
      <P VAL="VID_SubName7">中文界面</P>
      <P VAL="VID_SubName8">英文界面</P>
      <P VAL="VID_SubName9">English</P>

    </L>
  </RULE>
</GRAMMAR>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
源代码下载
注意,本代码是在原来的项目中截取出来的,但可以独立运行。 
Microsoft Speech SDK 安装包下载: 
http://download.csdn.net/detail/michaelliang12/9510691 
文中示例程序下载(之前下载分数太高,我已经重新上传了新版本,也解决了kincect20.lib报错的问题。由于自己经常在csdn上下东西,也需要积分,需要还是需要各位捧场,2积分。。): 
http://download.csdn.net/detail/michaelliang12/9766783

存在的bug:每次运行完程序,Windows的语音识别助手不会自动关闭,需要自己手动关闭。若不关闭,则下次启动程序可能会出错。大家如果有好的解决办法,请联系我,谢了!

参考网站
1,http://www.cnblogs.com/eping/archive/2010/05/23/1742201.html 
2,http://blog.csdn.net/pamchen/article/details/7856207 
3,http://blog.csdn.net/jmxiaocai/article/details/7036033 
4,http://blog.csdn.net/buaalei/article/details/5372544(主要参考) 
5,http://blog.csdn.net/itcastcpp/article/details/5313204 
6,http://blog.csdn.net/artemisrj/article/details/8723095(MFC的消息处理响应版本)
--------------------- 
作者:Michael__CSDN 
来源:CSDN 
原文:https://blog.csdn.net/michaelliang12/article/details/51317531 
版权声明:本文为博主原创文章,转载请附上博文链接!

2017-07-22 15:39:40 fsz520w 阅读数 3669
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

        C++语音识别接口快速入门(Microsoft Speech SDK)                                                  

                           

C++语音识别接口快速入门(Microsoft Speech SDK)

最近毕业设计用到了微软的C++语音识别接口,查找了很多资料,也碰到了很多问题,走了很多弯路。现在把我自己的经验写下来,一是提升自己,二是回报社会。希望大家看了这篇blog之后,5min就学会C++语音识别接口的实现。(采用的平台为win8+VS2013)

目录

一、安装SDK

安装MicrosoftSpeechPlatformSDK.msi,默认路径安装即可。
下载路径:
http://download.csdn.net/detail/michaelliang12/9510691

二、新建工程,配置环境

设置:
1,属性–配置属性–C/C++–常规–附加包含目录:C:\Program Files\Microsoft SDKs\Speech\v11.0\Include(具体路径与安装路径有关)
2,属性–配置属性–链接器–输入–附加依赖项:sapi.lib;

三、语音识别代码

语音识别接口可分为文字转语音和语音转文字

1、文字转语音

需要添加的头文件:

#include <sapi.h> //导入语音头文件
#pragma comment(lib,"sapi.lib") //导入语音头文件库
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

函数:

void  CBodyBasics::MSSSpeak(LPCTSTR speakContent)// speakContent为LPCTSTR型的字符串,调用此函数即可将文字转为语音
{
    ISpVoice *pVoice = NULL;

    //初始化COM接口

    if (FAILED(::CoInitialize(NULL)))
        MessageBox(NULL, (LPCWSTR)L"COM接口初始化失败!", (LPCWSTR)L"提示", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);

    //获取SpVoice接口

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);


    if (SUCCEEDED(hr))
    {
        pVoice->SetVolume((USHORT)100); //设置音量,范围是 0 -100
        pVoice->SetRate(2); //设置速度,范围是 -10 - 10
        hr = pVoice->Speak(speakContent, 0, NULL);

        pVoice->Release();

        pVoice = NULL;
    }

    //释放com资源
    ::CoUninitialize();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

2、语音转文字

这个稍微麻烦一点,因为需要实时监控麦克风,涉及到windows的消息机制。
(1)首先设置工程属性:
属性–配置属性–C/C++–预处理器–预处理器定义:_WIN32_DCOM;

(2)需要添加的头文件:

#include <sapi.h> //导入语音头文件
#pragma comment(lib,"sapi.lib") //导入语音头文件库
#include <sphelper.h>//语音识别头文件
#include <atlstr.h>//要用到CString

#pragma once
const int WM_RECORD = WM_USER + 100;//定义消息
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

(3)在程序的.h头文件中定义变量

//定义变量
CComPtr<ISpRecognizer>m_cpRecoEngine;// 语音识别引擎(recognition)的接口。
CComPtr<ISpRecoContext>m_cpRecoCtxt;// 识别引擎上下文(context)的接口。
CComPtr<ISpRecoGrammar>m_cpCmdGrammar;// 识别文法(grammar)的接口。
CComPtr<ISpStream>m_cpInputStream;// 流()的接口。
CComPtr<ISpObjectToken>m_cpToken;// 语音特征的(token)接口。
CComPtr<ISpAudio>m_cpAudio;// 音频(Audio)的接口。(用来保存原来默认的输入流)
ULONGLONG  ullGrammerID;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(4)创建语音识别初始化函数(程序刚开始执行的时候调用,例如文末示例代码中,将此初始化函数放在对话框初始化消息WM_INITDIALOG的响应代码里)

//语音识别初始化函数
void  CBodyBasics::MSSListen()
{

    //初始化COM接口

    if (FAILED(::CoInitialize(NULL)))
        MessageBox(NULL, (LPCWSTR)L"COM接口初始化失败!", (LPCWSTR)L"提示", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);


    HRESULT hr = m_cpRecoEngine.CoCreateInstance(CLSID_SpSharedRecognizer);//创建Share型识别引擎
    if (SUCCEEDED(hr))
    {


        hr = m_cpRecoEngine->CreateRecoContext(&m_cpRecoCtxt);//创建识别上下文接口

        hr = m_cpRecoCtxt->SetNotifyWindowMessage(m_hWnd, WM_RECORD, 0, 0);//设置识别消息

        const ULONGLONG ullInterest = SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_SOUND_END) | SPFEI(SPEI_RECOGNITION);//设置我们感兴趣的事件
        hr = m_cpRecoCtxt->SetInterest(ullInterest, ullInterest);

        hr = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &m_cpAudio);
        m_cpRecoEngine->SetInput(m_cpAudio, true);



        //创建语法规则
        //dictation听说式
        //hr = m_cpRecoCtxt->CreateGrammar(GIDDICTATION, &m_cpDictationGrammar);
        //if (SUCCEEDED(hr))
        //{
        //  hr = m_cpDictationGrammar->LoadDictation(NULL, SPLO_STATIC);//加载词典
        //}

        //C&C命令式,此时语法文件使用xml格式
        ullGrammerID = 1000;
        hr = m_cpRecoCtxt->CreateGrammar(ullGrammerID, &m_cpCmdGrammar);

        WCHAR wszXMLFile[20] = L"";//加载语法
        MultiByteToWideChar(CP_ACP, 0, (LPCSTR)"CmdCtrl.xml", -1, wszXMLFile, 256);//ANSI转UNINCODE
        hr = m_cpCmdGrammar->LoadCmdFromFile(wszXMLFile, SPLO_DYNAMIC);


        //MessageBox(NULL, (LPCWSTR)L"语音识别已启动!", (LPCWSTR)L"提示", MB_CANCELTRYCONTINUE );
        //激活语法进行识别
        //hr = m_cpDictationGrammar->SetDictationState(SPRS_ACTIVE);//dictation
        hr = m_cpCmdGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE);//C&C
        hr = m_cpRecoEngine->SetRecoState(SPRST_ACTIVE);

    }

    else
    {
        MessageBox(NULL, (LPCWSTR)L"语音识别引擎启动出错!", (LPCWSTR)L"警告", MB_OK);
        exit(0);
    }


    //释放com资源
    ::CoUninitialize();
    //hr = m_cpCmdGrammar->SetRuleState(NULL, NULL, SPRS_INACTIVE);//C&C


}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

(5)定义消息处理函数
需要和其他的消息处理代码放在一起,如本文代码中,放在文末示例代码的DlgProc()函数尾部。本文整个其他的代码块都可以直接照搬,只需要更改如下的消息反应模块即可

//消息处理函数
USES_CONVERSION;
    CSpEvent event;

    if (m_cpRecoCtxt)
    {
        while (event.GetFrom(m_cpRecoCtxt) == S_OK){

            switch (event.eEventId)
            {
            case SPEI_RECOGNITION:
            {
                                     //识别出了语音
                                     m_bGotReco = TRUE; 

                                     static const WCHAR wszUnrecognized[] = L"<Unrecognized>";

                                     CSpDynamicString dstrText;

                                     ////取得识别结果 
                                     if (FAILED(event.RecoResult()->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL)))
                                     {
                                         dstrText = wszUnrecognized;
                                     }

                                     BSTR SRout;
                                     dstrText.CopyToBSTR(&SRout);
                                     CString Recstring;
                                     Recstring.Empty();
                                     Recstring = SRout;

                                    //做出反应(*****消息反应模块*****)
                                    if (Recstring == "发短信")
                                     {
                                         //MessageBox(NULL, (LPCWSTR)L"好的", (LPCWSTR)L"提示", MB_OK);
                                         MSSSpeak(LPCTSTR(_T("好,马上发短信!")));

                                     }

                                     else if (Recstring == "李雷")
                                     {
                                         MSSSpeak(LPCTSTR(_T("好久没看见他了,真是 long time no see")));
                                     }   

            }
                break;
            }
        }
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

(6)修改语法文件
修改CmdCtrl.xml文件,可以提高某些词汇的识别度,对里面的词识别效果会很好多,如人名等。(此外,单独运行exe时也需要将此文件和exe放在同一文件夹内,不放也不会报错,只是语法文件里的词汇识别效果变差)

<?xml version="1.0" encoding="utf-8"?>
<GRAMMAR LANGID="804">
  <DEFINE>
    <ID NAME="VID_SubName1" VAL="4001"/>
    <ID NAME="VID_SubName2" VAL="4002"/>
    <ID NAME="VID_SubName3" VAL="4003"/>
    <ID NAME="VID_SubName4" VAL="4004"/>
    <ID NAME="VID_SubName5" VAL="4005"/>
    <ID NAME="VID_SubName6" VAL="4006"/>
    <ID NAME="VID_SubName7" VAL="4007"/>
    <ID NAME="VID_SubName8" VAL="4008"/>
    <ID NAME="VID_SubName9" VAL="4009"/>
    <ID NAME="VID_SubNameRule" VAL="3001"/>
    <ID NAME="VID_TopLevelRule" VAL="3000"/>
  </DEFINE>
  <RULE ID="VID_TopLevelRule" TOPLEVEL="ACTIVE">
    <O>
      <L>
        <P>我要</P>
        <P>运行</P>
        <P>执行</P>
      </L>
    </O>
    <RULEREF REFID="VID_SubNameRule" />
  </RULE>
  <RULE ID="VID_SubNameRule" >
    <L PROPID="VID_SubNameRule">
      <P VAL="VID_SubName1">发短信</P>
      <P VAL="VID_SubName2">是的</P>
      <P VAL="VID_SubName3">好的</P>
      <P VAL="VID_SubName4">不用</P>
      <P VAL="VID_SubName5">李雷</P>
      <P VAL="VID_SubName6">韩梅梅</P>
      <P VAL="VID_SubName7">中文界面</P>
      <P VAL="VID_SubName8">英文界面</P>
      <P VAL="VID_SubName9">English</P>

    </L>
  </RULE>
</GRAMMAR>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

源代码下载

注意,本代码是在原来的项目中截取出来的,但可以独立运行。
Microsoft Speech SDK 安装包下载:
http://download.csdn.net/detail/michaelliang12/9510691
文中示例程序下载(之前下载分数太高,我已经重新上传了新版本,也解决了kincect20.lib报错的问题。由于自己经常在csdn上下东西,也需要积分,需要还是需要各位捧场,2积分。。):
http://download.csdn.net/detail/michaelliang12/9766783

存在的bug:每次运行完程序,Windows的语音识别助手不会自动关闭,需要自己手动关闭。若不关闭,则下次启动程序可能会出错。大家如果有好的解决办法,请联系我,谢了!

参考网站

1,http://www.cnblogs.com/eping/archive/2010/05/23/1742201.html
2,http://blog.csdn.net/pamchen/article/details/7856207
3,http://blog.csdn.net/jmxiaocai/article/details/7036033
4,http://blog.csdn.net/buaalei/article/details/5372544(主要参考)
5,http://blog.csdn.net/itcastcpp/article/details/5313204
6,http://blog.csdn.net/artemisrj/article/details/8723095(MFC的消息处理响应版本)

2012-05-04 09:29:34 about58238 阅读数 1355
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

转载地址:点击打开链接

 Android中主要通过RecognizerIntent来实现语音识别,其实代码比较简单,但是如果找不到设置,就会抛出异常ActivityNotFoundException,所以我们需要捕捉这个异常。而且语音识别在模拟器上是无法测试的,因为语音识别是访问google云端数据,所以如果手机的网络没有开启,就无法实现识别声音的!一定要开启手机的网络,如果手机不存在语音识别功能的话,也是无法启用识别!

主要代码:

package com.VoiceRecognition;
import android.app.Activity;  
import android.content.Intent;  
import android.content.pm.PackageManager;  
import android.content.pm.ResolveInfo;  
import android.os.Bundle;  
import android.speech.RecognizerIntent;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.widget.ArrayAdapter;  
import android.widget.Button;  
import android.widget.ListView;  
import java.util.ArrayList;  
import java.util.List;  
 
public class VoiceRecognition extends Activity implements OnClickListener {  
      
    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;  
      
    private ListView mList;  
 
    /**  
     * Called with the activity is first created.  
     */  
    @Override  
    public void onCreate(Bundle savedInstanceState)   
    {  
        super.onCreate(savedInstanceState);  
 
        setContentView(R.layout.main);  
 
        Button speakButton = (Button) findViewById(R.id.btn_speak);  
          
        mList = (ListView) findViewById(R.id.list);  
 
        // Check to see if a recognition activity is present  
        PackageManager pm = getPackageManager();  
        List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);  
        if (activities.size() != 0)  
        {  
            speakButton.setOnClickListener(this);  
        }  
        else  
        {  
            speakButton.setEnabled(false);  
            speakButton.setText("Recognizer not present");  
        }  
    }  
 
 
    public void onClick(View v)  
    {  
        if (v.getId() == R.id.btn_speak)  
        {  
            startVoiceRecognitionActivity();  
        }  
    }  
 
    private void startVoiceRecognitionActivity()  
    {  
        //通过Intent传递语音识别的模式  
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);  
        //语言模式和自由形式的语音识别  
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);  
        //提示语音开始  
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo");  
        //开始执行我们的Intent、语音识别  
        startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);  
    }  
 
 
    //当语音结束时的回调函数onActivityResult  
    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data)  
    {  
        if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK)  
        {  
            // 取得语音的字符  
            ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);  
            mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, matches));  
        }  
 
        super.onActivityResult(requestCode, resultCode, data);  
    }  
}  

布局xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button 
 android:id="@+id/btn_speak"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />
    <ListView
    android:id="@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />
</LinearLayout>

最后要注意的是,因为其主要原理就是将语音发送到google云端,然后云端处理,匹配相应的数据,发送到客户端。 所以不要忘记,在manifest中加入网络访问权限:

<uses-permission android:name="android.permission.INTERNET" />



2018-08-22 17:24:55 yuanlulu 阅读数 8585
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

概述

目前市场上有很多家的语音识别接口可用,简单测试都不要钱。国内的BAT和科大讯飞,国外的微软和谷歌都提供了中文的语音识别接口,既有sdk又有webAPI。我的测试都是在python3环境下进行的。

最终选择百度和科大讯飞的接口。主要是考虑中文识别应该国内厂商做的更好。

免费试用阶段,科大讯飞每天限定500次调用。百度则只限制每秒20次,总次数没限制。

试用下来的感觉就是,科大讯飞的接口更快,断句什么的也更好。但是试用次数少是个问题,只能评估玩玩。

科大讯飞语音识别webAPI

使用之前需要先去https://xfyun.cn注册并创建应用。获得APPID和APPkey.

官方的webAPI接口文档在:https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E5%90%AC%E5%86%99.html

代码是官网上的,但是那是个python2上的,我改成python3版本了(python3对于参数的编码格式更严格)。

注意:将脚本中 AUDIO_PATH, API_KEY, APPID, 换成相应的音频路径,讯飞开放平台提供的 apiKey,讯飞开放平台应用的 appid 即可。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib.request
import time
import urllib
import json
import hashlib
import base64
from urllib import parse

def main():
    f = open("AUDIO_PATH", 'rb')
    file_content = f.read()
    base64_audio = base64.b64encode(file_content)
    body = parse.urlencode({'audio': base64_audio})

    url = 'http://api.xfyun.cn/v1/service/v1/iat'
    api_key = 'API_KEY'
    param = {"engine_type":"sms16k","aue":"raw"}

    x_appid = 'APPID'
    json_str = json.dumps(param).replace(' ', '')
    print('json_str:{}'.format(json_str))
    x_param = base64.b64encode(bytes(json_str, 'ascii'))
    x_time = int(int(round(time.time() * 1000)) / 1000)
    x_checksum_str = api_key + str( x_time ) + str(x_param)[2:-1]
    print('x_checksum_str:[{}]'.format(x_checksum_str))
    x_checksum = hashlib.md5(x_checksum_str.encode(encoding='ascii')).hexdigest()
    print('x_checksum:{}'.format(x_checksum))
    x_header = {'X-Appid': x_appid,
                'X-CurTime': x_time,
                'X-Param': x_param,
                'X-CheckSum': x_checksum}

    start_time = time.time()
    req = urllib.request.Request(url, bytes(body, 'ascii'), x_header)
    result = urllib.request.urlopen(req)
    result = result.read()
    print( "used time: {}s".format( round( time.time() - start_time, 2 ) ) )
    print('result:'+str(result.decode(encoding='UTF8')))
    return

if __name__ == '__main__':
    main() 

我的一个测试输出:

json_str:{"engine_type":"sms16k","aue":"raw"}

used time: 0.82s
result:{"code":"0","data":"特别是跨省区电网超计划用电,不仅损害自己,也损害别人,损害电网,损害国家。","desc":"success","sid":"zat006392f7@ch6b010ed8627f3d3700"}

一个注意点

如果没有把ip放到白名单中,就会返回以下错误信息,错误码是10105

al access|illegal client_ip:xxxxx

在‘控制台->我的应用’里把信息里的IP加上就行。

百度语音识别webAPI

需要先在百度云上注册:https://cloud.baidu.com/

然后在管理控制台上创建一个语音识别应用,你会得到AppId\AppKey\SecretKey等信息,这些需要在调用接口的时候用到。

百度的python接口用起来比较简单,先pip install baidu-aip即可。
具体文档参考:https://cloud.baidu.com/doc/SPEECH/ASR-Online-Python-SDK.html#.E9.85.8D.E7.BD.AEAipSpeech

参考官方例子,我的代码如下(注意替换自己的APP_ID、API_KEY、SECRET_KEY):

from aip import AipSpeech
import time

APP_ID = 'APP_ID'
API_KEY = 'API_KEY'
SECRET_KEY = 'SECRET_KEY'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
        return fp.read()

# 识别本地文件
start_time = time.time()
ret = client.asr(get_file_content('./aideo_files/A2_58.wav'), 'pcm', 16000, {
    'dev_pid': 1537,
})
used_time = time.time() - start_time

print( "used time: {}s".format( round( time.time() - start_time, 2 ) ) )
print('ret:{}'.format(ret))

我测试的输出结果为:

used time: 8.18s
ret:{'corpus_no': '6592465378279780417', 'err_msg': 'success.', 'err_no': 0, 'result':
['特别是跨省区电网超计划用电,不仅损害自己也损害别人损害电网损害国家,'], 'sn': '148955205071534927957'}

时间上比科大讯飞长了好几倍,断句也不是很好。胜在试用次数基本不限。

小结

比较 优点 缺点
百度 试用次数多 速度慢,断句不太好
科大讯飞 速度快,断句好 试用次数有限

今天测试比较简单,等后面大规模测试了再来补充。

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