2 * Speech API (SAPI) text-to-speech implementation.
4 * Copyright 2019 Jactry Zeng for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/debug.h"
33 #include "sapi_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(sapi
);
39 ISpeechVoice ISpeechVoice_iface
;
40 ISpVoice ISpVoice_iface
;
41 IConnectionPointContainer IConnectionPointContainer_iface
;
44 ISpStreamFormat
*output
;
51 static inline struct speech_voice
*impl_from_ISpeechVoice(ISpeechVoice
*iface
)
53 return CONTAINING_RECORD(iface
, struct speech_voice
, ISpeechVoice_iface
);
56 static inline struct speech_voice
*impl_from_ISpVoice(ISpVoice
*iface
)
58 return CONTAINING_RECORD(iface
, struct speech_voice
, ISpVoice_iface
);
61 static inline struct speech_voice
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
63 return CONTAINING_RECORD(iface
, struct speech_voice
, IConnectionPointContainer_iface
);
66 static HRESULT
create_default_token(const WCHAR
*cat_id
, ISpObjectToken
**token
)
68 ISpObjectTokenCategory
*cat
;
69 WCHAR
*default_token_id
= NULL
;
72 TRACE("(%s, %p).\n", debugstr_w(cat_id
), token
);
74 if (FAILED(hr
= CoCreateInstance(&CLSID_SpObjectTokenCategory
, NULL
, CLSCTX_INPROC_SERVER
,
75 &IID_ISpObjectTokenCategory
, (void **)&cat
)))
78 if (FAILED(hr
= ISpObjectTokenCategory_SetId(cat
, cat_id
, FALSE
)) ||
79 FAILED(hr
= ISpObjectTokenCategory_GetDefaultTokenId(cat
, &default_token_id
)))
81 ISpObjectTokenCategory_Release(cat
);
84 ISpObjectTokenCategory_Release(cat
);
86 if (FAILED(hr
= CoCreateInstance(&CLSID_SpObjectToken
, NULL
, CLSCTX_INPROC_SERVER
,
87 &IID_ISpObjectToken
, (void **)token
)))
90 if (FAILED(hr
= ISpObjectToken_SetId(*token
, NULL
, default_token_id
, FALSE
)))
92 ISpObjectToken_Release(*token
);
97 CoTaskMemFree(default_token_id
);
101 /* ISpeechVoice interface */
102 static HRESULT WINAPI
speech_voice_QueryInterface(ISpeechVoice
*iface
, REFIID iid
, void **obj
)
104 struct speech_voice
*This
= impl_from_ISpeechVoice(iface
);
106 TRACE("(%p, %s %p).\n", iface
, debugstr_guid(iid
), obj
);
108 if (IsEqualIID(iid
, &IID_IUnknown
) ||
109 IsEqualIID(iid
, &IID_IDispatch
) ||
110 IsEqualIID(iid
, &IID_ISpeechVoice
))
111 *obj
= &This
->ISpeechVoice_iface
;
112 else if (IsEqualIID(iid
, &IID_ISpVoice
))
113 *obj
= &This
->ISpVoice_iface
;
114 else if (IsEqualIID(iid
, &IID_IConnectionPointContainer
))
115 *obj
= &This
->IConnectionPointContainer_iface
;
119 FIXME("interface %s not implemented.\n", debugstr_guid(iid
));
120 return E_NOINTERFACE
;
123 IUnknown_AddRef((IUnknown
*)*obj
);
127 static ULONG WINAPI
speech_voice_AddRef(ISpeechVoice
*iface
)
129 struct speech_voice
*This
= impl_from_ISpeechVoice(iface
);
130 ULONG ref
= InterlockedIncrement(&This
->ref
);
132 TRACE("(%p): ref=%lu.\n", iface
, ref
);
137 static ULONG WINAPI
speech_voice_Release(ISpeechVoice
*iface
)
139 struct speech_voice
*This
= impl_from_ISpeechVoice(iface
);
140 ULONG ref
= InterlockedDecrement(&This
->ref
);
142 TRACE("(%p): ref=%lu.\n", iface
, ref
);
146 if (This
->output
) ISpStreamFormat_Release(This
->output
);
147 if (This
->engine
) ISpTTSEngine_Release(This
->engine
);
148 DeleteCriticalSection(&This
->cs
);
156 static HRESULT WINAPI
speech_voice_GetTypeInfoCount(ISpeechVoice
*iface
, UINT
*info
)
158 FIXME("(%p, %p): stub.\n", iface
, info
);
163 static HRESULT WINAPI
speech_voice_GetTypeInfo(ISpeechVoice
*iface
, UINT info
, LCID lcid
,
164 ITypeInfo
**type_info
)
166 FIXME("(%p, %u, %lu, %p): stub.\n", iface
, info
, lcid
, type_info
);
171 static HRESULT WINAPI
speech_voice_GetIDsOfNames(ISpeechVoice
*iface
, REFIID riid
, LPOLESTR
*names
,
172 UINT count
, LCID lcid
, DISPID
*dispid
)
174 FIXME("(%p, %s, %p, %u, %lu, %p): stub.\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
179 static HRESULT WINAPI
speech_voice_Invoke(ISpeechVoice
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
,
180 WORD flags
, DISPPARAMS
*params
, VARIANT
*result
,
181 EXCEPINFO
*excepinfo
, UINT
*argerr
)
183 FIXME("(%p, %ld, %s, %#lx, %#x, %p, %p, %p, %p): stub.\n", iface
, dispid
, debugstr_guid(riid
),
184 lcid
, flags
, params
, result
, excepinfo
, argerr
);
189 static HRESULT WINAPI
speech_voice_get_Status(ISpeechVoice
*iface
, ISpeechVoiceStatus
**status
)
191 FIXME("(%p, %p): stub.\n", iface
, status
);
196 static HRESULT WINAPI
speech_voice_get_Voice(ISpeechVoice
*iface
, ISpeechObjectToken
**voice
)
198 FIXME("(%p, %p): stub.\n", iface
, voice
);
203 static HRESULT WINAPI
speech_voice_putref_Voice(ISpeechVoice
*iface
, ISpeechObjectToken
*voice
)
205 FIXME("(%p, %p): stub.\n", iface
, voice
);
210 static HRESULT WINAPI
speech_voice_get_AudioOutput(ISpeechVoice
*iface
, ISpeechObjectToken
**output
)
212 FIXME("(%p, %p): stub.\n", iface
, output
);
217 static HRESULT WINAPI
speech_voice_putref_AudioOutput(ISpeechVoice
*iface
, ISpeechObjectToken
*output
)
219 FIXME("(%p, %p): stub.\n", iface
, output
);
224 static HRESULT WINAPI
speech_voice_get_AudioOutputStream(ISpeechVoice
*iface
, ISpeechBaseStream
**output
)
226 FIXME("(%p, %p): stub.\n", iface
, output
);
231 static HRESULT WINAPI
speech_voice_putref_AudioOutputStream(ISpeechVoice
*iface
, ISpeechBaseStream
*output
)
233 FIXME("(%p, %p): stub.\n", iface
, output
);
238 static HRESULT WINAPI
speech_voice_get_Rate(ISpeechVoice
*iface
, LONG
*rate
)
240 FIXME("(%p, %p): stub.\n", iface
, rate
);
245 static HRESULT WINAPI
speech_voice_put_Rate(ISpeechVoice
*iface
, LONG rate
)
247 FIXME("(%p, %ld): stub.\n", iface
, rate
);
252 static HRESULT WINAPI
speech_voice_get_Volume(ISpeechVoice
*iface
, LONG
*volume
)
254 FIXME("(%p, %p): stub.\n", iface
, volume
);
259 static HRESULT WINAPI
speech_voice_put_Volume(ISpeechVoice
*iface
, LONG volume
)
261 FIXME("(%p, %ld): stub.\n", iface
, volume
);
266 static HRESULT WINAPI
speech_voice_put_AllowAudioOutputFormatChangesOnNextSet(ISpeechVoice
*iface
,
269 FIXME("(%p, %d): stub.\n", iface
, allow
);
274 static HRESULT WINAPI
speech_voice_get_AllowAudioOutputFormatChangesOnNextSet(ISpeechVoice
*iface
, VARIANT_BOOL
*allow
)
276 FIXME("(%p, %p): stub.\n", iface
, allow
);
281 static HRESULT WINAPI
speech_voice_get_EventInterests(ISpeechVoice
*iface
, SpeechVoiceEvents
*flags
)
283 FIXME("(%p, %p): stub.\n", iface
, flags
);
288 static HRESULT WINAPI
speech_voice_put_EventInterests(ISpeechVoice
*iface
, SpeechVoiceEvents flags
)
290 FIXME("(%p, %#x): stub.\n", iface
, flags
);
295 static HRESULT WINAPI
speech_voice_put_Priority(ISpeechVoice
*iface
, SpeechVoicePriority priority
)
297 FIXME("(%p, %d): stub.\n", iface
, priority
);
302 static HRESULT WINAPI
speech_voice_get_Priority(ISpeechVoice
*iface
, SpeechVoicePriority
*priority
)
304 FIXME("(%p, %p): stub.\n", iface
, priority
);
309 static HRESULT WINAPI
speech_voice_put_AlertBoundary(ISpeechVoice
*iface
, SpeechVoiceEvents boundary
)
311 FIXME("(%p, %#x): stub.\n", iface
, boundary
);
316 static HRESULT WINAPI
speech_voice_get_AlertBoundary(ISpeechVoice
*iface
, SpeechVoiceEvents
*boundary
)
318 FIXME("(%p, %p): stub.\n", iface
, boundary
);
323 static HRESULT WINAPI
speech_voice_put_SynchronousSpeakTimeout(ISpeechVoice
*iface
, LONG timeout
)
325 FIXME("(%p, %ld): stub.\n", iface
, timeout
);
330 static HRESULT WINAPI
speech_voice_get_SynchronousSpeakTimeout(ISpeechVoice
*iface
, LONG
*timeout
)
332 FIXME("(%p, %p): stub.\n", iface
, timeout
);
337 static HRESULT WINAPI
speech_voice_Speak(ISpeechVoice
*iface
, BSTR text
, SpeechVoiceSpeakFlags flags
, LONG
*number
)
339 FIXME("(%p, %s, %#x, %p): stub.\n", iface
, debugstr_w(text
), flags
, number
);
344 static HRESULT WINAPI
speech_voice_SpeakStream(ISpeechVoice
*iface
, ISpeechBaseStream
*stream
,
345 SpeechVoiceSpeakFlags flags
, LONG
*number
)
347 FIXME("(%p, %p, %#x, %p): stub.\n", iface
, stream
, flags
, number
);
352 static HRESULT WINAPI
speech_voice_Pause(ISpeechVoice
*iface
)
354 FIXME("(%p): stub.\n", iface
);
359 static HRESULT WINAPI
speech_voice_Resume(ISpeechVoice
*iface
)
361 FIXME("(%p): stub.\n", iface
);
366 static HRESULT WINAPI
speech_voice_Skip(ISpeechVoice
*iface
, const BSTR type
, LONG items
, LONG
*skipped
)
368 FIXME("(%p, %s, %ld, %p): stub.\n", iface
, debugstr_w(type
), items
, skipped
);
373 static HRESULT WINAPI
speech_voice_GetVoices(ISpeechVoice
*iface
, BSTR required
, BSTR optional
,
374 ISpeechObjectTokens
**tokens
)
376 FIXME("(%p, %s, %s, %p): stub.\n", iface
, debugstr_w(required
), debugstr_w(optional
), tokens
);
381 static HRESULT WINAPI
speech_voice_GetAudioOutputs(ISpeechVoice
*iface
, BSTR required
, BSTR optional
,
382 ISpeechObjectTokens
**tokens
)
384 FIXME("(%p, %s, %s, %p): stub.\n", iface
, debugstr_w(required
), debugstr_w(optional
), tokens
);
389 static HRESULT WINAPI
speech_voice_WaitUntilDone(ISpeechVoice
*iface
, LONG timeout
, VARIANT_BOOL
*done
)
391 FIXME("(%p, %ld, %p): stub.\n", iface
, timeout
, done
);
396 static HRESULT WINAPI
speech_voice_SpeakCompleteEvent(ISpeechVoice
*iface
, LONG
*handle
)
398 FIXME("(%p, %p): stub.\n", iface
, handle
);
403 static HRESULT WINAPI
speech_voice_IsUISupported(ISpeechVoice
*iface
, const BSTR typeui
, const VARIANT
*data
,
404 VARIANT_BOOL
*supported
)
406 FIXME("(%p, %s, %p, %p): stub.\n", iface
, debugstr_w(typeui
), data
, supported
);
411 static HRESULT WINAPI
speech_voice_DisplayUI(ISpeechVoice
*iface
, LONG hwnd
, BSTR title
,
412 const BSTR typeui
, const VARIANT
*data
)
414 FIXME("(%p, %ld, %s, %s, %p): stub.\n", iface
, hwnd
, debugstr_w(title
), debugstr_w(typeui
), data
);
419 static const ISpeechVoiceVtbl speech_voice_vtbl
=
421 speech_voice_QueryInterface
,
423 speech_voice_Release
,
424 speech_voice_GetTypeInfoCount
,
425 speech_voice_GetTypeInfo
,
426 speech_voice_GetIDsOfNames
,
428 speech_voice_get_Status
,
429 speech_voice_get_Voice
,
430 speech_voice_putref_Voice
,
431 speech_voice_get_AudioOutput
,
432 speech_voice_putref_AudioOutput
,
433 speech_voice_get_AudioOutputStream
,
434 speech_voice_putref_AudioOutputStream
,
435 speech_voice_get_Rate
,
436 speech_voice_put_Rate
,
437 speech_voice_get_Volume
,
438 speech_voice_put_Volume
,
439 speech_voice_put_AllowAudioOutputFormatChangesOnNextSet
,
440 speech_voice_get_AllowAudioOutputFormatChangesOnNextSet
,
441 speech_voice_get_EventInterests
,
442 speech_voice_put_EventInterests
,
443 speech_voice_put_Priority
,
444 speech_voice_get_Priority
,
445 speech_voice_put_AlertBoundary
,
446 speech_voice_get_AlertBoundary
,
447 speech_voice_put_SynchronousSpeakTimeout
,
448 speech_voice_get_SynchronousSpeakTimeout
,
450 speech_voice_SpeakStream
,
454 speech_voice_GetVoices
,
455 speech_voice_GetAudioOutputs
,
456 speech_voice_WaitUntilDone
,
457 speech_voice_SpeakCompleteEvent
,
458 speech_voice_IsUISupported
,
459 speech_voice_DisplayUI
,
462 /* ISpVoice interface */
463 static HRESULT WINAPI
spvoice_QueryInterface(ISpVoice
*iface
, REFIID iid
, void **obj
)
465 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
467 TRACE("(%p, %s %p).\n", iface
, debugstr_guid(iid
), obj
);
469 return ISpeechVoice_QueryInterface(&This
->ISpeechVoice_iface
, iid
, obj
);
472 static ULONG WINAPI
spvoice_AddRef(ISpVoice
*iface
)
474 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
476 TRACE("(%p).\n", iface
);
478 return ISpeechVoice_AddRef(&This
->ISpeechVoice_iface
);
481 static ULONG WINAPI
spvoice_Release(ISpVoice
*iface
)
483 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
485 TRACE("(%p).\n", iface
);
487 return ISpeechVoice_Release(&This
->ISpeechVoice_iface
);
490 static HRESULT WINAPI
spvoice_SetNotifySink(ISpVoice
*iface
, ISpNotifySink
*sink
)
492 FIXME("(%p, %p): stub.\n", iface
, sink
);
497 static HRESULT WINAPI
spvoice_SetNotifyWindowMessage(ISpVoice
*iface
, HWND hwnd
, UINT msg
,
498 WPARAM wparam
, LPARAM lparam
)
500 FIXME("(%p, %p, %u, %Ix, %Ix): stub.\n", iface
, hwnd
, msg
, wparam
, lparam
);
505 static HRESULT WINAPI
spvoice_SetNotifyCallbackFunction(ISpVoice
*iface
, SPNOTIFYCALLBACK
*callback
,
506 WPARAM wparam
, LPARAM lparam
)
508 FIXME("(%p, %p, %Ix, %Ix): stub.\n", iface
, callback
, wparam
, lparam
);
513 static HRESULT WINAPI
spvoice_SetNotifyCallbackInterface(ISpVoice
*iface
, ISpNotifyCallback
*callback
,
514 WPARAM wparam
, LPARAM lparam
)
516 FIXME("(%p, %p, %Ix, %Ix): stub.\n", iface
, callback
, wparam
, lparam
);
521 static HRESULT WINAPI
spvoice_SetNotifyWin32Event(ISpVoice
*iface
)
523 FIXME("(%p): stub.\n", iface
);
528 static HRESULT WINAPI
spvoice_WaitForNotifyEvent(ISpVoice
*iface
, DWORD milliseconds
)
530 FIXME("(%p, %ld): stub.\n", iface
, milliseconds
);
535 static HANDLE WINAPI
spvoice_GetNotifyEventHandle(ISpVoice
*iface
)
537 FIXME("(%p): stub.\n", iface
);
542 static HRESULT WINAPI
spvoice_SetInterest(ISpVoice
*iface
, ULONGLONG event
, ULONGLONG queued
)
544 FIXME("(%p, %s, %s): stub.\n", iface
, wine_dbgstr_longlong(event
), wine_dbgstr_longlong(queued
));
549 static HRESULT WINAPI
spvoice_GetEvents(ISpVoice
*iface
, ULONG count
, SPEVENT
*array
, ULONG
*fetched
)
551 FIXME("(%p, %lu, %p, %p): stub.\n", iface
, count
, array
, fetched
);
556 static HRESULT WINAPI
spvoice_GetInfo(ISpVoice
*iface
, SPEVENTSOURCEINFO
*info
)
558 FIXME("(%p, %p): stub.\n", iface
, info
);
563 static HRESULT WINAPI
spvoice_SetOutput(ISpVoice
*iface
, IUnknown
*unk
, BOOL allow_format_changes
)
565 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
566 ISpStreamFormat
*stream
= NULL
;
567 ISpObjectToken
*token
= NULL
;
570 TRACE("(%p, %p, %d).\n", iface
, unk
, allow_format_changes
);
572 if (!allow_format_changes
)
573 FIXME("ignoring allow_format_changes = FALSE.\n");
577 /* TODO: Create the default SpAudioOut token here once SpMMAudioEnum is implemented. */
578 if (FAILED(hr
= CoCreateInstance(&CLSID_SpMMAudioOut
, NULL
, CLSCTX_INPROC_SERVER
,
579 &IID_ISpStreamFormat
, (void **)&stream
)))
584 if (FAILED(IUnknown_QueryInterface(unk
, &IID_ISpStreamFormat
, (void **)&stream
)))
586 if (FAILED(IUnknown_QueryInterface(unk
, &IID_ISpObjectToken
, (void **)&token
)))
593 hr
= ISpObjectToken_CreateInstance(token
, NULL
, CLSCTX_ALL
, &IID_ISpStreamFormat
, (void **)&stream
);
594 ISpObjectToken_Release(token
);
599 EnterCriticalSection(&This
->cs
);
602 ISpStreamFormat_Release(This
->output
);
603 This
->output
= stream
;
605 LeaveCriticalSection(&This
->cs
);
610 static HRESULT WINAPI
spvoice_GetOutputObjectToken(ISpVoice
*iface
, ISpObjectToken
**token
)
612 FIXME("(%p, %p): stub.\n", iface
, token
);
617 static HRESULT WINAPI
spvoice_GetOutputStream(ISpVoice
*iface
, ISpStreamFormat
**stream
)
619 FIXME("(%p, %p): stub.\n", iface
, stream
);
624 static HRESULT WINAPI
spvoice_Pause(ISpVoice
*iface
)
626 FIXME("(%p): stub.\n", iface
);
631 static HRESULT WINAPI
spvoice_Resume(ISpVoice
*iface
)
633 FIXME("(%p): stub.\n", iface
);
638 static HRESULT WINAPI
spvoice_SetVoice(ISpVoice
*iface
, ISpObjectToken
*token
)
640 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
641 ISpTTSEngine
*engine
;
645 TRACE("(%p, %p).\n", iface
, token
);
649 if (FAILED(hr
= create_default_token(SPCAT_VOICES
, &token
)))
653 hr
= ISpObjectToken_CreateInstance(token
, NULL
, CLSCTX_ALL
, &IID_ISpTTSEngine
, (void **)&engine
);
654 ISpObjectToken_Release(token
);
658 EnterCriticalSection(&This
->cs
);
661 ISpTTSEngine_Release(This
->engine
);
662 This
->engine
= engine
;
664 LeaveCriticalSection(&This
->cs
);
669 static HRESULT WINAPI
spvoice_GetVoice(ISpVoice
*iface
, ISpObjectToken
**token
)
671 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
672 ISpObjectWithToken
*engine_token_iface
;
675 TRACE("(%p, %p).\n", iface
, token
);
680 EnterCriticalSection(&This
->cs
);
684 LeaveCriticalSection(&This
->cs
);
685 return create_default_token(SPCAT_VOICES
, token
);
688 if (SUCCEEDED(hr
= ISpTTSEngine_QueryInterface(This
->engine
, &IID_ISpObjectWithToken
, (void **)&engine_token_iface
)))
690 hr
= ISpObjectWithToken_GetObjectToken(engine_token_iface
, token
);
691 ISpObjectWithToken_Release(engine_token_iface
);
694 LeaveCriticalSection(&This
->cs
);
699 static HRESULT WINAPI
spvoice_Speak(ISpVoice
*iface
, const WCHAR
*contents
, DWORD flags
, ULONG
*number
)
701 FIXME("(%p, %p, %#lx, %p): stub.\n", iface
, contents
, flags
, number
);
706 static HRESULT WINAPI
spvoice_SpeakStream(ISpVoice
*iface
, IStream
*stream
, DWORD flags
, ULONG
*number
)
708 FIXME("(%p, %p, %#lx, %p): stub.\n", iface
, stream
, flags
, number
);
713 static HRESULT WINAPI
spvoice_GetStatus(ISpVoice
*iface
, SPVOICESTATUS
*status
, WCHAR
**bookmark
)
715 FIXME("(%p, %p, %p): stub.\n", iface
, status
, bookmark
);
720 static HRESULT WINAPI
spvoice_Skip(ISpVoice
*iface
, const WCHAR
*type
, LONG items
, ULONG
*skipped
)
722 FIXME("(%p, %s, %ld, %p): stub.\n", iface
, debugstr_w(type
), items
, skipped
);
727 static HRESULT WINAPI
spvoice_SetPriority(ISpVoice
*iface
, SPVPRIORITY priority
)
729 FIXME("(%p, %d): stub.\n", iface
, priority
);
734 static HRESULT WINAPI
spvoice_GetPriority(ISpVoice
*iface
, SPVPRIORITY
*priority
)
736 FIXME("(%p, %p): stub.\n", iface
, priority
);
741 static HRESULT WINAPI
spvoice_SetAlertBoundary(ISpVoice
*iface
, SPEVENTENUM boundary
)
743 FIXME("(%p, %d): stub.\n", iface
, boundary
);
748 static HRESULT WINAPI
spvoice_GetAlertBoundary(ISpVoice
*iface
, SPEVENTENUM
*boundary
)
750 FIXME("(%p, %p): stub.\n", iface
, boundary
);
755 static HRESULT WINAPI
spvoice_SetRate(ISpVoice
*iface
, LONG rate
)
757 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
759 TRACE("(%p, %ld).\n", iface
, rate
);
761 EnterCriticalSection(&This
->cs
);
763 LeaveCriticalSection(&This
->cs
);
768 static HRESULT WINAPI
spvoice_GetRate(ISpVoice
*iface
, LONG
*rate
)
770 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
772 TRACE("(%p, %p).\n", iface
, rate
);
774 EnterCriticalSection(&This
->cs
);
776 LeaveCriticalSection(&This
->cs
);
781 static HRESULT WINAPI
spvoice_SetVolume(ISpVoice
*iface
, USHORT volume
)
783 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
785 TRACE("(%p, %d).\n", iface
, volume
);
790 EnterCriticalSection(&This
->cs
);
791 This
->volume
= volume
;
792 LeaveCriticalSection(&This
->cs
);
797 static HRESULT WINAPI
spvoice_GetVolume(ISpVoice
*iface
, USHORT
*volume
)
799 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
801 TRACE("(%p, %p).\n", iface
, volume
);
803 EnterCriticalSection(&This
->cs
);
804 *volume
= This
->volume
;
805 LeaveCriticalSection(&This
->cs
);
810 static HRESULT WINAPI
spvoice_WaitUntilDone(ISpVoice
*iface
, ULONG timeout
)
812 FIXME("(%p, %ld): stub.\n", iface
, timeout
);
817 static HRESULT WINAPI
spvoice_SetSyncSpeakTimeout(ISpVoice
*iface
, ULONG timeout
)
819 FIXME("(%p, %ld): stub.\n", iface
, timeout
);
824 static HRESULT WINAPI
spvoice_GetSyncSpeakTimeout(ISpVoice
*iface
, ULONG
*timeout
)
826 FIXME("(%p, %p): stub.\n", iface
, timeout
);
831 static HANDLE WINAPI
spvoice_SpeakCompleteEvent(ISpVoice
*iface
)
833 FIXME("(%p): stub.\n", iface
);
838 static HRESULT WINAPI
spvoice_IsUISupported(ISpVoice
*iface
, const WCHAR
*type
, void *extra
,
839 ULONG count
, BOOL
*supported
)
841 FIXME("(%p, %p, %p, %ld, %p): stub.\n", iface
, type
, extra
, count
, supported
);
846 static HRESULT WINAPI
spvoice_DisplayUI(ISpVoice
*iface
, HWND parent
, const WCHAR
*title
,
847 const WCHAR
*type
, void *extra
, ULONG count
)
849 FIXME("(%p, %p, %p, %p, %p, %ld): stub.\n", iface
, parent
, title
, type
, extra
, count
);
854 static const ISpVoiceVtbl spvoice_vtbl
=
856 spvoice_QueryInterface
,
859 spvoice_SetNotifySink
,
860 spvoice_SetNotifyWindowMessage
,
861 spvoice_SetNotifyCallbackFunction
,
862 spvoice_SetNotifyCallbackInterface
,
863 spvoice_SetNotifyWin32Event
,
864 spvoice_WaitForNotifyEvent
,
865 spvoice_GetNotifyEventHandle
,
870 spvoice_GetOutputObjectToken
,
871 spvoice_GetOutputStream
,
882 spvoice_SetAlertBoundary
,
883 spvoice_GetAlertBoundary
,
888 spvoice_WaitUntilDone
,
889 spvoice_SetSyncSpeakTimeout
,
890 spvoice_GetSyncSpeakTimeout
,
891 spvoice_SpeakCompleteEvent
,
892 spvoice_IsUISupported
,
896 /* IConnectionPointContainer interface */
897 static HRESULT WINAPI
container_QueryInterface(IConnectionPointContainer
*iface
, REFIID iid
, void **obj
)
899 struct speech_voice
*This
= impl_from_IConnectionPointContainer(iface
);
901 TRACE("(%p, %s %p).\n", iface
, debugstr_guid(iid
), obj
);
903 return ISpeechVoice_QueryInterface(&This
->ISpeechVoice_iface
, iid
, obj
);
906 static ULONG WINAPI
container_AddRef(IConnectionPointContainer
*iface
)
908 struct speech_voice
*This
= impl_from_IConnectionPointContainer(iface
);
910 TRACE("(%p).\n", iface
);
912 return ISpeechVoice_AddRef(&This
->ISpeechVoice_iface
);
915 static ULONG WINAPI
container_Release(IConnectionPointContainer
*iface
)
917 struct speech_voice
*This
= impl_from_IConnectionPointContainer(iface
);
919 TRACE("(%p).\n", iface
);
921 return ISpeechVoice_Release(&This
->ISpeechVoice_iface
);
924 static HRESULT WINAPI
container_EnumConnectionPoints(IConnectionPointContainer
*iface
,
925 IEnumConnectionPoints
**enum_cp
)
927 FIXME("(%p, %p): stub.\n", iface
, enum_cp
);
932 static HRESULT WINAPI
container_FindConnectionPoint(IConnectionPointContainer
*iface
, REFIID riid
,
933 IConnectionPoint
**cp
)
935 FIXME("(%p, %s, %p): stub.\n", iface
, debugstr_guid(riid
), cp
);
940 const static IConnectionPointContainerVtbl container_vtbl
=
942 container_QueryInterface
,
945 container_EnumConnectionPoints
,
946 container_FindConnectionPoint
949 HRESULT
speech_voice_create(IUnknown
*outer
, REFIID iid
, void **obj
)
951 struct speech_voice
*This
= heap_alloc(sizeof(*This
));
954 if (!This
) return E_OUTOFMEMORY
;
955 This
->ISpeechVoice_iface
.lpVtbl
= &speech_voice_vtbl
;
956 This
->ISpVoice_iface
.lpVtbl
= &spvoice_vtbl
;
957 This
->IConnectionPointContainer_iface
.lpVtbl
= &container_vtbl
;
965 InitializeCriticalSection(&This
->cs
);
967 hr
= ISpeechVoice_QueryInterface(&This
->ISpeechVoice_iface
, iid
, obj
);
969 ISpeechVoice_Release(&This
->ISpeechVoice_iface
);