Bender979
asked on
Very odd SAPI 5.1 Text2Speech problem
Hello,
I have a very weird Problem with the SAPI text to speech interface:
I use the Text2Speech API in a MDI MFC application. I have a little toolwindow (Dialogbased) that "speaks" out text via the SAPI and visualizes the spoken text. The text is sent by the active MDI Childwindow to the dialog via a Registered Window Message.
Here is the code, the problem is described below:
BOOL CVoiceDlg::InitSAPI()
{
if(FAILED(CoInitialize(NUL L))) {
m_strError=_T("Error intialization COM");
return FALSE;
}
HRESULT hRes;
hRes = IpVoice.CoCreateInstance(C LSID_SpVoi ce);
if(FAILED(hRes)) {
m_strError=_T("Error creating voice");
return FALSE;
}
hRes = IpVoice->SetInterest(SPFEI (SPEI_VISE ME), SPFEI(SPEI_VISEME));
if(FAILED(hRes)) {
m_strError=_T("Error creating interest.");
return FALSE;
}
hRes = IpVoice->SetNotifyWindowMe ssage(m_hW nd, WM_RECOEVENT, 0, 0);
if(FAILED(hRes)) {
m_strError=_T("Error setting notification window");
return FALSE;
}
return TRUE;
}
// This is a test function
void CVoiceDlg::OnBtnClickedTes t()
{
if(!m_strError.IsEmpty() || !IsWindowVisible()) return;
SpeakChat("squish.squash.t he.debug.r at.494_000 00", "This is a test", FALSE);
}
// This handles the Registered Window-Message
LRESULT CVoiceDlg::OnSpeak(WPARAM wParam, LPARAM lParam)
{
CString strName = ((EXT_MSG_STRUCT*)lParam)- >lpszParam ;
CString strText = ((EXT_MSG_STRUCT*)lParam)- >lpszMsg;
SpeakChat(strName, strText, (BOOL)wParam);
return 1;
}
void CVoiceDlg::SpeakChat(CStri ng strName, CString strText, BOOL bAction)
{
if(!m_strError.IsEmpty() || !IsWindowVisible()) return;
if(bAction){
strOut = strName + " " + strText;
}
else{
strOut = strName + " says: " + strText;
}
TRACE("SpeakChat: %s\n", strOut);
IpVoice->Speak(strOut.Allo cSysString (), SPF_ASYNC, NULL);
}
Here the problem:
When SpeakChat is called from the OnBtnClickTest() method, it works correctly,
but if it is called from the OnSpeak(...) method, it reads the text out twice:
One time with punctuations in the form strName + " " + strMsg and one time, without
punctioations with the bAction condition handled correctly. The first time, the visualization of the
speech, does not work, the second time it does.
I have verified, that the Window message is send correctly (only once).
I have a very weird Problem with the SAPI text to speech interface:
I use the Text2Speech API in a MDI MFC application. I have a little toolwindow (Dialogbased) that "speaks" out text via the SAPI and visualizes the spoken text. The text is sent by the active MDI Childwindow to the dialog via a Registered Window Message.
Here is the code, the problem is described below:
BOOL CVoiceDlg::InitSAPI()
{
if(FAILED(CoInitialize(NUL
m_strError=_T("Error intialization COM");
return FALSE;
}
HRESULT hRes;
hRes = IpVoice.CoCreateInstance(C
if(FAILED(hRes)) {
m_strError=_T("Error creating voice");
return FALSE;
}
hRes = IpVoice->SetInterest(SPFEI
if(FAILED(hRes)) {
m_strError=_T("Error creating interest.");
return FALSE;
}
hRes = IpVoice->SetNotifyWindowMe
if(FAILED(hRes)) {
m_strError=_T("Error setting notification window");
return FALSE;
}
return TRUE;
}
// This is a test function
void CVoiceDlg::OnBtnClickedTes
{
if(!m_strError.IsEmpty() || !IsWindowVisible()) return;
SpeakChat("squish.squash.t
}
// This handles the Registered Window-Message
LRESULT CVoiceDlg::OnSpeak(WPARAM wParam, LPARAM lParam)
{
CString strName = ((EXT_MSG_STRUCT*)lParam)-
CString strText = ((EXT_MSG_STRUCT*)lParam)-
SpeakChat(strName, strText, (BOOL)wParam);
return 1;
}
void CVoiceDlg::SpeakChat(CStri
{
if(!m_strError.IsEmpty() || !IsWindowVisible()) return;
if(bAction){
strOut = strName + " " + strText;
}
else{
strOut = strName + " says: " + strText;
}
TRACE("SpeakChat: %s\n", strOut);
IpVoice->Speak(strOut.Allo
}
Here the problem:
When SpeakChat is called from the OnBtnClickTest() method, it works correctly,
but if it is called from the OnSpeak(...) method, it reads the text out twice:
One time with punctuations in the form strName + " " + strMsg and one time, without
punctioations with the bAction condition handled correctly. The first time, the visualization of the
speech, does not work, the second time it does.
I have verified, that the Window message is send correctly (only once).
Put a breakpoint in your SpeakChat function and see where the first/second call is coming from.
ASKER
Does not work, the execution does not break there. I have a TRACE statement in that function though, whih is printed out only once on the debug trace...
Does not work, the execution does not break there.
If the breakpoint isn't reached then your function is not being called!!!
If the breakpoint isn't reached then your function is not being called!!!
ASKER
It is called, as the TRACE does put the text on the console. Why it does not break there is really beyond me.
ASKER
OK, my fault, it does break...
However it only breaks once so it is only called once.
BUT this call:
IpVoice->Speak(strText.All ocSysStrin g(), SPF_ASYNC, NULL);
is blocking, regardless of the SPF_ASYNC flag. Additionally it speaks as if the SPF_NLP_SPEAK_PUNC flags was specified.
When the Speak call exits, It speaks the text out again (this time not blocking) and without speaking the punctuations.
Microsoft SAPI SDK 5.1
Microsoft Visual C++ 7.1
Could this be a compiler bug?
However it only breaks once so it is only called once.
BUT this call:
IpVoice->Speak(strText.All
is blocking, regardless of the SPF_ASYNC flag. Additionally it speaks as if the SPF_NLP_SPEAK_PUNC flags was specified.
When the Speak call exits, It speaks the text out again (this time not blocking) and without speaking the punctuations.
Microsoft SAPI SDK 5.1
Microsoft Visual C++ 7.1
Could this be a compiler bug?
ASKER
And it gets even weirder (do you believe in ghosts?):
if I change the code in the method
SpeakChat(CString strName, CString strText, BOOL bAction)
to:
------- snip ------------
strText = "Why does this not work";
IpVoice->Speak(strText.All ocSysStrin g(), SPF_ASYNC, NULL);
------- snip ------------
It still reads out strName + " " + strMsg;
and after that it reads out "Why does this not work"
This is really the one and only time IpVoice->Speak is called in the entire project.
I cleaned the intermediate files, tried a clean configuration to avoid any wrong compiler/project settings, even in a seperate project it behaves the same. I am totally lost and frustrated :-(
if I change the code in the method
SpeakChat(CString strName, CString strText, BOOL bAction)
to:
------- snip ------------
strText = "Why does this not work";
IpVoice->Speak(strText.All
------- snip ------------
It still reads out strName + " " + strMsg;
and after that it reads out "Why does this not work"
This is really the one and only time IpVoice->Speak is called in the entire project.
I cleaned the intermediate files, tried a clean configuration to avoid any wrong compiler/project settings, even in a seperate project it behaves the same. I am totally lost and frustrated :-(
I'm no expert with the text to speech interface. I don't think I can offer anything further.
ASKER
Oh my, anyone?
It get's even weirder:
even if I change the function to
void CVoiceDlg::SpeakChat(CStri ng strName, CString strText, BOOL bAction)
{
}
so it does nothing, it still speaks strOut + " " + strText;
It get's even weirder:
even if I change the function to
void CVoiceDlg::SpeakChat(CStri
{
}
so it does nothing, it still speaks strOut + " " + strText;
Do you have this strOut + " " + strText; anywhere else in the project? If you do put a breakpoint there and see if it is somehow being called by this speech out routine.
ASKER
Solved by reinstalling the SAPI... I hate that...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.