2

Please can anyone help me? I search some example how can i get information about speeching text in TTS through SAPI (I am programming my aplication in C# but it is not needed, SAPI is the same in C++, etc.) Information what I need is for example: User will write in textbox:

"This is a Text"..

tts.Speak("This is a text"); // this will "read" it..

ok, nice... but I need too get informations about "timing"..

for example:

"Th" (first sound (phoneme) of "This") was "read" in 0.01ms..

"i" (first sound of "is") was "read" in 0.5ms..

"e" (second sound of "Text") was "read" in 1.02ms..

when I save the .wav file generated by SAPI, I need to get information about the timing in the .wav for subsequent "processing" of the wav file.

Sorry for my english and sorry for my bad description of my problem but the problem is i think very simple and all will understand it. If not I will try to describe the problem again :) ^^..

Community
  • 1
  • 1
tomdelahaba
  • 948
  • 3
  • 13
  • 26
  • 2
    That's not how the TTS engine works. The unit of speech is a *phoneme*. You can subscribe to the Phoneme event, it gives you character position and duration. http://msdn.microsoft.com/en-us/library/ms723588%28v=vs.85%29.aspx – Hans Passant Jan 14 '12 at 13:02
  • 2
    He can subscribe to word events as well http://msdn.microsoft.com/en-us/library/ms723593(v=VS.85).aspx – Nikolay Shmyrev Jan 14 '12 at 14:49
  • thanks you guys, i will look on the links and learn something about it..only one more ask..if i "declare" it or when i will make it with the phonemes or words then i can get the information about the timing?? (if I understand it good)..again thanks you..:) Edit: sry, i read bad :).. "it gives you character position and duration" its answer on my ask :) thanks :) – tomdelahaba Jan 15 '12 at 22:17
  • but..one ask more..how can i "use" the SpVoice.phoneme()? :-/ im trying get some informations about the text..and i get always error SpeechLib._ISpeechVoiceEvents_Event.Phoneme' can only appear on the left hand side of += or -=..:-/ and some examples aren't there.. – tomdelahaba Jan 19 '12 at 01:19

1 Answers1

4

I have used C++ and SAPI 5.1 to synthesize speech and have a virtual character move its lips accordingly. Here is some code that works with visemes. According to the documentation at http://msdn.microsoft.com/en-us/library/ms720164(v=vs.85).aspx, phonemes work the same, except replace SPEI_VISEME with SPEI_PHONEME.

DWORD WINAPI Character::sayMessage(LPVOID lpParam){
    HRESULT hres;
    try{
        ::CoInitialize(NULL);
        ThreadParam * param = (ThreadParam *)lpParam;
        wstring s = param->message;

        //first check the string for null
        if (s == L"") return false;

        //http://msdn.microsoft.com/en-us/library/ms720163(VS.85,classic).asp is my source for this
        //set up text to speech

        //get the voice associated with the character
        ISpVoice * pVoice;
        pVoice = param->sceneObject->characterVoice;

        if (pVoice != NULL){
            pVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0 );

            SPEVENT event;
            ULONG ul;

            pVoice->SetInterest(SPFEI(SPEI_VISEME)|SPFEI(SPEI_END_INPUT_STREAM),SPFEI(SPEI_VISEME)|SPFEI(SPEI_END_INPUT_STREAM));
            pVoice->SetNotifyCallbackFunction(&eventFunction,0,0);
            pVoice->WaitForNotifyEvent(INFINITE);

            if (param->sceneObject->age == CHILD){
                s = L"<pitch middle=\"+10\">" + s + L"</pitch>";
            }

            hres = pVoice->Speak(s.c_str(),SPF_ASYNC,NULL);

            bool isDone = false;
            while(!isDone && pVoice != NULL && !FAILED(hres)){                  
                if(pVoice->GetEvents(1,&event, &ul) == S_OK){
                    if(event.eEventId==SPEI_VISEME){
                        //get the viseme
                        int vis = LOWORD(event.lParam);  //handle it however you'd like after this


                    }
                    else if(event.eEventId== SPEI_END_INPUT_STREAM){
                        isDone = true;
                        s = L"";
                        return true;
                    }
                }                   
            }
        }
    }
    catch(...){
        return false;
    }       
    return !FAILED(hres);
}
laurenelizabeth
  • 786
  • 1
  • 7
  • 19
  • Hi, I wonder if you can help me with this problem. http://stackoverflow.com/questions/17966387/c-msapi-5-setnotifycallbackfunction-not-working – Marl Jul 31 '13 at 09:21
  • 1
    Unfortunately in this case the callback function is empty. I had to add in the callback to make the threading work right but nothing actually happens on the callback for my application. I also can't compile on the computer I'm working on at the moment, but I'm wondering if the difference is that you need a pVoice->WaitForNotifyEvent(INFINITE) somewhere? That's the only big difference I see between your code and mine. – laurenelizabeth Jul 31 '13 at 16:51
  • I've only used pVoice->WaitForNotifyEvent(INFINITE) in a part of my code that I've commented out. There is no difference if I commented out that line also. Thanks anyways. – Marl Aug 01 '13 at 06:43