dmsynth: Create default clock for SynthSink object and assign it to Synth object...
[wine] / dlls / dmsynth / synthsink.c
1 /*
2  * IDirectMusicSynthSink Implementation
3  *
4  * Copyright (C) 2003-2004 Rok Mandeljc
5  *
6  * This program 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.
10  *
11  * This program 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.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "dmsynth_private.h"
22 #include "initguid.h"
23 #include "uuids.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(dmsynth);
26
27 static inline IDirectMusicSynthSinkImpl *impl_from_IDirectMusicSynthSink(IDirectMusicSynthSink *iface)
28 {
29     return CONTAINING_RECORD(iface, IDirectMusicSynthSinkImpl, IDirectMusicSynthSink_iface);
30 }
31
32 /* IDirectMusicSynthSinkImpl IUnknown part: */
33 static HRESULT WINAPI IDirectMusicSynthSinkImpl_QueryInterface(LPDIRECTMUSICSYNTHSINK iface, REFIID riid, LPVOID *ppobj)
34 {
35         IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
36         TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
37
38         if (IsEqualIID (riid, &IID_IUnknown) || 
39             IsEqualIID (riid, &IID_IDirectMusicSynthSink)) {
40                 IUnknown_AddRef(iface);
41                 *ppobj = This;
42                 return S_OK;
43         }
44         WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
45         return E_NOINTERFACE;
46 }
47
48 static ULONG WINAPI IDirectMusicSynthSinkImpl_AddRef(LPDIRECTMUSICSYNTHSINK iface)
49 {
50         IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
51         ULONG refCount = InterlockedIncrement(&This->ref);
52
53         TRACE("(%p)->(ref before=%u)\n", This, refCount - 1);
54
55         DMSYNTH_LockModule();
56
57         return refCount;
58 }
59
60 static ULONG WINAPI IDirectMusicSynthSinkImpl_Release(LPDIRECTMUSICSYNTHSINK iface)
61 {
62         IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
63         ULONG refCount = InterlockedDecrement(&This->ref);
64
65         TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
66
67         if (!refCount) {
68                 if (This->latency_clock)
69                         IReferenceClock_Release(This->latency_clock);
70                 HeapFree(GetProcessHeap(), 0, This);
71         }
72
73         DMSYNTH_UnlockModule();
74
75         return refCount;
76 }
77
78 /* IDirectMusicSynthSinkImpl IDirectMusicSynthSink part: */
79 static HRESULT WINAPI IDirectMusicSynthSinkImpl_Init(LPDIRECTMUSICSYNTHSINK iface, IDirectMusicSynth* synth)
80 {
81     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
82
83     FIXME("(%p)->(%p): stub\n", This, synth);
84
85     return S_OK;
86 }
87
88 static HRESULT WINAPI IDirectMusicSynthSinkImpl_SetMasterClock(LPDIRECTMUSICSYNTHSINK iface, IReferenceClock* clock)
89 {
90     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
91
92     FIXME("(%p)->(%p): stub\n", This, clock);
93
94     return S_OK;
95 }
96
97 static HRESULT WINAPI IDirectMusicSynthSinkImpl_GetLatencyClock(LPDIRECTMUSICSYNTHSINK iface, IReferenceClock** clock)
98 {
99     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
100
101     TRACE("(%p)->(%p)\n", iface, clock);
102
103     if (!clock)
104         return E_POINTER;
105
106     *clock = This->latency_clock;
107     IReferenceClock_AddRef(This->latency_clock);
108
109     return S_OK;
110 }
111
112 static HRESULT WINAPI IDirectMusicSynthSinkImpl_Activate(LPDIRECTMUSICSYNTHSINK iface, BOOL enable)
113 {
114     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
115
116     FIXME("(%p)->(%d): stub\n", This, enable);
117
118     return S_OK;
119 }
120
121 static HRESULT WINAPI IDirectMusicSynthSinkImpl_SampleToRefTime(LPDIRECTMUSICSYNTHSINK iface, LONGLONG sample_time, REFERENCE_TIME* ref_time)
122 {
123     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
124
125     FIXME("(%p)->(0x%s, %p): stub\n", This, wine_dbgstr_longlong(sample_time), ref_time);
126
127     return S_OK;
128 }
129
130 static HRESULT WINAPI IDirectMusicSynthSinkImpl_RefTimeToSample(LPDIRECTMUSICSYNTHSINK iface, REFERENCE_TIME ref_time, LONGLONG* sample_time)
131 {
132     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
133
134     FIXME("(%p)->(0x%s, %p): stub\n", This, wine_dbgstr_longlong(ref_time), sample_time);
135
136     return S_OK;
137 }
138
139 static HRESULT WINAPI IDirectMusicSynthSinkImpl_SetDirectSound(LPDIRECTMUSICSYNTHSINK iface, LPDIRECTSOUND dsound, LPDIRECTSOUNDBUFFER dsound_buffer)
140 {
141     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
142
143     FIXME("(%p)->(%p, %p): stub\n", This, dsound, dsound_buffer);
144
145     return S_OK;
146 }
147
148 static HRESULT WINAPI IDirectMusicSynthSinkImpl_GetDesiredBufferSize(LPDIRECTMUSICSYNTHSINK iface, LPDWORD buffer_size_in_samples)
149 {
150     IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
151
152     FIXME("(%p)->(%p): stub\n", This, buffer_size_in_samples);
153
154     return S_OK;
155 }
156
157 static const IDirectMusicSynthSinkVtbl DirectMusicSynthSink_Vtbl = {
158         IDirectMusicSynthSinkImpl_QueryInterface,
159         IDirectMusicSynthSinkImpl_AddRef,
160         IDirectMusicSynthSinkImpl_Release,
161         IDirectMusicSynthSinkImpl_Init,
162         IDirectMusicSynthSinkImpl_SetMasterClock,
163         IDirectMusicSynthSinkImpl_GetLatencyClock,
164         IDirectMusicSynthSinkImpl_Activate,
165         IDirectMusicSynthSinkImpl_SampleToRefTime,
166         IDirectMusicSynthSinkImpl_RefTimeToSample,
167         IDirectMusicSynthSinkImpl_SetDirectSound,
168         IDirectMusicSynthSinkImpl_GetDesiredBufferSize
169 };
170
171 /* for ClassFactory */
172 HRESULT WINAPI DMUSIC_CreateDirectMusicSynthSinkImpl(LPCGUID riid, LPVOID* ret_iface, LPUNKNOWN unkouter)
173 {
174     IDirectMusicSynthSinkImpl *obj;
175     HRESULT hr;
176
177     TRACE("(%p,%p,%p)\n", riid, ret_iface, unkouter);
178
179     *ret_iface = NULL;
180
181     obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSynthSinkImpl));
182     if (!obj)
183         return E_OUTOFMEMORY;
184
185     obj->IDirectMusicSynthSink_iface.lpVtbl = &DirectMusicSynthSink_Vtbl;
186     obj->ref = 0;
187
188     hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (LPVOID*)&obj->latency_clock);
189     if (FAILED(hr))
190     {
191         HeapFree(GetProcessHeap(), 0, obj);
192         return hr;
193     }
194
195     hr = IDirectMusicSynthSinkImpl_QueryInterface((LPDIRECTMUSICSYNTHSINK)obj, riid, ret_iface);
196     if (FAILED(hr))
197     {
198         IReferenceClock_Release(obj->latency_clock);
199         HeapFree(GetProcessHeap(), 0, obj);
200         return hr;
201     }
202
203     return S_OK;
204 }