Skip to content
Snippets Groups Projects
Commit 17635423 authored by Shaun Ren's avatar Shaun Ren Committed by Alexandre Julliard
Browse files

sapi: Implement ISpVoice::Set/GetVoice.

parent 8c6bb3ca
Branches
Tags
No related merge requests found
......@@ -97,6 +97,9 @@ static void test_spvoice(void)
{
ISpVoice *voice;
ISpMMSysAudio *audio_out;
ISpObjectTokenCategory *token_cat;
ISpObjectToken *token;
WCHAR *token_id = NULL, *default_token_id = NULL;
HRESULT hr;
if (waveOutGetNumDevs() == 0) {
......@@ -118,6 +121,34 @@ static void test_spvoice(void)
hr = ISpVoice_SetOutput(voice, (IUnknown *)audio_out, TRUE);
todo_wine ok(hr == S_FALSE, "got %#lx.\n", hr);
hr = ISpVoice_SetVoice(voice, NULL);
todo_wine ok(hr == S_OK, "got %#lx.\n", hr);
hr = ISpVoice_GetVoice(voice, &token);
todo_wine ok(hr == S_OK, "got %#lx.\n", hr);
if (SUCCEEDED(hr))
{
hr = ISpObjectToken_GetId(token, &token_id);
ok(hr == S_OK, "got %#lx.\n", hr);
hr = CoCreateInstance(&CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
&IID_ISpObjectTokenCategory, (void **)&token_cat);
ok(hr == S_OK, "Failed to create SpObjectTokenCategory: %#lx.\n", hr);
hr = ISpObjectTokenCategory_SetId(token_cat, SPCAT_VOICES, FALSE);
ok(hr == S_OK, "got %#lx.\n", hr);
hr = ISpObjectTokenCategory_GetDefaultTokenId(token_cat, &default_token_id);
ok(hr == S_OK, "got %#lx.\n", hr);
ok(!wcscmp(token_id, default_token_id), "token_id != default_token_id\n");
CoTaskMemFree(token_id);
CoTaskMemFree(default_token_id);
ISpObjectToken_Release(token);
ISpObjectTokenCategory_Release(token_cat);
}
ISpVoice_Release(voice);
ISpMMSysAudio_Release(audio_out);
}
......
......@@ -42,6 +42,7 @@ struct speech_voice
LONG ref;
ISpStreamFormat *output;
ISpTTSEngine *engine;
CRITICAL_SECTION cs;
};
......@@ -60,6 +61,41 @@ static inline struct speech_voice *impl_from_IConnectionPointContainer(IConnecti
return CONTAINING_RECORD(iface, struct speech_voice, IConnectionPointContainer_iface);
}
static HRESULT create_default_token(const WCHAR *cat_id, ISpObjectToken **token)
{
ISpObjectTokenCategory *cat;
WCHAR *default_token_id = NULL;
HRESULT hr;
TRACE("(%s, %p).\n", debugstr_w(cat_id), token);
if (FAILED(hr = CoCreateInstance(&CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
&IID_ISpObjectTokenCategory, (void **)&cat)))
return hr;
if (FAILED(hr = ISpObjectTokenCategory_SetId(cat, cat_id, FALSE)) ||
FAILED(hr = ISpObjectTokenCategory_GetDefaultTokenId(cat, &default_token_id)))
{
ISpObjectTokenCategory_Release(cat);
return hr;
}
ISpObjectTokenCategory_Release(cat);
if (FAILED(hr = CoCreateInstance(&CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
&IID_ISpObjectToken, (void **)token)))
goto done;
if (FAILED(hr = ISpObjectToken_SetId(*token, NULL, default_token_id, FALSE)))
{
ISpObjectToken_Release(*token);
*token = NULL;
}
done:
CoTaskMemFree(default_token_id);
return hr;
}
/* ISpeechVoice interface */
static HRESULT WINAPI speech_voice_QueryInterface(ISpeechVoice *iface, REFIID iid, void **obj)
{
......@@ -106,6 +142,7 @@ static ULONG WINAPI speech_voice_Release(ISpeechVoice *iface)
if (!ref)
{
if (This->output) ISpStreamFormat_Release(This->output);
if (This->engine) ISpTTSEngine_Release(This->engine);
DeleteCriticalSection(&This->cs);
heap_free(This);
......@@ -598,16 +635,63 @@ static HRESULT WINAPI spvoice_Resume(ISpVoice *iface)
static HRESULT WINAPI spvoice_SetVoice(ISpVoice *iface, ISpObjectToken *token)
{
FIXME("(%p, %p): stub.\n", iface, token);
struct speech_voice *This = impl_from_ISpVoice(iface);
ISpTTSEngine *engine;
HRESULT hr;
return E_NOTIMPL;
TRACE("(%p, %p).\n", iface, token);
if (!token)
{
if (FAILED(hr = create_default_token(SPCAT_VOICES, &token)))
return hr;
}
hr = ISpObjectToken_CreateInstance(token, NULL, CLSCTX_ALL, &IID_ISpTTSEngine, (void **)&engine);
ISpObjectToken_Release(token);
if (FAILED(hr))
return hr;
EnterCriticalSection(&This->cs);
if (This->engine)
ISpTTSEngine_Release(This->engine);
This->engine = engine;
LeaveCriticalSection(&This->cs);
return S_OK;
}
static HRESULT WINAPI spvoice_GetVoice(ISpVoice *iface, ISpObjectToken **token)
{
FIXME("(%p, %p): stub.\n", iface, token);
struct speech_voice *This = impl_from_ISpVoice(iface);
ISpObjectWithToken *engine_token_iface;
HRESULT hr;
TRACE("(%p, %p).\n", iface, token);
return token_create(NULL, &IID_ISpObjectToken, (void **)token);
if (!token)
return E_POINTER;
EnterCriticalSection(&This->cs);
if (!This->engine)
{
LeaveCriticalSection(&This->cs);
return create_default_token(SPCAT_VOICES, token);
}
if (SUCCEEDED(hr = ISpTTSEngine_QueryInterface(This->engine, &IID_ISpObjectWithToken, (void **)&engine_token_iface)))
{
hr = ISpObjectWithToken_GetObjectToken(engine_token_iface, token);
ISpObjectWithToken_Release(engine_token_iface);
}
LeaveCriticalSection(&This->cs);
return hr;
}
static HRESULT WINAPI spvoice_Speak(ISpVoice *iface, const WCHAR *contents, DWORD flags, ULONG *number)
......@@ -845,6 +929,7 @@ HRESULT speech_voice_create(IUnknown *outer, REFIID iid, void **obj)
This->ref = 1;
This->output = NULL;
This->engine = NULL;
InitializeCriticalSection(&This->cs);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment