So I've tried the MSAPI 5.4 TTS with event example. Now I create an cmd prompt app that utilize the SetNotifyCallbackFunction but the function that I've pass is not being called. I'm not an expert in C++ so I am having difficulty in solving this one, can anyone point me in the right direction or at least give me a good example of SetNotifyCallbackFunction?
Here is a simplified version of my code:
typedef void __stdcall SPNOTIFYCALLBACK(WPARAM wParam, LPARAM lParam);
void __stdcall outsideeventFunction(WPARAM, LPARAM);
void __stdcall outsideeventFunction(WPARAM wParam, LPARAM lParam){
std::cout << "Event called::wParam: " << wParam << " lParam: " << lParam << std::endl;
SPEVENT eventItem;
memset(&eventItem, 0, sizeof(SPEVENT));
while (SUCCEEDED(pV->GetEvents(1, &eventItem, NULL)))
{
bool exitNa = false;
switch (eventItem.eEventId)
{
case SPEI_WORD_BOUNDARY:
SPVOICESTATUS eventStatus;
pV->GetStatus(&eventStatus, NULL);
ULONG start, end;
start = eventStatus.ulInputWordPos;
end = eventStatus.ulInputWordLen;
std::cout << "From event Test: " << start << ", " << end << std::endl;
std::cout << "From event Length: " << theString.length() - 1 << ", " << start + end << std::endl;
if (theString.length() - 1 <= start + end){
std::cout << "From event Exit!" << std::endl;
exitNa = true;
}
break;
}
SpClearEvent(&eventItem);
if (exitNa){
break;
}
}
return;
}
int _tmain(int argc, TCHAR* argv [], TCHAR* envp [])
{
pV = NULL;
std::string nativeString("Hello world, this is a test! For the purpose of a longer message, I'll add another sentence. And here comes the new sentence.");
SPNOTIFYCALLBACK *cb = &outsideeventFunction;
if (FAILED(::CoInitialize(NULL)))
return FALSE;
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **) &pV);
if (SUCCEEDED(hr))
{
if (SUCCEEDED(pV->SetNotifyCallbackFunction(cb, 0, 0))){
std::cout << "Success adding callback" << std::endl;
}
ULONGLONG ullMyEvents = SPFEI(SPEI_WORD_BOUNDARY);
pV->SetInterest(ullMyEvents, ullMyEvents);
}
theString = std::wstring(nativeString.begin(), nativeString.end());
printf("Speak: %s\n", nativeString.c_str());
hr = pV->Speak(theString.c_str(), SPF_ASYNC, NULL);
pV->WaitUntilDone(INFINITE);
std::system("pause");
pV->Release();
pV = NULL;
::CoUninitialize();
return TRUE;
}
The result of this app is that the synthesizing of words are done smoothly, but the outsideeventFunction is never been called. As you can see the SetInterest is properly set. How I can fix this?
Two problems:
1) SAPI doesn't let you reassign event targets, so the line
will always fail.
2) You need to pump messages to get events delivered. So instead of calling
you need to get the handle and pump messages until the event is set: