Последующие экземпляры SpVoice молчат

Обнаружен ключ к проблеме / вылету, смотрите внизу поста.

При создании экземпляров ISpVoice с помощью CoCreateInstanceКажется, что случаи, когда первый человек не может говорить, как только первый из них говорит. То есть если pVoice говорит первым, pVoice2 не буду говорить. Если pVoice2 говорит первым, pVoice не буду говорить. Порядок создания / размещения не имеет значения.

Когда я говорю «не буду говорить», я имею в виду: призывы к ISpVoice::Speak немедленно вернуться с результатом S_OK; голос не был синтезирован.

Исправление: вышеописанное происходит в версии D, когда отладчик не подключен. Когда отладчик Visual Studio подключен, нарушение прав доступа происходит в vtjpnsapi50.dll!10004e65, Кроме того, нарушение прав доступа происходит в версии C ++ независимо от того, подключен ли отладчик или генерируется отладочная информация.

Вставка звонка в sleep Между вызовами Speak ничего не меняется (за исключением, конечно, того, что он вставляет задержку).

Воспроизведение в D (эквивалент C ++ ниже):

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;
}

Это эквивалентная программа на C ++:

#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;
}

В приведенном выше примере оба голоса распределены с одинаковыми параметрами, и первый голос, который говорит, работает правильно. В версии D, когда отладчик не подключен, второй вызов Speak на pVoice тоже работает.

Если кто-нибудь знает, что может вызвать это, или знает о каком-либо программном обеспечении с открытым исходным кодом, где используются несколько голосовых объектов, пожалуйста, дайте мне знать, спасибо!

редактировать
Это происходит только с голосами NeoSpeech. Он прекрасно работает с голосами Microsoft и eSpeak. Я все еще хотел бы знать, могу ли я что-нибудь сделать, чтобы решить проблему (у NeoSpeech есть действительно очень хорошие голоса …).

4

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]