windows下利用微软的SpeechSDK实现语音控制

语音识别是当前研究的热点,我们可以利用微软的语音识别引擎来进行二次开发。首先需要安装微软的SpeechSDK,安装完成后配置项目的包含目录和库目录,这些都不是重点,不会的可以去百度。然后就可以写代码了,码农嘛,还是看代码有感觉。

源文件<Demo.cpp>

#include <Windows.h>
#include <atlstr.h>
#include <sphelper.h>
#include <sapi.h>
#include <comutil.h>
#include <string.h>

#pragma comment(lib,"sapi.lib")
#ifdef _UNICODE
#pragma   comment(lib,   "comsuppw.lib")  //_com_util::ConvertBSTRToString
#else
#pragma   comment(lib,   "comsupp.lib")  //_com_util::ConvertBSTRToString
#endif

#define GID_CMD_GR 333333
#define WM_RECOEVENT WM_USER+1

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

TCHAR szAppName[] = TEXT("语音控制Demo");
BOOL b_initSR;
BOOL b_Cmd_Grammar;
CComPtr<ISpRecoContext> m_cpRecoCtxt;//语音识别程序接口
CComPtr<ISpRecoGrammar> m_cpCmdGramma;//识别语法
CComPtr<ISpRecognizer> m_cpRecoEngine; //语音识别引擎
int speak(wchar_t *str);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
	HWND hwnd;
	MSG msg;
	WNDCLASS wndclass;

	//窗口类结构体初始化值
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
	wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
	wndclass.hInstance = hInstance;
	wndclass.lpfnWndProc = WndProc;
	wndclass.lpszClassName = szAppName;
	wndclass.lpszMenuName = NULL;
	wndclass.style = CS_HREDRAW|CS_VREDRAW;

	//注册窗口类
	if(!RegisterClass(&wndclass))
	{
		//失败后提示并返回
		MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR);
		return 0;
	}

	//创建窗口
	hwnd = CreateWindow(szAppName,
						TEXT("语音识别"),
						WS_OVERLAPPEDWINDOW,
						CW_USEDEFAULT,
						CW_USEDEFAULT,
						CW_USEDEFAULT,
						CW_USEDEFAULT,
						NULL,
						NULL,
						hInstance,
						NULL);

	//显示窗口
	ShowWindow(hwnd,iCmdShow);
	UpdateWindow(hwnd);

	//进入消息循环
	while(GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);//翻译消息
		DispatchMessage(&msg);//分发消息
	}
	return msg.wParam;
}

/*
*消息回调函数,由操作系统调用
*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;

	switch(message)
	{
	case WM_CREATE:
		{
			//初始化COM端口
			::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
			//创建识别上下文接口
			HRESULT hr = m_cpRecoEngine.CoCreateInstance(CLSID_SpSharedRecognizer);
			if(SUCCEEDED(hr))
			{
				hr = m_cpRecoEngine->CreateRecoContext(&m_cpRecoCtxt);
			}
			else
			{
				MessageBox(hwnd,TEXT("引擎实例化出错"),TEXT("提示"),S_OK);
			}
			//设置识别消息,使计算机时刻监听语音消息
			if(SUCCEEDED(hr))
			{
				hr = m_cpRecoCtxt->SetNotifyWindowMessage(hwnd,WM_RECOEVENT,0,0);
			}
			else
			{
				MessageBox(hwnd,TEXT("创建上下文接口出错"),TEXT("提示"),S_OK);
			}
			//设置我们感兴趣的事件
			if(SUCCEEDED(hr))
			{
				ULONGLONG ullMyEvents = SPFEI(SPEI_SOUND_START)|SPFEI(SPEI_RECOGNITION)|SPFEI(SPEI_SOUND_END);
				hr = m_cpRecoCtxt->SetInterest(ullMyEvents,ullMyEvents);
			}
			else
			{
				MessageBox(hwnd,TEXT("设置识别消息出错"),TEXT("提示"),S_OK);
			}
			//创建语法规则
			b_Cmd_Grammar = TRUE;
			if(FAILED(hr))
			{
				MessageBox(hwnd,TEXT("创建语法规则出错"),TEXT("提示"),S_OK);
			}
			hr = m_cpRecoCtxt->CreateGrammar(GID_CMD_GR,&m_cpCmdGramma);
			hr = m_cpCmdGramma->LoadCmdFromFile(L"cmd.xml",SPLO_DYNAMIC);
			if(FAILED(hr))
			{
				MessageBox(hwnd,TEXT("配置文件打开出错"),TEXT("提示"),S_OK);
			}
			b_initSR = TRUE;
			//在开始识别时,激活语法进行识别
			hr = m_cpCmdGramma->SetRuleState(NULL,NULL,SPRS_ACTIVE);
			break;
		}
	case WM_RECOEVENT:
		{
			RECT rect;
			GetClientRect(hwnd,&rect);
			hdc = GetDC(hwnd);
			USES_CONVERSION;
			CSpEvent event;
			while(event.GetFrom(m_cpRecoCtxt)==S_OK)
			{
				switch(event.eEventId)
				{
				case SPEI_RECOGNITION:
					{
						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);
						char * lpszText2 = _com_util::ConvertBSTRToString(SRout);
						if(b_Cmd_Grammar)
						{
							//MessageBoxA(0,lpszText2,"内容",0);
							if(strcmp("腾讯QQ",lpszText2)==0)
							{
								//MessageBox(0,TEXT("计算机"),TEXT("内容"),0);
								speak(L"好的");
								//打开QQ.exe
								ShellExecuteA(NULL,"open","D:\\QQ\\QQProtect\\Bin\\QQProtect.exe",0,0,1);
							}
							if(strcmp("确定",lpszText2)==0)
							{
								//按下回车键
								keybd_event(VK_RETURN,0,0,0);
								keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0);
							}
							if(strcmp("音乐",lpszText2)==0)
							{
								speak(L"好的");
								//调用系统程序wmplayer.exe播放音乐
								ShellExecuteA(NULL,"open","\"C:\\Program Files (x86)\\Windows Media Player\\wmplayer.exe\"","C:\\Users\\KYT\\Desktop\\123.mp3",0,0);
							}
						}
					}
				}
			}
			break;
		}
	case WM_PAINT:
		hdc = BeginPaint(hwnd,&ps);
		EndPaint(hwnd,&ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hwnd,message,wParam,lParam);
}

#pragma comment(lib,"ole32.lib")//CoInitialize CoCreateInstance 需要调用ole32.dll

/*
*语音合成函数,朗读字符串str
*/
int speak(wchar_t *str)
{
	ISpVoice * pVoice = NULL;
	::CoInitialize(NULL);
	//获得ISpVoice接口
	long hr = CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void **)&pVoice);
	hr = pVoice->Speak(str,0,NULL);
	pVoice->Release();
	pVoice = NULL;
	//千万不要忘记
	::CoUninitialize();
	return TRUE;
}

只有源文件还不行,程序中还用到一个XML格式的语音配置文件cmd.xml。如果是利用编译器调试程序,cmd.xml需要和源代码同目录;发布程序以后,cmd.xml就得放到程序可执行文件所在的目录下了。总之,程序必须访问到cmd.xml文件,方便起见,可以在两个目录下都放一个cmd.xml文件。

配置文件<cmd.xml>

<?xml version="1.0" encoding="utf-8"?>
<GRAMMAR LANGID="804">
 <DEFINE>
    <ID NAME="CMD" VAL="10"/>
    </DEFINE>
  <RULE NAME="COMMAND" ID="CMD" TOPLEVEL="ACTIVE">
   <L>
    <P>腾讯QQ</P>
    <P>确定</P>
    <P>音乐</P>
    </L>
   </RULE>
</GRAMMAR>

到这里,一个简单的语音控制程序Demo就算完成了,你对它说:“腾迅QQ”,它就打开了一个QQ,你说:“确定”,默认的QQ账号就自己登陆了。你还可以说:“音乐”,于是一首曼妙的音乐响起(为什么看不见播放器呢,因为在代码

ShellExecuteA(NULL,"open","\"C:\\Program Files (x86)\\Windows Media Player\\wmplayer.exe\"","C:\\Users\\KYT\\Desktop\\123.mp3",0,0);

设置了wmplayer.exe隐藏执行,想要关闭,嘻嘻,请打开任务管理器。另外,一定要设置你电脑上的音乐路径,不然你懂得)。

语音识别是不是挺有意思的,发挥你的想象,去震精别人吧。

时间: 2024-08-29 09:53:27

windows下利用微软的SpeechSDK实现语音控制的相关文章

Windows下利用rsync实现邮件服务器数据的同步

Windows下利用rsync实现邮件服务器数据的同步 背景环境 对系统管理员来说,平时的工作重心应该集中在维护 系统正常运转,能够正常提供服务上,这里往往牵涉到 一个数据备份的问题,在我所了解的情况中,有80%的系统管理员不是太关心自己服务器的安全性,但往往对 备份镜像的技术相当感兴趣,但由于商业产品的软硬件价格都相当高昂,因此往往会选择自由软件.rsync就 是这样的软件,它可以满足绝大多数要求不是特 别高的备份需求.适用于数据不是很大,海量小的文件的存储备份,结合服务器本身的磁盘阵列技术,

windows下利用OpenVPN搭建VPNserver

一.OpenVPN是一款功能强大,可跨平台(支持Win 2000/XP/2003, Linux, Mac OS X, Solaris, FreeBSD, NetBSD, 和 OpenBSD)使用的SSL VPNserver软件(详细说明见官方主页官方主页http://openvpn.net). 下载地址:http://openvpn.net/index.php/download.html 二.安装与配置 第一步:安装openvpn这一部分是服务端跟client都要做的工作,操作全然同样双击 op

Windows下利用py2exe生成静默运行的命令行程序

py2exe是python的第三方库,可以利用它将你的python脚本编译成可执行文件(exe),而在实际的开发过程中生成的dos窗口很影响用户体验,建议按以下方式让exe静默运行. 首先将你的python脚本后缀名改成:.pyw 再编辑Setup文件: from distutils.core import setup import py2exe setup(windows=['test.pyw']) 这样就成功组建了一个静默运行的python模块. 如果在运行过程中出现“RuntimeErro

Windows下利用live555实现H264实时流RTSP发送

文如其名,最近在做的项目要求利用RTSP协议转发处理完的H264视频数据给上一层客户端,环境是Windows的VS2013,于是就各种百度谷歌找代码.结果在得到利用live555去做比较简单的结论的同时也悲情地发现,网上别人贴出来的代码基本都是Linux上面的.在修改了两份来适用于Windows无效后,又一次陷入了百度谷歌的无尽搜索中.Anyway,最后终于解决了,所以贴出代码跟大家分享下,希望能给和我需求相似的童鞋一点启发,也希望有高手指正其中的问题. 用live555进行RTSP的播放基本上

windows下利用线程池完成多任务的分配和运行

在做项目的过程中有时候为了提升效率,用了多线程的方法来对任务进行分割和应用,后来发现,采用线程池的方法能更好的利用线程资源来计算任务,网上有很多关于如何运行线程池的例子,msdn上也给出了对应的例子:https://msdn.microsoft.com/en-us/library/windows/desktop/ms686980(v=vs.85).aspx 感兴趣的话大家可以去看看,这里我给出一个简单的demo,利用线程池单次调用多次调用,例子如下: [cpp] view plain copy

Windows下利用Android Studio进行JNI开发准备

因为公司项目需要,要进行jni的开发,进行arr,acr音频格式转化,后期上项目代码,现在先上测试代码 其中参考了http://blog.csdn.net/sodino/article/details/41946607的书写,不过有些说的好含蓄,博主摸索了一个小时,现在把详细的细节分享给大家 首先,要去官方下载ndk,因为博主的机子是win7 64位,博主就贴上这个地址,其余的楼主没有查http://dl.google.com/android/ndk/android-ndk32-r10-wind

Windows下利用Python动态检测外网IP并发邮件给邮箱

我们知道,运营商给分配的都是动态IP,IP地址过一段时间会自己变化,这就给需要静态地址的应用带来不便,例如搭建服务器或者远程控制电脑,这种情况必须知道自己电脑的IP,利用Python可以方便的自动检测并向邮箱发送邮箱. 但是,个人网络一般都是通过路由器来上网,直接检测电脑的IP并不可行,需要得到外网的IP.内网电脑可以通过端口映射来映射到外网.检测的原理如下: 1.通过自己的电脑信息不太好获取外网IP,幸好有一些雷锋网站可以帮助我们来检测,例如 http://city.ip138.com/ip2

Windows下利用原始套接字实现的一个抓包程序Demo

早就学过了套接字编程,但是原始套接字还没用过.最近听了网络安全老师的课,心血来潮,写了个抓包程序Demo,把代码分享给大家,感兴趣的可以看看.引用一句网络安全老师的话:"你们要本着技术的心态去实践,哎,一部分人,写着写着就成黑客了". #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <WinSock2.h> #include <WS2tcpip.h> #include <s

Windows下利用Cygwin搭建C/C++开发环境GCC

1.下载cygwin 下载地址:http://www.cygwin.com/ 2.下载完成后点击运行 3.选择镜像时可以选择添加清华镜像,在"User URL"处输入以下地址: https://mirrors.tuna.tsinghua.edu.cn/cygwin/ 点击"Add"按钮, 然后选中"https://mirrors.tuna.tsinghua.edu.cn", 点击"下一步"进行安装. 4.在这个页面之后,就是最