comctl32/tests: Use CRT allocation functions.
[wine.git] / dlls / dmime / audiopath.c
blob65691f4705f780a017071543de1b7511c3a7fd00
1 /* IDirectMusicAudioPath Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "dmime_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(dmime);
24 struct IDirectMusicAudioPathImpl {
25 IDirectMusicAudioPath IDirectMusicAudioPath_iface;
26 struct dmobject dmobj;
27 LONG ref;
28 IDirectMusicPerformance8* pPerf;
29 IDirectMusicGraph* pToolGraph;
30 IDirectSoundBuffer* pDSBuffer;
31 IDirectSoundBuffer* pPrimary;
33 BOOL fActive;
36 static inline struct IDirectMusicAudioPathImpl *impl_from_IDirectMusicAudioPath(IDirectMusicAudioPath *iface)
38 return CONTAINING_RECORD(iface, struct IDirectMusicAudioPathImpl, IDirectMusicAudioPath_iface);
41 static inline struct IDirectMusicAudioPathImpl *impl_from_IPersistStream(IPersistStream *iface)
43 return CONTAINING_RECORD(iface, struct IDirectMusicAudioPathImpl, dmobj.IPersistStream_iface);
46 void set_audiopath_perf_pointer(IDirectMusicAudioPath *iface, IDirectMusicPerformance8 *performance)
48 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
49 This->pPerf = performance;
52 void set_audiopath_dsound_buffer(IDirectMusicAudioPath *iface, IDirectSoundBuffer *buffer)
54 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
55 This->pDSBuffer = buffer;
58 void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath *iface, IDirectSoundBuffer *buffer)
60 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
61 This->pPrimary = buffer;
64 /*****************************************************************************
65 * IDirectMusicAudioPathImpl implementation
67 static HRESULT WINAPI IDirectMusicAudioPathImpl_QueryInterface (IDirectMusicAudioPath *iface, REFIID riid, void **ppobj)
69 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
71 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
73 *ppobj = NULL;
75 if (IsEqualIID (riid, &IID_IDirectMusicAudioPath) || IsEqualIID (riid, &IID_IUnknown))
76 *ppobj = &This->IDirectMusicAudioPath_iface;
77 else if (IsEqualIID (riid, &IID_IDirectMusicObject))
78 *ppobj = &This->dmobj.IDirectMusicObject_iface;
79 else if (IsEqualIID (riid, &IID_IPersistStream))
80 *ppobj = &This->dmobj.IPersistStream_iface;
82 if (*ppobj) {
83 IUnknown_AddRef((IUnknown*)*ppobj);
84 return S_OK;
87 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
88 return E_NOINTERFACE;
91 static ULONG WINAPI IDirectMusicAudioPathImpl_AddRef (IDirectMusicAudioPath *iface)
93 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
94 ULONG ref = InterlockedIncrement(&This->ref);
96 TRACE("(%p): ref=%ld\n", This, ref);
98 return ref;
101 static ULONG WINAPI IDirectMusicAudioPathImpl_Release (IDirectMusicAudioPath *iface)
103 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
104 ULONG ref = InterlockedDecrement(&This->ref);
106 TRACE("(%p): ref=%ld\n", This, ref);
108 if (ref == 0) {
109 if (This->pPrimary)
110 IDirectSoundBuffer_Release(This->pPrimary);
111 if (This->pDSBuffer)
112 IDirectSoundBuffer_Release(This->pDSBuffer);
113 This->pPerf = NULL;
114 free(This);
117 return ref;
120 static HRESULT WINAPI IDirectMusicAudioPathImpl_GetObjectInPath (IDirectMusicAudioPath *iface, DWORD dwPChannel, DWORD dwStage, DWORD dwBuffer,
121 REFGUID guidObject, WORD dwIndex, REFGUID iidInterface, void** ppObject)
123 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
124 HRESULT hr;
126 FIXME("(%p, %ld, %ld, %ld, %s, %d, %s, %p): stub\n", This, dwPChannel, dwStage, dwBuffer, debugstr_dmguid(guidObject),
127 dwIndex, debugstr_dmguid(iidInterface), ppObject);
129 switch (dwStage) {
130 case DMUS_PATH_BUFFER:
131 if (This->pDSBuffer)
133 if (IsEqualIID (iidInterface, &IID_IUnknown) ||
134 IsEqualIID (iidInterface, &IID_IDirectSoundBuffer) ||
135 IsEqualIID (iidInterface, &IID_IDirectSoundBuffer8) ||
136 IsEqualIID (iidInterface, &IID_IDirectSound3DBuffer)) {
137 return IDirectSoundBuffer_QueryInterface(This->pDSBuffer, iidInterface, ppObject);
140 WARN("Unsupported interface %s\n", debugstr_dmguid(iidInterface));
141 *ppObject = NULL;
142 return E_NOINTERFACE;
144 break;
146 case DMUS_PATH_PRIMARY_BUFFER: {
147 if (IsEqualIID (iidInterface, &IID_IDirectSound3DListener)) {
148 IDirectSoundBuffer_QueryInterface(This->pPrimary, &IID_IDirectSound3DListener, ppObject);
149 return S_OK;
150 } else {
151 FIXME("bad iid...\n");
154 break;
156 case DMUS_PATH_AUDIOPATH_GRAPH:
158 if (IsEqualIID (iidInterface, &IID_IDirectMusicGraph)) {
159 if (NULL == This->pToolGraph) {
160 IDirectMusicGraph* pGraph;
161 hr = create_dmgraph(&IID_IDirectMusicGraph, (void**)&pGraph);
162 if (FAILED(hr))
163 return hr;
164 This->pToolGraph = pGraph;
166 *ppObject = This->pToolGraph;
167 IDirectMusicGraph_AddRef((LPDIRECTMUSICGRAPH) *ppObject);
168 return S_OK;
171 break;
173 case DMUS_PATH_AUDIOPATH_TOOL:
175 /* TODO */
177 break;
179 case DMUS_PATH_PERFORMANCE:
181 /* TODO check wanted GUID */
182 *ppObject = This->pPerf;
183 IUnknown_AddRef((LPUNKNOWN) *ppObject);
184 return S_OK;
186 break;
188 case DMUS_PATH_PERFORMANCE_GRAPH:
190 IDirectMusicGraph* pPerfoGraph = NULL;
191 IDirectMusicPerformance8_GetGraph(This->pPerf, &pPerfoGraph);
192 if (NULL == pPerfoGraph) {
193 IDirectMusicGraph* pGraph = NULL;
194 hr = create_dmgraph(&IID_IDirectMusicGraph, (void**)&pGraph);
195 if (FAILED(hr))
196 return hr;
197 IDirectMusicPerformance8_SetGraph(This->pPerf, pGraph);
198 pPerfoGraph = pGraph;
200 *ppObject = pPerfoGraph;
201 return S_OK;
203 break;
205 case DMUS_PATH_PERFORMANCE_TOOL:
206 default:
207 break;
210 *ppObject = NULL;
211 return E_INVALIDARG;
214 static HRESULT WINAPI IDirectMusicAudioPathImpl_Activate(IDirectMusicAudioPath *iface, BOOL activate)
216 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
218 FIXME("(%p, %d): semi-stub\n", This, activate);
220 if (!!activate == This->fActive)
221 return S_FALSE;
223 if (!activate && This->pDSBuffer) {
224 /* Path is being deactivated */
225 IDirectSoundBuffer_Stop(This->pDSBuffer);
228 This->fActive = !!activate;
230 return S_OK;
233 static HRESULT WINAPI IDirectMusicAudioPathImpl_SetVolume (IDirectMusicAudioPath *iface, LONG lVolume, DWORD dwDuration)
235 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
236 FIXME("(%p, %li, %ld): stub\n", This, lVolume, dwDuration);
237 return S_OK;
240 static HRESULT WINAPI IDirectMusicAudioPathImpl_ConvertPChannel (IDirectMusicAudioPath *iface, DWORD dwPChannelIn, DWORD* pdwPChannelOut)
242 struct IDirectMusicAudioPathImpl *This = impl_from_IDirectMusicAudioPath(iface);
243 FIXME("(%p, %ld, %p): stub\n", This, dwPChannelIn, pdwPChannelOut);
244 return S_OK;
247 static const IDirectMusicAudioPathVtbl DirectMusicAudioPathVtbl = {
248 IDirectMusicAudioPathImpl_QueryInterface,
249 IDirectMusicAudioPathImpl_AddRef,
250 IDirectMusicAudioPathImpl_Release,
251 IDirectMusicAudioPathImpl_GetObjectInPath,
252 IDirectMusicAudioPathImpl_Activate,
253 IDirectMusicAudioPathImpl_SetVolume,
254 IDirectMusicAudioPathImpl_ConvertPChannel
257 /* IDirectMusicObject */
258 static HRESULT WINAPI path_IDirectMusicObject_ParseDescriptor(IDirectMusicObject *iface,
259 IStream *stream, DMUS_OBJECTDESC *desc)
261 struct chunk_entry riff = {0};
262 HRESULT hr;
264 TRACE("(%p, %p, %p)\n", iface, stream, desc);
266 if (!stream)
267 return E_POINTER;
268 if (!desc || desc->dwSize != sizeof(*desc))
269 return E_INVALIDARG;
271 if ((hr = stream_get_chunk(stream, &riff)) != S_OK)
272 return hr;
273 if (riff.id != FOURCC_RIFF || riff.type != DMUS_FOURCC_AUDIOPATH_FORM) {
274 TRACE("loading failed: unexpected %s\n", debugstr_chunk(&riff));
275 stream_skip_chunk(stream, &riff);
276 return DMUS_E_CHUNKNOTFOUND;
279 hr = dmobj_parsedescriptor(stream, &riff, desc,
280 DMUS_OBJ_OBJECT|DMUS_OBJ_NAME|DMUS_OBJ_CATEGORY|DMUS_OBJ_VERSION);
281 if (FAILED(hr))
282 return hr;
284 desc->guidClass = CLSID_DirectMusicAudioPathConfig;
285 desc->dwValidData |= DMUS_OBJ_CLASS;
287 dump_DMUS_OBJECTDESC(desc);
288 return S_OK;
291 static const IDirectMusicObjectVtbl dmobject_vtbl = {
292 dmobj_IDirectMusicObject_QueryInterface,
293 dmobj_IDirectMusicObject_AddRef,
294 dmobj_IDirectMusicObject_Release,
295 dmobj_IDirectMusicObject_GetDescriptor,
296 dmobj_IDirectMusicObject_SetDescriptor,
297 path_IDirectMusicObject_ParseDescriptor
300 /* IPersistStream */
301 static HRESULT WINAPI path_IPersistStream_Load(IPersistStream *iface, IStream *stream)
303 struct IDirectMusicAudioPathImpl *This = impl_from_IPersistStream(iface);
305 FIXME("(%p, %p): Loading not implemented yet\n", This, stream);
307 return IDirectMusicObject_ParseDescriptor(&This->dmobj.IDirectMusicObject_iface, stream,
308 &This->dmobj.desc);
311 static const IPersistStreamVtbl persiststream_vtbl = {
312 dmobj_IPersistStream_QueryInterface,
313 dmobj_IPersistStream_AddRef,
314 dmobj_IPersistStream_Release,
315 dmobj_IPersistStream_GetClassID,
316 unimpl_IPersistStream_IsDirty,
317 path_IPersistStream_Load,
318 unimpl_IPersistStream_Save,
319 unimpl_IPersistStream_GetSizeMax
322 /* for ClassFactory */
323 HRESULT create_dmaudiopath(REFIID riid, void **ppobj)
325 IDirectMusicAudioPathImpl* obj;
326 HRESULT hr;
328 *ppobj = NULL;
329 if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY;
330 obj->IDirectMusicAudioPath_iface.lpVtbl = &DirectMusicAudioPathVtbl;
331 obj->ref = 1;
332 dmobject_init(&obj->dmobj, &CLSID_DirectMusicAudioPathConfig,
333 (IUnknown *)&obj->IDirectMusicAudioPath_iface);
334 obj->dmobj.IDirectMusicObject_iface.lpVtbl = &dmobject_vtbl;
335 obj->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
337 hr = IDirectMusicAudioPath_QueryInterface(&obj->IDirectMusicAudioPath_iface, riid, ppobj);
338 IDirectMusicAudioPath_Release(&obj->IDirectMusicAudioPath_iface);
339 return hr;