您的位置:首页 > 编程语言 > C语言/C++

c++ 用微软SAPI进行实时语音识别

2016-08-23 11:21 239 查看
VS2015,c++:

#include <windows.h>
#include <sapi.h>
#include <stdio.h>
#include <string.h>
#include <atlbase.h>
#include "sphelper.h"
#include <iostream>

using namespace std;

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;
}
cout<<"Usage: %s [-noTTS] [-noReplay]  "<<argv[0]<<endl;
return hr;
}
}
//此前只是在cmd黑窗里读取命令行到argv中罢了,为了设置是否使用TTS和是否使用Replay功能的,默认情况下都是不填写并且fUseTTS和fReplay值均为true

if (SUCCEEDED(hr = ::CoInitialize(NULL)))
{
{
CComPtr<ISpRecoContext> cpRecoCtxt;
CComPtr<ISpRecoGrammar> cpGrammar;
CComPtr<ISpVoice> cpVoice;
hr = cpRecoCtxt.CoCreateInstance(CLSID_SpSharedRecoContext);//运行次行后打开win8语音识别应用
if (SUCCEEDED(hr))
{
hr = cpRecoCtxt->GetVoice(&cpVoice);
}

if (cpRecoCtxt && cpVoice &&
SUCCEEDED(hr = cpRecoCtxt->SetNotifyWin32Event()) &&
SUCCEEDED(hr = cpRecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION))) &&
SUCCEEDED(hr = cpRecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL)) &&
SUCCEEDED(hr = cpRecoCtxt->CreateGrammar(0, &cpGrammar)) &&
SUCCEEDED(hr = cpGrammar->LoadDictation(NULL, SPLO_STATIC)) &&
SUCCEEDED(hr = cpGrammar->SetDictationState(SPRS_ACTIVE)))
{
USES_CONVERSION;

const WCHAR * const pchStop = StopWord();
CComPtr<ISpRecoResult> cpResult;

cout<<"I will repeat everything you say. Say "<<W2A(pchStop)<< " to exit. "<<endl;//打开监听完毕,此后可开始说语音进行识别

while (SUCCEEDED(hr = BlockForResult(cpRecoCtxt, &cpResult)))
{
cpGrammar->SetDictationState(SPRS_INACTIVE);

CSpDynamicString dstrText;

if (SUCCEEDED(cpResult->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE,
TRUE, &dstrText, NULL)))
{
cout<<"I heard:  "<<W2A(dstrText)<<endl;

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);
else
cout<<" when you said "<<endl;
cpResult->SpeakAudio(NULL, 0, NULL, NULL);
}

cpResult.Release();
}
if (_wcsicmp(dstrText, pchStop) == 0)
{
break;
}

cpGrammar->SetDictationState(SPRS_ACTIVE);
}
}
}
::CoUninitialize();
}
return hr;
}




单独使用WIN8自带的语音识别应用时,可以识别中英文混合语音并执行命令,但是用VS运行启动该应用时就只能识别中文不能识别英文了,所以说“stop”也不能退出该程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: