C# (C++) SAPI - TTS - как получить тайминги речи для читаемого текста

Пожалуйста, кто-нибудь может мне помочь? Я ищу пример, как я могу получить информацию о речевом тексте в TTS через SAPI (я программирую свое приложение на С#, но это не нужно, SAPI такой же на С++ и т. д.). Мне нужна информация, например: Пользователь будет написать в текстовом поле:

Это текст..

tts.Speak(Это текст); // это будет его читать..

хорошо, хорошо... но мне тоже нужно получить информацию о времени...

Например:

Th (первый звук (фонема) This) был прочитан за 0,01 мс.

i (первый звук is) был прочитан за 0,5 мс..

e (второй звук текста) был прочитан за 1,02 мс.

когда я сохраняю файл .wav, сгенерированный SAPI, мне нужно получить информацию о времени в .wav для последующей обработки файла wav.

Извините за мой английский и извините за плохое описание моей проблемы, но проблема, я думаю, очень проста, и все ее поймут. Если нет, то попробую еще раз описать проблему :) ^^..


person piggy    schedule 14.01.2012    source источник
comment
Это не то, как работает двигатель TTS. Единицей речи является фонема. Вы можете подписаться на событие Phoneme, оно дает вам положение персонажа и продолжительность. msdn.microsoft.com/en-us/ библиотека/ms723588%28v=vs.85%29.aspx   -  person Hans Passant    schedule 14.01.2012
comment
Он также может подписываться на события слов msdn.microsoft. .com/en-us/library/ms723593(v=VS.85).aspx   -  person Nikolay Shmyrev    schedule 14.01.2012
comment
спасибо, ребята, я посмотрю ссылки и узнаю кое-что об этом.. только еще один вопрос.. если я заявлю об этом или когда я сделаю это с фонемами или словами, тогда я смогу получить информацию о сроках?? (если я правильно понимаю).. еще раз спасибо..:) Редактировать: извините, я плохо прочитал :).. он дает вам позицию персонажа и продолжительность его ответа на мой вопрос :) спасибо :)   -  person piggy    schedule 16.01.2012
comment
но... еще один вопрос... как я могу использовать SpVoice.phoneme()? :-/ я пытаюсь получить некоторую информацию о тексте... и я всегда получаю сообщение об ошибке SpeechLib._ISpeechVoiceEvents_Event.Phoneme' может появляться только слева от += или -=..:-/ а некоторых примеров там нет ..   -  person piggy    schedule 19.01.2012


Ответы (1)


Я использовал C++ и SAPI 5.1 для синтеза речи и соответствующего движения губ виртуального персонажа. Вот некоторый код, который работает с виземами. Согласно документации на http://msdn.microsoft.com/en-us/library/ms720164(v=vs.85).aspx, фонемы работают так же, за исключением замены SPEI_VISEME на 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);
}
person laurenelizabeth    schedule 08.05.2012