Link to home
Start Free TrialLog in
Avatar of Bender979
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(NULL))) {
            
            m_strError=_T("Error intialization COM");
            return FALSE;
      }

    HRESULT hRes;
      
      hRes = IpVoice.CoCreateInstance(CLSID_SpVoice);
      
      if(FAILED(hRes)) {
            m_strError=_T("Error creating voice");
            return FALSE;
      }
      
      hRes = IpVoice->SetInterest(SPFEI(SPEI_VISEME), SPFEI(SPEI_VISEME));      

      if(FAILED(hRes)) {

            m_strError=_T("Error creating interest.");
            return FALSE;
      }
      
      hRes = IpVoice->SetNotifyWindowMessage(m_hWnd, 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::OnBtnClickedTest()
{

      if(!m_strError.IsEmpty() || !IsWindowVisible()) return;

      SpeakChat("squish.squash.the.debug.rat.494_00000", "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(CString 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.AllocSysString(), 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).
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Put a breakpoint in your SpeakChat function and see where the first/second call is coming from.
Avatar of Bender979
Bender979

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!!!
It is called, as the TRACE does put the text on the console. Why it does not break there is really beyond me.
OK, my fault, it does break...

However it only breaks once so it is only called once.

BUT this call:

IpVoice->Speak(strText.AllocSysString(), 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?

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.AllocSysString(), 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 :-(
I'm no expert with the text to speech interface.  I don't think I can offer anything further.
Oh my, anyone?

It get's even weirder:

even if I change the function to

void CVoiceDlg::SpeakChat(CString strName, CString strText, BOOL bAction)
{

}

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.
Solved by reinstalling the SAPI... I hate that...
ASKER CERTIFIED SOLUTION
Avatar of CetusMOD
CetusMOD
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial