2 * IDirectMusicSynthSink Implementation
4 * Copyright (C) 2003-2004 Rok Mandeljc
5 * Copyright (C) 2012 Christian Costa
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
24 #include "dmsynth_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dmsynth
);
30 static inline IDirectMusicSynthSinkImpl
*impl_from_IDirectMusicSynthSink(IDirectMusicSynthSink
*iface
)
32 return CONTAINING_RECORD(iface
, IDirectMusicSynthSinkImpl
, IDirectMusicSynthSink_iface
);
35 /* IDirectMusicSynthSinkImpl IUnknown part: */
36 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_QueryInterface(IDirectMusicSynthSink
*iface
,
37 REFIID riid
, void **ret_iface
)
39 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
41 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
43 if (IsEqualIID (riid
, &IID_IUnknown
) ||
44 IsEqualIID (riid
, &IID_IDirectMusicSynthSink
))
46 IUnknown_AddRef(iface
);
50 else if (IsEqualIID(riid
, &IID_IKsControl
))
52 IUnknown_AddRef(iface
);
53 *ret_iface
= &This
->IKsControl_iface
;
59 WARN("(%p)->(%s, %p): not found\n", iface
, debugstr_dmguid(riid
), ret_iface
);
64 static ULONG WINAPI
IDirectMusicSynthSinkImpl_AddRef(IDirectMusicSynthSink
*iface
)
66 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
67 ULONG ref
= InterlockedIncrement(&This
->ref
);
69 TRACE("(%p): new ref = %lu\n", This
, ref
);
74 static ULONG WINAPI
IDirectMusicSynthSinkImpl_Release(IDirectMusicSynthSink
*iface
)
76 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
77 ULONG ref
= InterlockedDecrement(&This
->ref
);
79 TRACE("(%p): new ref = %lu\n", This
, ref
);
82 if (This
->latency_clock
)
83 IReferenceClock_Release(This
->latency_clock
);
84 if (This
->master_clock
)
85 IReferenceClock_Release(This
->master_clock
);
86 HeapFree(GetProcessHeap(), 0, This
);
87 DMSYNTH_UnlockModule();
93 /* IDirectMusicSynthSinkImpl IDirectMusicSynthSink part: */
94 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_Init(IDirectMusicSynthSink
*iface
,
95 IDirectMusicSynth
*synth
)
97 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
99 TRACE("(%p)->(%p)\n", This
, synth
);
101 /* Not holding a reference to avoid circular dependencies.
102 The synth will release the sink during the synth's destruction. */
108 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_SetMasterClock(IDirectMusicSynthSink
*iface
,
109 IReferenceClock
*clock
)
111 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
113 TRACE("(%p)->(%p)\n", This
, clock
);
120 IReferenceClock_AddRef(clock
);
121 This
->master_clock
= clock
;
126 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_GetLatencyClock(IDirectMusicSynthSink
*iface
,
127 IReferenceClock
**clock
)
129 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
131 TRACE("(%p)->(%p)\n", iface
, clock
);
136 *clock
= This
->latency_clock
;
137 IReferenceClock_AddRef(This
->latency_clock
);
142 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_Activate(IDirectMusicSynthSink
*iface
,
145 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
147 FIXME("(%p)->(%d): stub\n", This
, enable
);
152 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_SampleToRefTime(IDirectMusicSynthSink
*iface
,
153 LONGLONG sample_time
, REFERENCE_TIME
*ref_time
)
155 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
157 FIXME("(%p)->(0x%s, %p): stub\n", This
, wine_dbgstr_longlong(sample_time
), ref_time
);
162 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_RefTimeToSample(IDirectMusicSynthSink
*iface
,
163 REFERENCE_TIME ref_time
, LONGLONG
*sample_time
)
165 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
167 FIXME("(%p)->(0x%s, %p): stub\n", This
, wine_dbgstr_longlong(ref_time
), sample_time
);
172 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_SetDirectSound(IDirectMusicSynthSink
*iface
,
173 IDirectSound
*dsound
, IDirectSoundBuffer
*dsound_buffer
)
175 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
177 FIXME("(%p)->(%p, %p): stub\n", This
, dsound
, dsound_buffer
);
182 static HRESULT WINAPI
IDirectMusicSynthSinkImpl_GetDesiredBufferSize(IDirectMusicSynthSink
*iface
,
185 IDirectMusicSynthSinkImpl
*This
= impl_from_IDirectMusicSynthSink(iface
);
187 DWORD fmtsize
= sizeof(format
);
189 TRACE("(%p, %p)\n", This
, size
);
194 return DMUS_E_SYNTHNOTCONFIGURED
;
196 if (FAILED(IDirectMusicSynth_GetFormat(This
->synth
, &format
, &fmtsize
)))
198 *size
= format
.nSamplesPerSec
* format
.nChannels
* 4;
203 static const IDirectMusicSynthSinkVtbl DirectMusicSynthSink_Vtbl
= {
204 IDirectMusicSynthSinkImpl_QueryInterface
,
205 IDirectMusicSynthSinkImpl_AddRef
,
206 IDirectMusicSynthSinkImpl_Release
,
207 IDirectMusicSynthSinkImpl_Init
,
208 IDirectMusicSynthSinkImpl_SetMasterClock
,
209 IDirectMusicSynthSinkImpl_GetLatencyClock
,
210 IDirectMusicSynthSinkImpl_Activate
,
211 IDirectMusicSynthSinkImpl_SampleToRefTime
,
212 IDirectMusicSynthSinkImpl_RefTimeToSample
,
213 IDirectMusicSynthSinkImpl_SetDirectSound
,
214 IDirectMusicSynthSinkImpl_GetDesiredBufferSize
217 static inline IDirectMusicSynthSinkImpl
*impl_from_IKsControl(IKsControl
*iface
)
219 return CONTAINING_RECORD(iface
, IDirectMusicSynthSinkImpl
, IKsControl_iface
);
222 static HRESULT WINAPI
DMSynthSinkImpl_IKsControl_QueryInterface(IKsControl
* iface
, REFIID riid
, LPVOID
*ppobj
)
224 IDirectMusicSynthSinkImpl
*This
= impl_from_IKsControl(iface
);
226 return IDirectMusicSynthSinkImpl_QueryInterface(&This
->IDirectMusicSynthSink_iface
, riid
, ppobj
);
229 static ULONG WINAPI
DMSynthSinkImpl_IKsControl_AddRef(IKsControl
* iface
)
231 IDirectMusicSynthSinkImpl
*This
= impl_from_IKsControl(iface
);
233 return IDirectMusicSynthSinkImpl_AddRef(&This
->IDirectMusicSynthSink_iface
);
236 static ULONG WINAPI
DMSynthSinkImpl_IKsControl_Release(IKsControl
* iface
)
238 IDirectMusicSynthSinkImpl
*This
= impl_from_IKsControl(iface
);
240 return IDirectMusicSynthSinkImpl_Release(&This
->IDirectMusicSynthSink_iface
);
243 static HRESULT WINAPI
DMSynthSinkImpl_IKsControl_KsProperty(IKsControl
* iface
, PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
,
244 ULONG DataLength
, ULONG
* BytesReturned
)
246 TRACE("(%p, %p, %lu, %p, %lu, %p)\n", iface
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
248 TRACE("Property = %s - %lu - %lu\n", debugstr_guid(&Property
->u
.s
.Set
), Property
->u
.s
.Id
, Property
->u
.s
.Flags
);
250 if (Property
->u
.s
.Flags
!= KSPROPERTY_TYPE_GET
)
252 FIXME("Property flags %lu not yet supported\n", Property
->u
.s
.Flags
);
256 if (DataLength
< sizeof(DWORD
))
257 return E_NOT_SUFFICIENT_BUFFER
;
259 if (IsEqualGUID(&Property
->u
.s
.Set
, &GUID_DMUS_PROP_SinkUsesDSound
))
261 *(DWORD
*)PropertyData
= TRUE
;
262 *BytesReturned
= sizeof(DWORD
);
266 FIXME("Unknown property %s\n", debugstr_guid(&Property
->u
.s
.Set
));
267 *(DWORD
*)PropertyData
= FALSE
;
268 *BytesReturned
= sizeof(DWORD
);
274 static HRESULT WINAPI
DMSynthSinkImpl_IKsControl_KsMethod(IKsControl
* iface
, PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
,
275 ULONG DataLength
, ULONG
* BytesReturned
)
277 FIXME("(%p, %p, %lu, %p, %lu, %p): stub\n", iface
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
282 static HRESULT WINAPI
DMSynthSinkImpl_IKsControl_KsEvent(IKsControl
* iface
, PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
,
283 ULONG DataLength
, ULONG
* BytesReturned
)
285 FIXME("(%p, %p, %lu, %p, %lu, %p): stub\n", iface
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
291 static const IKsControlVtbl DMSynthSinkImpl_IKsControl_Vtbl
= {
292 DMSynthSinkImpl_IKsControl_QueryInterface
,
293 DMSynthSinkImpl_IKsControl_AddRef
,
294 DMSynthSinkImpl_IKsControl_Release
,
295 DMSynthSinkImpl_IKsControl_KsProperty
,
296 DMSynthSinkImpl_IKsControl_KsMethod
,
297 DMSynthSinkImpl_IKsControl_KsEvent
300 /* for ClassFactory */
301 HRESULT
DMUSIC_CreateDirectMusicSynthSinkImpl(REFIID riid
, void **ret_iface
)
303 IDirectMusicSynthSinkImpl
*obj
;
306 TRACE("(%s, %p)\n", debugstr_guid(riid
), ret_iface
);
310 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicSynthSinkImpl
));
312 return E_OUTOFMEMORY
;
314 obj
->IDirectMusicSynthSink_iface
.lpVtbl
= &DirectMusicSynthSink_Vtbl
;
315 obj
->IKsControl_iface
.lpVtbl
= &DMSynthSinkImpl_IKsControl_Vtbl
;
318 hr
= CoCreateInstance(&CLSID_SystemClock
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IReferenceClock
, (LPVOID
*)&obj
->latency_clock
);
321 HeapFree(GetProcessHeap(), 0, obj
);
325 DMSYNTH_LockModule();
326 hr
= IDirectMusicSynthSink_QueryInterface(&obj
->IDirectMusicSynthSink_iface
, riid
, ret_iface
);
327 IDirectMusicSynthSink_Release(&obj
->IDirectMusicSynthSink_iface
);