regsvr32: Use neutral language for the version resource.
[wine.git] / dlls / dmusic / port.c
blob07da1ae8916cbac03073100540fc0a9cd155a096
1 /*
2 * IDirectMusicPort 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 #include <assert.h>
23 #include "dmusic_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(dmusic);
27 typedef struct SynthPortImpl {
28 IDirectMusicPort IDirectMusicPort_iface;
29 IDirectMusicPortDownload IDirectMusicPortDownload_iface;
30 IDirectMusicThru IDirectMusicThru_iface;
31 IKsControl IKsControl_iface;
32 LONG ref;
33 IDirectSound *pDirectSound;
34 IReferenceClock *pLatencyClock;
35 IDirectMusicSynth *synth;
36 IDirectMusicSynthSink *synth_sink;
37 BOOL fActive;
38 DMUS_PORTCAPS caps;
39 DMUS_PORTPARAMS params;
40 int nrofgroups;
41 DMUSIC_PRIVATE_CHANNEL_GROUP group[1];
42 } SynthPortImpl;
44 static inline IDirectMusicDownloadedInstrumentImpl* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface)
46 return CONTAINING_RECORD(iface, IDirectMusicDownloadedInstrumentImpl, IDirectMusicDownloadedInstrument_iface);
49 static inline SynthPortImpl *impl_from_SynthPortImpl_IDirectMusicPort(IDirectMusicPort *iface)
51 return CONTAINING_RECORD(iface, SynthPortImpl, IDirectMusicPort_iface);
54 static inline SynthPortImpl *impl_from_SynthPortImpl_IDirectMusicPortDownload(IDirectMusicPortDownload *iface)
56 return CONTAINING_RECORD(iface, SynthPortImpl, IDirectMusicPortDownload_iface);
59 static inline SynthPortImpl *impl_from_SynthPortImpl_IDirectMusicThru(IDirectMusicThru *iface)
61 return CONTAINING_RECORD(iface, SynthPortImpl, IDirectMusicThru_iface);
64 static inline SynthPortImpl *impl_from_IKsControl(IKsControl *iface)
66 return CONTAINING_RECORD(iface, SynthPortImpl, IKsControl_iface);
69 /* IDirectMusicDownloadedInstrument IUnknown part follows: */
70 static HRESULT WINAPI IDirectMusicDownloadedInstrumentImpl_QueryInterface(IDirectMusicDownloadedInstrument *iface, REFIID riid, VOID **ret_iface)
72 TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
74 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicDownloadedInstrument))
76 IDirectMusicDownloadedInstrument_AddRef(iface);
77 *ret_iface = iface;
78 return S_OK;
81 WARN("(%p, %s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
83 return E_NOINTERFACE;
86 static ULONG WINAPI IDirectMusicDownloadedInstrumentImpl_AddRef(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface)
88 IDirectMusicDownloadedInstrumentImpl *This = impl_from_IDirectMusicDownloadedInstrument(iface);
89 ULONG ref = InterlockedIncrement(&This->ref);
91 TRACE("(%p)->(): new ref = %u\n", iface, ref);
93 return ref;
96 static ULONG WINAPI IDirectMusicDownloadedInstrumentImpl_Release(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface)
98 IDirectMusicDownloadedInstrumentImpl *This = impl_from_IDirectMusicDownloadedInstrument(iface);
99 ULONG ref = InterlockedDecrement(&This->ref);
101 TRACE("(%p)->(): new ref = %u\n", iface, ref);
103 if (!ref)
105 HeapFree(GetProcessHeap(), 0, This->data);
106 HeapFree(GetProcessHeap(), 0, This);
107 DMUSIC_UnlockModule();
110 return ref;
113 static const IDirectMusicDownloadedInstrumentVtbl DirectMusicDownloadedInstrument_Vtbl = {
114 IDirectMusicDownloadedInstrumentImpl_QueryInterface,
115 IDirectMusicDownloadedInstrumentImpl_AddRef,
116 IDirectMusicDownloadedInstrumentImpl_Release
119 static inline IDirectMusicDownloadedInstrumentImpl* unsafe_impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface)
121 if (!iface)
122 return NULL;
123 assert(iface->lpVtbl == &DirectMusicDownloadedInstrument_Vtbl);
125 return impl_from_IDirectMusicDownloadedInstrument(iface);
128 static HRESULT DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(IDirectMusicDownloadedInstrument **instrument)
130 IDirectMusicDownloadedInstrumentImpl *object;
132 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
133 if (!object)
135 *instrument = NULL;
136 return E_OUTOFMEMORY;
139 object->IDirectMusicDownloadedInstrument_iface.lpVtbl = &DirectMusicDownloadedInstrument_Vtbl;
140 object->ref = 1;
142 *instrument = &object->IDirectMusicDownloadedInstrument_iface;
143 DMUSIC_LockModule();
145 return S_OK;
148 /* SynthPortImpl IDirectMusicPort IUnknown part follows: */
149 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_QueryInterface(LPDIRECTMUSICPORT iface, REFIID riid, LPVOID *ret_iface)
151 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
153 TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_dmguid(riid), ret_iface);
155 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirectMusicPort))
156 *ret_iface = &This->IDirectMusicPort_iface;
157 else if (IsEqualGUID(riid, &IID_IDirectMusicPortDownload))
158 *ret_iface = &This->IDirectMusicPortDownload_iface;
159 else if (IsEqualGUID(riid, &IID_IDirectMusicThru))
160 *ret_iface = &This->IDirectMusicThru_iface;
161 else if (IsEqualGUID(riid, &IID_IKsControl))
162 *ret_iface = &This->IKsControl_iface;
163 else {
164 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
165 *ret_iface = NULL;
166 return E_NOINTERFACE;
169 IUnknown_AddRef((IUnknown*)*ret_iface);
171 return S_OK;
174 static ULONG WINAPI SynthPortImpl_IDirectMusicPort_AddRef(LPDIRECTMUSICPORT iface)
176 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
177 ULONG ref = InterlockedIncrement(&This->ref);
179 TRACE("(%p)->(): new ref = %u\n", This, ref);
181 DMUSIC_LockModule();
183 return ref;
186 static ULONG WINAPI SynthPortImpl_IDirectMusicPort_Release(LPDIRECTMUSICPORT iface)
188 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
189 ULONG ref = InterlockedDecrement(&This->ref);
191 TRACE("(%p)->(): new ref = %u\n", This, ref);
193 if (!ref)
195 IDirectMusicSynth_Activate(This->synth, FALSE);
196 IDirectMusicSynth_Close(This->synth);
197 IDirectMusicSynth_Release(This->synth);
198 IDirectMusicSynthSink_Release(This->synth_sink);
199 IReferenceClock_Release(This->pLatencyClock);
200 HeapFree(GetProcessHeap(), 0, This);
203 DMUSIC_UnlockModule();
205 return ref;
208 /* SynthPortImpl IDirectMusicPort interface follows: */
209 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_PlayBuffer(LPDIRECTMUSICPORT iface, LPDIRECTMUSICBUFFER buffer)
211 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
212 HRESULT hr;
213 REFERENCE_TIME time;
214 LPBYTE data;
215 DWORD size;
217 TRACE("(%p/%p)->(%p)\n", iface, This, buffer);
219 if (!buffer)
220 return E_POINTER;
222 hr = IDirectMusicBuffer_GetStartTime(buffer, &time);
224 if (SUCCEEDED(hr))
225 hr = IDirectMusicBuffer_GetRawBufferPtr(buffer, &data);
227 if (SUCCEEDED(hr))
228 hr = IDirectMusicBuffer_GetUsedBytes(buffer, &size);
230 if (SUCCEEDED(hr))
231 hr = IDirectMusicSynth_PlayBuffer(This->synth, time, data, size);
233 return hr;
236 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle(LPDIRECTMUSICPORT iface, HANDLE event)
238 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
240 FIXME("(%p/%p)->(%p): stub\n", iface, This, event);
242 return S_OK;
245 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_Read(LPDIRECTMUSICPORT iface, LPDIRECTMUSICBUFFER buffer)
247 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
249 FIXME("(%p/%p)->(%p): stub\n", iface, This, buffer);
251 return S_OK;
254 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_DownloadInstrument(LPDIRECTMUSICPORT iface, IDirectMusicInstrument* instrument, IDirectMusicDownloadedInstrument** downloaded_instrument, DMUS_NOTERANGE* note_ranges, DWORD num_note_ranges)
256 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
257 IDirectMusicInstrumentImpl *instrument_object;
258 HRESULT ret;
259 BOOL free;
260 HANDLE download;
261 DMUS_DOWNLOADINFO *info;
262 DMUS_OFFSETTABLE *offset_table;
263 DMUS_INSTRUMENT *instrument_info;
264 BYTE *data;
265 ULONG offset;
266 ULONG nb_regions;
267 ULONG size;
268 ULONG i;
270 TRACE("(%p/%p)->(%p, %p, %p, %d)\n", iface, This, instrument, downloaded_instrument, note_ranges, num_note_ranges);
272 if (!instrument || !downloaded_instrument || (num_note_ranges && !note_ranges))
273 return E_POINTER;
275 instrument_object = impl_from_IDirectMusicInstrument(instrument);
277 nb_regions = instrument_object->header.cRegions;
278 size = sizeof(DMUS_DOWNLOADINFO) + sizeof(ULONG) * (1 + nb_regions) + sizeof(DMUS_INSTRUMENT) + sizeof(DMUS_REGION) * nb_regions;
280 data = HeapAlloc(GetProcessHeap(), 0, size);
281 if (!data)
282 return E_OUTOFMEMORY;
284 info = (DMUS_DOWNLOADINFO*)data;
285 offset_table = (DMUS_OFFSETTABLE*)(data + sizeof(DMUS_DOWNLOADINFO));
286 offset = sizeof(DMUS_DOWNLOADINFO) + sizeof(ULONG) * (1 + nb_regions);
288 info->dwDLType = DMUS_DOWNLOADINFO_INSTRUMENT2;
289 info->dwDLId = 0;
290 info->dwNumOffsetTableEntries = 1 + instrument_object->header.cRegions;
291 info->cbSize = size;
293 offset_table->ulOffsetTable[0] = offset;
294 instrument_info = (DMUS_INSTRUMENT*)(data + offset);
295 offset += sizeof(DMUS_INSTRUMENT);
296 instrument_info->ulPatch = MIDILOCALE2Patch(&instrument_object->header.Locale);
297 instrument_info->ulFirstRegionIdx = 1;
298 instrument_info->ulGlobalArtIdx = 0; /* FIXME */
299 instrument_info->ulFirstExtCkIdx = 0; /* FIXME */
300 instrument_info->ulCopyrightIdx = 0; /* FIXME */
301 instrument_info->ulFlags = 0; /* FIXME */
303 for (i = 0; i < nb_regions; i++)
305 DMUS_REGION *region = (DMUS_REGION*)(data + offset);
307 offset_table->ulOffsetTable[1 + i] = offset;
308 offset += sizeof(DMUS_REGION);
309 region->RangeKey = instrument_object->regions[i].header.RangeKey;
310 region->RangeVelocity = instrument_object->regions[i].header.RangeVelocity;
311 region->fusOptions = instrument_object->regions[i].header.fusOptions;
312 region->usKeyGroup = instrument_object->regions[i].header.usKeyGroup;
313 region->ulRegionArtIdx = 0; /* FIXME */
314 region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0;
315 region->ulFirstExtCkIdx = 0; /* FIXME */
316 region->WaveLink = instrument_object->regions[i].wave_link;
317 region->WSMP = instrument_object->regions[i].wave_sample;
318 region->WLOOP[0] = instrument_object->regions[i].wave_loop;
321 ret = IDirectMusicSynth8_Download(This->synth, &download, (VOID*)data, &free);
323 if (SUCCEEDED(ret))
324 ret = DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(downloaded_instrument);
326 if (SUCCEEDED(ret))
328 IDirectMusicDownloadedInstrumentImpl *downloaded_object = impl_from_IDirectMusicDownloadedInstrument(*downloaded_instrument);
330 downloaded_object->data = data;
331 downloaded_object->downloaded = TRUE;
334 *downloaded_instrument = NULL;
335 HeapFree(GetProcessHeap(), 0, data);
337 return E_FAIL;
340 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_UnloadInstrument(LPDIRECTMUSICPORT iface, IDirectMusicDownloadedInstrument *downloaded_instrument)
342 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
343 IDirectMusicDownloadedInstrumentImpl *downloaded_object = unsafe_impl_from_IDirectMusicDownloadedInstrument(downloaded_instrument);
345 TRACE("(%p/%p)->(%p)\n", iface, This, downloaded_instrument);
347 if (!downloaded_instrument)
348 return E_POINTER;
350 if (!downloaded_object->downloaded)
351 return DMUS_E_NOT_DOWNLOADED_TO_PORT;
353 HeapFree(GetProcessHeap(), 0, downloaded_object->data);
354 downloaded_object->data = NULL;
355 downloaded_object->downloaded = FALSE;
357 return S_OK;
360 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetLatencyClock(LPDIRECTMUSICPORT iface, IReferenceClock** clock)
362 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
364 TRACE("(%p/%p)->(%p)\n", iface, This, clock);
366 *clock = This->pLatencyClock;
367 IReferenceClock_AddRef(*clock);
369 return S_OK;
372 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetRunningStats(LPDIRECTMUSICPORT iface, LPDMUS_SYNTHSTATS stats)
374 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
376 FIXME("(%p/%p)->(%p): stub\n", iface, This, stats);
378 return S_OK;
381 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_Compact(LPDIRECTMUSICPORT iface)
383 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
385 FIXME("(%p/%p)->(): stub\n", iface, This);
387 return S_OK;
390 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetCaps(LPDIRECTMUSICPORT iface, LPDMUS_PORTCAPS port_caps)
392 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
394 TRACE("(%p/%p)->(%p)\n", iface, This, port_caps);
396 *port_caps = This->caps;
398 return S_OK;
401 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_DeviceIoControl(LPDIRECTMUSICPORT iface, DWORD io_control_code, LPVOID in_buffer, DWORD in_buffer_size,
402 LPVOID out_buffer, DWORD out_buffer_size, LPDWORD bytes_returned, LPOVERLAPPED overlapped)
404 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
406 FIXME("(%p/%p)->(%d, %p, %d, %p, %d, %p, %p): stub\n", iface, This, io_control_code, in_buffer, in_buffer_size, out_buffer, out_buffer_size, bytes_returned, overlapped);
408 return S_OK;
411 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetNumChannelGroups(LPDIRECTMUSICPORT iface, DWORD channel_groups)
413 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
415 FIXME("(%p/%p)->(%d): semi-stub\n", iface, This, channel_groups);
417 This->nrofgroups = channel_groups;
419 return S_OK;
422 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetNumChannelGroups(LPDIRECTMUSICPORT iface, LPDWORD channel_groups)
424 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
426 TRACE("(%p/%p)->(%p)\n", iface, This, channel_groups);
428 *channel_groups = This->nrofgroups;
430 return S_OK;
433 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_Activate(LPDIRECTMUSICPORT iface, BOOL active)
435 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
437 TRACE("(%p/%p)->(%d)\n", iface, This, active);
439 This->fActive = active;
441 return S_OK;
444 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetChannelPriority(LPDIRECTMUSICPORT iface, DWORD channel_group, DWORD channel, DWORD priority)
446 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
448 FIXME("(%p/%p)->(%d, %d, %d): semi-stub\n", iface, This, channel_group, channel, priority);
450 if (channel > 16)
452 WARN("isn't there supposed to be 16 channels (no. %d requested)?! (faking as it is ok)\n", channel);
453 /*return E_INVALIDARG;*/
456 return S_OK;
459 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetChannelPriority(LPDIRECTMUSICPORT iface, DWORD channel_group, DWORD channel, LPDWORD priority)
461 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
463 TRACE("(%p/%p)->(%u, %u, %p)\n", iface, This, channel_group, channel, priority);
465 *priority = This->group[channel_group - 1].channel[channel].priority;
467 return S_OK;
470 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetDirectSound(LPDIRECTMUSICPORT iface, LPDIRECTSOUND direct_sound, LPDIRECTSOUNDBUFFER direct_sound_buffer)
472 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
474 FIXME("(%p/%p)->(%p, %p): stub\n", iface, This, direct_sound, direct_sound_buffer);
476 return S_OK;
479 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetFormat(LPDIRECTMUSICPORT iface, LPWAVEFORMATEX pWaveFormatEx, LPDWORD pdwWaveFormatExSize, LPDWORD pdwBufferSize)
481 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
482 WAVEFORMATEX format;
483 FIXME("(%p, %p, %p, %p): stub\n", This, pWaveFormatEx, pdwWaveFormatExSize, pdwBufferSize);
485 if (pWaveFormatEx == NULL)
487 if (pdwWaveFormatExSize)
488 *pdwWaveFormatExSize = sizeof(format);
489 else
490 return E_POINTER;
492 else
494 if (pdwWaveFormatExSize == NULL)
495 return E_POINTER;
497 /* Just fill this in with something that will not crash Direct Sound for now. */
498 /* It won't be used anyway until Performances are completed */
499 format.wFormatTag = WAVE_FORMAT_PCM;
500 format.nChannels = 2; /* This->params.dwAudioChannels; */
501 format.nSamplesPerSec = 44100; /* This->params.dwSampleRate; */
502 format.wBitsPerSample = 16; /* FIXME: check this */
503 format.nBlockAlign = (format.wBitsPerSample * format.nChannels) / 8;
504 format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
505 format.cbSize = 0;
507 if (*pdwWaveFormatExSize >= sizeof(format))
509 CopyMemory(pWaveFormatEx, &format, min(sizeof(format), *pdwWaveFormatExSize));
510 *pdwWaveFormatExSize = sizeof(format); /* FIXME check if this is set */
512 else
513 return E_POINTER; /* FIXME find right error */
516 if (pdwBufferSize)
517 *pdwBufferSize = 44100 * 2 * 2;
518 else
519 return E_POINTER;
521 return S_OK;
524 static const IDirectMusicPortVtbl SynthPortImpl_DirectMusicPort_Vtbl = {
525 /**** IDirectMusicPort IUnknown part methods ***/
526 SynthPortImpl_IDirectMusicPort_QueryInterface,
527 SynthPortImpl_IDirectMusicPort_AddRef,
528 SynthPortImpl_IDirectMusicPort_Release,
529 /**** IDirectMusicPort methods ***/
530 SynthPortImpl_IDirectMusicPort_PlayBuffer,
531 SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle,
532 SynthPortImpl_IDirectMusicPort_Read,
533 SynthPortImpl_IDirectMusicPort_DownloadInstrument,
534 SynthPortImpl_IDirectMusicPort_UnloadInstrument,
535 SynthPortImpl_IDirectMusicPort_GetLatencyClock,
536 SynthPortImpl_IDirectMusicPort_GetRunningStats,
537 SynthPortImpl_IDirectMusicPort_Compact,
538 SynthPortImpl_IDirectMusicPort_GetCaps,
539 SynthPortImpl_IDirectMusicPort_DeviceIoControl,
540 SynthPortImpl_IDirectMusicPort_SetNumChannelGroups,
541 SynthPortImpl_IDirectMusicPort_GetNumChannelGroups,
542 SynthPortImpl_IDirectMusicPort_Activate,
543 SynthPortImpl_IDirectMusicPort_SetChannelPriority,
544 SynthPortImpl_IDirectMusicPort_GetChannelPriority,
545 SynthPortImpl_IDirectMusicPort_SetDirectSound,
546 SynthPortImpl_IDirectMusicPort_GetFormat
549 /* SynthPortImpl IDirectMusicPortDownload IUnknown part follows: */
550 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_QueryInterface(LPDIRECTMUSICPORTDOWNLOAD iface, REFIID riid, LPVOID *ret_iface)
552 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
554 TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_dmguid(riid), ret_iface);
556 return IDirectMusicPort_QueryInterface(&This->IDirectMusicPort_iface, riid, ret_iface);
559 static ULONG WINAPI SynthPortImpl_IDirectMusicPortDownload_AddRef (LPDIRECTMUSICPORTDOWNLOAD iface)
561 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
563 TRACE("(%p/%p)->()\n", iface, This);
565 return IDirectMusicPort_AddRef(&This->IDirectMusicPort_iface);
568 static ULONG WINAPI SynthPortImpl_IDirectMusicPortDownload_Release(LPDIRECTMUSICPORTDOWNLOAD iface)
570 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
572 TRACE("(%p/%p)->()\n", iface, This);
574 return IDirectMusicPort_Release(&This->IDirectMusicPort_iface);
577 /* SynthPortImpl IDirectMusicPortDownload Interface follows: */
578 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_GetBuffer(LPDIRECTMUSICPORTDOWNLOAD iface, DWORD DLId, IDirectMusicDownload** IDMDownload)
580 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
582 FIXME("(%p/%p)->(%u, %p): stub\n", iface, This, DLId, IDMDownload);
584 if (!IDMDownload)
585 return E_POINTER;
587 return DMUSIC_CreateDirectMusicDownloadImpl(&IID_IDirectMusicDownload, (LPVOID*)IDMDownload, NULL);
590 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer(LPDIRECTMUSICPORTDOWNLOAD iface, DWORD size, IDirectMusicDownload** IDMDownload)
592 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
594 FIXME("(%p/%p)->(%u, %p): stub\n", iface, This, size, IDMDownload);
596 return S_OK;
599 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_GetDLId(LPDIRECTMUSICPORTDOWNLOAD iface, DWORD* start_DLId, DWORD count)
601 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
603 FIXME("(%p/%p)->(%p, %u): stub\n", iface, This, start_DLId, count);
605 return S_OK;
608 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_GetAppend (LPDIRECTMUSICPORTDOWNLOAD iface, DWORD* append)
610 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
612 FIXME("(%p/%p)->(%p): stub\n", iface, This, append);
614 return S_OK;
617 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_Download(LPDIRECTMUSICPORTDOWNLOAD iface, IDirectMusicDownload* IDMDownload)
619 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
621 FIXME("(%p/%p)->(%p): stub\n", iface, This, IDMDownload);
623 return S_OK;
626 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_Unload(LPDIRECTMUSICPORTDOWNLOAD iface, IDirectMusicDownload* IDMDownload)
628 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
630 FIXME("(%p/%p)->(%p): stub\n", iface, This, IDMDownload);
632 return S_OK;
635 static const IDirectMusicPortDownloadVtbl SynthPortImpl_DirectMusicPortDownload_Vtbl = {
636 /*** IDirectMusicPortDownload IUnknown part methods ***/
637 SynthPortImpl_IDirectMusicPortDownload_QueryInterface,
638 SynthPortImpl_IDirectMusicPortDownload_AddRef,
639 SynthPortImpl_IDirectMusicPortDownload_Release,
640 /*** IDirectMusicPortDownload methods ***/
641 SynthPortImpl_IDirectMusicPortDownload_GetBuffer,
642 SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer,
643 SynthPortImpl_IDirectMusicPortDownload_GetDLId,
644 SynthPortImpl_IDirectMusicPortDownload_GetAppend,
645 SynthPortImpl_IDirectMusicPortDownload_Download,
646 SynthPortImpl_IDirectMusicPortDownload_Unload
649 /* SynthPortImpl IDirectMusicThru IUnknown part follows: */
650 static HRESULT WINAPI SynthPortImpl_IDirectMusicThru_QueryInterface(LPDIRECTMUSICTHRU iface, REFIID riid, LPVOID *ret_iface)
652 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
654 TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_dmguid(riid), ret_iface);
656 return IDirectMusicPort_QueryInterface(&This->IDirectMusicPort_iface, riid, ret_iface);
659 static ULONG WINAPI SynthPortImpl_IDirectMusicThru_AddRef(LPDIRECTMUSICTHRU iface)
661 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
663 TRACE("(%p/%p)->()\n", iface, This);
665 return IDirectMusicPort_AddRef(&This->IDirectMusicPort_iface);
668 static ULONG WINAPI SynthPortImpl_IDirectMusicThru_Release(LPDIRECTMUSICTHRU iface)
670 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
672 TRACE("(%p/%p)->()\n", iface, This);
674 return IDirectMusicPort_Release(&This->IDirectMusicPort_iface);
677 /* SynthPortImpl IDirectMusicThru Interface follows: */
678 static HRESULT WINAPI SynthPortImpl_IDirectMusicThru_ThruChannel(LPDIRECTMUSICTHRU iface, DWORD source_channel_group, DWORD source_channel, DWORD destination_channel_group,
679 DWORD destination_channel, LPDIRECTMUSICPORT destination_port)
681 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
683 FIXME("(%p/%p)->(%d, %d, %d, %d, %p): stub\n", iface, This, source_channel_group, source_channel, destination_channel_group, destination_channel, destination_port);
685 return S_OK;
688 static const IDirectMusicThruVtbl SynthPortImpl_DirectMusicThru_Vtbl = {
689 /*** IDirectMusicThru IUnknown part methods */
690 SynthPortImpl_IDirectMusicThru_QueryInterface,
691 SynthPortImpl_IDirectMusicThru_AddRef,
692 SynthPortImpl_IDirectMusicThru_Release,
693 /*** IDirectMusicThru methods ***/
694 SynthPortImpl_IDirectMusicThru_ThruChannel
697 static HRESULT WINAPI IKsControlImpl_QueryInterface(IKsControl *iface, REFIID riid,
698 void **ret_iface)
700 SynthPortImpl *This = impl_from_IKsControl(iface);
702 return IDirectMusicPort_QueryInterface(&This->IDirectMusicPort_iface, riid, ret_iface);
705 static ULONG WINAPI IKsControlImpl_AddRef(IKsControl *iface)
707 SynthPortImpl *This = impl_from_IKsControl(iface);
709 return IDirectMusicPort_AddRef(&This->IDirectMusicPort_iface);
712 static ULONG WINAPI IKsControlImpl_Release(IKsControl *iface)
714 SynthPortImpl *This = impl_from_IKsControl(iface);
716 return IDirectMusicPort_Release(&This->IDirectMusicPort_iface);
719 static HRESULT WINAPI IKsControlImpl_KsProperty(IKsControl *iface, KSPROPERTY *prop,
720 ULONG prop_len, void *data, ULONG data_len, ULONG *ret_len)
722 TRACE("(%p)->(%p, %u, %p, %u, %p)\n", iface, prop, prop_len, data, data_len, ret_len);
723 TRACE("prop = %s - %u - %u\n", debugstr_guid(&prop->Set), prop->Id, prop->Flags);
725 if (prop->Flags != KSPROPERTY_TYPE_GET)
727 FIXME("prop flags %u not yet supported\n", prop->Flags);
728 return S_FALSE;
731 if (data_len < sizeof(DWORD))
732 return E_NOT_SUFFICIENT_BUFFER;
734 FIXME("Unknown property %s\n", debugstr_guid(&prop->Set));
735 *(DWORD*)data = FALSE;
736 *ret_len = sizeof(DWORD);
738 return S_OK;
741 static HRESULT WINAPI IKsControlImpl_KsMethod(IKsControl *iface, KSMETHOD *method,
742 ULONG method_len, void *data, ULONG data_len, ULONG *ret_len)
744 FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, method, method_len, data, data_len, ret_len);
746 return E_NOTIMPL;
749 static HRESULT WINAPI IKsControlImpl_KsEvent(IKsControl *iface, KSEVENT *event, ULONG event_len,
750 void *data, ULONG data_len, ULONG *ret_len)
752 FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, event, event_len, data, data_len, ret_len);
754 return E_NOTIMPL;
757 static const IKsControlVtbl ikscontrol_vtbl = {
758 IKsControlImpl_QueryInterface,
759 IKsControlImpl_AddRef,
760 IKsControlImpl_Release,
761 IKsControlImpl_KsProperty,
762 IKsControlImpl_KsMethod,
763 IKsControlImpl_KsEvent
766 HRESULT DMUSIC_CreateSynthPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device)
768 SynthPortImpl *obj;
769 HRESULT hr = E_FAIL;
770 int i;
772 TRACE("(%s, %p, %p, %p, %p, %d)\n", debugstr_guid(guid), object, unkouter, port_params,
773 port_caps, device);
775 *object = NULL;
777 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SynthPortImpl));
778 if (!obj)
779 return E_OUTOFMEMORY;
781 obj->IDirectMusicPort_iface.lpVtbl = &SynthPortImpl_DirectMusicPort_Vtbl;
782 obj->IDirectMusicPortDownload_iface.lpVtbl = &SynthPortImpl_DirectMusicPortDownload_Vtbl;
783 obj->IDirectMusicThru_iface.lpVtbl = &SynthPortImpl_DirectMusicThru_Vtbl;
784 obj->IKsControl_iface.lpVtbl = &ikscontrol_vtbl;
785 obj->ref = 0; /* Will be inited by QueryInterface */
786 obj->fActive = FALSE;
787 obj->params = *port_params;
788 obj->caps = *port_caps;
790 hr = DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock, (LPVOID*)&obj->pLatencyClock, NULL);
791 if (hr != S_OK)
793 HeapFree(GetProcessHeap(), 0, obj);
794 return hr;
797 if (SUCCEEDED(hr))
798 hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth, (void**)&obj->synth);
800 if (SUCCEEDED(hr))
801 hr = CoCreateInstance(&CLSID_DirectMusicSynthSink, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynthSink, (void**)&obj->synth_sink);
803 if (SUCCEEDED(hr))
804 hr = IDirectMusicSynth_SetMasterClock(obj->synth, obj->pLatencyClock);
806 if (SUCCEEDED(hr))
807 hr = IDirectMusicSynthSink_SetMasterClock(obj->synth_sink, obj->pLatencyClock);
809 if (SUCCEEDED(hr))
810 hr = IDirectMusicSynth_SetSynthSink(obj->synth, obj->synth_sink);
812 if (SUCCEEDED(hr))
813 hr = IDirectMusicSynth_Open(obj->synth, port_params);
815 if (0)
817 if (port_params->dwValidParams & DMUS_PORTPARAMS_CHANNELGROUPS) {
818 obj->nrofgroups = port_params->dwChannelGroups;
819 /* Setting default priorities */
820 for (i = 0; i < obj->nrofgroups; i++) {
821 TRACE ("Setting default channel priorities on channel group %i\n", i + 1);
822 obj->group[i].channel[0].priority = DAUD_CHAN1_DEF_VOICE_PRIORITY;
823 obj->group[i].channel[1].priority = DAUD_CHAN2_DEF_VOICE_PRIORITY;
824 obj->group[i].channel[2].priority = DAUD_CHAN3_DEF_VOICE_PRIORITY;
825 obj->group[i].channel[3].priority = DAUD_CHAN4_DEF_VOICE_PRIORITY;
826 obj->group[i].channel[4].priority = DAUD_CHAN5_DEF_VOICE_PRIORITY;
827 obj->group[i].channel[5].priority = DAUD_CHAN6_DEF_VOICE_PRIORITY;
828 obj->group[i].channel[6].priority = DAUD_CHAN7_DEF_VOICE_PRIORITY;
829 obj->group[i].channel[7].priority = DAUD_CHAN8_DEF_VOICE_PRIORITY;
830 obj->group[i].channel[8].priority = DAUD_CHAN9_DEF_VOICE_PRIORITY;
831 obj->group[i].channel[9].priority = DAUD_CHAN10_DEF_VOICE_PRIORITY;
832 obj->group[i].channel[10].priority = DAUD_CHAN11_DEF_VOICE_PRIORITY;
833 obj->group[i].channel[11].priority = DAUD_CHAN12_DEF_VOICE_PRIORITY;
834 obj->group[i].channel[12].priority = DAUD_CHAN13_DEF_VOICE_PRIORITY;
835 obj->group[i].channel[13].priority = DAUD_CHAN14_DEF_VOICE_PRIORITY;
836 obj->group[i].channel[14].priority = DAUD_CHAN15_DEF_VOICE_PRIORITY;
837 obj->group[i].channel[15].priority = DAUD_CHAN16_DEF_VOICE_PRIORITY;
842 if (SUCCEEDED(hr))
843 return IDirectMusicPort_QueryInterface((LPDIRECTMUSICPORT)obj, guid, object);
845 if (obj->synth)
846 IDirectMusicSynth_Release(obj->synth);
847 if (obj->synth_sink)
848 IDirectMusicSynthSink_Release(obj->synth_sink);
849 if (obj->pLatencyClock)
850 IReferenceClock_Release(obj->pLatencyClock);
851 HeapFree(GetProcessHeap(), 0, obj);
853 return hr;
856 HRESULT DMUSIC_CreateMidiOutPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device)
858 TRACE("(%s, %p, %p, %p, %p, %d): stub\n", debugstr_guid(guid), object, unkouter, port_params,
859 port_caps, device);
861 return E_NOTIMPL;
864 HRESULT DMUSIC_CreateMidiInPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device)
866 TRACE("(%s, %p, %p, %p, %p, %d): stub\n", debugstr_guid(guid), object, unkouter, port_params,
867 port_caps, device);
869 return E_NOTIMPL;