d3d9/tests: Add test for regression in IDirect3DDevice9_Reset().
[wine.git] / dlls / dmsynth / synth.c
blob88ba53ea475aa76b32beb936ad0628bb76410ad4
1 /*
2 * IDirectMusicSynth8 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 COBJMACROS
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
26 #include "objbase.h"
27 #include "initguid.h"
28 #include "dmksctrl.h"
30 #include "dmsynth_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(dmsynth);
34 static inline IDirectMusicSynth8Impl *impl_from_IDirectMusicSynth8(IDirectMusicSynth8 *iface)
36 return CONTAINING_RECORD(iface, IDirectMusicSynth8Impl, IDirectMusicSynth8_iface);
39 /* IDirectMusicSynth8Impl IUnknown part: */
40 static HRESULT WINAPI IDirectMusicSynth8Impl_QueryInterface(LPDIRECTMUSICSYNTH8 iface, REFIID riid, LPVOID *ret_iface)
42 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
44 TRACE("(%p)->(%s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
46 if (IsEqualIID (riid, &IID_IUnknown) ||
47 IsEqualIID (riid, &IID_IDirectMusicSynth) ||
48 IsEqualIID (riid, &IID_IDirectMusicSynth8))
50 IUnknown_AddRef(iface);
51 *ret_iface = iface;
52 return S_OK;
54 else if (IsEqualIID(riid, &IID_IKsControl))
56 IUnknown_AddRef(iface);
57 *ret_iface = &This->IKsControl_iface;
58 return S_OK;
61 *ret_iface = NULL;
63 WARN("(%p)->(%s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
65 return E_NOINTERFACE;
68 static ULONG WINAPI IDirectMusicSynth8Impl_AddRef(LPDIRECTMUSICSYNTH8 iface)
70 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
71 ULONG ref = InterlockedIncrement(&This->ref);
73 TRACE("(%p)->(): new ref = %u\n", This, ref);
75 return ref;
78 static ULONG WINAPI IDirectMusicSynth8Impl_Release(LPDIRECTMUSICSYNTH8 iface)
80 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
81 ULONG ref = InterlockedDecrement(&This->ref);
83 TRACE("(%p)->(): new ref = %u\n", This, ref);
85 if (!ref) {
86 if (This->pLatencyClock)
87 IReferenceClock_Release(This->pLatencyClock);
88 HeapFree(GetProcessHeap(), 0, This);
89 DMSYNTH_UnlockModule();
92 return ref;
95 /* IDirectMusicSynth8Impl IDirectMusicSynth part: */
96 static HRESULT WINAPI IDirectMusicSynth8Impl_Open(LPDIRECTMUSICSYNTH8 iface, LPDMUS_PORTPARAMS pPortParams)
98 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
100 FIXME("(%p)->(%p): stub\n", This, pPortParams);
102 return S_OK;
105 static HRESULT WINAPI IDirectMusicSynth8Impl_Close(LPDIRECTMUSICSYNTH8 iface)
107 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
109 FIXME("(%p)->(): stub\n", This);
111 return S_OK;
114 static HRESULT WINAPI IDirectMusicSynth8Impl_SetNumChannelGroups(LPDIRECTMUSICSYNTH8 iface, DWORD groups)
116 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
118 FIXME("(%p)->(%d): stub\n", This, groups);
120 return S_OK;
123 static HRESULT WINAPI IDirectMusicSynth8Impl_Download(LPDIRECTMUSICSYNTH8 iface, LPHANDLE hDownload, LPVOID data, LPBOOL free)
125 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
126 LPBYTE buffer = data;
127 DMUS_DOWNLOADINFO *info = (DMUS_DOWNLOADINFO*)buffer;
128 ULONG *offsets = ((DMUS_OFFSETTABLE*)(buffer + sizeof(DMUS_DOWNLOADINFO)))->ulOffsetTable;
129 LPBYTE object = buffer + sizeof(DMUS_DOWNLOADINFO) + info->dwNumOffsetTableEntries * sizeof(ULONG);
131 FIXME("(%p)->(%p, %p, %p): stub\n", This, hDownload, data, free);
133 /* FIXME: Currently we only dump data which is very useful to known how native dmusic behave and debug builtin dmusic */
135 if (!hDownload || !free)
136 return E_POINTER;
138 if (TRACE_ON(dmsynth))
140 TRACE("Dump DMUS_DOWNLOADINFO struct:\n");
141 TRACE(" - dwDLType = %u\n", info->dwDLType);
142 TRACE(" - dwDLId = %u\n", info->dwDLId);
143 TRACE(" - dwNumOffsetTableEntries = %u\n", info->dwNumOffsetTableEntries);
144 TRACE(" - cbSize = %u\n", info->cbSize);
147 /* The struct should have at least one offset corresponding to the download object itself */
148 if (!info->dwNumOffsetTableEntries)
150 FIXME("Offset table is empty\n");
151 return DMUS_E_BADOFFSETTABLE;
154 /* First offset should point to the download object */
155 if ((buffer + offsets[0]) != object)
157 FIXME("Object is not at the beginning\n");
158 return DMUS_E_BADOFFSETTABLE;
161 if (info->dwDLType == DMUS_DOWNLOADINFO_INSTRUMENT)
163 FIXME("Download type DMUS_DOWNLOADINFO_INSTRUMENT not yet supported\n");
165 else if (info->dwDLType == DMUS_DOWNLOADINFO_WAVE)
167 DMUS_WAVE *wave = (DMUS_WAVE*)object;
168 DMUS_WAVEDATA *wave_data;
170 TRACE("Processing download type DMUS_DOWNLOADINFO_WAVE\n");
172 if (TRACE_ON(dmsynth))
174 TRACE("Dump DMUS_WAVE struct\n");
175 TRACE(" - ulFirstExtCkIdx = %u\n", wave->ulFirstExtCkIdx);
176 TRACE(" - ulCopyrightIdx = %u\n", wave->ulCopyrightIdx);
177 TRACE(" - ulWaveDataIdx = %u\n", wave->ulWaveDataIdx);
178 TRACE(" - WaveformatEx:\n");
179 TRACE(" - wFormatTag = %u\n", wave->WaveformatEx.wFormatTag);
180 TRACE(" - nChannels = %u\n", wave->WaveformatEx.nChannels);
181 TRACE(" - nSamplesPerSec = %u\n", wave->WaveformatEx.nSamplesPerSec);
182 TRACE(" - nAvgBytesPerSec = %u\n", wave->WaveformatEx.nAvgBytesPerSec);
183 TRACE(" - nBlockAlign = %u\n", wave->WaveformatEx.nBlockAlign);
184 TRACE(" - wBitsPerSample = %u\n", wave->WaveformatEx.wBitsPerSample);
185 TRACE(" - cbSize = %u\n", wave->WaveformatEx.cbSize);
187 if (wave->ulCopyrightIdx)
189 DMUS_COPYRIGHT *copyright = (DMUS_COPYRIGHT*)(buffer + offsets[wave->ulCopyrightIdx]);
190 TRACE("Copyright = '%s'\n", (char*)copyright->byCopyright);
193 wave_data = (DMUS_WAVEDATA*)(buffer + offsets[wave->ulWaveDataIdx]);
194 TRACE("Found %u bytes of wave data\n", wave_data->cbSize);
197 else if (info->dwDLType == DMUS_DOWNLOADINFO_INSTRUMENT2)
199 DMUS_INSTRUMENT *instrument = (DMUS_INSTRUMENT*)object;
200 ULONG nb_regions = 0;
202 TRACE("Processing download type DMUS_DOWNLOADINFO_INSTRUMENT2\n");
204 if (TRACE_ON(dmsynth))
206 TRACE("Dump DMUS_INSTRUMENT struct\n");
207 TRACE(" - ulPatch = %u\n", instrument->ulPatch);
208 TRACE(" - ulFirstRegionIdx = %u\n", instrument->ulFirstRegionIdx);
209 TRACE(" - ulGlobalArtIdx = %u\n", instrument->ulGlobalArtIdx);
210 TRACE(" - ulFirstExtCkIdx = %u\n", instrument->ulFirstExtCkIdx);
211 TRACE(" - ulCopyrightIdx = %u\n", instrument->ulCopyrightIdx);
212 TRACE(" - ulFlags = %u\n", instrument->ulFlags);
214 if (instrument->ulCopyrightIdx)
216 DMUS_COPYRIGHT *copyright = (DMUS_COPYRIGHT*)(buffer + offsets[instrument->ulCopyrightIdx]);
217 TRACE("Copyright = '%s'\n", (char*)copyright->byCopyright);
221 if (instrument->ulFirstRegionIdx)
223 ULONG region_idx = instrument->ulFirstRegionIdx;
225 while (region_idx)
227 DMUS_REGION *region = (DMUS_REGION*)(buffer + offsets[region_idx]);
229 region_idx = region->ulNextRegionIdx;
230 nb_regions++;
234 TRACE("Number of regions = %u\n", nb_regions);
236 else if (info->dwDLType == DMUS_DOWNLOADINFO_WAVEARTICULATION)
238 FIXME("Download type DMUS_DOWNLOADINFO_WAVEARTICULATION not yet supported\n");
240 else if (info->dwDLType == DMUS_DOWNLOADINFO_STREAMINGWAVE)
242 FIXME("Download type DMUS_DOWNLOADINFO_STREAMINGWAVE not yet supported\n");
244 else if (info->dwDLType == DMUS_DOWNLOADINFO_ONESHOTWAVE)
246 FIXME("Download type DMUS_DOWNLOADINFO_ONESHOTWAVE not yet supported\n");
248 else
250 WARN("Unknown download type %u\n", info->dwDLType);
251 return DMUS_E_UNKNOWNDOWNLOAD;
254 return S_OK;
257 static HRESULT WINAPI IDirectMusicSynth8Impl_Unload(LPDIRECTMUSICSYNTH8 iface, HANDLE hDownload, HRESULT (CALLBACK* lpFreeHandle)(HANDLE,HANDLE), HANDLE hUserData)
259 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
261 FIXME("(%p)->(%p, %p, %p): stub\n", This, hDownload, lpFreeHandle, hUserData);
263 return S_OK;
266 static HRESULT WINAPI IDirectMusicSynth8Impl_PlayBuffer(LPDIRECTMUSICSYNTH8 iface, REFERENCE_TIME rt, LPBYTE buffer, DWORD size)
268 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
270 FIXME("(%p)->(0x%s, %p, %u): stub\n", This, wine_dbgstr_longlong(rt), buffer, size);
272 return S_OK;
275 static HRESULT WINAPI IDirectMusicSynth8Impl_GetRunningStats(LPDIRECTMUSICSYNTH8 iface, LPDMUS_SYNTHSTATS stats)
277 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
279 FIXME("(%p)->(%p): stub\n", This, stats);
281 return S_OK;
284 static HRESULT WINAPI IDirectMusicSynth8Impl_GetPortCaps(LPDIRECTMUSICSYNTH8 iface, LPDMUS_PORTCAPS caps)
286 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
288 TRACE("(%p)->(%p)\n", This, caps);
290 *caps = This->pCaps;
292 return S_OK;
295 static HRESULT WINAPI IDirectMusicSynth8Impl_SetMasterClock(LPDIRECTMUSICSYNTH8 iface, IReferenceClock* clock)
297 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
299 FIXME("(%p)->(%p): stub\n", This, clock);
301 return S_OK;
304 static HRESULT WINAPI IDirectMusicSynth8Impl_GetLatencyClock(LPDIRECTMUSICSYNTH8 iface, IReferenceClock** clock)
306 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
308 TRACE("(%p)->(%p)\n", iface, clock);
310 if (!clock)
311 return E_POINTER;
313 if (!This->pSynthSink)
314 return DMUS_E_NOSYNTHSINK;
316 *clock = This->pLatencyClock;
317 IReferenceClock_AddRef(This->pLatencyClock);
319 return S_OK;
322 static HRESULT WINAPI IDirectMusicSynth8Impl_Activate(LPDIRECTMUSICSYNTH8 iface, BOOL enable)
324 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
326 TRACE("(%p)->(%d)\n", This, enable);
328 This->fActive = enable;
330 return S_OK;
333 static HRESULT WINAPI IDirectMusicSynth8Impl_SetSynthSink(LPDIRECTMUSICSYNTH8 iface, IDirectMusicSynthSink* synth_sink)
335 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
337 TRACE("(%p)->(%p)\n", iface, synth_sink);
339 This->pSynthSink = (IDirectMusicSynthSinkImpl*)synth_sink;
341 if (synth_sink)
342 return IDirectMusicSynthSink_GetLatencyClock(synth_sink, &This->pLatencyClock);
344 return S_OK;
347 static HRESULT WINAPI IDirectMusicSynth8Impl_Render(LPDIRECTMUSICSYNTH8 iface, short* buffer, DWORD length, LONGLONG position)
349 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
351 FIXME("(%p)->(%p, %d, 0x%s): stub\n", This, buffer, length, wine_dbgstr_longlong(position));
353 return S_OK;
356 static HRESULT WINAPI IDirectMusicSynth8Impl_SetChannelPriority(LPDIRECTMUSICSYNTH8 iface, DWORD channel_group, DWORD channel, DWORD priority)
358 /* IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface); */
360 /* Silenced because of too many messages - 1000 groups * 16 channels ;=) */
361 /* FIXME("(%p)->(%ld, %ld, %ld): stub\n", This, channel_group, channel, priority); */
363 return S_OK;
366 static HRESULT WINAPI IDirectMusicSynth8Impl_GetChannelPriority(LPDIRECTMUSICSYNTH8 iface, DWORD channel_group, DWORD channel, LPDWORD priority)
368 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
370 FIXME("(%p)->(%d, %d, %p): stub\n", This, channel_group, channel, priority);
372 return S_OK;
375 static HRESULT WINAPI IDirectMusicSynth8Impl_GetFormat(LPDIRECTMUSICSYNTH8 iface, LPWAVEFORMATEX wave_format, LPDWORD wave_format_size)
377 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
379 FIXME("(%p)->(%p, %p): stub\n", This, wave_format, wave_format_size);
381 return S_OK;
384 static HRESULT WINAPI IDirectMusicSynth8Impl_GetAppend(LPDIRECTMUSICSYNTH8 iface, DWORD* append)
386 TRACE("(%p)->(%p)\n", iface, append);
388 /* We don't need extra space at the end of buffers passed to us for now */
389 *append = 0;
391 return S_OK;
394 /* IDirectMusicSynth8Impl IDirectMusicSynth8 part: */
395 static HRESULT WINAPI IDirectMusicSynth8Impl_PlayVoice(LPDIRECTMUSICSYNTH8 iface, REFERENCE_TIME ref_time, DWORD voice_id, DWORD channel_group, DWORD channel,
396 DWORD dwDLId, LONG prPitch, LONG vrVolume, SAMPLE_TIME stVoiceStart, SAMPLE_TIME stLoopStart, SAMPLE_TIME stLoopEnd)
398 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
400 FIXME("(%p)->(0x%s, %d, %d, %d, %d, %i, %i,0x%s, 0x%s, 0x%s): stub\n",
401 This, wine_dbgstr_longlong(ref_time), voice_id, channel_group, channel, dwDLId, prPitch, vrVolume,
402 wine_dbgstr_longlong(stVoiceStart), wine_dbgstr_longlong(stLoopStart), wine_dbgstr_longlong(stLoopEnd));
404 return S_OK;
407 static HRESULT WINAPI IDirectMusicSynth8Impl_StopVoice(LPDIRECTMUSICSYNTH8 iface, REFERENCE_TIME ref_time, DWORD voice_id)
409 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
411 FIXME("(%p)->(0x%s, %d): stub\n", This, wine_dbgstr_longlong(ref_time), voice_id);
413 return S_OK;
416 static HRESULT WINAPI IDirectMusicSynth8Impl_GetVoiceState(LPDIRECTMUSICSYNTH8 iface, DWORD dwVoice[], DWORD cbVoice, DMUS_VOICE_STATE dwVoiceState[])
418 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
420 FIXME("(%p)->(%p, %d, %p): stub\n", This, dwVoice, cbVoice, dwVoiceState);
422 return S_OK;
425 static HRESULT WINAPI IDirectMusicSynth8Impl_Refresh(LPDIRECTMUSICSYNTH8 iface, DWORD download_id, DWORD flags)
427 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
429 FIXME("(%p)->(%d, %d): stub\n", This, download_id, flags);
431 return S_OK;
434 static HRESULT WINAPI IDirectMusicSynth8Impl_AssignChannelToBuses(LPDIRECTMUSICSYNTH8 iface, DWORD channel_group, DWORD channel, LPDWORD pdwBuses, DWORD cBuses)
436 IDirectMusicSynth8Impl *This = impl_from_IDirectMusicSynth8(iface);
438 FIXME("(%p)->(%d, %d, %p, %d): stub\n", This, channel_group, channel, pdwBuses, cBuses);
440 return S_OK;
443 static const IDirectMusicSynth8Vtbl DirectMusicSynth8_Vtbl = {
444 IDirectMusicSynth8Impl_QueryInterface,
445 IDirectMusicSynth8Impl_AddRef,
446 IDirectMusicSynth8Impl_Release,
447 IDirectMusicSynth8Impl_Open,
448 IDirectMusicSynth8Impl_Close,
449 IDirectMusicSynth8Impl_SetNumChannelGroups,
450 IDirectMusicSynth8Impl_Download,
451 IDirectMusicSynth8Impl_Unload,
452 IDirectMusicSynth8Impl_PlayBuffer,
453 IDirectMusicSynth8Impl_GetRunningStats,
454 IDirectMusicSynth8Impl_GetPortCaps,
455 IDirectMusicSynth8Impl_SetMasterClock,
456 IDirectMusicSynth8Impl_GetLatencyClock,
457 IDirectMusicSynth8Impl_Activate,
458 IDirectMusicSynth8Impl_SetSynthSink,
459 IDirectMusicSynth8Impl_Render,
460 IDirectMusicSynth8Impl_SetChannelPriority,
461 IDirectMusicSynth8Impl_GetChannelPriority,
462 IDirectMusicSynth8Impl_GetFormat,
463 IDirectMusicSynth8Impl_GetAppend,
464 IDirectMusicSynth8Impl_PlayVoice,
465 IDirectMusicSynth8Impl_StopVoice,
466 IDirectMusicSynth8Impl_GetVoiceState,
467 IDirectMusicSynth8Impl_Refresh,
468 IDirectMusicSynth8Impl_AssignChannelToBuses
471 static inline IDirectMusicSynth8Impl *impl_from_IKsControl(IKsControl *iface)
473 return CONTAINING_RECORD(iface, IDirectMusicSynth8Impl, IKsControl_iface);
476 static HRESULT WINAPI DMSynthImpl_IKsControl_QueryInterface(IKsControl* iface, REFIID riid, LPVOID *ppobj)
478 IDirectMusicSynth8Impl *This = impl_from_IKsControl(iface);
480 return IDirectMusicSynth8Impl_QueryInterface(&This->IDirectMusicSynth8_iface, riid, ppobj);
483 static ULONG WINAPI DMSynthImpl_IKsControl_AddRef(IKsControl* iface)
485 IDirectMusicSynth8Impl *This = impl_from_IKsControl(iface);
487 return IDirectMusicSynth8Impl_AddRef(&This->IDirectMusicSynth8_iface);
490 static ULONG WINAPI DMSynthImpl_IKsControl_Release(IKsControl* iface)
492 IDirectMusicSynth8Impl *This = impl_from_IKsControl(iface);
494 return IDirectMusicSynth8Impl_Release(&This->IDirectMusicSynth8_iface);
497 static HRESULT WINAPI DMSynthImpl_IKsControl_KsProperty(IKsControl* iface, PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData,
498 ULONG DataLength, ULONG* BytesReturned)
500 TRACE("(%p)->(%p, %u, %p, %u, %p)\n", iface, Property, PropertyLength, PropertyData, DataLength, BytesReturned);
502 TRACE("Property = %s - %u - %u\n", debugstr_guid(&Property->u.s.Set), Property->u.s.Id, Property->u.s.Flags);
504 if (Property->u.s.Flags != KSPROPERTY_TYPE_GET)
506 FIXME("Property flags %u not yet supported\n", Property->u.s.Flags);
507 return S_FALSE;
510 if (DataLength < sizeof(DWORD))
511 return E_NOT_SUFFICIENT_BUFFER;
513 if (IsEqualGUID(&Property->u.s.Set, &GUID_DMUS_PROP_INSTRUMENT2))
515 *(DWORD*)PropertyData = TRUE;
516 *BytesReturned = sizeof(DWORD);
518 else if (IsEqualGUID(&Property->u.s.Set, &GUID_DMUS_PROP_DLS2))
520 *(DWORD*)PropertyData = TRUE;
521 *BytesReturned = sizeof(DWORD);
523 else if (IsEqualGUID(&Property->u.s.Set, &GUID_DMUS_PROP_GM_Hardware))
525 *(DWORD*)PropertyData = FALSE;
526 *BytesReturned = sizeof(DWORD);
528 else if (IsEqualGUID(&Property->u.s.Set, &GUID_DMUS_PROP_GS_Hardware))
530 *(DWORD*)PropertyData = FALSE;
531 *BytesReturned = sizeof(DWORD);
533 else if (IsEqualGUID(&Property->u.s.Set, &GUID_DMUS_PROP_XG_Hardware))
535 *(DWORD*)PropertyData = FALSE;
536 *BytesReturned = sizeof(DWORD);
538 else
540 FIXME("Unknown property %s\n", debugstr_guid(&Property->u.s.Set));
541 *(DWORD*)PropertyData = FALSE;
542 *BytesReturned = sizeof(DWORD);
545 return S_OK;
548 static HRESULT WINAPI DMSynthImpl_IKsControl_KsMethod(IKsControl* iface, PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData,
549 ULONG DataLength, ULONG* BytesReturned)
551 FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, Method, MethodLength, MethodData, DataLength, BytesReturned);
553 return E_NOTIMPL;
556 static HRESULT WINAPI DMSynthImpl_IKsControl_KsEvent(IKsControl* iface, PKSEVENT Event, ULONG EventLength, LPVOID EventData,
557 ULONG DataLength, ULONG* BytesReturned)
559 FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, Event, EventLength, EventData, DataLength, BytesReturned);
561 return E_NOTIMPL;
565 static const IKsControlVtbl DMSynthImpl_IKsControl_Vtbl = {
566 DMSynthImpl_IKsControl_QueryInterface,
567 DMSynthImpl_IKsControl_AddRef,
568 DMSynthImpl_IKsControl_Release,
569 DMSynthImpl_IKsControl_KsProperty,
570 DMSynthImpl_IKsControl_KsMethod,
571 DMSynthImpl_IKsControl_KsEvent
574 /* for ClassFactory */
575 HRESULT WINAPI DMUSIC_CreateDirectMusicSynthImpl(REFIID riid, void **ppobj)
577 static const WCHAR descrW[] = {'M','i','c','r','o','s','o','f','t',' ',
578 'S','y','n','t','h','e','s','i','z','e','r',0};
579 IDirectMusicSynth8Impl *obj;
580 HRESULT hr;
582 TRACE("(%s, %p)\n", debugstr_guid(riid), ppobj);
584 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
585 if (NULL == obj) {
586 *ppobj = NULL;
587 return E_OUTOFMEMORY;
589 obj->IDirectMusicSynth8_iface.lpVtbl = &DirectMusicSynth8_Vtbl;
590 obj->IKsControl_iface.lpVtbl = &DMSynthImpl_IKsControl_Vtbl;
591 obj->ref = 1;
592 /* fill in caps */
593 obj->pCaps.dwSize = sizeof(DMUS_PORTCAPS);
594 obj->pCaps.dwFlags = DMUS_PC_DLS | DMUS_PC_SOFTWARESYNTH | DMUS_PC_DIRECTSOUND | DMUS_PC_DLS2 | DMUS_PC_AUDIOPATH | DMUS_PC_WAVE;
595 obj->pCaps.guidPort = CLSID_DirectMusicSynth;
596 obj->pCaps.dwClass = DMUS_PC_OUTPUTCLASS;
597 obj->pCaps.dwType = DMUS_PORT_USER_MODE_SYNTH;
598 obj->pCaps.dwMemorySize = DMUS_PC_SYSTEMMEMORY;
599 obj->pCaps.dwMaxChannelGroups = 1000;
600 obj->pCaps.dwMaxVoices = 1000;
601 obj->pCaps.dwMaxAudioChannels = 2;
602 obj->pCaps.dwEffectFlags = DMUS_EFFECT_REVERB;
603 strcpyW(obj->pCaps.wszDescription, descrW);
605 DMSYNTH_LockModule();
606 hr = IDirectMusicSynth8_QueryInterface(&obj->IDirectMusicSynth8_iface, riid, ppobj);
607 IDirectMusicSynth8_Release(&obj->IDirectMusicSynth8_iface);
609 return hr;