Subsequent instances of SpVoice are silent

Detected key to the problem / failure, see the bottom of the message.

When creating instances of ISpVoice using CoCreateInstance , it seems that the instances after the first can not speak as soon as the first utters. That is, if pVoice speaks first, pVoice2 will not speak. If pVoice2 speaks first, pVoice will not speak. The order of creation / selection does not matter.

When I say β€œI won’t speak,” I mean: calls to ISpVoice::Speak immediately return with the result S_OK ; the voice was not synthesized.

Correction: higher in version D when the debugger is not connected. When the Visual Studio debugger is connected, access violation occurs in vtjpnsapi50.dll!10004e65 . In addition, access violation occurs in the C ++ version, regardless of whether a debugger or debugging information is installed.

Inserting a sleep call between calls in Speak does not change anything (except, of course, that it inserts a delay).

Playback in D (C ++ equivalent below):

 import std.c.windows.com; import core.sys.windows.windows; import speech.windows.sapi; import std.stdio; int main() { if (FAILED(CoInitialize(null))) return 1; scope(exit) CoUninitialize(); ISpVoice pVoice; HRESULT hr = CoCreateInstance(&CLSID_SpVoice, null, CLSCTX_ALL, &IID_ISpVoice, cast(void**)&pVoice); assert(hr == S_OK); hr = pVoice.Speak("Hello world", 0, null); // This speaks fine assert(hr == S_OK); ISpVoice pVoice2; hr = CoCreateInstance(&CLSID_SpVoice, null, CLSCTX_ALL, &IID_ISpVoice, cast(void**)&pVoice2); assert(hr == S_OK); hr = pVoice2.Speak("hello again", 0, null); // This returns immediately assert(hr == S_OK); // Yet it still returns S_OK hr = pVoice.Speak("first voice again", 0, null); // This speaks fine too, immediately after "hello world" finishes assert(hr == S_OK); // The two objects are indeed at different memory addresses writefln("voice 1: %s, voice 2: %s", cast(void*)pVoice, cast(void*)pVoice2); pVoice.Release(); pVoice = null; pVoice2.Release(); pVoice2 = null; return 0; } 

This is the equivalent C ++ program:

 #include <sapi.h> #include<Windows.h> int main() { if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) return 1; ISpVoice* pVoice; HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice); hr = pVoice->Speak(L"Hello world", 0, NULL); // This speaks fine ISpVoice* pVoice2; hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice2); hr = pVoice2->Speak(L"hello again", 0, NULL); // This causes an access violation hr = pVoice->Speak(L"first voice again", 0, NULL); pVoice->Release(); pVoice = NULL; pVoice2->Release(); pVoice2 = NULL; CoUninitialize(); return 0; } 

In the above example, both voices are distributed with the same parameters, and the first voice is working correctly. In version D, when the debugger is not connected, the second Speak on pVoice call also works.

If anyone knows what might cause this, or find out about any open source software that uses multiple voice objects, please let me know, thanks!

change This only happens with NeoSpeech votes. It works great with Microsoft and eSpeak voices. Anyway, I would like to know if I can do anything to fix this problem (NeoSpeech has really, really good voices ...).

+4
source share

Source: https://habr.com/ru/post/1437729/


All Articles