mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 04:34:48 +00:00
sapi: Implement ISpTTSEngineSite::GetActions/Rate/Volume.
This commit is contained in:
parent
0d09ab378e
commit
ee8c8f6533
|
@ -112,6 +112,8 @@ struct test_engine
|
|||
DWORD flags;
|
||||
GUID fmtid;
|
||||
SPVTEXTFRAG *frag_list;
|
||||
LONG rate;
|
||||
USHORT volume;
|
||||
};
|
||||
|
||||
static void copy_frag_list(const SPVTEXTFRAG *frag_list, SPVTEXTFRAG **ret_frag_list)
|
||||
|
@ -154,6 +156,8 @@ static void reset_engine_params(struct test_engine *engine)
|
|||
engine->speak_called = FALSE;
|
||||
engine->flags = 0xdeadbeef;
|
||||
memset(&engine->fmtid, 0xde, sizeof(engine->fmtid));
|
||||
engine->rate = 0xdeadbeef;
|
||||
engine->volume = 0xbeef;
|
||||
|
||||
for (frag = engine->frag_list; frag; frag = next)
|
||||
{
|
||||
|
@ -206,6 +210,7 @@ static HRESULT WINAPI test_engine_Speak(ISpTTSEngine *iface, DWORD flags, REFGUI
|
|||
ISpTTSEngineSite *site)
|
||||
{
|
||||
struct test_engine *engine = impl_from_ISpTTSEngine(iface);
|
||||
DWORD actions;
|
||||
char *buf;
|
||||
int i;
|
||||
HRESULT hr;
|
||||
|
@ -215,11 +220,26 @@ static HRESULT WINAPI test_engine_Speak(ISpTTSEngine *iface, DWORD flags, REFGUI
|
|||
copy_frag_list(frag_list, &engine->frag_list);
|
||||
engine->speak_called = TRUE;
|
||||
|
||||
actions = ISpTTSEngineSite_GetActions(site);
|
||||
ok(actions == (SPVES_CONTINUE | SPVES_RATE | SPVES_VOLUME), "got %#lx.\n", actions);
|
||||
|
||||
hr = ISpTTSEngineSite_GetRate(site, &engine->rate);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
actions = ISpTTSEngineSite_GetActions(site);
|
||||
ok(actions == (SPVES_CONTINUE | SPVES_VOLUME), "got %#lx.\n", actions);
|
||||
|
||||
hr = ISpTTSEngineSite_GetVolume(site, &engine->volume);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
actions = ISpTTSEngineSite_GetActions(site);
|
||||
ok(actions == SPVES_CONTINUE, "got %#lx.\n", actions);
|
||||
|
||||
buf = calloc(1, 22050 * 2 / 5);
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (ISpTTSEngineSite_GetActions(site) & SPVES_ABORT)
|
||||
break;
|
||||
hr = ISpTTSEngineSite_Write(site, buf, 22050 * 2 / 5, NULL);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
ok(hr == S_OK || hr == SP_AUDIO_STOPPED, "got %#lx.\n", hr);
|
||||
Sleep(100);
|
||||
}
|
||||
free(buf);
|
||||
|
@ -507,7 +527,10 @@ static void test_spvoice(void)
|
|||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
ok(stream_num == 0xdeadbeef, "got %lu.\n", stream_num);
|
||||
|
||||
test_engine.speak_called = FALSE;
|
||||
ISpVoice_SetRate(voice, 0);
|
||||
ISpVoice_SetVolume(voice, 100);
|
||||
|
||||
reset_engine_params(&test_engine);
|
||||
stream_num = 0xdeadbeef;
|
||||
start = GetTickCount();
|
||||
hr = ISpVoice_Speak(voice, test_text, SPF_DEFAULT, &stream_num);
|
||||
|
@ -520,6 +543,8 @@ static void test_spvoice(void)
|
|||
ok(test_engine.frag_list->ulTextLen == wcslen(test_text), "got %lu.\n", test_engine.frag_list->ulTextLen);
|
||||
ok(!wcsncmp(test_text, test_engine.frag_list->pTextStart, wcslen(test_text)),
|
||||
"got %s.\n", wine_dbgstr_w(test_engine.frag_list->pTextStart));
|
||||
ok(test_engine.rate == 0, "got %ld.\n", test_engine.rate);
|
||||
ok(test_engine.volume == 100, "got %d.\n", test_engine.volume);
|
||||
ok(stream_num == 1, "got %lu.\n", stream_num);
|
||||
ok(duration > 800 && duration < 3000, "took %lu ms.\n", duration);
|
||||
|
||||
|
@ -540,6 +565,21 @@ static void test_spvoice(void)
|
|||
ok(test_engine.frag_list->ulTextLen == wcslen(test_text), "got %lu.\n", test_engine.frag_list->ulTextLen);
|
||||
ok(!wcsncmp(test_text, test_engine.frag_list->pTextStart, wcslen(test_text)),
|
||||
"got %s.\n", wine_dbgstr_w(test_engine.frag_list->pTextStart));
|
||||
ok(test_engine.rate == 0, "got %ld.\n", test_engine.rate);
|
||||
ok(test_engine.volume == 100, "got %d.\n", test_engine.volume);
|
||||
|
||||
Sleep(2000);
|
||||
|
||||
reset_engine_params(&test_engine);
|
||||
hr = ISpVoice_Speak(voice, test_text, SPF_DEFAULT | SPF_ASYNC, NULL);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
Sleep(200);
|
||||
start = GetTickCount();
|
||||
hr = ISpVoice_Speak(voice, NULL, SPF_PURGEBEFORESPEAK, NULL);
|
||||
duration = GetTickCount() - start;
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
ok(duration < 300, "took %lu ms.\n", duration);
|
||||
|
||||
done:
|
||||
reset_engine_params(&test_engine);
|
||||
|
|
|
@ -45,6 +45,7 @@ struct speech_voice
|
|||
ISpStreamFormat *output;
|
||||
ISpTTSEngine *engine;
|
||||
LONG cur_stream_num;
|
||||
DWORD actions;
|
||||
USHORT volume;
|
||||
LONG rate;
|
||||
struct async_queue queue;
|
||||
|
@ -777,6 +778,13 @@ static void speak_proc(struct async_task *task)
|
|||
|
||||
EnterCriticalSection(&This->cs);
|
||||
|
||||
if (This->actions & SPVES_ABORT)
|
||||
{
|
||||
LeaveCriticalSection(&This->cs);
|
||||
hr = S_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (FAILED(hr = set_output_format(This->output, This->engine, &fmtid, &wfx)))
|
||||
{
|
||||
LeaveCriticalSection(&This->cs);
|
||||
|
@ -789,6 +797,8 @@ static void speak_proc(struct async_task *task)
|
|||
if (SUCCEEDED(ISpStreamFormat_QueryInterface(This->output, &IID_ISpAudio, (void **)&audio)))
|
||||
ISpAudio_SetState(audio, SPAS_RUN, 0);
|
||||
|
||||
This->actions = SPVES_RATE | SPVES_VOLUME;
|
||||
|
||||
LeaveCriticalSection(&This->cs);
|
||||
|
||||
hr = ISpTTSEngine_Speak(engine, speak_task->flags, &fmtid, wfx, speak_task->frag_list, speak_task->site);
|
||||
|
@ -847,6 +857,7 @@ static HRESULT WINAPI spvoice_Speak(ISpVoice *iface, const WCHAR *contents, DWOR
|
|||
|
||||
EnterCriticalSection(&This->cs);
|
||||
|
||||
This->actions = SPVES_ABORT;
|
||||
if (This->output && SUCCEEDED(ISpStreamFormat_QueryInterface(This->output, &IID_ISpAudio, (void **)&audio)))
|
||||
{
|
||||
ISpAudio_SetState(audio, SPAS_CLOSED, 0);
|
||||
|
@ -857,6 +868,10 @@ static HRESULT WINAPI spvoice_Speak(ISpVoice *iface, const WCHAR *contents, DWOR
|
|||
|
||||
async_empty_queue(&This->queue);
|
||||
|
||||
EnterCriticalSection(&This->cs);
|
||||
This->actions = SPVES_CONTINUE;
|
||||
LeaveCriticalSection(&This->cs);
|
||||
|
||||
if (!contents || !*contents)
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1007,6 +1022,7 @@ static HRESULT WINAPI spvoice_SetRate(ISpVoice *iface, LONG rate)
|
|||
|
||||
EnterCriticalSection(&This->cs);
|
||||
This->rate = rate;
|
||||
This->actions |= SPVES_RATE;
|
||||
LeaveCriticalSection(&This->cs);
|
||||
|
||||
return S_OK;
|
||||
|
@ -1036,6 +1052,7 @@ static HRESULT WINAPI spvoice_SetVolume(ISpVoice *iface, USHORT volume)
|
|||
|
||||
EnterCriticalSection(&This->cs);
|
||||
This->volume = volume;
|
||||
This->actions |= SPVES_VOLUME;
|
||||
LeaveCriticalSection(&This->cs);
|
||||
|
||||
return S_OK;
|
||||
|
@ -1205,9 +1222,16 @@ static HRESULT WINAPI ttsenginesite_GetEventInterest(ISpTTSEngineSite *iface, UL
|
|||
|
||||
static DWORD WINAPI ttsenginesite_GetActions(ISpTTSEngineSite *iface)
|
||||
{
|
||||
FIXME("(%p): stub.\n", iface);
|
||||
struct tts_engine_site *This = impl_from_ISpTTSEngineSite(iface);
|
||||
DWORD actions;
|
||||
|
||||
return SPVES_CONTINUE;
|
||||
TRACE("(%p).\n", iface);
|
||||
|
||||
EnterCriticalSection(&This->voice->cs);
|
||||
actions = This->voice->actions;
|
||||
LeaveCriticalSection(&This->voice->cs);
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ttsenginesite_Write(ISpTTSEngineSite *iface, const void *buf, ULONG cb, ULONG *cb_written)
|
||||
|
@ -1224,16 +1248,30 @@ static HRESULT WINAPI ttsenginesite_Write(ISpTTSEngineSite *iface, const void *b
|
|||
|
||||
static HRESULT WINAPI ttsenginesite_GetRate(ISpTTSEngineSite *iface, LONG *rate)
|
||||
{
|
||||
FIXME("(%p, %p): stub.\n", iface, rate);
|
||||
struct tts_engine_site *This = impl_from_ISpTTSEngineSite(iface);
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p, %p).\n", iface, rate);
|
||||
|
||||
EnterCriticalSection(&This->voice->cs);
|
||||
*rate = This->voice->rate;
|
||||
This->voice->actions &= ~SPVES_RATE;
|
||||
LeaveCriticalSection(&This->voice->cs);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ttsenginesite_GetVolume(ISpTTSEngineSite *iface, USHORT *volume)
|
||||
{
|
||||
FIXME("(%p, %p): stub.\n", iface, volume);
|
||||
struct tts_engine_site *This = impl_from_ISpTTSEngineSite(iface);
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p, %p).\n", iface, volume);
|
||||
|
||||
EnterCriticalSection(&This->voice->cs);
|
||||
*volume = This->voice->volume;
|
||||
This->voice->actions &= ~SPVES_VOLUME;
|
||||
LeaveCriticalSection(&This->voice->cs);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ttsenginesite_GetSkipInfo(ISpTTSEngineSite *iface, SPVSKIPTYPE *type, LONG *skip_count)
|
||||
|
@ -1351,6 +1389,7 @@ HRESULT speech_voice_create(IUnknown *outer, REFIID iid, void **obj)
|
|||
This->output = NULL;
|
||||
This->engine = NULL;
|
||||
This->cur_stream_num = 0;
|
||||
This->actions = SPVES_CONTINUE;
|
||||
This->volume = 100;
|
||||
This->rate = 0;
|
||||
memset(&This->queue, 0, sizeof(This->queue));
|
||||
|
|
Loading…
Reference in a new issue