0
votes

I'm trying to write a program for Text-To-Speech using Microsoft SAPI. For that, I have the following code:

ISpVoice * pVoice = NULL;

int main(int argc, char* argv[])
{

    if (FAILED(::CoInitialize(NULL)))
        return FALSE;

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
    if (SUCCEEDED(hr))
    {
        hr = pVoice->Speak(L"Anyone who reads Old and Middle English literary texts will be familiar with the mid-brown volumes of the EETS, with the symbol of Alfred's jewel embossed on the front cover. Most of the works attributed to King Alfred or to Aelfric, along with some of those by bishop Wulfstan and much anonymous prose and verse from the pre-Conquest period, are to be found within the Society's three series; all of the surviving medieval drama, most of the Middle English romances, much religious and secular prose and verse including the English works of John Gower, Thomas Hoccleve and most of Caxton's prints all find their place in the publications. Without EETS editions, study of medieval English texts would hardly be possible.", SPF_IS_XML, NULL);
        pVoice->Release();
        pVoice = NULL;
    }
    ::CoUninitialize();
    return TRUE;
}

I want to print the speak progress to the screen, printing each word when it's spoken. Similar to this in System.Speech.Synthesis:

synth.SpeakProgress += new EventHandler<SpeakProgressEventArgs>(synth_SpeakProgress);

For more details: Use Speech Synthesis Events

So, how can I do that using SAPI?

1

1 Answers

1
votes

ISpVoice inherits from ISpEventSource, which in turn inherits from ISpNotifySource.

Use the ISpEventSource::SetInterest() method to register for desired events, such as SPEI_WORD_BOUNDARY:

A word is beginning to synthesize. Markup language (XML) markers are counted in the boundaries and offsets. wParam is the character length of the word in the current input stream being synthesized. lParam is the character position within the current text input stream of the word being synthesized.

Use the various ISpNotifySource::SetNotify...() methods to specify how you want to receive events from SAPI:

When you receive notification of new events, use ISpEventSource::GetEvents() to get detailed event info, if needed.