微软的语音识别,在这里我们简称它为SR(speech recognition),SR分为两种模式的监听:第一种模式:听写模式,即随意输入语音,监听对象将最为接近的字或者词,句反馈出来;第二种模式:命令与控制模式,划定范围监听,制定一组被选项做为监听的,用户的语音输入被反馈成最为接近的一个选项。说得通俗一些:第一种是填空题,第二种是选择题目。

之前转载的一品文章《用SAPI实现Speech Recognition(SR) - 听写模式》,介绍了“听写模式”的实现,这一篇给出“命令与控制”模式的例子程序。

#include <windows.h>
#include <sapi.h>
#include <stdio.h>
#include <string.h>
#include <atlbase.h>
#include "sphelper.h"  inline HRESULT BlockForResult(ISpRecoContext * pRecoCtxt, ISpRecoResult ** ppResult)
{HRESULT hr = S_OK;CSpEvent event;while (SUCCEEDED(hr) && SUCCEEDED(hr = event.GetFrom(pRecoCtxt)) && hr == S_FALSE){hr = pRecoCtxt->WaitForNotifyEvent(INFINITE);}*ppResult = event.RecoResult();if (*ppResult){(*ppResult)->AddRef();}return hr;
}const WCHAR * StopWord()
{const WCHAR * pchStop;LANGID LangId = ::SpGetUserDefaultUILanguage();switch (LangId){case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT):pchStop = L"}42N86\0b70e50fc0ea0e70fc/05708504608a087046";;break;default:pchStop = L"Stop";break;}return pchStop;
}int main(int argc, char* argv[])
{HRESULT hr = E_FAIL;bool fUseTTS = true;            // turn TTS play back on or off  bool fReplay = true;            // turn Audio replay on or off  // Process optional arguments  if (argc > 1){int i;for (i = 1; i < argc; i++){if (_stricmp(argv[i], "-noTTS") == 0){fUseTTS = false;continue;}if (_stricmp(argv[i], "-noReplay") == 0){fReplay = false;continue;}printf("Usage: %s [-noTTS] [-noReplay]  ", argv[0]);return -1;}}if (SUCCEEDED(hr = ::CoInitialize(NULL))){{CComPtr<ISpRecoContext> cpRecoCtxt;CComPtr<ISpRecoGrammar> cpRecoGrammar;CComPtr<ISpVoice> cpVoice;if (FAILED(hr = cpRecoCtxt.CoCreateInstance(CLSID_SpSharedRecoContext))){printf("cpRecoCtxt.CoCreateInstance() fail. hr = %x", hr);return -2;}if (FAILED(hr = cpRecoCtxt->GetVoice(&cpVoice))){printf("cpRecoCtxt->GetVoice() fail. hr = %x", hr);return -3;}if (cpRecoCtxt && cpVoice){if (FAILED(hr = cpRecoCtxt->SetNotifyWin32Event())){printf("cpRecoCtxt->SetNotifyWin32Event() fail. hr = %x", hr);return -4;}if (FAILED(hr = cpRecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION)))){printf("cpRecoCtxt->SetInterest() fail. hr = %x", hr);return -5;}if (FAILED(hr = cpRecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL))){printf("cpRecoCtxt->SetAudioOptions() fail. hr = %x", hr);return -6;}if (FAILED(hr = cpRecoCtxt->CreateGrammar(7, &cpRecoGrammar))){printf("cpRecoCtxt->CreateGrammar() fail. hr = %x", hr);return -7;}if (FAILED(hr = cpRecoGrammar->SetGrammarState(SPGS_DISABLED))){printf("cpRecoGrammar->SetGrammarState() fail. hr = %x", hr);return -8;}if (FAILED(hr = cpRecoGrammar->LoadCmdFromFile(L"conf.xml", SPLO_DYNAMIC))){printf("cpRecoGrammar->LoadCmdFromFile() fail. hr = %x", hr);return -9;}SPSTATEHANDLE hRule;if (FAILED(hr = cpRecoGrammar->GetRule(L"COMMAND", NULL, SPRAF_Active, FALSE, &hRule))){printf("cpRecoGrammar->GetRule() fail. hr = %x", hr);return -9;}///目前使用的是静态配置文件,以后可以研究动态加载命令/////if (FAILED(hr = cpRecoGrammar->ClearRule(hRule)))//{//  printf("cpRecoGrammar->ClearRule() fail. hr = %x", hr);//  return -10;//}//if (FAILED(hr = cpRecoGrammar->AddWordTransition(hRule, NULL, L"Frank Lee", NULL, SPWT_LEXICAL, 1, NULL)))//{//  printf("cpRecoGrammar->AddWordTransition(1) fail. hr = %x", hr);//  return -11;//}//if (FAILED(hr = cpRecoGrammar->AddWordTransition(hRule, NULL, L"self", NULL, SPWT_LEXICAL, 1, NULL)))//{//  printf("cpRecoGrammar->AddWordTransition(2) fail. hr = %x", hr);//  return -12;//}//if (FAILED(hr = cpRecoGrammar->AddWordTransition(hRule, NULL, L"SAPI beta", NULL, SPWT_LEXICAL, 1, NULL)))//{//  printf("cpRecoGrammar->AddWordTransition(3) fail. hr = %x", hr);//  return -13;//}if (FAILED(hr = cpRecoGrammar->Commit(NULL))){printf("cpRecoGrammar->Commit() fail. hr = %x", hr);return -14;}if (FAILED(hr = cpRecoGrammar->SetGrammarState(SPGS_ENABLED))){printf("cpRecoGrammar->SetGrammarState() fail. hr = %x", hr);return -15;}if (FAILED(hr = cpRecoGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE))){printf("cpRecoGrammar->SetRuleState() fail. hr = %x", hr);}/printf("Read to listen your command:\n");USES_CONVERSION;CComPtr<ISpRecoResult> cpResult; while (SUCCEEDED(hr = BlockForResult(cpRecoCtxt, &cpResult))){CSpDynamicString dstrText;if (SUCCEEDED(cpResult->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL))){printf("I heard:  %s \n", W2A(dstrText));if (fUseTTS){cpVoice->Speak(L"I heard", SPF_ASYNC, NULL);cpVoice->Speak(dstrText, SPF_ASYNC, NULL);}if (fReplay){if (fUseTTS)cpVoice->Speak(L"when you said", SPF_ASYNC, NULL);elseprintf(" when you said ");cpResult->SpeakAudio(NULL, 0, NULL, NULL);}cpResult.Release();}}}}::CoUninitialize();}return hr;
}

命令与控制模式需要使用到配置文件来定义“候选命令”范围,本例中用到XML配置文件“conf.xml”如下:

<GRAMMAR LANGID="804"> <DEFINE><ID NAME="CMD" VAL="10"/></DEFINE><RULE NAME="COMMAND" ID="CMD" TOPLEVEL="ACTIVE"><L><p>东南大学</P><p>滴水洞</p><p>运行趋势分析</p><p>接地监视</p><p>模型异动</p><p>中科院</p></L></RULE>
</GRAMMAR>

C&C模式的优点是识别范围小,识别准确率高,可以识别非常用字词组合。
后续如果有机会将在以下几个方面继续研究:
1. 如何实现动态修改识别范围;
2. 如何实现用候选字词组合成的基本语法,例如“毕业于”+“东南大学”;
3. 如何阻断操作系统“控制指令”对识别过程的干扰。

用SAPI实现Speech Recognition(SR) - 命令控制模式相关推荐

  1. 用SAPI实现Speech Recognition(SR) - 听写模式

    摘选自:"北极悠蓝"的博客<C++使用SAPI实现语音合成和语音识别的方法和代码> 微软的语音识别,在这里我们简称它为SR(speech recognition),SR ...

  2. C++ 九阴真经之命令控制模式

    所谓命令控制模式,就是对应的行为进行封装,通过命令就能控制,你可以理解为linux下指令操作. 比如一个操作包括,A1.A2......A10这10步操作,如果某一步失败,那么就进行倒回,如果这10个 ...

  3. 语音识别系列1:语音识别Speech recognition综述

    名词约定: 语声识别----- VOICE RECOGNITION 语音识别-----SPEECH RECOGNITION 1 什么是语声识别VOICE RECOGNITION? 语音或说话者识别是程 ...

  4. Deep Audio-Visual Speech Recognition翻译

    原文链接:https://arxiv.org/pdf/1809.02108.pdf 这是一篇较为系统的介绍音视频融合的语音识别文章.翻译参考博客园一篇翻译,进行了大量修正和增补. 摘要 本文的目的是基 ...

  5. SIEVE: Secure In-Vehicle Automatic Speech Recognition Systems 论文报告

    一.论文信息 标题:SIEVE: Secure In-Vehicle Automatic Speech Recognition Systems 作者:Shu Wang, Jiahao Cao, Kun ...

  6. 访问者用语音命令控制你的网站。

    语音命令控制你的网站. <script src="//cdnjs.cloudflare.com/ajax/libs/annyang/2.6.0/annyang.min.js" ...

  7. (ICASSP 19)Streaming End-to-end Speech Recognition for Mobile Devices

    会议:ICASSP 2019 论文:Streaming End-to-end Speech Recognition for Mobile Devices 作者:Yanzhang He, Tara N. ...

  8. 体验 Vista Speech Recognition,使梦想成为可能

    还记得我们经常在电影里看到的一个场景么?某人在操作计算机时不单单只是使用键盘或鼠标与计算机进行对话,而是使用语音来直接控制操作计算机,这便是语音识别技术.这项技术其实很早就已经开始在使用,但是应用面却 ...

  9. JS中的语音识别——Speech Recognition API

    JS中的语音识别--Speech Recognition API 简介 HTML5中和Web Speech相关的API实际上有两类,一类是"语音识别(Speech Recognition)& ...

最新文章

  1. 【Android 插件化】DroidPlugin 编译运行 ( DroidPlugin 简介 | 编译 DroidPlugin 官方示例 | 运行 DroidPlugin 官方示例 )
  2. 【C# 调用 Go 语言】0x2 参数、返回值与类型转换
  3. Linux系统有od程序吗,Linux od命令
  4. git remote 命令的用法
  5. qt获取cpu使用率_又一次生产 CPU 高负载排查实践
  6. HTTP请求字符限制和HTTP状态码
  7. python3 十六进制字符串进行分割并累加
  8. (数字IC)低功耗设计入门(五)——RTL级低功耗设计(续)
  9. postman高级用法--断言(Response body:JSON value check)
  10. 使用Arduino Pro Mini和BC95-B5连接物联网
  11. 【EI会议征稿】山西财经大学主办!往届全部成功检索!机器学习、大数据与商务智能征稿中!...
  12. 今日头条文章评论内容爬取
  13. python绘制单列多色柱状图
  14. EnPass+WebDAV(一个跨平台密码管理解决方案)
  15. Java微信公众平台开发之获取地理位置
  16. 【C语言知识梳理之分支语句】
  17. Eclipse运行结果中文为乱码的问题
  18. 位在c语言中用什么定义,C语言中位段的详细介绍
  19. 边缘计算场景下云边端一体化的挑战与实践
  20. Java常见面试题整理(一)

热门文章

  1. Android APK反编译得到Java源代码或资源文件
  2. C++中嵌入ie浏览器总结 .
  3. 收藏:TerryLee的.NET设计模式系列文章
  4. 使用QT定时器 隐藏 label
  5. Java 第一个Java程序
  6. java在注解中绑定方法参数的解决方案
  7. 大文件分片上传,断点续传,秒传 实现
  8. leetcode342合理运用位操作判断4的幂
  9. Atitit.java相比c#.net的优点 优缺点  v2 q330
  10. Markdown大法的尝试