设为首页 收藏本站
查看: 852|回复: 0

[经验分享] 一个通用的IBM viavoice语音识别语音朗读的接口,适用于基于IBM viavoice开发

[复制链接]
发表于 2017-5-26 11:06:19 | 显示全部楼层 |阅读模式
  
DSC0000.jpg //------------------------------------------------------------------------------
// sapi.cpp - IBMSapi speech engine interface
//------------------------------------------------------------------------------
  #include "stdafx.h"
#include "winnls.h"
  #ifndef _SPEECH_
#include "objbase.h"
#include "initguid.h"
#include <objerror.h>
#include <speech.h>
#include <ibmspch.h>
#include <mmsystem.h>
#endif
  #include "SRWrapEn.h"
#include "myresource.h"
#include "global.hpp"
#include "sapi.hpp"
  
DWORD ListenKey;
WantNotificationstellMe;// Notification Sink flags
const char*pGStopPhr;// "stop dictation" phrase for various languages
  //------------------------------------------------------------------------------
// Description: SapiSpeech class implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Description: constructor
//------------------------------------------------------------------------------
SapiSpeech:: SapiSpeech(CEdit *pCEdit)
{
pGStopPhr = 0;
  m_pCEdit= pCEdit;
m_pSpchCentral= 0;
m_pSpchEngSink= 0;
m_pSpchDctSink= 0;
m_pSpchGramDict= 0;
m_pGramCommon= 0;
m_pStatusLB = 0;

m_pLtdGramCommon = 0;
m_pSpchLtdSink = 0;
  // setup the nofification sink's notifications.
memset(&tellMe, 0, sizeof(tellMe));
tellMe.bDctPhraseStart= TRUE;
tellMe.bDctPhraseHypothesis= TRUE;
tellMe.bDctPhraseFinish= TRUE;
  // initialize the speech engine and grammars for Dictation
if ( !initForDictation(SRSEQUENCE_CONTINUOUS) )
{
if ( !initForDictation(SRSEQUENCE_DISCRETE) )
state = RC_SPEECH_FAILED;
else
state = RC_SUCCESS;
}
else
{
state = RC_SUCCESS;
}
}
  //------------------------------------------------------------------------------
// Description: destructor
//------------------------------------------------------------------------------
SapiSpeech:: ~SapiSpeech()
{
m_pStatusLB = 0;

terminate();
}
  //------------------------------------------------------------------------------
// Description: terminate speech session... cleanup
//------------------------------------------------------------------------------
void SapiSpeech:: terminate()
{
deactivate();
  if (m_pSpchCentral && m_pSpchEngSink->m_dwKey )
m_pSpchCentral->UnRegister( m_pSpchEngSink->m_dwKey );
  if (m_pIBMAcoustics)
m_pIBMAcoustics->Release();
  if (m_pSpchCentral)
m_pSpchCentral->Release();
  if( m_pSpchGramDict ) m_pSpchGramDict->Release();
  if( m_pGramCommon ) m_pGramCommon->Release();

if ( m_pLtdGramCommon ) m_pLtdGramCommon->Release();
  
if (m_pISRListen )
{
if (m_dwListenKey)
m_pISRListen->Unregister(m_dwListenKey);
  m_pISRListen->Release();
}
if( m_pGramActionCommon ) m_pGramActionCommon->Release();
}
  //----------------------------------------------------------------------------------------------
// Description: Initializes the Speech engine via SAPI. Only the IBM dictation speech engine
//is searched.
//----------------------------------------------------------------------------------------------
int SapiSpeech:: initForDictation(intSequencing)
{
HRESULT hRes;
SRMODEINFO wantSRMode;
SRMODEINFO gotSRMode;
PISRFIND pFind= 0;
PISRENUM pEnum= 0;
PIAUDIOMULTIMEDIADEVICE pMMDev= 0;
int yes=1, no=0;
int success = yes;

  //
// First we create the enumerator so we can search for the IBM dictation engine
//
hRes = CoCreateInstance( CLSID_SREnumerator, NULL, CLSCTX_ALL, IID_ISREnum, (void**)&pEnum );
if( FAILED(hRes) )
{
pEnum = NULL;
Error(hRes, TEXT("Error creating SREnumerator (CoCreateInstance)."), NULL, MB_OK );
goto initForDictation_done;
}
  ASSERT( pEnum );
  // Get the find interface so we can search for the IBM dictation engine
hRes = pEnum->QueryInterface(IID_ISRFind, (void**)&pFind);
pEnum->Release(); pEnum = 0;
if( FAILED(hRes) )
{
pFind = NULL;
Error( hRes, _T("Could not create PISRFIND interface") );
goto initForDictation_done;
}
  //Setup the SRMODEINFO structure with the parameters we are interested in having in out speech
// engine. Then use the enumerator to find the engine we want.
memset( &wantSRMode, 0, sizeof(SRMODEINFO) );
hRes = MultiByteToWideChar(CP_ACP, 0, "IBM", -1, wantSRMode.szMfgName, SRMI_NAMELEN);
wantSRMode.dwGrammars= SRGRAM_DICTATION | SRGRAM_LIMITEDDOMAIN;
  wantSRMode.dwSequencing = Sequencing;
  hRes = pFind->Find( &wantSRMode, NULL, &gotSRMode );
if (FAILED(hRes))
{
Error( hRes, TEXT("Failed trying to find engine mode (Find)") );
goto initForDictation_done;
}
  // Did we get the IBM dictation engine???
if (wcscmp(wantSRMode.szMfgName, gotSRMode.szMfgName) != 0)
{
Error(-1, TEXT("Could not find IBM dictation engine"));
success = no;
goto initForDictation_done;
}
  //
// It is preferred to not share the dictation engine. Usually, it does not make sense to do so.
// Therefore, create a non-shared dictation engine. For a nonshared engine, we must get the
// mmdevice
//
hRes = CoCreateInstance( CLSID_MMAudioSource, NULL, CLSCTX_ALL, IID_IAudioMultiMediaDevice, (void**)&pMMDev);
if( FAILED(hRes))
{
Error(hRes, TEXT("CoCreateInstance for mm device failed in EngModeSelect()."));
goto initForDictation_done;
}
  hRes = pMMDev->DeviceNumSet( WAVE_MAPPER );
if (FAILED(hRes))
{
Error( hRes, TEXT("Error in IAudioMultimediaDevice::DeviceNumSet().") );
}
  // Select now...
  // if the mode was found using the ISRFind interface then use the Find::Select()...
hRes = pFind->Select(gotSRMode.gModeID, &m_pSpchCentral, (LPUNKNOWN)pMMDev);
  pMMDev->Release();
pMMDev = 0;
  pFind->Release();
pFind = 0;
  if (FAILED(hRes))
{
Error(hRes, TEXT("Could not select the engine"));
m_pSpchCentral = 0;
goto initForDictation_done;
}
  if (0 == m_pSpchCentral)
{
Error(hRes, TEXT("Failed to create speech engine (m_pSpchCentral = 0)"));
success = no;
goto initForDictation_done;
}
  
// register the notification object to the engine
m_pSpchEngSink = new SpchEngSink(this);
hRes = m_pSpchCentral->Register (m_pSpchEngSink, IID_ISRNotifySink, &(m_pSpchEngSink->m_dwKey) );
if (FAILED(hRes))
{
Error( hRes, TEXT("Error Registering engine notification class") );
m_pSpchEngSink = 0;
goto initForDictation_done;
}

hRes = m_pSpchCentral->QueryInterface(IID_IIBM_SRListen, (void**)&m_pISRListen);

if (FAILED(hRes))
{
Error( hRes, TEXT("Error Querying IBM Listen Extension") );
m_pISRListen = 0;
goto initForDictation_done;
}
  m_pISRListen->Register(&m_dwListenKey);
  //
// In order to work in non-US languages, the phrase to stop dictation needs to reflect the language
// we are working in.
//
const char*pGramLangSuffix;
GUIDengGuid = gotSRMode.gModeID;
pGramLangSuffix = getGrammarLanguageSuffix(engGuid);
pGStopPhr = getStopPhrase(pGramLangSuffix);

//
// Create the dictation and limited-domain grammars in memory and load
// them into the engine.
//
success = initGrammars( pGStopPhr );
  hRes = m_pSpchCentral->QueryInterface(IID_IIBM_SRDialogs, (void**)&m_pIBMTrainDialog);

if (FAILED(hRes))
{
Error( hRes, TEXT("Error Querying IBM Dialogs Extension") );
m_pIBMTrainDialog = 0;
goto initForDictation_done;
}

hRes = m_pSpchCentral->QueryInterface(IID_IIBM_SRAcousticPronunciations, (void**)&m_pIBMAcoustics);

if (FAILED(hRes))
{
Error( hRes, TEXT("Error Querying IBM Acoustic Pronunciations Extension") );
m_pIBMAcoustics = 0;
goto initForDictation_done;
}
  initForDictation_done:
if (pMMDev) pMMDev->Release();
if (pFind) pFind->Release();
  if (FAILED(hRes))
{
success = no;
}
  if ( success == no && Sequencing == SRSEQUENCE_CONTINUOUS )
{
AfxMessageBox(TEXT("Now, trying for discrete engine"));
}
  return success;
}
  //----------------------------------------------------------------------------------------------
// Description: Initializes the Dictation and Limite-domain Grammars for SAPI speech.
//----------------------------------------------------------------------------------------------
int SapiSpeech:: initGrammars( const char * const stopPhrase )
{
int Actionlen,wordlen;
HRESULT hRes;
SDATA dictGram, ltdGram, actionGram;
PSRCHUNK pSRChunk= 0;
PSRHEADER pSRHeader= 0;
PSRACTIONVERB pSRActionVerb = 0;
LPUNKNOWN lpUnkDict = 0;
LPUNKNOWN lpUnkLtd = 0;
LPUNKNOWN lpUnkAction= 0;
int yes=1, no=0;
int success = yes;


dictGram.pData = 0;
  //
// Create the dictation grammar in memory and load it into the engine.

//
  wordlen = strlen(stopPhrase) * 2 + 2;// +2 for ending null
  dictGram.dwSize = sizeof(SRHEADER) + sizeof(SRCHUNK) + wordlen;
dictGram.pData = (void*) new unsigned int[dictGram.dwSize];
  pSRHeader = (SRHEADER *)dictGram.pData;
pSRHeader->dwType = SRHDRTYPE_DICTATION;
pSRHeader->dwFlags = SRHDRFLAG_UNICODE;


pSRChunk = (SRCHUNK *) ((PBYTE)dictGram.pData + sizeof(SRHEADER));
pSRChunk->dwChunkID = SRCKD_SUBTOPIC;
pSRChunk->dwChunkSize = wordlen;
MultiByteToWideChar(CP_ACP, 0, "dummy", -1, (unsigned short *)&pSRChunk->avInfo[0], wordlen);
  
m_pSpchDctSink = new SpchDctSink(this);
hRes = m_pSpchCentral->GrammarLoad(SRGRMFMT_DICTATION,
dictGram,
(PVOID)m_pSpchDctSink,
IID_ISRGramNotifySink,
&lpUnkDict );
if( FAILED(hRes))
{
Error(hRes, TEXT("Could not load the dictation grammar"));
goto initGrammars_done;
}
  
/*------------------------------------------------------------------------------------*/
/* Now that we have the Unknown to the grammer object, lets get the common interface. */
/*------------------------------------------------------------------------------------*/
hRes = lpUnkDict->QueryInterface( IID_ISRGramCommon, (void**)&m_pGramCommon );
if (FAILED(hRes))
{
Error( hRes, TEXT("Could not get ISRGramCommon interface."));
goto initGrammars_done;
}

hRes = lpUnkDict->QueryInterface( IID_ISRGramDictation, (void**)&m_pSpchGramDict );
if (FAILED(hRes))
{
Error( hRes, TEXT("Could not get the ISRGramDictation interface."));
goto initGrammars_done;
}
  hRes = lpUnkDict->QueryInterface( IID_IIBM_SRGramDictation, (void**)&m_pIBMGramDict );
if (FAILED(hRes))
{
Error( hRes, TEXT("Could not get the IBM SRGramDictation interface."));
goto initGrammars_done;
}

  //
// Create the limited-domain grammar in memory and load it into the engine.
//
ltdGram.pData = 0;
  wordlen = strlen(stopPhrase) * 2 + 2;// +2 for ending null
  ltdGram.dwSize = sizeof(SRHEADER) + sizeof(SRCHUNK) + wordlen;
ltdGram.pData = (void*) new unsigned int[ltdGram.dwSize];
  pSRHeader = (SRHEADER *)ltdGram.pData;
pSRHeader->dwType = SRHDRTYPE_LIMITEDDOMAIN;
pSRHeader->dwFlags = SRHDRFLAG_UNICODE;
  pSRChunk = (SRCHUNK *) ((PBYTE)ltdGram.pData + sizeof(SRHEADER));
pSRChunk->dwChunkID = SRCKLD_WORDS;
pSRChunk->dwChunkSize = wordlen;
MultiByteToWideChar(CP_ACP, 0, stopPhrase, -1, (unsigned short *)&pSRChunk->avInfo[0], wordlen);
  
m_pSpchLtdSink = new SpchLtdSink(this);
hRes = m_pSpchCentral->GrammarLoad(SRGRMFMT_LIMITEDDOMAIN,
ltdGram,
(PVOID)m_pSpchLtdSink,
IID_ISRGramNotifySink,
&lpUnkLtd );
if( FAILED(hRes))
{
Error(hRes, TEXT("Could not load the dictation grammar"));
goto initGrammars_done;
}
  
/*------------------------------------------------------------------------------------*/
/* Now that we have the Unknown to the grammer object, lets get the Action interface. */
/*------------------------------------------------------------------------------------*/
hRes = lpUnkLtd->QueryInterface( IID_IIBM_SRUpdateWords, (void**)&m_pIBMUpdateWords );
if (FAILED(hRes))
{
Error( hRes, TEXT("Could not get IBM SRUpdateWords interface."));
goto initGrammars_done;
}
  
/*------------------------------------------------------------------------------------*/
/* Now that we have the Unknown to the grammer object, lets get the common interface. */
/*------------------------------------------------------------------------------------*/
hRes = lpUnkLtd->QueryInterface( IID_ISRGramCommon, (void**)&m_pLtdGramCommon );
if (FAILED(hRes))
{
Error( hRes, TEXT("Could not get ISRGramCommon interface."));
goto initGrammars_done;
}
  actionGram.pData = 0;
  
Actionlen = strlen("sel") * 2 + 2;
wordlen = strlen("dummy") * 2 + 2;
  
actionGram.dwSize = sizeof(SRHEADER) + (sizeof(SRCHUNK) *2) + sizeof(SRACTIONVERB) + Actionlen + wordlen;
actionGram.pData = (void*) new unsigned int[actionGram.dwSize];
  // Set Header Data
pSRHeader = (SRHEADER *)actionGram.pData;
pSRHeader->dwType = IBM_SRHDRTYPE_ACTION;
pSRHeader->dwFlags = SRHDRFLAG_UNICODE;

  // Fill in Chunk Data
pSRChunk = (SRCHUNK *) ((PBYTE)actionGram.pData + sizeof(SRHEADER));
pSRChunk->dwChunkID = SRCKACTION_ACTIONVERB;
pSRChunk->dwChunkSize = sizeof(SRACTIONVERB) + Actionlen;

// Fill In Action Verb Data
  pSRActionVerb = (PSRACTIONVERB)((PBYTE)actionGram.pData + sizeof(SRHEADER)+ sizeof(SRCHUNK));
pSRActionVerb->dwSize = sizeof(SRACTIONVERB) + Actionlen;
pSRActionVerb->dwActionNum = 1;
MultiByteToWideChar(CP_ACP, 0, "sel", -1, (unsigned short *)&pSRActionVerb->szString[0], Actionlen);
  // Fill in Word Data
pSRChunk = (SRCHUNK *) ((PBYTE)pSRActionVerb + sizeof(SRACTIONVERB) + Actionlen);
pSRChunk->dwChunkID = SRCKACTION_WORDSSEQUENCE;
pSRChunk->dwChunkSize = wordlen;
MultiByteToWideChar(CP_ACP, 0, "dummy", -1, (unsigned short *)&pSRChunk->avInfo[0], wordlen);
  m_pSpchActionSink = new SpchActionSink(this);
hRes = m_pSpchCentral->GrammarLoad((SRGRMFMT) IBM_SRGRMFMT_ACTION,
actionGram,
(PVOID)m_pSpchActionSink,
IID_ISRGramNotifySink,
&lpUnkAction );
if( FAILED(hRes))
{
Error(hRes, TEXT("Could not load the IBM Action grammar"));
goto initGrammars_done;
}
  
/*------------------------------------------------------------------------------------*/
/* Now that we have the Unknown to the grammer object, lets get the Action interface. */
/*------------------------------------------------------------------------------------*/
hRes = lpUnkAction->QueryInterface( IID_IIBM_SRGramAction, (void**)&m_pGramAction );
if (FAILED(hRes))
{
Error( hRes, TEXT("Could not get IBM SRGramAction interface."));
goto initGrammars_done;
}
  hRes = lpUnkAction->QueryInterface( IID_ISRGramCommon, (void**)&m_pGramActionCommon );
if (FAILED(hRes))
{
Error( hRes, TEXT("Could not get ISRGramCommon interface."));
goto initGrammars_done;
}
  

  
initGrammars_done:
if (lpUnkDict) lpUnkDict->Release();
if (dictGram.pData) delete dictGram.pData;
if (lpUnkLtd) lpUnkLtd->Release();
if (ltdGram.pData) delete ltdGram.pData;
  if (lpUnkAction) lpUnkAction->Release();
if (actionGram.pData) delete actionGram.pData;
  if (FAILED(hRes))
{
success = no;
}
  return success;
}
  //--------------------------------------------------------------------------
// Description: returns the "stop dictation" phrase that is appropriate for
//the current language.
//--------------------------------------------------------------------------
const char *SapiSpeech:: getStopPhrase(const char *pCountryCode)
{
if (0 == strcmp(pCountryCode, "US")) return "stop dictation";// United States
if (0 == strcmp(pCountryCode, "UK")) return "stop dictation";// United Kingdom
if (0 == strcmp(pCountryCode, "FR")) return "stop dictation";// French
if (0 == strcmp(pCountryCode, "GR")) return "stop dictation";// German
if (0 == strcmp(pCountryCode, "IT")) return "stop dictation";// Italian
if (0 == strcmp(pCountryCode, "ES")) return "stop dictation";// Spanish
  return "unknown language";
}
  //--------------------------------------------------------------------------
// Description: returns the prefix for the grammars based upon which language
// we are in.
//--------------------------------------------------------------------------
const char * SapiSpeech:: getGrammarLanguageSuffix(GUID &engGuid)
{
if (engGuid == CLSID_SREngineEnumIBMDiscreteDictationModeUS ||
engGuid == CLSID_SREngineEnumIBMContinuousDictationModeUS)// US english
return "US";
if (engGuid == CLSID_SREngineEnumIBMDiscreteDictationModeUK ||
engGuid == CLSID_SREngineEnumIBMContinuousDictationModeUK)// UK english
return "UK";
if (engGuid == CLSID_SREngineEnumIBMDiscreteDictationModeFR ||
engGuid == CLSID_SREngineEnumIBMContinuousDictationModeFR)// french
return "FR";
if (engGuid == CLSID_SREngineEnumIBMDiscreteDictationModeGR ||
engGuid == CLSID_SREngineEnumIBMContinuousDictationModeGR)// german
return "GR";
if (engGuid == CLSID_SREngineEnumIBMDiscreteDictationModeIT ||
engGuid == CLSID_SREngineEnumIBMContinuousDictationModeIT)// italian
return "IT";
if (engGuid == CLSID_SREngineEnumIBMDiscreteDictationModeES ||
engGuid == CLSID_SREngineEnumIBMContinuousDictationModeES)// spanish
return "ES";
  return "";
}

//--------------------------------------------------------------------------
// Description: Activates the Grammar
//--------------------------------------------------------------------------
int SapiSpeech:: activate(BOOL pause)
{
HRESULT hres;
  m_pCEdit->SetFocus();
  hres = m_pISRListen->StartListening(m_dwListenKey);
if ( FAILED(hres) )
{
return( hres );
}
  hres = m_pGramCommon->Activate( m_pCEdit->GetParent()->m_hWnd, pause, NULL );
if ( FAILED(hres) )
{
return( hres );
}
  return m_pLtdGramCommon->Activate( m_pCEdit->GetParent()->m_hWnd, pause, NULL );

}
  //--------------------------------------------------------------------------
// Description: Deactivates the Grammar
//--------------------------------------------------------------------------
int SapiSpeech:: deactivate()
{
HRESULT hres;
  if (0 != m_pISRListen)
{
hres = m_pISRListen->StopListening(m_dwListenKey);
if ( FAILED(hres) )
{
return( hres );
}
}
  if (0 != m_pGramCommon)
{
hres = m_pGramCommon->Deactivate(NULL);
if ( FAILED(hres) )
{
return hres;
}
}
  if (0 != m_pLtdGramCommon)
{
hres = m_pLtdGramCommon->Deactivate(NULL);
if ( FAILED(hres) )
{
return hres;
}
}
  return RC_SUCCESS;
}
  //--------------------------------------------------------------------------
// Description: Activates an Action in an action Grammar
//--------------------------------------------------------------------------
int SapiSpeech:: ActivateAction(char * szAction)
{
HRESULT hres;
WCHAR wszAction[100];
  
// Activate Action Specified
  hres = MultiByteToWideChar(CP_ACP, 0, szAction, -1, wszAction, 100);
hres = m_pGramActionCommon->Activate( m_pCEdit->GetParent()->m_hWnd, false, wszAction );

  return hres;

}
  //--------------------------------------------------------------------------
// Description: Activates an Action in an action Grammar
//--------------------------------------------------------------------------
int SapiSpeech:: DeActivateAction(char * szAction)
{
HRESULT hres;
WCHAR wszAction[100];

// Activate Action Specified
  hres = MultiByteToWideChar(CP_ACP, 0, szAction, -1, wszAction, 100);
hres = m_pGramActionCommon->Deactivate(wszAction );

  return hres;

}
  
//--------------------------------------------------------------------------
// Description: This logs the events from the grammar sink and the engine sink.
//--------------------------------------------------------------------------
void SapiSpeech::logEventSink(SPCHEVENTID id, char *fmt, ...)
{
static char buf[1000];
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
  if (m_pStatusLB)
m_pStatusLB->AddString(buf);
else
{
TRACE(buf);
TRACE("/n");
}
}
  //----------------------------------------------------------------------------------------------
// Description: reset the context for word(s) that are to be corrected.
//----------------------------------------------------------------------------------------------
int SapiSpeech:: resetContext( void )
{
  PWSTR pszPrior = NULL;
PWSTR pszAfter = NULL;
  // reset the context... prior and after words are null
HRESULT hres = m_pSpchGramDict->Context( pszPrior, pszAfter );
if ( hres != NOERROR )
{
return 0;
}
  return 1;
}
  void SapiSpeech::DisplayTopics(CListBox *pLB)
{
HRESULT hRes;
PIIBM_SRSUBTOPIC pISRTopic = 0;
PCWSTR pTopicList = NULL;
DWORD dwTopicSize;
char szTopic[256];
  
hRes = m_pSpchCentral->QueryInterface(IID_IIBM_SRSubTopic, (void**)&pISRTopic);
  if (FAILED(hRes))
{
Error( hRes, TEXT("Error Querying IBM Topics Extension") );
return;
}
else
{
pISRTopic->EnumSubTopics(&dwTopicSize,&pTopicList);
  // loop through all of the Topics and display them...
  if (dwTopicSize > 0)
{
WCHAR * pSRWord= (WCHAR *) pTopicList;
WCHAR * pSRMax = (WCHAR *) ((BYTE*)pTopicList + (dwTopicSize-2));
while( pSRWord < pSRMax)
{
int count = WideCharToMultiByte(CP_ACP, NULL, (unsigned short *)pSRWord, -1, szTopic, dwTopicSize, NULL, NULL);
if (count == 0)
{
Error( -1000, TEXT("WideCharToMultiByte failed") );
continue;
}
else
{
if (pLB)
pLB->AddString(szTopic);
}
  pSRWord = (WCHAR *) pSRWord + count;

}
}
  pISRTopic->Release();
if (pTopicList)
CoTaskMemFree((VOID*)pTopicList);
}
return;
}
  
//------------------------------------------------------------------------------
// Description: Speech engine notification sink implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Description: constructor
//------------------------------------------------------------------------------
SpchEngSink::SpchEngSink( SapiSpeech *pSpchObj )
{
m_pSpchObj = pSpchObj;
m_dwRefCnt = 0;
}
  //----------------------------------------------------------------------------------------------
// Description: destructor
//----------------------------------------------------------------------------------------------
SpchEngSink::~SpchEngSink()
{
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchEngSink::QueryInterface( REFIID riid, LPVOID *ppv )
{
*ppv = NULL;
  // always return our IUnkown for IID_IUnknown...
if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID(riid,IID_ISRNotifySink))
{
AddRef();
*ppv = (LPVOID)this;
return S_OK;
}
  // otherwise, cant find...
return ResultFromScode (E_NOINTERFACE);
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_ (ULONG) SpchEngSink::AddRef()
{
return ++m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) SpchEngSink::Release()
{
if( --m_dwRefCnt == 0 )
{
delete this;
return 0;
}
return m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchEngSink::AttribChanged( DWORD dwAttribID )
{
if (tellMe.bEngAttribChanged)
m_pSpchObj->logEventSink(ENG_ATTRIBCHANGED, TEXT("Attrib Id: 0x%x"), dwAttribID);
  return NOERROR;
}
  
//----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchEngSink::Interference( QWORD qTimeStampBegin,QWORD qTimeStampEnd, DWORD dwType )
{
if (tellMe.bEngInterference)
m_pSpchObj->logEventSink(ENG_INTERFERENCE, TEXT("Interference Beg: %I64x End: %I64x Type: 0x%04x"),
qTimeStampBegin, qTimeStampEnd, dwType);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchEngSink::Sound( QWORD qTimeStampBegin, QWORD qTimeStampEnd )
{
if (tellMe.bEngSound)
m_pSpchObj->logEventSink(ENG_SOUND, TEXT("Sound: Beg: %I64x, end %I64x"), qTimeStampBegin, qTimeStampEnd);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchEngSink::UtteranceBegin( QWORD qTimeStampBegin )
{
if (tellMe.bEngUtteranceBegin)
m_pSpchObj->logEventSink(ENG_UTTERANCEBEGIN, TEXT("UtteranceBeg Beg: %I64x"), qTimeStampBegin);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchEngSink::UtteranceEnd( QWORD qTimeStampBegin,QWORD qTimeStampEnd )
{
if (tellMe.bEngUtteranceEnd)
m_pSpchObj->logEventSink(ENG_UTTERANCEEND, TEXT("UtteranceEnd Beg: %I64x End: %I64x"), qTimeStampBegin, qTimeStampEnd);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchEngSink::VUMeter( QWORD qTimeStampBegin, WORD wLevel )
{
if (tellMe.bEngVUMeter)
m_pSpchObj->logEventSink(ENG_VUMETER, TEXT("VUMeter Beg: %I64x Level: 0x%04x"), qTimeStampBegin, wLevel);
  return NOERROR;
}
  
//------------------------------------------------------------------------------
// Description: Dictation Grammar notification sink implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Description: constructor
//------------------------------------------------------------------------------
SpchDctSink::SpchDctSink( SapiSpeech *pSpch)
:m_ResList(pSpch)
{
m_pSpchObj = pSpch;
m_dwRefCnt= 0;
}
  //----------------------------------------------------------------------------------------------
// Description: destructor
//----------------------------------------------------------------------------------------------
SpchDctSink::~SpchDctSink()
{
}
  
//----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::QueryInterface( REFIID riid, LPVOID *ppv )
{
*ppv = NULL;
  // always return our IUnknown for IID_IUnknown...
if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID(riid,IID_ISRGramNotifySink))
{
AddRef();
*ppv = (LPVOID)this;
return S_OK;
}
  // otherwise, cant find...
return ResultFromScode (E_NOINTERFACE);
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_ (ULONG) SpchDctSink::AddRef()
{
return ++m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) SpchDctSink::Release()
{
if( --m_dwRefCnt == 0 )
{
delete this;
return 0;
}
return m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::BookMark( DWORD dwID )
{
if (tellMe.bDctBookmark)
m_pSpchObj->logEventSink(DCT_BOOKMARK, TEXT("Dict:BookMark id: 0x%lx"), dwID);
return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::Paused()
{
if (tellMe.bDctPaused)
m_pSpchObj->logEventSink(DCT_PAUSED, TEXT("Dict:Paused..."));
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::PhraseStart( QWORD qTimeStampBegin )
{
if (tellMe.bDctPhraseStart)
m_pSpchObj->logEventSink(DCT_PHRASESTART, TEXT("Dict:PhraseStart Beg: %I64x"), qTimeStampBegin );
  m_ResList.dctPhStart(qTimeStampBegin);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::PhraseHypothesis( DWORD dwFlags, QWORD qTimeStampBegin,
QWORD qTimeStampEnd, PSRPHRASE pSRPhrase, LPUNKNOWN lpResults )
{
if (tellMe.bDctPhraseHypothesis)
m_pSpchObj->logEventSink(DCT_PHRASEHYPOTHESIS, TEXT("Dict:PhraseHypothesis Beg: %I64x End: %I64x Flags: 0x%lx"), qTimeStampBegin, qTimeStampEnd, dwFlags );
  char buf[MAX_PHRASELEN];
CString phrase;
  // Make sure that the reco is for us
if ( !(dwFlags & ISRNOTEFIN_THISGRAMMAR)) return NOERROR;
if ( !(dwFlags & ISRNOTEFIN_RECOGNIZED )) return NOERROR;
  // unrecognized utterance
if( !pSRPhrase )
return NOERROR;
  // loop through all of the words and display them...
PSRWORDpSRWord = (PSRWORD) (pSRPhrase->abWords);
PSRWORDpSRMax = (PSRWORD) ((BYTE*)pSRPhrase + pSRPhrase->dwSize);
while( pSRWord < pSRMax )
{
int count = WideCharToMultiByte(CP_ACP, NULL, pSRWord->szWord, -1, buf, MAX_PHRASELEN, NULL, NULL);
if (count = 0)
{
Error( -1000, TEXT("Dct PhraseHypothesis: WideCharToMultiByte failed") );
continue;
}
if (phrase.GetLength() > 0)
phrase += " ";
phrase += buf;
pSRWord = (PSRWORD) ((BYTE*) pSRWord + pSRWord->dwSize);
}
  m_ResList.dctPhHypothesis(phrase);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::PhraseFinish( DWORD dwFlags,
QWORD qTimeStampBegin,
QWORD qTimeStampEnd,
PSRPHRASE pSRPhrase,
LPUNKNOWN lpResults )
{
charbuf[MAX_PHRASELEN];
  
// Make sure that the reco is for us
if ( !(dwFlags & ISRNOTEFIN_THISGRAMMAR)) return NOERROR;
if ( !(dwFlags & ISRNOTEFIN_RECOGNIZED )) return NOERROR;
  if (tellMe.bDctPhraseFinish)
m_pSpchObj->logEventSink(DCT_PHRASEFINISH, TEXT("Dict:PhraseFinish Beg: %I64x End: %I64x Flags: 0x%lx"), qTimeStampBegin, qTimeStampEnd, dwFlags );
  PSRWORD pSRWord, pSRMax;
CString phrase;
  // unrecognized utterance
if( !pSRPhrase )
return NOERROR;
  // loop through all of the words and display them...
pSRMax = (PSRWORD) ((BYTE*)pSRPhrase + pSRPhrase->dwSize);
pSRWord = (PSRWORD) (pSRPhrase->abWords);
while( pSRWord < pSRMax )
{
int count = WideCharToMultiByte(CP_ACP, NULL, pSRWord->szWord, -1, buf, MAX_PHRASELEN, NULL, NULL);
if (count = 0)
{
Error( -1000, TEXT("Dct PhraseHypothesis: WideCharToMultiByte failed") );
continue;
}
  // store the phrase to display in the results list box...
if( lpResults )
{
if (phrase.GetLength() > 0)
phrase += " ";
phrase += buf;
}
pSRWord = (PSRWORD) ((BYTE*) pSRWord + pSRWord->dwSize);
}
  if ("" == phrase)// new phrase is empty
return NOERROR;
  return m_ResList.dctText(lpResults, phrase);
  
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::ReEvaluate( LPUNKNOWN lpUnk )
{
if (tellMe.bDctReevaluate)
m_pSpchObj->logEventSink(DCT_REEVALUATE, TEXT("Dict:Reevaluate lpUnk: %08x"), lpUnk);
  if ( 0 == lpUnk ) return NOERROR;
  //Let the ResultList do its thing for correction.
m_ResList.dctReevaluate(lpUnk);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::Training( DWORD dwTrain )
{
if (tellMe.bDctTraining)
m_pSpchObj->logEventSink(DCT_TRAINING, TEXT("Dict:TrainingRequest Flag: 0x%lx."), dwTrain );
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchDctSink::UnArchive( LPUNKNOWN lpUnk )
{
if (tellMe.bDctUnarchive)
m_pSpchObj->logEventSink(DCT_UNARCHIVE, TEXT("Dict:Unarchive lpUnk: %08x"), lpUnk);
  return NOERROR;
}
  
//------------------------------------------------------------------------------
// Description: Limited-domain Grammar notification sink implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Description: constructor
//------------------------------------------------------------------------------
SpchLtdSink::SpchLtdSink( SapiSpeech *pSpch)
:m_ResList(pSpch)
{
m_pSpchObj = pSpch;
m_dwRefCnt= 0;
}
  //----------------------------------------------------------------------------------------------
// Description: destructor
//----------------------------------------------------------------------------------------------
SpchLtdSink::~SpchLtdSink()
{
}
  
//----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::QueryInterface( REFIID riid, LPVOID *ppv )
{
*ppv = NULL;
  // always return our IUnknown for IID_IUnknown...
if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID(riid,IID_ISRGramNotifySink))
{
AddRef();
*ppv = (LPVOID)this;
return S_OK;
}
  // otherwise, cant find...
return ResultFromScode (E_NOINTERFACE);
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_ (ULONG) SpchLtdSink::AddRef()
{
return ++m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) SpchLtdSink::Release()
{
if( --m_dwRefCnt == 0 )
{
delete this;
return 0;
}
return m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::BookMark( DWORD dwID )
{
if (tellMe.bDctBookmark)
m_pSpchObj->logEventSink(DCT_BOOKMARK, TEXT("Ltd:BookMark id: 0x%lx"), dwID);
return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::Paused()
{
if (tellMe.bDctPaused)
m_pSpchObj->logEventSink(DCT_PAUSED, TEXT("Ltd:Paused..."));
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::PhraseStart( QWORD qTimeStampBegin )
{
if (tellMe.bDctPhraseStart)
m_pSpchObj->logEventSink(DCT_PHRASESTART, TEXT("Ltd:PhraseStart Beg: %I64x"), qTimeStampBegin );
  m_ResList.dctPhStart(qTimeStampBegin);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::PhraseHypothesis( DWORD dwFlags, QWORD qTimeStampBegin,
QWORD qTimeStampEnd, PSRPHRASE pSRPhrase, LPUNKNOWN lpResults )
{
if (tellMe.bDctPhraseHypothesis)
m_pSpchObj->logEventSink(DCT_PHRASEHYPOTHESIS, TEXT("Ltd:PhraseHypothesis Beg: %I64x End: %I64x Flags: 0x%lx"), qTimeStampBegin, qTimeStampEnd, dwFlags );
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec...
// The "stop dictation" phrase is searched for here. If it is found, then dictaiton
//is deactivated. Note that additional PhraseFinish invocation will still come
//since the speech engine will firm up all remaining word
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::PhraseFinish( DWORD dwFlags,
QWORD qTimeStampBegin,
QWORD qTimeStampEnd,
PSRPHRASE pSRPhrase,
LPUNKNOWN lpResults )
{
charbuf[MAX_PHRASELEN];
  
// Make sure that the reco is for us
if ( !(dwFlags & ISRNOTEFIN_THISGRAMMAR)) return NOERROR;
if ( !(dwFlags & ISRNOTEFIN_RECOGNIZED )) return NOERROR;
  if (tellMe.bDctPhraseFinish)
m_pSpchObj->logEventSink(DCT_PHRASEFINISH, TEXT("Ltd:PhraseFinish Beg: %I64x End: %I64x Flags: 0x%lx"), qTimeStampBegin, qTimeStampEnd, dwFlags );
  PSRWORD pSRWord, pSRMax;
CString phrase;
  // unrecognized utterance
if( !pSRPhrase )
return NOERROR;
  // loop through all of the words and display them...
pSRMax = (PSRWORD) ((BYTE*)pSRPhrase + pSRPhrase->dwSize);
pSRWord = (PSRWORD) (pSRPhrase->abWords);
while( pSRWord < pSRMax )
{
int count = WideCharToMultiByte(CP_ACP, NULL, pSRWord->szWord, -1, buf, MAX_PHRASELEN, NULL, NULL);
if (count = 0)
{
Error( -1000, TEXT("Ltd PhraseHypothesis: WideCharToMultiByte failed") );
continue;
}
  // store the phrase to display in the results list box...
if (phrase.GetLength() > 0)
phrase += " ";
phrase += buf;
  pSRWord = (PSRWORD) ((BYTE*) pSRWord + pSRWord->dwSize);
}
  if ("" == phrase)// new phrase is empty
return NOERROR;
  // did we recognize the stop dictation phrase for this language
if ( phrase.Compare(pGStopPhr) == 0 )
{
m_pSpchObj->m_pCEdit->GetParent()->PostMessage(WM_DICT_STOPPING, 0, 0);
}
  

return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::ReEvaluate( LPUNKNOWN lpUnk )
{
if (tellMe.bDctReevaluate)
m_pSpchObj->logEventSink(DCT_REEVALUATE, TEXT("Ltd:Reevaluate lpUnk: %08x"), lpUnk);
  if ( 0 == lpUnk ) return NOERROR;
  // Let the ResultList do its thing for correction.
m_ResList.dctReevaluate(lpUnk);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::Training( DWORD dwTrain )
{
if (tellMe.bDctTraining)
m_pSpchObj->logEventSink(DCT_TRAINING, TEXT("Ltd:TrainingRequest Flag: 0x%lx."), dwTrain );
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchLtdSink::UnArchive( LPUNKNOWN lpUnk )
{
if (tellMe.bDctUnarchive)
m_pSpchObj->logEventSink(DCT_UNARCHIVE, TEXT("Ltd:Unarchive lpUnk: %08x"), lpUnk);
  return NOERROR;
}
  
//------------------------------------------------------------------------------
// Description: Action Grammar notification sink implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Description: constructor
//------------------------------------------------------------------------------
SpchActionSink::SpchActionSink( SapiSpeech *pSpch)
:m_ResList(pSpch)
{
m_pSpchObj = pSpch;
m_dwRefCnt= 0;
}
  //----------------------------------------------------------------------------------------------
// Description: destructor
//----------------------------------------------------------------------------------------------
SpchActionSink::~SpchActionSink()
{
}
  
//----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::QueryInterface( REFIID riid, LPVOID *ppv )
{
*ppv = NULL;
  // always return our IUnknown for IID_IUnknown...
if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID(riid,IID_ISRGramNotifySink))
{
AddRef();
*ppv = (LPVOID)this;
return S_OK;
}
  // otherwise, cant find...
return ResultFromScode (E_NOINTERFACE);
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_ (ULONG) SpchActionSink::AddRef()
{
return ++m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) SpchActionSink::Release()
{
if( --m_dwRefCnt == 0 )
{
delete this;
return 0;
}
return m_dwRefCnt;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::BookMark( DWORD dwID )
{
if (tellMe.bDctBookmark)
m_pSpchObj->logEventSink(DCT_BOOKMARK, TEXT("Action:BookMark id: 0x%lx"), dwID);
return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::Paused()
{
if (tellMe.bDctPaused)
m_pSpchObj->logEventSink(DCT_PAUSED, TEXT("Action:Paused..."));
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::PhraseStart( QWORD qTimeStampBegin )
{
if (tellMe.bDctPhraseStart)
m_pSpchObj->logEventSink(DCT_PHRASESTART, TEXT("Action:PhraseStart Beg: %I64x"), qTimeStampBegin );
  m_ResList.dctPhStart(qTimeStampBegin);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::PhraseHypothesis( DWORD dwFlags, QWORD qTimeStampBegin,
QWORD qTimeStampEnd, PSRPHRASE pSRPhrase, LPUNKNOWN lpResults )
{
if (tellMe.bDctPhraseHypothesis)
m_pSpchObj->logEventSink(DCT_PHRASEHYPOTHESIS, TEXT("Action:PhraseHypothesis Beg: %I64x End: %I64x Flags: 0x%lx"), qTimeStampBegin, qTimeStampEnd, dwFlags );
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec...
// The "stop dictation" phrase is searched for here. If it is found, then dictaiton
//is deactivated. Note that additional PhraseFinish invocation will still come
//since the speech engine will firm up all remaining word
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::PhraseFinish( DWORD dwFlags,
QWORD qTimeStampBegin,
QWORD qTimeStampEnd,
PSRPHRASE pSRPhrase,
LPUNKNOWN lpResults )
{
charbuf[MAX_PHRASELEN];
DWORD dwActionID = 0;
  
// Make sure that the reco is for us
if ( !(dwFlags & ISRNOTEFIN_THISGRAMMAR)) return NOERROR;
if ( !(dwFlags & ISRNOTEFIN_RECOGNIZED )) return NOERROR;
  if (tellMe.bDctPhraseFinish)
m_pSpchObj->logEventSink(DCT_PHRASEFINISH, TEXT("Action:PhraseFinish Beg: %I64x End: %I64x Flags: 0x%lx"), qTimeStampBegin, qTimeStampEnd, dwFlags );
  
PSRWORD pSRWord, pSRMax;
CString phrase;
  // unrecognized utterance
if( !pSRPhrase )
return NOERROR;
  // loop through all of the words
pSRMax = (PSRWORD) ((BYTE*)pSRPhrase + pSRPhrase->dwSize);
pSRWord = (PSRWORD) (pSRPhrase->abWords);
while( pSRWord < pSRMax )
{
int count = WideCharToMultiByte(CP_ACP, NULL, pSRWord->szWord, -1, buf, MAX_PHRASELEN, NULL, NULL);
if (count = 0)
{
Error( -1000, TEXT("Ltd PhraseHypothesis: WideCharToMultiByte failed") );
continue;
}
  // store the phrase to display in the results list box...
if (phrase.GetLength() > 0)
phrase += " ";
phrase += buf;
  if (dwActionID == 0)
dwActionID = pSRWord->dwWordNum;
  pSRWord = (PSRWORD) ((BYTE*) pSRWord + pSRWord->dwSize);
}
  if ("" == phrase)// new phrase is empty
return NOERROR;
  m_pSpchObj->logEventSink(DCT_PHRASEFINISH, TEXT("Action Recognized: %s Action ID = %d"), (LPCSTR)phrase , dwActionID);
  

return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::ReEvaluate( LPUNKNOWN lpUnk )
{
if (tellMe.bDctReevaluate)
m_pSpchObj->logEventSink(DCT_REEVALUATE, TEXT("Action:Reevaluate lpUnk: %08x"), lpUnk);
  if ( 0 == lpUnk ) return NOERROR;
  // Let the ResultList do its thing for correction.
m_ResList.dctReevaluate(lpUnk);
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::Training( DWORD dwTrain )
{
if (tellMe.bDctTraining)
m_pSpchObj->logEventSink(DCT_TRAINING, TEXT("Action:TrainingRequest Flag: 0x%lx."), dwTrain );
  return NOERROR;
}
  //----------------------------------------------------------------------------------------------
// Description: Defined in SAPI Spec
//----------------------------------------------------------------------------------------------
STDMETHODIMP SpchActionSink::UnArchive( LPUNKNOWN lpUnk )
{
if (tellMe.bDctUnarchive)
m_pSpchObj->logEventSink(DCT_UNARCHIVE, TEXT("Action:Unarchive lpUnk: %08x"), lpUnk);
  return NOERROR;
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-381302-1-1.html 上篇帖子: 使用java技术实现IBM VIAVOICE 语音朗读技术 下篇帖子: IBM WebSphere Application Server V6.1 Fix Pack 27于2009.09.21发布
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表