乙肝大三阳是哪几项阳性,DNA阳性,华为体检能通过吗

21403人阅读
VC++编程技术(782)
基于Windows Sdk 与visual C++2008 在微软平台上构架自己的语音识别引擎(适用于windows 2000/xp2003/vista&& windows CE /mobile),本项目开源,源码请留下你们的Email,我给大家发
本人闲来无事,自行开发了一个小型的语音识别引擎,搭建起在微软平台上的语音识别框架服务体系,
鉴于本人个人力量有限,为了将语音识别引擎做的功能更加强悍,强大,
现在将该系统开源,需要源码的请在本人CSDN博客下留下EMail,
本系统属于系统框架,搭建起一个语音识别的引擎服务框架,
在微软平台上畅通无阻,
现在将本系统构架公布一下,
并贴出相关核心源码,源码体积为37M,编译后为3M,
适用于windows 2000/xp2003/vista&& windows CE /mobile
框架头文件简介:
srengalt.h文件
此文件包含的语音CSrEngineAlternates类。
这实现了接口ISpSRAlternates ,
当一个应用程序GetAlternates或识别的结果, 将
寻找AlternatesCLSID的识别引擎对象,并
创建此对象。 并返回结果
#pragma once
#include "stdafx.h"
#include "SampleSrEngine.h"
#include "resource.h"
class ATL_NO_VTABLE CSrEngineAlternates :
public CComObjectRootEx&CComMultiThreadModel&,
public CComCoClass&CSrEngineAlternates, &CLSID_SampleSREngineAlternates&,
public ISpSRAlternates
DECLARE_REGISTRY_RESOURCEID(IDR_SRENGALT)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSrEngineAlternates)
COM_INTERFACE_ENTRY(ISpSRAlternates)
END_COM_MAP()
STDMETHODIMP GetAlternates(
SPPHRASEALTREQUEST *pAltRequest,
SPPHRASEALT **ppAlts,
ULONG *pcAlts);
STDMETHODIMP Commit(
SPPHRASEALTREQUEST *pAltRequest,
SPPHRASEALT *pAlt,
void **ppvResultExtra,
ULONG *pcbResultExtra);
srengext.h 文件
此文件包含CSampleSRExtension类。
这实现了自定义接口ISampleSRExtension
当一个应用程序开始识别, SAPI的将
寻找ExtensionCLSID领域中的引擎对象的指针,并
创建该对象,然后创建语音识别的要求。
#pragma once
#include "stdafx.h"
#include "SampleSrEngine.h"
#include "resource.h"
class ATL_NO_VTABLE CSampleSRExtension :
public CComObjectRootEx&CComMultiThreadModel&,
public CComCoClass&CSampleSRExtension, &CLSID_SampleSRExtension&,
public ISampleSRExtension,
public ISpDisplayAlternates,
public ISpEnginePronunciation
DECLARE_REGISTRY_RESOURCEID(IDR_SRENGEXT)
DECLARE_GET_CONTROLLING_UNKNOWN()
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSampleSRExtension)
COM_INTERFACE_ENTRY(ISampleSRExtension)
COM_INTERFACE_ENTRY(ISpDisplayAlternates)
COM_INTERFACE_ENTRY(ISpEnginePronunciation)
END_COM_MAP()
HRESULT FinalConstruct()
/ /失败CRecoExt作为一个非累计对象。
/ /创建CRecoExt的SAPI
if(GetControllingUnknown() == dynamic_cast&ISampleSRExtension *&(this) )
return E_FAIL;
/ /这个接口的处理的SAPI 5.1 。
/ /必须QI'd中的FinalConstruct对象并没有释放。
return OuterQueryInterface(IID__ISpPrivateEngineCall, (void **)&m_pEngineCall);
void FinalRelease()
// 不释放IID__ISpPrivateEngineCall这里
STDMETHODIMP ExamplePrivateEngineCall(void); // 测试方法
// ISpDisplayAlternates 方法
STDMETHODIMP GetDisplayAlternates(
const SPDISPLAYPHRASE *pPhrase,
ULONG cRequestCount,
SPDISPLAYPHRASE **ppCoMemPhrases,
ULONG *pcPhrasesReturned);
STDMETHODIMP SetFullStopTrailSpace(ULONG ulTrailSpace);
// ISpEnginePronunciation 方法
STDMETHODIMP Normalize(
LPCWSTR pszWord,
LPCWSTR pszLeftContext,
LPCWSTR pszRightContext,
WORD LangID,
SPNORMALIZATIONLIST *pNormalizationList);
STDMETHODIMP GetPronunciations(
LPCWSTR pszWord,
LPCWSTR pszLeftContext,
LPCWSTR pszRightContext,
WORD LangID,
SPWORDPRONUNCIATIONLIST *pEnginePronunciationList);
_ISpPrivateEngineCall *m_pEngineC
/******************************************************************************
srengobj.h
*此文件包含的宣言CSrEngine类。
*本实施ISpSREngine , ISpSREngine2和ISpObjectWithToken 。
*这是主要识别引擎对象
******************************************************************************/
#pragma once
#include "stdafx.h"
#include "SampleSrEngine.h"
#include "resource.h"
//语音识别对象。每个条目的列表中的一个实例这个类。
class CContext
CContext *
BOOL operator==(SPRECOCONTEXTHANDLE hContext)
return (m_hSapiContext == hContext);
CContext(SPRECOCONTEXTHANDLE hSapiContext) :
m_hSapiContext(hSapiContext)
SPRECOCONTEXTHANDLE m_hSapiC
};//reco语法存储。每个条目的列表中的一个实例这个类。
class CDrvGrammar
CDrvGrammar *
SPGRAMMARHANDLE m_hSapiG //
// 语法是否与听写相关
// 词典是否被激活
WCHAR* m_pWordSequenceT
// 词典词表放在缓冲区
ULONG m_cchT
// 字序缓冲区大小
SPTEXTSELECTIONINFO* m_pI // 文字选择字序缓冲区
CDrvGrammar(SPGRAMMARHANDLE hSapiGrammar) :
m_hSapiGrammar(hSapiGrammar),
m_SLMLoaded(FALSE),
m_SLMActive(FALSE),
m_pWordSequenceText(NULL),
m_cchText(0),
m_pInfo(NULL)
~CDrvGrammar()
/ /释放资源
/ /对于每个语法对象将被释放
SetWordSequenceData(NULL, 0, NULL).
/ / SetWordSequenceData和SetTextSelection将释放的内存
/ /在这里没有必要释放内存的m_pWordSequenceText和m_pInfo .
#ifdef _WIN32_WCE
CDrvGrammar()
static LONG Compare(const CDrvGrammar *, const CDrvGrammar *)
/ /读取的RecognizeStream线程中的音频数据块。每一组
/ /决定如果数据讲话或沉默和价值补充说,此队列。
/ /解码器读取这些线程和进程。
/ /关键部分是用来使队列线程安全的,和一个事件是用来
/ /显示如果缓冲区已空或没有。
/ /这非常象roughtly模拟,这样做的特征提取
/ /一个线程,并通过功能流的解码器。
class CFrameQueue
m_aFrames[100]; // 语音识别返回值
m_hSpaceAvailE
CRITICAL_SECTION m_
CFrameQueue()
m_cFrames = 0;
m_ulHeadIndex = 0;
m_hSpaceAvailEvent = NULL;
InitializeCriticalSection(&m_cs);
~CFrameQueue()
DeleteCriticalSection(&m_cs);
void SetSpaceAvailEvent(HANDLE h)
m_hSpaceAvailEvent =
void InsertTail(BOOL b)
EnterCriticalSection(&m_cs);
ULONG ulTailIndex = (m_ulHeadIndex + m_cFrames) % sp_countof(m_aFrames);
m_aFrames[ulTailIndex] =
m_cFrames++;
if (m_cFrames == sp_countof(m_aFrames))
ResetEvent(m_hSpaceAvailEvent);
LeaveCriticalSection(&m_cs);
BOOL IsFull()
EnterCriticalSection(&m_cs);
BOOL b = (m_cFrames == sp_countof(m_aFrames));
LeaveCriticalSection(&m_cs);
BOOL RemoveHead()
EnterCriticalSection(&m_cs);
BOOL b = m_aFrames[m_ulHeadIndex];
m_ulHeadIndex = (m_ulHeadIndex + 1) % sp_countof(m_aFrames);
m_cFrames--;
SetEvent(m_hSpaceAvailEvent);
LeaveCriticalSection(&m_cs);
BOOL HasData()
EnterCriticalSection(&m_cs);
ULONG cFrames = m_cF
LeaveCriticalSection(&m_cs);
//我们可以使用CSpBasicQueue信息存储规则
class CRuleEntry
BOOL operator==(SPRULEHANDLE rh)
return (m_hRule == rh);
CRuleEntry
SPRULEHANDLE m_hR
// SAPI 规则句柄
BOOL m_fTopL
// 显示规则是否被激活
// 显示识别引擎的设置
// 语音识别类
class ATL_NO_VTABLE CSrEngine :
public CComObjectRootEx&CComMultiThreadModel&,
public CComCoClass&CSrEngine, &CLSID_SampleSREngine&,
public ISpSREngine2,
public ISpObjectWithToken,
public ISpThreadTask
CSrEngine() :
m_ulNextGrammarIndex(0),
m_cActive(0),
m_bPhraseStarted(FALSE),
m_bSoundStarted(FALSE),
m_hQueueHasRoom(NULL),
m_hRequestSync(NULL),
m_LangID(0)
DECLARE_REGISTRY_RESOURCEID(IDR_SRENG)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSrEngine)
COM_INTERFACE_ENTRY(ISpSREngine)
COM_INTERFACE_ENTRY(ISpSREngine2)
COM_INTERFACE_ENTRY(ISpObjectWithToken)
END_COM_MAP()
m_hRequestS
CFrameQueue
CSpBasicQueue&CDrvGrammar&
m_GrammarL
CSpBasicQueue&CContext&
m_ContextL
m_ulNextGrammarI
m_bSoundStarted:1;
m_bPhraseStarted:1;
CComPtr&ISpSREngineSite&
CComPtr&ISpThreadControl&
m_cpDecoderT
m_hQueueHasR
CSpBasicQueue&CRuleEntry&
CComPtr&ISpLexicon&
CComPtr&ISpObjectToken&
m_cpEngineObjectT
CComPtr&ISpObjectToken&
m_cpUserObjectT
HRESULT RandomlyWalkRule(SPRECORESULTINFO * pResult, ULONG nWords, ULONGLONG ullAudioPos, ULONG ulAudioSize);
HRESULT RecurseWalk(SPSTATEHANDLE hState, SPPATHENTRY * pPath, ULONG * pcTrans);
HRESULT WalkCFGRule(SPRECORESULTINFO * pResult, ULONG cRulesActive, BOOL fHypothesis,
ULONG nWords, ULONGLONG ullAudioPos, ULONG ulAudioSize);
HRESULT WalkSLM(SPRECORESULTINFO * pResult, ULONG cSLMActive,
ULONG nWords, ULONGLONG ullAudioPos, ULONG ulAudioSize);
HRESULT WalkTextBuffer(void* pvGrammarCookie, SPPATHENTRY * pPath, SPTRANSITIONID hId, ULONG * pcTrans);
HRESULT AddEvent(SPEVENTENUM eEvent, ULONGLONG ullStreamPos, WPARAM wParam = 0, LPARAM lParam = 0);
HRESULT AddEventString(SPEVENTENUM eEvent, ULONGLONG ulLStreamPos, const WCHAR * psz, WPARAM = 0);
HRESULT CreatePhraseFromRule( CRuleEntry * pRule, BOOL fHypothesis,
ULONGLONG ullAudioPos, ULONG ulAudioSize,
ISpPhraseBuilder** ppPhrase );
CRuleEntry* FindRule( ULONG ulRuleIndex );
CRuleEntry* NextRuleAlt( CRuleEntry * pPriRule, CRuleEntry * pLastRule );
void _CheckRecognition();
void _NotifyRecognition(BOOL fHypothesis, ULONG nWords);
HRESULT FinalConstruct();
HRESULT FinalRelease();
STDMETHODIMP SetObjectToken(ISpObjectToken * pToken);
STDMETHODIMP GetObjectToken(ISpObjectToken ** ppToken);
STDMETHODIMP SetRecoProfile(ISpObjectToken * pProfileToken);
STDMETHODIMP SetSite(ISpSREngineSite *pSite);
STDMETHODIMP GetInputAudioFormat(const GUID * pSrcFormatId, const WAVEFORMATEX * pSrcWFEX,
GUID * pDesiredFormatId, WAVEFORMATEX ** ppCoMemDesiredWFEX);
STDMETHODIMP OnCreateRecoContext(SPRECOCONTEXTHANDLE hSAPIRecoContext, void ** ppvDrvCtxt);
STDMETHODIMP OnDeleteRecoContext(void * pvDrvCtxt);
STDMETHODIMP OnCreateGrammar(void * pvEngineRecoContext,
SPGRAMMARHANDLE hSAPIGrammar,
void ** ppvEngineGrammar);
STDMETHODIMP OnDeleteGrammar(void * pvEngineGrammar);
STDMETHODIMP WordNotify(SPCFGNOTIFY Action, ULONG cWords, const SPWORDENTRY * pWords);
STDMETHODIMP RuleNotify(SPCFGNOTIFY Action, ULONG cRules, const SPRULEENTRY * pRules);
STDMETHODIMP LoadProprietaryGrammar(void * pvEngineGrammar,
REFGUID rguidParam,
const WCHAR * pszStringParam,
const void * pvDataParam,
ULONG ulDataSize,
SPLOADOPTIONS Options)
return E_NOTIMPL;
STDMETHODIMP UnloadProprietaryGrammar(void * pvEngineGrammar)
return E_NOTIMPL;
STDMETHODIMP SetProprietaryRuleState(void * pvEngineGrammar,
const WCHAR * pszName,
void * pvReserved,
SPRULESTATE NewState,
ULONG * pcRulesChanged)
return E_NOTIMPL;
STDMETHODIMP SetProprietaryRuleIdState(void * pvEngineGrammar,
DWORD dwRuleId,
SPRULESTATE NewState)
return E_NOTIMPL;
/由于这个引擎不支持专有的语法,我们并不需要执行
/ /此方法不仅仅是返回S_OK 。注意执行不返回 E_NOTIMPL 。
/ /仅仅返回S_OK ,并忽略这个数据如果您不需要它执行专有语法。
STDMETHODIMP SetGrammarState(void * pvEngineGrammar, SPGRAMMARSTATE eGrammarState)
return S_OK;
STDMETHODIMP SetContextState(void * pvEngineContxt, SPCONTEXTSTATE eCtxtState)
return S_OK;
// 字典方法
STDMETHODIMP LoadSLM(void * pvEngineGrammar, const WCHAR * pszTopicName);
STDMETHODIMP UnloadSLM(void * pvEngineGrammar);
STDMETHODIMP SetSLMState(void * pvEngineGrammar, SPRULESTATE NewState);
STDMETHODIMP IsPronounceable(void *pDrvGrammar, const WCHAR *pszWord, SPWORDPRONOUNCEABLE * pWordPronounceable);
STDMETHODIMP SetWordSequenceData(void * pvEngineGrammar, const WCHAR * pText, ULONG cchText, const SPTEXTSELECTIONINFO * pInfo);
STDMETHODIMP SetTextSelection(void * pvEngineGrammar, const SPTEXTSELECTIONINFO * pInfo);
STDMETHODIMP SetAdaptationData(void * pvEngineCtxtCookie, const WCHAR * pText, const ULONG cch);
STDMETHODIMP SetPropertyNum( SPPROPSRC eSrc, void* pvSrcObj, const WCHAR* pName, LONG lValue );
STDMETHODIMP GetPropertyNum( SPPROPSRC eSrc, void* pvSrcObj, const WCHAR* pName, LONG * plValue );
STDMETHODIMP SetPropertyString( SPPROPSRC eSrc, void* pvSrcObj, const WCHAR* pName, const WCHAR* pValue );
STDMETHODIMP GetPropertyString( SPPROPSRC eSrc, void* pvSrcObj, const WCHAR* pName, __deref_out_opt WCHAR** ppCoMemValue );
// 语音识别方法
STDMETHODIMP RecognizeStream(REFGUID rguidFmtId, const WAVEFORMATEX * pWaveFormatEx,
HANDLE hRequestSync, HANDLE hDataAvailable,
HANDLE hExit, BOOL fNewAudioStream, BOOL fRealTimeAudio,
ISpObjectToken * pAudioObjectToken);
STDMETHODIMP PrivateCall(void * pvEngineContext, void * pCallFrame, ULONG ulCallFrameSize);
STDMETHODIMP PrivateCallEx(void * pvEngineContext, const void * pInCallFrame, ULONG ulCallFrameSize,
void ** ppvCoMemResponse, ULONG * pcbResponse);
// 语音识别线程
STDMETHODIMP InitThread( void * pvTaskData, HWND hwnd )
return S_OK;
LRESULT STDMETHODCALLTYPE WindowMessage( void *pvTaskData, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
return E_UNEXPECTED;
STDMETHODIMP ThreadProc( void *pvTaskData, HANDLE hExitThreadEvent, HANDLE hNotifyEvent, HWND hwndWorker, volatile const BOOL * pfContinueProcessing );
// 语音引擎方法
STDMETHODIMP PrivateCallImmediate(
void *pvEngineContext,
const void *pInCallFrame,
ULONG ulInCallFrameSize,
void **ppvCoMemResponse,
ULONG *pulResponseSize);
STDMETHODIMP SetAdaptationData2(
void *pvEngineContext,
__in_ecount(cch)
const WCHAR *pAdaptationData,
const ULONG cch,
LPCWSTR pTopicName,
SPADAPTATIONSETTINGS eSettings,
SPADAPTATIONRELEVANCE eRelevance);
STDMETHODIMP SetGrammarPrefix(
void *pvEngineGrammar,
LPCWSTR pszPrefix,
BOOL fIsPrefixRequired);
STDMETHODIMP SetRulePriority(
SPRULEHANDLE hRule,
void *pvClientRuleContext,
int nRulePriority);
STDMETHODIMP EmulateRecognition(
ISpPhrase *pPhrase,
DWORD dwCompareFlags);
STDMETHODIMP SetSLMWeight(
void *pvEngineGrammar,
float flWeight);
STDMETHODIMP SetRuleWeight(
SPRULEHANDLE hRule,
void *pvClientRuleContext,
float flWeight);
STDMETHODIMP SetTrainingState(
BOOL fDoingTraining,
BOOL fAdaptFromTrainingData);
STDMETHODIMP ResetAcousticModelAdaptation( void);
STDMETHODIMP OnLoadCFG(
void *pvEngineGrammar,
const SPBINARYGRAMMAR *pGrammarData,
ULONG ulGrammarID);
STDMETHODIMP OnUnloadCFG(
void *pvEngineGrammar,
ULONG ulGrammarID);
/******************************************************************************
*此文件包含的语音识别界面CSrEngineUI类。
*这里的方法可以是所谓的应用程序直接从ISpObjectToken获取识别结果
******************************************************************************/
#pragma once
#include "resource.h"
class ATL_NO_VTABLE CSrEngineUI :
public CComObjectRootEx&CComMultiThreadModel&,
public CComCoClass&CSrEngineUI, &CLSID_SampleSREngineUI&,
public ISpTokenUI
DECLARE_REGISTRY_RESOURCEID(IDR_SRENGUI)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSrEngineUI)
COM_INTERFACE_ENTRY(ISpTokenUI)
END_COM_MAP()
STDMETHODIMP IsUISupported(
const WCHAR * pszTypeOfUI,
void * pvExtraData,
ULONG cbExtraData,
IUnknown * punkObject,
BOOL *pfSupported);
STDMETHODIMP DisplayUI(
HWND hwndParent,
const WCHAR * pszTitle,
const WCHAR * pszTypeOfUI,
void * pvExtraData,
ULONG cbExtraData,
ISpObjectToken * pToken,
IUnknown * punkObject);
#ifndef VER_H
/* ver.h 定义用到的常用值 */
//#include &winver.h&
#include &windows.h&
#define VER_FILETYPE
#define VER_FILESUBTYPE
VFT2_UNKNOWN
#define VER_FILEDESCRIPTION_STR
"SR SAMPLE ENGINE 5"
#define VER_INTERNALNAME_STR
"SRSAMPLEENG5"
#define VERSION
#define VER_FILEVERSION_STR
#define VER_FILEVERSION
#define VER_PRODUCTVERSION_STR
#define VER_PRODUCTVERSION
#define OFFICIAL
#define FINAL
#if _DEBUG
#define VER_DEBUG
VS_FF_DEBUG
#define VER_DEBUG
#ifndef OFFICIAL
#define VER_PRIVATEBUILD
VS_FF_PRIVATEBUILD
#define VER_PRIVATEBUILD
#ifndef FINAL
#define VER_PRERELEASE
VS_FF_PRERELEASE
#define VER_PRERELEASE
#define VER_FILEFLAGSMASK
VS_FFI_FILEFLAGSMASK
#define VER_FILEOS
VOS_DOS_WINDOWS32
#define VER_FILEFLAGS
(VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG)
#define VER_COMPANYNAME_STR
"Microsoft Corporation/0"
#define VER_PRODUCTNAME_STR
"Microsoft/256 Windows(TM) Operating System/0"
#define VER_LEGALTRADEMARKS_STR
SampleSrEngine.cpp语音识别引擎实例
创建一个语音识别服务
#include "stdafx.h"
#include "resource.h"
#include &initguid.h&
#include "SampleSrEngine.h"
#include "SampleSrEngine_i.c"
#include "SampleSrEngine.h"
#include "srengobj.h"
#include "srengui.h"
#include "srengext.h"
#include "srengalt.h"
CComModule _M
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SampleSREngine,
CSrEngine)
OBJECT_ENTRY(CLSID_SampleSREngineUI, CSrEngineUI)
OBJECT_ENTRY(CLSID_SampleSRExtension,
CSampleSRExtension)
OBJECT_ENTRY(CLSID_SampleSREngineAlternates, CSrEngineAlternates)
END_OBJECT_MAP()
/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
#ifdef _WIN32_WCE
extern "C"
BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
if (dwReason == DLL_PROCESS_ATTACH)
_Module.Init(ObjectMap, (HINSTANCE)hInstance, &LIBID_SRENGLib);
else if (dwReason == DLL_PROCESS_DETACH)
_Module.Term();
return TRUE;
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
if (dwReason == DLL_PROCESS_ATTACH)
_Module.Init(ObjectMap, hInstance, &LIBID_SRENGLib);
DisableThreadLibraryCalls(hInstance);
else if (dwReason == DLL_PROCESS_DETACH)
_Module.Term();
return TRUE;
STDAPI DllCanUnloadNow(void)
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
return _Module.GetClassObject(rclsid, riid, ppv);
STDAPI DllRegisterServer(void)
return _Module.RegisterServer(TRUE);
STDAPI DllUnregisterServer(void)
return _Module.UnregisterServer(TRUE);
SampleSrEngine.def引擎公开
"SampleSrEngine.DLL"
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer PRIVATE
/ / SampleSrEngine.idl : IDL编译器源SampleSrEngine.dll
/ /此文件将由MIDL工具
/ /产生的类型库( SampleSrEngine.tlb )和编组代码
import "oaidl.idl";
import "ocidl.idl";
import "sapiddk.idl";
typedef [restricted, hidden] struct SPDISPLAYTOKEN
const WCHAR
const WCHAR
} SPDISPLAYTOKEN;
typedef [restricted, hidden] struct SPDISPLAYPHRASE
SPDISPLAYTOKEN
} SPDISPLAYPHRASE;
uuid(BBC18F3B-CF35-4f7c-99E8-D1F803AB4851),
helpstring("ISampleSRExtension Interface"),
pointer_default(unique)
interface ISampleSRExtension : IUnknown
HRESULT ExamplePrivateEngineCall(void);
uuid(C8D7C7E2-0DDE-44b7-AFE3-B0C991FBEB5E),
helpstring("ISpDisplayAlternates Interface"),
pointer_default(unique),
interface ISpDisplayAlternates : IUnknown
HRESULT GetDisplayAlternates(
[in] const SPDISPLAYPHRASE *pPhrase,
[in] ULONG cRequestCount,
[annotation("__out_ecount_part(cRequestCount, *pcPhrasesReturned)")][out] SPDISPLAYPHRASE **ppCoMemPhrases,
[out] ULONG *pcPhrasesReturned);
HRESULT SetFullStopTrailSpace([in] ULONG ulTrailSpace);
uuid(41B89B6C--F8EE628),
version(1.0),
helpstring("SampleSrEngine 1.0 Type Library")
library SRENGLib
importlib("stdole32.tlb");
importlib("stdole2.tlb");
uuid(41B89B79--F8EE628),
helpstring("Sample SR Engine Class")
coclass SampleSREngine
[default] interface ISpSRE
uuid(BBFD-405D-83C5-E9C),
helpstring("Sample SR Engine UI Class")
coclass SampleSREngineUI
[default] interface ISpTokenUI;
uuid(78771A48-CE55-46a5-B78C-B813E3403F82),
helpstring("Sample SR Engine Extension Class")
coclass SampleSRExtension
[default] interface ISampleSRE
interface ISpDisplayA
uuid(882CAE4A-99BA-490b-BF80-CF69A60454A7),
helpstring("Sample SR Engine Alternates Class")
coclass SampleSREngineAlternates
[default] interface ISpSRA
* srengui.cpp
*此文件包含执行CSrEngineUI界面。
*本实施ISpTokenUI 。这是使用的应用程序,以显示用户界面。
*这里的方法可以是所谓的应用程序直接从ISpObjectToken获取电话
*能作为一个电话识别服务
******************************************************************************/
#include "stdafx.h"
#include "SampleSrEngine.h"
#include "srengui.h"
/************************************************* ***************************
* CSrEngineUI : : IsUISupported *
*----------------------------*
*确定是否对用户界面的支持。提到主要引擎
*对象(如果已建立) ,可从punkObject 。
*如果没有空,这可能是一个ISpRecoContext ,其中一个引擎
*扩展接口可以得到。
* S_OK成功
* E_INVALIDARG无效论点
************************************************** ***************************/
STDMETHODIMP CSrEngineUI::IsUISupported(const WCHAR * pszTypeOfUI, void * pvExtraData, ULONG cbExtraData, IUnknown * punkObject, BOOL *pfSupported)
*pfSupported = FALSE;
if (wcscmp(pszTypeOfUI, SPDUI_EngineProperties) == 0)
*pfSupported = TRUE;
if (wcscmp(pszTypeOfUI, SPDUI_UserTraining) == 0 && punkObject != NULL)
*pfSupported = TRUE;
if (wcscmp(pszTypeOfUI, SPDUI_MicTraining) == 0 && punkObject != NULL)
*pfSupported = TRUE;
return S_OK;
STDMETHODIMP CSrEngineUI::DisplayUI(HWND hwndParent, const WCHAR * pszTitle, const WCHAR * pszTypeOfUI, void * pvExtraData, ULONG cbExtraData, ISpObjectToken * pToken, IUnknown * punkObject)
if (wcscmp(pszTypeOfUI, SPDUI_EngineProperties) == 0)
if (punkObject)
MessageBoxW(hwndParent, L"Developer Sample Engine: Replace this with real engine properties dialog.", pszTitle, MB_OK);
if (wcscmp(pszTypeOfUI, SPDUI_UserTraining) == 0)
MessageBoxW(hwndParent, L"Developer Sample Engine: Replace this with real user training wizard / dialog.", pszTitle, MB_OK);
if (wcscmp(pszTypeOfUI, SPDUI_MicTraining) == 0)
MessageBoxW(hwndParent, L"Developer Sample Engine: Replace this with real microphone training wizard / dialog.", pszTitle, MB_OK);
return S_OK;
/******************************************************************************
* srengobj.cpp
*此文件包含执行CSrEngine级。
*本实施ISpSREngine , ISpSREngine2和ISpObjectWithToken 。
*这是主要识别对象
******************************************************************************/
#include "stdafx.h"
#include "SampleSrEngine.h"
#include "srengobj.h"
#include "SpHelper.h"
#ifndef _WIN32_WCE
#include "shfolder.h"
static const WCHAR DICT_WORD[] = L"Blah";
static const WCHAR ALT_WORD[] = L"Alt";
HRESULT CSrEngine::FinalConstruct()
HRESULT hr = S_OK;
m_hQueueHasRoom = ::CreateEvent(NULL, TRUE, TRUE, NULL);
m_FrameQueue.SetSpaceAvailEvent(m_hQueueHasRoom);
CComPtr&ISpTaskManager& cpTaskM
hr = cpTaskMgr.CoCreateInstance(CLSID_SpResourceManager);
if (SUCCEEDED(hr))
hr = cpTaskMgr-&CreateThreadControl(this, this, THREAD_PRIORITY_NORMAL, &m_cpDecoderThread);
if(SUCCEEDED(hr))
hr = m_cpLexicon.CoCreateInstance(CLSID_SpLexicon);
HRESULT CSrEngine::FinalRelease()
::CloseHandle(m_hQueueHasRoom);
return S_OK;
/****************************************************************************
* CSrEngine : : SetObjectToken *
*---------------------------*
*这种方法被称为后立即通过的SAPI引擎创建。
*它可以用来获得特定的注册表信息引擎。
*新的扫描引擎能恢复过来的凭证文件路径存储在安装过程中。
*该引擎还可以恢复用户设置为默认值的准确性,排斥等
*也可以有不同的发动机共享同一代码基础(的CLSID ) ,但具有不同登录信息
*例如:如果引擎支持不同的语言
*失败(小时)
*****************************************************************************/
STDMETHODIMP CSrEngine::SetObjectToken(ISpObjectToken * pToken)
HRESULT hr = S_OK;
hr = SpGenericSetObjectToken(pToken, m_cpEngineObjectToken);
if(FAILED(hr))
CComPtr&ISpDataKey& cpAttribK
hr = pToken-&OpenKey(L"Attributes", &cpAttribKey);
if(SUCCEEDED(hr))
WCHAR *psz = NULL;
hr = cpAttribKey-&GetStringValue(L"Desktop", &psz);
::CoTaskMemFree(psz);
if(SUCCEEDED(hr))
else if(hr == SPERR_NOT_FOUND)
hr = cpAttribKey-&GetStringValue(L"Telephony", &psz);
::CoTaskMemFree(psz);
if(SUCCEEDED(hr))
if(SUCCEEDED(hr))
WCHAR *pszLangID = NULL;
hr = cpAttribKey-&GetStringValue(L"Language", &pszLangID);
if(SUCCEEDED(hr))
m_LangID = (unsigned short)wcstol(pszLangID, NULL, 16);
::CoTaskMemFree(pszLangID);
// Default language (US English)
m_LangID = 0x409;
WCHAR *pszPath = NULL;
hr = pToken-&GetStorageFileName(CLSID_SampleSREngine, L"SampleEngDataFile", NULL, 0, &pszPath);
::CoTaskMemFree(pszPath);
/****************************************************************************
* CSrEngine : : GetObjectToken *
*---------------------------*
*这种方法被称为的SAPI令牌,如果找到这些对象令牌,该引擎使用
*失败(小时)
*****************************************************************************/
STDMETHODIMP CSrEngine::GetObjectToken(ISpObjectToken ** ppToken)
return SpGenericGetObjectToken(ppToken, m_cpEngineObjectToken);
/****************************************************************************
* CSrEngine : : SetSite *
*---------------------------*
*这就是所谓的让引擎的参考ISpSREngineSite 。
*引擎使用此呼吁回的SAPI 。
*失败(小时)
*****************************************************************************/
STDMETHODIMP CSrEngine::SetSite(ISpSREngineSite *pSite)
m_cpSite = pS
return S_OK;
/****************************************************************************
* CSrEngine : : SetRecoProfile *
*---------------------------*
*在RecoProfile是一个对象令牌举行关于当前
*用户和注册会议。该引擎可以存储在这里的任何信息
*它喜欢。它应存放在一个关键的RecoProfile主要命名引擎类ID 。
*失败(小时)
*****************************************************************************/
STDMETHODIMP CSrEngine::SetRecoProfile(ISpObjectToken *pProfile)
HRESULT hr = S_OK;
WCHAR *pszCLSID, *pszPath = NULL;
CComPtr&ISpDataKey& dataK
m_cpUserObjectToken = pP
hr = ::StringFromCLSID(CLSID_SampleSREngine, &pszCLSID);
if(FAILED(hr))
hr = pProfile-&OpenKey(pszCLSID, &dataKey);
if(hr == SPERR_NOT_FOUND)
hr = pProfile-&CreateKey(pszCLSID, &dataKey);
if(SUCCEEDED(hr))
hr = dataKey-&SetStringValue(L"GENDER", L"UNKNOWN");
if(SUCCEEDED(hr))
hr = dataKey-&SetStringValue(L"AGE", L"UNKNOWN");
if(SUCCEEDED(hr))
pProfile-&GetStorageFileName(CLSID_SampleSREngine, L"SampleEngTrainingFile", NULL, CSIDL_FLAG_CREATE | CSIDL_LOCAL_APPDATA, &pszPath);
hr = AddEventString(SPEI_REQUEST_UI, 0, SPDUI_UserTraining);
else if(SUCCEEDED(hr))
WCHAR *pszGender = NULL, *pszAge = NULL;
hr = dataKey-&GetStringValue(L"GENDER", &pszGender);
if(SUCCEEDED(hr))
hr = dataKey-&GetStringValue(L"AGE", &pszAge);
if(SUCCEEDED(hr))
hr = pProfile-&GetStorageFileName(CLSID_SampleSREngine, L"SampleEngTrainingFile", NULL, 0, &pszPath);
::CoTaskMemFree(pszGender);
::CoTaskMemFree(pszAge);
::CoTaskMemFree(pszPath);
::CoTaskMemFree(pszCLSID);
/****************************************************************************
* CSrEngine : : OnCreateRecoContext *
*---------------------------*
*这种方法被称为每当有新reco方面是建立在
*申请使用这个引擎。
*本示例引擎不严格需要信息reco背景
*但是,以供参考,我们将继续清单一人。
*失败(小时)
*****************************************************************************/
STDMETHODIMP CSrEngine::OnCreateRecoContext(SPRECOCONTEXTHANDLE hSapiContext, void ** ppvDrvCtxt)
CContext * pContext = new CContext(hSapiContext);
// Store a reference to the CContext structure
*ppvDrvCtxt = pC
m_ContextList.InsertHead(pContext);
return S_OK;
/****************************************************************************
* CSrEngine : : OnDeleteRecoContext *
*---------------------------*
*这种方法被称为每次reco方面被删除。
*****************************************************************************/
STDMETHODIMP CSrEngine::OnDeleteRecoContext(void * pvDrvCtxt)
CContext * pContext = (CContext *) pvDrvC
m_ContextList.Remove(pContext);
return S_OK;
/****************************************************************************
* CSrEngine : : OnCreateGrammar *
*---------------------------*
*这种方法被称为每当有新reco语法中创建
*申请使用这个引擎。
*我们保留名单语法-存储一个指针列表条目ppvEngineGrammar 。
*****************************************************************************/
STDMETHODIMP CSrEngine::OnCreateGrammar(void * pvEngineRecoContext, SPGRAMMARHANDLE hSapiGrammar, void ** ppvEngineGrammar)
CContext * pContext = (CContext *) pvEngineRecoC
_ASSERT(m_ContextList.Find(pContext-&m_hSapiContext));
CDrvGrammar * pGrammar = new CDrvGrammar(hSapiGrammar);
*ppvEngineGrammar = pG
m_GrammarList.InsertHead(pGrammar);
return S_OK;
/****************************************************************************
* CSrEngine : : OnDeleteGrammar *
*---------------------------*
*这种方法被称为每次reco语法被删除。
*****************************************************************************/
STDMETHODIMP CSrEngine::OnDeleteGrammar(void * pvDrvGrammar)
CDrvGrammar * pGrammar = (CDrvGrammar *)pvDrvG
m_GrammarList.Remove(pGrammar);
return S_OK;
STDMETHODIMP CSrEngine::WordNotify(SPCFGNOTIFY Action, ULONG cWords, const SPWORDENTRY * pWords)
HRESULT hr = S_OK;
WCHAR *wordP
switch(Action){
case SPCFGN_ADD:
SPWORDENTRY WordE
for(i = 0; SUCCEEDED(hr) && i & cW i++)
WordEntry = pWords[i];
hr = m_cpSite-&GetWordInfo(&WordEntry, SPWIO_WANT_TEXT);
if(SUCCEEDED(hr) && WordEntry.aPhoneId)
size_t cWordPron = wcslen(WordEntry.aPhoneId) + 1;
wordPron = new WCHAR[cWordPron];
wcscpy_s(wordPron, cWordPron, WordEntry.aPhoneId);
::CoTaskMemFree((void*)WordEntry.aPhoneId);
SPWORDPRONUNCIATIONLIST PronL
PronList.pFirstWordPronunciation = 0;
PronList.pvBuffer = 0;
PronList.ulSize = 0;
hr = m_cpLexicon-&GetPronunciations(WordEntry.pszLexicalForm, eLEXTYPE_APP | eLEXTYPE_USER, pWords[i].LangID, &PronList);
if(SUCCEEDED(hr))
if(PronList.pFirstWordPronunciation != NULL)
size_t cWordPron = wcslen(PronList.pFirstWordPronunciation-&szPronunciation) + 1;
wordPron = new WCHAR[cWordPron];
wcscpy_s(wordPron, cWordPron, PronList.pFirstWordPronunciation-&szPronunciation);
::CoTaskMemFree(PronList.pvBuffer);
wordPron = NULL;
else if(hr == SPERR_NOT_IN_LEX)
wordPron = NULL;
hr = S_OK;
if(SUCCEEDED(hr))
hr = m_cpSite-&SetWordClientContext(WordEntry.hWord, wordPron);
if (SUCCEEDED(hr))
::CoTaskMemFree((void*)WordEntry.pszDisplayText);
::CoTaskMemFree((void*)WordEntry.pszLexicalForm);
case SPCFGN_REMOVE:
for(i = 0; i & cW i++)
WordEntry = pWords[i];
wordPron = (WCHAR *) WordEntry.pvClientC
if(wordPron)
delete[] wordP
/****************************************************************************
* CSrEngine : : RuleNotify *
*---------------------------*
*这种方法被称为由SAPI的通知引擎的规则,
*指挥及控制语法。该命令或行动CFG桩语法是这种形式:
* WordNotify ( SPCFGN_ADD ) -添加关键词
* RuleNotify ( SPCFGN_ADD ) -添加规则
* RuleNotify ( SPCFGN_ACTIVATE ) -激活规则,以表明它们是用于识别
* RuleNotify ( SPCFGN_INVALIDATE ) -如果规则得到编辑的应用程序那么这就是所谓的
* RuleNotify ( SPCFGN_DEACTIVE ) -停用规则
* RuleNotify ( SPCFGN_REMOVE ) -删除规则
* WordNotify ( SPCFGN_REMOVE ) -删除字词
*该引擎可致电GetRuleInfo找到初始状态中的规则,
*然后GetStateInfo找到有关国家和转型以后的规则。
*如果规则编辑然后SPCFGN_INVALIDATE称为表明规则已经改变,使引擎
*必须重法治的信息。
*新的扫描引擎能获得所有有关的规则之前或期间承认。
*在此示例中,我们只是保持发动机的清单规则最初然后等待
*直到我们要生成的结果,然后找到一个随机的路径规则。
*****************************************************************************/
STDMETHODIMP CSrEngine::RuleNotify(SPCFGNOTIFY Action, ULONG cRules, const SPRULEENTRY * pRules)
CRuleEntry *pRuleE
switch (Action)
case SPCFGN_ADD:
for (i = 0; i & cR i++)
pRuleEntry = new CRuleE
pRuleEntry-&m_hRule = pRules[i].hR
pRuleEntry-&m_fTopLevel = (pRules[i].Attributes & SPRAF_TopLevel);
pRuleEntry-&m_fActive = (pRules[i].Attributes & SPRAF_Active);
m_RuleList.InsertHead(pRuleEntry);
m_cpSite-&SetRuleClientContext(pRules[i].hRule, (void *)pRuleEntry);
case SPCFGN_REMOVE:
for (i = 0; i & cR i++)
pRuleEntry = m_RuleList.Find(pRules[i].hRule);
_ASSERT(pRuleEntry); // The rule must have been added before being removed
m_RuleList.Remove(pRuleEntry);
delete pRuleE
case SPCFGN_ACTIVATE:
for (i = 0; i & cR i++)
pRuleEntry = m_RuleList.Find(pRules[i].hRule);
_ASSERT(pRuleEntry && !pRuleEntry-&m_fActive && pRuleEntry-&m_fTopLevel);
if (pRuleEntry != NULL)
pRuleEntry-&m_fActive = TRUE;
case SPCFGN_DEACTIVATE:
for (i = 0; i & cR i++)
pRuleEntry = m_RuleList.Find(pRules[i].hRule);
_ASSERT(pRuleEntry && pRuleEntry-&m_fActive && pRuleEntry-&m_fTopLevel);
if (pRuleEntry != NULL)
pRuleEntry-&m_fActive = FALSE;
case SPCFGN_INVALIDATE:
for (i = 0; i & cR i++)
pRuleEntry = m_RuleList.Find(pRules[i].hRule);
_ASSERT(pRuleEntry);
if (pRuleEntry != NULL)
pRuleEntry-&m_fTopLevel = (pRules[i].Attributes & SPRAF_TopLevel);
pRuleEntry-&m_fActive = (pRules[i].Attributes & SPRAF_Active);
return S_OK;
/****************************************************************************
* CSrEngine : : LoadSLM *
*---------------------------*
*时调用的SAPI希望引擎加载dictaion语言模式( SLM ) 。
*对于每一个听写reco gramar以及命令与征服规则可以被装载。
*****************************************************************************/
STDMETHODIMP CSrEngine::LoadSLM(void * pvEngineGrammar, const WCHAR * pszTopicName)
if (pszTopicName)
CDrvGrammar * pGrammar = (CDrvGrammar *)pvEngineG
pGrammar-&m_SLMLoaded = TRUE;
return S_OK;
/****************************************************************************
* CSrEngine : : UnloadSLM *
*---------------------------*
*时调用的SAPI希望引擎删除解运。
*****************************************************************************/
STDMETHODIMP CSrEngine::UnloadSLM(void *pvEngineGrammar)
CDrvGrammar * pGrammar = (CDrvGrammar *)pvEngineG
pGrammar-&m_SLMLoaded = FALSE;
return S_OK;
/****************************************************************************
* CSrEngine : : SetSLMState *
*---------------------------*
*调用以激活或停用的语法
* NewState要么SPRS_ACTIVE或SPRS_INACTIVE 。
*****************************************************************************/
HRESULT CSrEngine::SetSLMState(void * pvDrvGrammar, SPRULESTATE NewState)
CDrvGrammar * pGrammar = (CDrvGrammar *)pvDrvG
if (NewState != SPRS_INACTIVE)
pGrammar-&m_SLMActive = TRUE;
pGrammar-&m_SLMActive = FALSE;
return S_OK;
/****************************************************************************
* CSrEngine : : SetWordSequenceData *
*---------------------------*
*如果应用程序提交一个文本缓冲区的SAPI这种方法被称为。
*的文本缓冲区这里提供可以用于CFGs的文本缓冲区过渡,
*或听写提供资料的发动机事先看见屏幕上的文字。
*本示例引擎就是使用文字的文本缓冲区缓冲区过渡。
*****************************************************************************/
STDMETHODIMP CSrEngine::SetWordSequenceData(void *pvEngineGrammar, const WCHAR *pText, ULONG cchText, const SPTEXTSELECTIONINFO *pInfo)
CDrvGrammar * pGrammar = (CDrvGrammar*)pvEngineG
if(pGrammar-&m_pWordSequenceText)
delete pGrammar-&m_pWordSequenceT
if(cchText)
pGrammar-&m_pWordSequenceText = new WCHAR[cchText];
memcpy((void *)pGrammar-&m_pWordSequenceText, pText, sizeof(WCHAR) * cchText);
pGrammar-&m_cchText = cchT
pGrammar-&m_pWordSequenceText = NULL;
pGrammar-&m_cchText = NULL;
SetTextSelection(pvEngineGrammar, pInfo);
return S_OK;
/****************************************************************************
* CSrEngine : : SetTextSelection *
*---------------------------*
*这种方法告诉引擎如果SPTEXTSELECTIONINFO结构
*已更新。本示例只使用发动机领域ulStartActiveOffset和cchActiveChars的SPTEXTSELECTIONINFO 。
*****************************************************************************/
STDMETHODIMP CSrEngine::SetTextSelection(void * pvEngineGrammar, const SPTEXTSELECTIONINFO * pInfo)
CDrvGrammar * pGrammar = (CDrvGrammar*)pvEngineG
if (pGrammar-&m_pInfo)
delete pGrammar-&m_pI
if (pInfo)
pGrammar-&m_pInfo = new SPTEXTSELECTIONINFO(*pInfo);
pGrammar-&m_pInfo = NULL;
return S_OK;
/****************************************************************************
* CSrEngine : : IsPronounceable *
*---------------------------*
*发动机应该回到它是否已经或将能够
*产生的这个词的发音。
*在此示例中的引擎,这是总是如此。
*****************************************************************************/
STDMETHODIMP CSrEngine::IsPronounceable(void * pDrvGrammar, const WCHAR * pszWord, SPWORDPRONOUNCEABLE * pWordPronounceable)
*pWordPronounceable = SPWP_KNOWN_WORD_PRONOUNCEABLE;
return S_OK;
/****************************************************************************
* CSrEngine : : SetAdaptationData *
*---------------------------*
*这种方法可以使用的应用程序,使文本数据引擎
*为适应语言模型等方法只能被称为
*的应用程序后,如果收到了SPEI_ADAPTATION活动。
* E_UNEXPECTED
*****************************************************************************/
STDMETHODIMP CSrEngine::SetAdaptationData(void * pvEngineCtxtCookie, const WCHAR *pAdaptationData, const ULONG cch)
_ASSERT(0);
return E_UNEXPECTED;
HRESULT CSrEngine::AddEvent(SPEVENTENUM eEventId, ULONGLONG ullStreamPos, WPARAM wParam, LPARAM lParam)
HRESULT hr = S_OK;
Event.eEventId = eEventId;
Event.elParamType = SPET_LPARAM_IS_UNDEFINED;
Event.ulStreamNum = 0;
Event.ullAudioStreamOffset = ullStreamP
Event.wParam = wP
Event.lParam = lP
hr = m_cpSite-&AddEvent(&Event, NULL);
HRESULT CSrEngine::AddEventString(SPEVENTENUM eEventId, ULONGLONG ullStreamPos, const WCHAR * psz, WPARAM wParam)
HRESULT hr = S_OK;
Event.eEventId = eEventId;
Event.elParamType = SPET_LPARAM_IS_STRING;
Event.ulStreamNum = 0;
Event.ullAudioStreamOffset = ullStreamP
Event.wParam = wP
Event.lParam = (LPARAM)
hr = m_cpSite-&AddEvent(&Event, NULL);
/************************************************* ***************************
* CSrEngine : : RecognizeStream *
#定义BLOCKSIZE 220 / / 1 / 100秒
*---------------------------*
*这是方法的SAPI呼吁承认发生。
*发动机只能由这个方法返回后,他们已经阅读所有数据
*并完成所有的承认,他们正在尽在此流。
*因此,这种方法是让一个线程的引擎做承认,
*和引擎可能会创造更多的线程。
*在此示例中,我们不断地读取数据,使用此线程,然后执行
*非常基本的语音检测,并通过数据传输到识别线程,这
*产生的假设和结果。
* - REFGUID rguidFormatId -这是的GUID输入的音频格式
* -常量WAVEFORMATEX * pWaveFormatEx -这是扩大信息WAV格式的音频格式
* -拉手hRequestSync -这是使用的Win32事件表明,有尚未完成的任务
*和发动机应要求同步( )的SAPI的来处理这些。
* -拉手hDataAvailable -本的Win32事件是用来告诉引擎,数据可以被读取。
*频率,这是一套可控制的SetBufferNotifySize方法。
* -拉手hExit -本的Win32事件表示引擎正在关闭,并应立即结束。
* -布尔fNewAudioStream -这表明这是一个新的输入流
*例如:在应用方面做了新的SetInput要求,而不是仅仅重新启动前流。
* -布尔fRealTimeAudio -这表明,从投入的实时ISpAudio流,而不是说,一个文件
* - ISpObjectToken * pAudioObjectToken -这是象征性的对象代表音频输入装置
*引擎可能要查询这一点。
*失败(小时)
************************************************** ***************************/
STDMETHODIMP CSrEngine::RecognizeStream(REFGUID rguidFormatId,
const WAVEFORMATEX * pWaveFormatEx,
HANDLE hRequestSync,
HANDLE hDataAvailable,
HANDLE hExit,
BOOL fNewAudioStream,
BOOL fRealTimeAudio,
ISpObjectToken * pAudioObjectToken)
HRESULT hr = S_OK;
m_hRequestSync = hRequestS
hr = m_cpDecoderThread-&StartThread(0, NULL);
if (SUCCEEDED(hr))
const HANDLE aWait[] = { hExit, m_hQueueHasRoom };
while (TRUE)
hr = m_cpSite-&Read(aData, sizeof(aData), &cbRead);
if (hr != S_OK || cbRead & sizeof(aData))
BOOL bNoiseDetected = FALSE;
SHORT * pBuffer = (SHORT *)aD
for (ULONG i = 0; i & cbR i += 2, pBuffer++)
if (*pBuffer & (SHORT)-3000 || *pBuffer & (SHORT)3000)
bNoiseDetected = TRUE;
BOOL bBlock = m_FrameQueue.IsFull();
if(bBlock)
if (::WaitForMultipleObjects(sp_countof(aWait), aWait, FALSE, INFINITE) == WAIT_OBJECT_0)
m_FrameQueue.InsertTail(bNoiseDetected);
m_cpDecoderThread-&Notify();
m_cpDecoderThread-&WaitForThreadDone(TRUE, &hr, 30 * 1000);
m_hRequestSync = NULL;
STDMETHODIMP CSrEngine::ThreadProc(void *, HANDLE hExitThreadEvent, HANDLE hNotifyEvent, HWND hwndWorker, volatile const BOOL * pfContinueProcessing)
HRESULT hr = S_OK;
const HANDLE aWait[] = { hExitThreadEvent, hNotifyEvent, m_hRequestSync };
ULONG block = 0;
ULONG silenceafternoise = 0;
m_bSoundStarted = FALSE;
m_bPhraseStarted = FALSE;
m_cBlahBlah = 0;
m_ullStart = 0;
m_ullEnd = 0;
while (*pfContinueProcessing)
if(m_bPhraseStarted && (block - m_ullStart / BLOCKSIZE) & 5 * 100)
waitres = ::WaitForMultipleObjects(cEvents, aWait, FALSE, INFINITE);
switch (waitres)
case WAIT_OBJECT_0:
case WAIT_OBJECT_0 + 1:
m_cpSite-&UpdateRecoPos((ULONGLONG)block * BLOCKSIZE);
if (m_ullStart == 0 && !m_bPhraseStarted)
m_cpSite-&Synchronize((ULONGLONG)block * BLOCKSIZE);
while (m_FrameQueue.HasData())
BOOL bNoise = m_FrameQueue.RemoveHead();
if (bNoise)
silenceafternoise = 0;
if (m_ullStart == 0)
m_ullStart = (ULONGLONG)block * BLOCKSIZE;
m_ullEnd = (ULONGLONG)block * BLOCKSIZE;
_CheckRecognition();
silenceafternoise++;
if (silenceafternoise & 50)
if (m_bSoundStarted)
if (m_bPhraseStarted)
_NotifyRecognition(FALSE, m_cBlahBlah);
AddEvent(SPEI_SOUND_END, m_ullEnd); // send the sound end event
m_bSoundStarted = FALSE;
m_bPhraseStarted = FALSE;
m_ullStart = 0;
m_ullEnd = 0;
if (block % (100 * 30) == 20 * 100)
const SPINTERFERENCE rgspi[] =
{ SPINTERFERENCE_NOISE, SPINTERFERENCE_NOSIGNAL, SPINTERFERENCE_TOOLOUD, SPINTERFERENCE_TOOQUIET };
AddEvent(SPEI_INTERFERENCE, block*BLOCKSIZE, 0, rgspi[rand() % 4]);
else if (block % (100 * 30) == 22 * 100)
AddEvent(SPEI_INTERFERENCE, block*BLOCKSIZE, 0, SPINTERFERENCE_NONE);
else if (block == 10 * 100)
AddEventString(SPEI_REQUEST_UI, block * BLOCKSIZE, SPDUI_UserTraining);
else if (block == 11 * 100)
AddEventString(SPEI_REQUEST_UI, block * BLOCKSIZE, NULL);
case WAIT_OBJECT_0 + 2:
m_cpSite-&Synchronize((ULONGLONG)block * BLOCKSIZE);
m_ullStart = block * BLOCKSIZE;
if(m_ullEnd & m_ullStart)
m_ullEnd = m_ullS
_ASSERT(FALSE);
if (m_bPhraseStarted)
_NotifyRecognition(FALSE, m_cBlahBlah);
if (m_bSoundStarted)
AddEvent(SPEI_SOUND_END, m_ullEnd);
return S_OK;
void CSrEngine::_CheckRecognition()
ULONG duration,
if (m_ullEnd & m_ullStart)
duration = (ULONG)(m_ullEnd - m_ullStart);
if (duration &= BLOCKSIZE * 100 * 1 / 8)
if (!m_bSoundStarted)
AddEvent(SPEI_SOUND_START, m_ullStart);
m_bSoundStarted = TRUE;
m_cBlahBlah = 0;
if (duration &= BLOCKSIZE * 100 * 1 / 4)
blahs = duration / (BLOCKSIZE * 100 * 1 / 4);
if (blahs != m_cBlahBlah)
m_cBlahBlah =
if (!m_bPhraseStarted)
m_bPhraseStarted = TRUE;
AddEvent(SPEI_PHRASE_START, m_ullStart);
_NotifyRecognition(TRUE, blahs);
void CSrEngine::_NotifyRecognition( BOOL fHypothesis, ULONG nWords )
HRESULT hr = S_OK;
ULONG cActiveCFGRules = 0;
CRuleEntry * pRule = m_RuleList.GetHead();
for(; pR pRule = m_RuleList.GetNext(pRule))
if( pRule-&m_fActive )
cActiveCFGRules++;
ULONG cActiveSLM = 0;
CDrvGrammar * pGram = m_GrammarList.GetHead();
for(; pG pGram = m_GrammarList.GetNext(pGram))
if(pGram-&m_SLMActive)
cActiveSLM++;
if(cActiveCFGRules && cActiveSLM)
if(rand() % 2)
cActiveSLM = 0;
cActiveCFGRules = 0;
SPRECORESULTINFO R
memset(&Result, 0, sizeof(SPRECORESULTINFO));
Result.cbSize
= sizeof(SPRECORESULTINFO);
Result.fHypothesis
Result.ullStreamPosStart
Result.ullStreamPosEnd
if( cActiveCFGRules )
hr = WalkCFGRule(&Result, cActiveCFGRules, fHypothesis, nWords, m_ullStart, (ULONG)(m_ullEnd - m_ullStart));
if( SUCCEEDED(hr) )
m_cpSite-&Recognition(&Result);
for(ULONG i = 0; i & Result.ulNumA i++)
Result.aPhraseAlts[i].pPhrase-&Release();
Result.pPhrase-&Release();
delete[] Result.aPhraseA
else if(cActiveSLM)
hr = WalkSLM(&Result, cActiveSLM, nWords, m_ullStart, (ULONG)(m_ullEnd - m_ullStart));
if( SUCCEEDED(hr) )
m_cpSite-&Recognition(&Result);
Result.pPhrase-&Release();
delete[] Result.pvEngineD
else if(!fHypothesis)
Result.eResultType = SPRT_FALSE_RECOGNITION;
m_cpSite-&Recognition(&Result);
HRESULT CSrEngine::CreatePhraseFromRule( CRuleEntry * pRule, BOOL fHypothesis,
ULONGLONG ullAudioPos, ULONG ulAudioSize,
ISpPhraseBuilder** ppPhrase )
HRESULT hr = S_OK;
SPRULEENTRY RuleI
RuleInfo.hRule = pRule-&m_hR
hr = m_cpSite-&GetRuleInfo(&RuleInfo, SPRIO_NONE);
if( SUCCEEDED(hr) )
const ULONG MAXPATH = 200;
SPPATHENTRY Path[MAXPATH];
hr = RecurseWalk(RuleInfo.hInitialState, Path, &cTrans);
if (cTrans)
ULONG ulInterval = ulAudioSize/cT
for (ULONG ul = 0; ul & cTrans && ul & MAXPATH; ul++)
Path[ul].elem.ulAudioStreamOffset = ul * ulI
Path[ul].elem.ulAudioSizeBytes = ulInterval/2;
if (SUCCEEDED(hr))
SPPARSEINFO ParseI
memset(&ParseInfo, 0, sizeof(ParseInfo));
ParseInfo.cbSize = sizeof(SPPARSEINFO);
ParseInfo.hRule = pRule-&m_hR
ParseInfo.ullAudioStreamPosition = ullAudioP
ParseInfo.ulAudioSize = ulAudioS
ParseInfo.cTransitions = cT
ParseInfo.pPath = P
ParseInfo.fHypothesis = fH
ParseInfo.SREngineID = CLSID_SampleSRE
ParseInfo.ulSREnginePrivateDataSize = 0;
ParseInfo.pSREnginePrivateData = NULL;
hr = m_cpSite-&ParseFromTransitions(&ParseInfo, ppPhrase );
if(SUCCEEDED(hr))
for(ULONG i = 0; i & cT i++)
if(Path[i].elem.pszDisplayText)
delete const_cast&WCHAR*&(Path[i].elem.pszDisplayText);
CRuleEntry* CSrEngine::FindRule( ULONG ulRuleIndex )
CRuleEntry * pRule = m_RuleList.GetHead();
ULONG ulRule = 0;
while( pRule )
if( pRule-&m_fActive && ( ulRule++ == ulRuleIndex ) )
pRule = m_RuleList.GetNext( pRule );
_ASSERT(pRule && pRule-&m_fActive);
CRuleEntry* CSrEngine::NextRuleAlt( CRuleEntry * pPriRule, CRuleEntry * pLastRule )
CRuleEntry * pRule = (pLastRule)?(pLastRule):(m_RuleList.GetHead());
for(; pR pRule = m_RuleList.GetNext(pRule))
if( pRule-&m_fActive &&
( m_cpSite-&IsAlternate( pPriRule-&m_hRule, pRule-&m_hRule ) == S_OK ) )
HRESULT CSrEngine::WalkCFGRule( SPRECORESULTINFO * pResult, ULONG cRulesActive, BOOL fHypothesis,
ULONG nWords, ULONGLONG ullAudioPos, ULONG ulAudioSize)
HRESULT hr = E_FAIL;
CRuleEntry * pPriRule = NULL;
pResult-&ulSizeEngineData = 0;
pResult-&pvEngineData
pResult-&eResultType
= SPRT_CFG;
pResult-&hGrammar
while (hr == E_FAIL)
pPriRule = FindRule( rand() % cRulesActive );
hr = CreatePhraseFromRule( pPriRule, fHypothesis, ullAudioPos,
ulAudioSize, &pResult-&pPhrase );
if (hr != S_OK)
_ASSERT(FALSE);
SPPHRASE* pPriPhraseInfo = NULL;
if( SUCCEEDED( hr ) )
hr = pResult-&pPhrase-&GetPhrase( &pPriPhraseInfo );
ULONG ulNumAlts = 0;
if( SUCCEEDED( hr ) )
hr = m_cpSite-&GetMaxAlternates( pPriRule-&m_hRule, &ulNumAlts );
if( SUCCEEDED( hr ) && ulNumAlts )
pResult-&aPhraseAlts = new SPPHRASEALT[ulNumAlts];
if( pResult-&aPhraseAlts )
memset( pResult-&aPhraseAlts, 0, ulNumAlts * sizeof(SPPHRASEALT) );
CRuleEntry * pAltRule = NULL;
for( ULONG i = 0; SUCCEEDED( hr ) && (i & ulNumAlts); ++i )
pAltRule = NextRuleAlt( pPriRule, pAltRule );
if( !pAltRule )
hr = CreatePhraseFromRule( pAltRule, fHypothesis, ullAudioPos,
ulAudioSize, &pResult-&aPhraseAlts[i].pPhrase );
SPPHRASE* pAltPhraseInfo = NULL;
if( SUCCEEDED( hr ) )
hr = pResult-&aPhraseAlts[i].pPhrase-&GetPhrase( &pAltPhraseInfo );
if( SUCCEEDED( hr ) )
++pResult-&ulNumA
pResult-&aPhraseAlts[i].cElementsInParent = pPriPhraseInfo-&Rule.ulCountOfE
pResult-&aPhraseAlts[i].cElementsInAlternate = pAltPhraseInfo-&Rule.ulCountOfE
static BYTE AltData[] = { 0xED, 0xED, 0xED, 0xED };
pResult-&aPhraseAlts[i].pvAltExtra = &AltD
pResult-&aPhraseAlts[i].cbAltExtra = sp_countof( AltData );
if( pAltPhraseInfo )
::CoTaskMemFree( pAltPhraseInfo );
E_OUTOFMEMORY;
// Cleanup main phrase information
if( pPriPhraseInfo )
::CoTaskMemFree( pPriPhraseInfo );
// Cleanup on failure
if( FAILED( hr ) )
if( pResult-&pPhrase )
pResult-&pPhrase-&Release();
pResult-&pPhrase = NULL;
for( ULONG i = 0; i & pResult-&ulNumA ++i )
pResult-&aPhraseAlts[i].pPhrase-&Release();
pResult-&aPhraseAlts[i].pPhrase = NULL;
pResult-&ulNumAlts = 0;
delete[] pResult-&aPhraseA
pResult-&aPhraseAlts = NULL;
HRESULT CSrEngine::WalkSLM(SPRECORESULTINFO * pResult, ULONG cSLMActive,
ULONG nWords, ULONGLONG ullAudioPos, ULONG ulAudioSize)
HRESULT hr = S_OK;
ULONG ulGramIndex = rand() % cSLMA
CDrvGrammar * pGram = m_GrammarList.GetHead();
ULONG nGram = 0;
for(; pG pGram = m_GrammarList.GetNext(pGram))
if(pGram-&m_SLMActive)
if(nGram == ulGramIndex)
_ASSERT(pGram && pGram-&m_SLMActive);
if( pGram == NULL )
return E_FAIL;
memset(&phrase, 0, sizeof(SPPHRASE));
phrase.cbSize = sizeof(SPPHRASE);
phrase.LangID = m_LangID;
phrase.ullAudioStreamPosition = ullAudioP
phrase.ulAudioSizeBytes = ulAudioS
phrase.SREngineID = CLSID_SampleSRE
ULONG cb = nWords * sizeof(SPPHRASEELEMENT);
SPPHRASEELEMENT* pElements = (SPPHRASEELEMENT *)_malloca(cb);
memset(pElements, 0, cb);
for (ULONG n = 0; n & nW n++)
ULONG ulInterval = ulAudioSize/nW
pElements[n].bDisplayAttributes = SPAF_ONE_TRAILING_SPACE;
pElements[n].pszDisplayText =
DICT_WORD;
pElements[n].ulAudioStreamOffset = n * ulI
pElements[n].ulAudioSizeBytes = ulInterval/2;
phrase.Rule.ulCountOfElements = nW
phrase.pElements = pE
CComPtr&ISpPhraseBuilder& cpB
hr = cpBuilder.CoCreateInstance(CLSID_SpPhraseBuilder);
if (SUCCEEDED(hr))
hr = cpBuilder-&InitFromPhrase(&phrase);
if (SUCCEEDED(hr))
pResult-&ulSizeEngineData = sizeof(ALT_WORD) * nW
pResult-&pvEngineData = new WCHAR[(sizeof(ALT_WORD) / sizeof(WCHAR )) * nWords];
if (pResult-&pvEngineData == NULL)
hr = E_OUTOFMEMORY;
if (SUCCEEDED(hr))
WCHAR *pC = (WCHAR *)pResult-&pvEngineD
size_t cRemainingSize = (size_t)pResult-&ulSizeEngineData / sizeof(WCHAR);
for(ULONG i = 0; i & nW i++)
wcscpy_s(pC, cRemainingSize, ALT_WORD);
size_t cAltWord = wcslen(ALT_WORD);
pC += cAltW
*pC = ' ';
cRemainingSize -= cAltWord + 1;
*(--pC) = '/0';
pResult-&eResultType = SPRT_SLM;
pResult-&hGrammar = pGram-&m_hSapiG
if (SUCCEEDED(hr))
pResult-&pPhrase = cpBuilder.Detach();
delete[] pResult-&pvEngineD
pResult-&pvEngineData = NULL;
pResult-&ulSizeEngineData = 0;
_freea(pElements);
HRESULT CSrEngine::WalkTextBuffer(void* pvGrammarCookie, SPPATHENTRY * pPath, SPTRANSITIONID hId, ULONG * pcTrans)
HRESULT hr = S_OK;
CDrvGrammar * pGrammar = (CDrvGrammar *) pvGrammarC
_ASSERT(pGrammar-&m_pWordSequenceText && pGrammar-&m_cchText &= 2);
if (!pGrammar-&m_pWordSequenceText || pGrammar-&m_cchText & 2)
return E_UNEXPECTED;
*pcTrans = 0;
ULONG nPhrase = 0;
const WCHAR *cP
ULONG ulStartActiveOffset = 0; //The default value with text selection
ULONG cchActiveChars = pGrammar-&m_cchText - 2; //The default value with text selection
ULONG ccChars = 0;
if (pGrammar-&m_pInfo)
ulStartActiveOffset = pGrammar-&m_pInfo-&ulStartActiveO
cchActiveChars = pGrammar-&m_pInfo-&cchActiveC
for (cPhrase = pGrammar-&m_pWordSequenceText + ulStartActiveO
ccChars & cchActiveChars && (*cPhrase != L'/0' || *(cPhrase + 1) != '/0');
ccChars++, cPhrase++)
if(*cPhrase != L'/0' && *(cPhrase + 1) == L'/0')
nPhrase++;
if (nPhrase == 0)
return E_FAIL;
nPhrase = rand() % nP //nPhrase would be 0 index
ULONG nP = 0;
for(cPhrase = pGrammar-&m_pWordSequenceText + ulStartActiveO nP != nP cPhrase++)
if(*cPhrase == L'/0')
// Count words in sentence
ULONG nWord = 1;
const WCHAR *cW
for(cWord = cP *cWord != L'/0' && ULONG(cWord - pGrammar-&m_pWordSequenceText) & ulStartActiveOffset + cchActiveC cWord++)
if(iswspace(*cWord))
while(*(cWord+1) && iswspace(*(cWord+1)) && ULONG(cWord - pGrammar-&m_pWordSequenceText) & ulStartActiveOffset + cchActiveChars - 1) {cWord++;}
ULONG startWord = rand() % nW
ULONG countWord = rand() % (nWord - startWord) + 1;
for(nWord = 0, cWord = cP nWord != startW cWord++)
if(iswspace(*cWord))
while(*(cWord+1) && iswspace(*(cWord+1)) && ULONG(cWord - pGrammar-&m_pWordSequenceText) & ulStartActiveOffset + cchActiveChars - 1) {cWord++;}
const WCHAR *cW = cW
for(nWord = 0; nWord != countW cWord++)
if(*cWord == L'/0' || iswspace(*cWord) || ULONG(cWord - pGrammar-&m_pWordSequenceText) == ulStartActiveOffset + cchActiveChars)
pPath-&hTransition = hId;
memset(&pPath-&elem, 0, sizeof(pPath-&elem));
pPath-&elem.bDisplayAttributes = SPAF_ONE_TRAILING_SPACE;
WCHAR *pszWord = new WCHAR[cWord - cW + 1];
wcsncpy_s(pszWord, cWord - cW + 1, cW, cWord - cW);
pszWord[cWord - cW] = '/0';
pPath-&elem.pszDisplayText = pszW
(*pcTrans)++;
while(*(cWord+1) && iswspace(*(cWord+1)) && ULONG(cWord - pGrammar-&m_pWordSequenceText) & ulStartActiveOffset + cchActiveChars - 1) {cWord++;}
cW = cWord + 1; // first char of next word
/****************************************************************************
/************************************************* ***************************
* CSrEngine : : RecognizeStream *
*---------------------------*
*这是方法的SAPI呼吁承认发生。
*发动机只能由这个方法返回后,他们已经阅读所有数据
*并完成所有的承认,他们正在尽在此流。
*因此,这种方法是让一个线程的引擎做承认,
*和引擎可能会创造更多的线程。
* CSrEngine : : RecurseWalk *
*----------------------*
*这种方法产生的随机路径通过积极CFG桩。如果路径中包含
*规则参考过渡RecurseWalk是递归要求生产的道路虽然
*分规则。结果是一系列的SPPATHENTRY内容包含过渡。
*初始状态每个规则中得到致电GetRuleInfo 。然后为每个
*国家GetStateInfo可称为。这使一系列SPTRANSITION条目
*在包含的信息类型的转型,转型的ID和
*在未来国家的过渡去。过渡编号是主要的信息
*包括在SPPATHENTRY 。只适用于Word过渡SPPATHENTRY创建,
*因为这是所有所需的ParseFromTransitions 。
*失败(小时)
****************************************************************************/
HRESULT CSrEngine::RecurseWalk(SPSTATEHANDLE hState, SPPATHENTRY * pPath, ULONG * pcTrans)
HRESULT hr = S_OK;
CSpStateInfo StateI
*pcTrans = 0;
while (SUCCEEDED(hr) && hState)
hr = m_cpSite-&GetStateInfo(hState, &StateInfo);
if (SUCCEEDED(hr))
ULONG cTransInState = StateInfo.cEpsilons + StateInfo.cWords + StateInfo.cRules + StateInfo.cSpecialT
if (cTransInState == 0)
hr = E_FAIL;
SPTRANSITIONENTRY * pTransEntry = StateInfo.pTransitions + (rand() % cTransInState);
switch(pTransEntry-&Type)
case SPTRANSEPSILON:
case SPTRANSRULE:
hr = RecurseWalk(pTransEntry-&hRuleInitialState, pPath, &cTrans);
*pcTrans += cT
pPath += cT
case SPTRANSWORD:
case SPTRANSWILDCARD:
pPath-&hTransition = pTransEntry-&ID;
memset(&pPath-&elem, 0, sizeof(pPath-&elem));
pPath-&elem.bDisplayAttributes = SPAF_ONE_TRAILING_SPACE;
(*pcTrans)++;
case SPTRANSTEXTBUF:
hr = WalkTextBuffer(pTransEntry-&pvGrammarCookie, pPath, pTransEntry-&ID, &cTrans);
*pcTrans += cT
pPath += cT
case SPTRANSDICTATION:
pPath-&hTransition = pTransEntry-&ID;
memset(&pPath-&elem, 0, sizeof(pPath-&elem));
pPath-&elem.bDisplayAttributes = SPAF_ONE_TRAILING_SPACE;
size_t cDictWord = wcslen(DICT_WORD);
WCHAR *pszWord = new WCHAR[cDictWord + 1];
wcscpy_s(pszWord, cDictWord + 1, DICT_WORD);
pPath-&elem.pszDisplayText = pszW
(*pcTrans)++;
hState = pTransEntry-&hNextS
STDMETHODIMP CSrEngine::GetInputAudioFormat(const GUID * pSourceFormatId, const WAVEFORMATEX * pSourceWaveFormatEx,
GUID * pDesiredFormatId, WAVEFORMATEX ** ppCoMemDesiredWFEX)
ppCoMemDesiredWFEX);
STDMETHODIMP CSrEngine::
SetPropertyNum( SPPROPSRC eSrc, PVOID pvSrcObj, const WCHAR* pName, LONG lValue )
HRESULT hr = S_OK;
hr = S_FALSE;
STDMETHODIMP CSrEngine::
GetPropertyNum( SPPROPSRC eSrc, PVOID pvSrcObj, const WCHAR* pName, LONG * plValue )
HRESULT hr = S_OK;
hr = S_FALSE;
*plValue = 0;
STDMETHODIMP CSrEngine::
SetPropertyString( SPPROPSRC eSrc, PVOID pvSrcObj, const WCHAR* pName, const WCHAR* pValue )
HRESULT hr = S_OK;
hr = S_FALSE;
STDMETHODIMP CSrEngine::
GetPropertyString( SPPROPSRC eSrc, PVOID pvSrcObj, const WCHAR* pName, __deref_out_opt WCHAR** ppCoMemValue )
HRESULT hr = S_OK;
hr = S_FALSE;
*ppCoMemValue = NULL;
STDMETHODIMP CSrEngine::PrivateCall(void * pvEngineContext, void * pCallFrame, ULONG ulCallFrameSize)
return S_OK;
STDMETHODIMP CSrEngine::PrivateCallEx(void * pvEngineContext, const void * pInCallFrame, ULONG ulCallFrameSize,
void ** ppvCoMemResponse, ULONG * pcbResponse)
HRESULT hr = S_OK;
*ppvCoMemResponse = NULL;
*pcbResponse = 0;
STDMETHODIMP CSrEngine::PrivateCallImmediate(
void *pvEngineContext,
const void *pInCallFrame,
ULONG ulInCallFrameSize,
void **ppvCoMemResponse,
ULONG *pulResponseSize)
*ppvCoMemResponse = NULL;
*pulResponseSize = 0;
return S_OK;
STDMETHODIMP CSrEngine::SetAdaptationData2(
void *pvEngineContext,
__in_ecount(cch)
const WCHAR *pAdaptationData,
const ULONG cch,
LPCWSTR pTopicName,
SPADAPTATIONSETTINGS eSettings,
SPADAPTATIONRELEVANCE eRelevance)
return S_OK;
STDMETHODIMP CSrEngine::SetGrammarPrefix(
void *pvEngineGrammar,
LPCWSTR pszPrefix,
BOOL fIsPrefixRequired)
return S_OK;
STDMETHODIMP CSrEngine::SetRulePriority(
SPRULEHANDLE hRule,
void *pvClientRuleContext,
int nRulePriority)
return S_OK;
STDMETHODIMP CSrEngine::EmulateRecognition(
ISpPhrase *pPhrase,
DWORD dwCompareFlags)
// Let SAPI do its own emulation.
return E_NOTIMPL;
STDMETHODIMP CSrEngine::SetSLMWeight(
void *pvEngineGrammar,
float flWeight)
return S_OK;
STDMETHODIMP CSrEngine::SetRuleWeight(
SPRULEHANDLE hRule,
void *pvClientRuleContext,
float flWeight)
return S_OK;
STDMETHODIMP CSrEngine::SetTrainingState(
BOOL fDoingTraining,
BOOL fAdaptFromTrainingData)
return S_OK;
STDMETHODIMP CSrEngine::ResetAcousticModelAdaptation( void)
return S_OK;
STDMETHODIMP CSrEngine::OnLoadCFG(
void *pvEngineGrammar,
const SPBINARYGRAMMAR *pGrammarData,
ULONG ulGrammarID)
return S_OK;
STDMETHODIMP CSrEngine::OnUnloadCFG(
void *pvEngineGrammar,
ULONG ulGrammarID)
return S_OK;
/******************************************************************************
srengext.cpp
*此文件包含执行CSampleSRExtension级。
*这实现了自定义接口ISampleSRExtension 。
*当一个应用程序启这一从reco方面, SAPI的将
*寻找ExtensionCLSID领域中的引擎对象的原因,并
*创建该对象,然后齐界面的要求。
******************************************************************************/
#include "stdafx.h"
#include "srengext.h"
STDMETHODIMP CSampleSRExtension::ExamplePrivateEngineCall(void)
static BYTE Data[4] = { 1, 2, 3, 4 };
HRESULT hr = S_OK;
CComPtr&ISpPrivateEngineCallEx& cpEngineCallEx;
OuterQueryInterface(IID_ISpPrivateEngineCallEx, (void **)&cpEngineCallEx);
if (cpEngineCallEx)
void *pCoMemOutFrame = NULL;
ULONG ulOutFrameS
hr = cpEngineCallEx-&CallEngineSynchronize( (void*)Data, sp_countof(Data), &pCoMemOutFrame, &ulOutFrameSize );
::CoTaskMemFree( pCoMemOutFrame );
hr = m_pEngineCall-&CallEngine( (void*)Data, sp_countof(Data) );
STDMETHODIMP CSampleSRExtension::GetDisplayAlternates(
const SPDISPLAYPHRASE *pPhrase,
ULONG cRequestCount,
SPDISPLAYPHRASE **ppCoMemPhrases,
ULONG *pcPhrasesReturned)
HRESULT hr = S_OK;
memset(ppCoMemPhrases, 0, sizeof(*ppCoMemPhrases) * cRequestCount);
*pcPhrasesReturned = cRequestC
for (unsigned int p=0; p&*pcPhrasesR p++)
size_t cbPhraseSize = sizeof(SPDISPLAYPHRASE);
cbPhraseSize += pPhrase-&ulNumTokens * sizeof(SPDISPLAYTOKEN);
for (unsigned int t=0; t&pPhrase-&ulNumT t++)
if (pPhrase-&pTokens[t].pszDisplay != NULL)
cbPhraseSize += (wcslen(pPhrase-&pTokens[t].pszDisplay) + 1) * sizeof(WCHAR);
if (pPhrase-&pTokens[t].pszLexical != NULL)
cbPhraseSize += (wcslen(pPhrase-&pTokens[t].pszLexical) + 1) * sizeof(WCHAR);
// Allocate the memory
ppCoMemPhrases[p] = (SPDISPLAYPHRASE *)CoTaskMemAlloc(cbPhraseSize);
if (ppCoMemPhrases[p] == NULL)
hr = E_OUTOFMEMORY;
goto CleanUp;
SPDISPLAYPHRASE *pCoMemPhrase = ppCoMemPhrases[p];
pCoMemPhrase-&ulNumTokens = pPhrase-&ulNumT
pCoMemPhrase-&pTokens = (SPDISPLAYTOKEN *)(pCoMemPhrase + 1);
LPWSTR pStringTable = (LPWSTR)(pCoMemPhrase-&pTokens + pCoMemPhrase-&ulNumTokens);
LPWSTR pEndOfStringTable = (LPWSTR)(((BYTE*)pCoMemPhrase) + cbPhraseSize);
for (unsigned int t=0; t&pPhrase-&ulNumT t++)
pCoMemPhrase-&pTokens[t].bDisplayAttributes = pPhrase-&pTokens[t].bDisplayA
if (t == 0)
if (pPhrase-&pTokens[t].pszDisplay != NULL)
pCoMemPhrase-&pTokens[t].bDisplayAttributes |= SPAF_ONE_TRAILING_SPACE;
if (t&pPhrase-&ulNumTokens-1)
pCoMemPhrase-&pTokens[t].bDisplayAttributes |= SPAF_ONE_TRAILING_SPACE;
if (pPhrase-&pTokens[t].pszDisplay != NULL)
size_t length = wcslen(pPhrase-&pTokens[t].pszDisplay);
if (wcscpy_s(pStringTable, pEndOfStringTable - pStringTable, pPhrase-&pTokens[t].pszDisplay))
hr = E_OUTOFMEMORY;
goto CleanUp;
pCoMemPhrase-&pTokens[t].pszDisplay = pStringT
pStringTable += length + 1;
ppCoMemPhrases[p]-&pTokens[t].pszDisplay = NULL;
if (pPhrase-&pTokens[t].pszLexical != NULL)
size_t length = wcslen(pPhrase-&pTokens[t].pszLexical);
if (wcscpy_s(pStringTable, pEndOfStringTable - pStringTable, pPhrase-&pTokens[t].pszLexical))
hr = E_OUTOFMEMORY;
goto CleanUp;
pCoMemPhrase-&pTokens[t].pszLexical = pStringT
pStringTable += length + 1;
ppCoMemPhrases[p]-&pTokens[t].pszLexical = NULL;
if (FAILED(hr))
for (unsigned int p=0; p&*pcPhrasesR p++)
CoTaskMemFree(ppCoMemPhrases[p]);
ppCoMemPhrases[p] = NULL;
*pcPhrasesReturned = 0;
STDMETHODIMP CSampleSRExtension::SetFullStopTrailSpace(ULONG ulTrailSpace)
return S_OK;
STDMETHODIMP CSampleSRExtension::Normalize(
LPCWSTR pszWord,
LPCWSTR pszLeftContext,
LPCWSTR pszRightContext,
WORD LangID,
SPNORMALIZATIONLIST *pNormalizationList)
pNormalizationList = NULL;
return S_NOTSUPPORTED;
STDMETHODIMP CSampleSRExtension::GetPronunciations(
LPCWSTR pszWord,
LPCWSTR pszLeftContext,
LPCWSTR pszRightContext,
WORD LangID,
SPWORDPRONUNCIATIONLIST *pEnginePronunciationList)
pEnginePronunciationList-&ulSize = 0;
pEnginePronunciationList-&pvBuffer = 0;
pEnginePronunciationList-&pFirstWordPronunciation = 0;
return S_NOTSUPPORTED;
/******************************************************************************
srengalt.h
*此文件包含执行CSrEngineAlternates级。
*这实现了接口ISpSRAlternates 。
*当一个应用程序要求GetAlternates或犯下的结果, SAPI的将
*寻找AlternatesCLSID领域中的引擎对象的原因,并
*创建此对象。
*然后,将在这里呼吁的方法,通过相关的结果信息。
*这包括任何序列数据的主要动力已返回
*结果让候补产生离线。
******************************************************************************/
#include "stdafx.h"
#include "srengalt.h"
STDMETHODIMP CSrEngineAlternates::GetAlternates(SPPHRASEALTREQUEST *pAltRequest,
SPPHRASEALT **ppAlts, ULONG *pcAlts)
HRESULT hr = S_OK;
*pcAlts = 1;
*ppAlts = (SPPHRASEALT *)::CoTaskMemAlloc(sizeof(SPPHRASEALT));
if( *ppAlts == NULL)
return E_OUTOFMEMORY;
(*ppAlts)[0].ulStartElementInParent = pAltRequest-&ulStartE
(*ppAlts)[0].cElementsInParent = pAltRequest-&cE
(*ppAlts)[0].cElementsInAlternate = pAltRequest-&cE
(*ppAlts)[0].pvAltExtra = NULL;
(*ppAlts)[0].cbAltExtra = 0;
memset(&phrase, 0, sizeof(phrase));
phrase.cbSize = sizeof(phrase);
phrase.LangID = 1033;
WCHAR *pAlts = (WCHAR *) pAltRequest-&pvResultE
ULONG nAltChars = pAltRequest-&cbResultExtra / sizeof(WCHAR);
ULONG nWord = 0;
for(i = 0; i & nAltC i++)
if(iswspace(pAlts[i]) || pAlts[i] == '/0')
SPPHRASEELEMENT* pElements = (SPPHRASEELEMENT*)_malloca(sizeof(SPPHRASEELEMENT) * nWord);
memset(pElements, 0, sizeof(SPPHRASEELEMENT)*nWord);
ULONG cW = 0;
ULONG cWord = 0;
for(i = 0; i & nAltChars && cWord & nW i++)
if(iswspace(pAlts[i]) || pAlts[i] == '/0')
pElements[cWord].bDisplayAttributes = SPAF_ONE_TRAILING_SPACE;
WCHAR *pszWord = (WCHAR *)_malloca(sizeof(WCHAR) * (i - cW + 1));
wcsncpy_s(pszWord, i - cW + 1, &pAlts[cW], i - cW);
pszWord[i - cW] = '/0';
pElements[cWord].pszDisplayText =
cW = i + 1;
phrase.Rule.ulCountOfElements = cW
phrase.pElements = pE
CComPtr&ISpPhraseBuilder& cpB
hr = cpBuilder.CoCreateInstance(CLSID_SpPhraseBuilder);
if(SUCCEEDED(hr))
hr = cpBuilder-&InitFromPhrase(&phrase);
if(SUCCEEDED(hr))
(*ppAlts)[0].pPhrase = cpB
(*ppAlts)[0].pPhrase-&AddRef();
CComPtr&ISampleSRExtension& m_cpE
hr = pAltRequest-&pRecoContext-&QueryInterface(&m_cpExt);
if(SUCCEEDED(hr))
hr = m_cpExt-&ExamplePrivateEngineCall();
for(i = 0; i & cW i++)
_freea((void*)pElements[i].pszDisplayText);
_freea(pElements);
if (FAILED(hr))
::CoTaskMemFree(*ppAlts);
STDMETHODIMP CSrEngineAlternates::Commit(SPPHRASEALTREQUEST *pAltRequest,
SPPHRASEALT *pAlt, void **ppvResultExtra, ULONG *pcbResultExtra)
return S_OK;
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4472695次
积分:59328
积分:59328
排名:第35名
原创:1272篇
转载:71篇
译文:34篇
评论:5602条
难度:初级
类型:技术教程
难度:初级
类型:技术教程
难度:初级
类型:技术教程
文章:80篇
阅读:266225
文章:24篇
阅读:34395
文章:180篇
阅读:242680
文章:35篇
阅读:76175
文章:50篇
阅读:179977
文章:60篇
阅读:259314
文章:44篇
阅读:619728
文章:202篇
阅读:1462816
文章:90篇
阅读:403166
文章:70篇
阅读:537363
文章:27篇
阅读:104789
(1)(1)(2)(20)(20)(3)(1)(1)(1)(1)(3)(136)(26)(98)(58)(12)(9)(14)(18)(58)(295)(1)(21)(1)(2)(2)(2)(2)(5)(5)(7)(4)(4)(63)(12)(13)(7)(12)(5)(4)(5)(7)(1)(84)(56)(1)(17)(3)(3)(2)(8)(4)(5)(4)(4)(1)(3)(4)(5)(5)(4)(2)(22)(33)(20)(20)(3)(3)(9)(2)(4)(5)(10)(2)(5)(1)(9)(20)(6)(10)(64)

我要回帖

更多关于 乙肝大三阳能转阴吗 的文章

 

随机推荐