TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / dmusic / port.c
blobf886d52bb3989968b01e0d93df73e3a5d34dc354
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 static inline IDirectMusicDownloadedInstrumentImpl* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface)
29 return CONTAINING_RECORD(iface, IDirectMusicDownloadedInstrumentImpl, IDirectMusicDownloadedInstrument_iface);
32 static inline SynthPortImpl *impl_from_SynthPortImpl_IDirectMusicPort(IDirectMusicPort *iface)
34 return CONTAINING_RECORD(iface, SynthPortImpl, IDirectMusicPort_iface);
37 static inline SynthPortImpl *impl_from_SynthPortImpl_IDirectMusicPortDownload(IDirectMusicPortDownload *iface)
39 return CONTAINING_RECORD(iface, SynthPortImpl, IDirectMusicPortDownload_iface);
42 static inline SynthPortImpl *impl_from_SynthPortImpl_IDirectMusicThru(IDirectMusicThru *iface)
44 return CONTAINING_RECORD(iface, SynthPortImpl, IDirectMusicThru_iface);
47 /* IDirectMusicDownloadedInstrument IUnknown part follows: */
48 static HRESULT WINAPI IDirectMusicDownloadedInstrumentImpl_QueryInterface(IDirectMusicDownloadedInstrument *iface, REFIID riid, VOID **ret_iface)
50 TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
52 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicDownloadedInstrument))
54 IDirectMusicDownloadedInstrument_AddRef(iface);
55 *ret_iface = iface;
56 return S_OK;
59 WARN("(%p, %s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
61 return E_NOINTERFACE;
64 static ULONG WINAPI IDirectMusicDownloadedInstrumentImpl_AddRef(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface)
66 IDirectMusicDownloadedInstrumentImpl *This = impl_from_IDirectMusicDownloadedInstrument(iface);
67 ULONG ref = InterlockedIncrement(&This->ref);
69 TRACE("(%p)->(): new ref = %u\n", iface, ref);
71 return ref;
74 static ULONG WINAPI IDirectMusicDownloadedInstrumentImpl_Release(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface)
76 IDirectMusicDownloadedInstrumentImpl *This = impl_from_IDirectMusicDownloadedInstrument(iface);
77 ULONG ref = InterlockedDecrement(&This->ref);
79 TRACE("(%p)->(): new ref = %u\n", iface, ref);
81 if (!ref)
83 HeapFree(GetProcessHeap(), 0, This->data);
84 HeapFree(GetProcessHeap(), 0, This);
85 DMUSIC_UnlockModule();
88 return ref;
91 static const IDirectMusicDownloadedInstrumentVtbl DirectMusicDownloadedInstrument_Vtbl = {
92 IDirectMusicDownloadedInstrumentImpl_QueryInterface,
93 IDirectMusicDownloadedInstrumentImpl_AddRef,
94 IDirectMusicDownloadedInstrumentImpl_Release
97 static inline IDirectMusicDownloadedInstrumentImpl* unsafe_impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface)
99 if (!iface)
100 return NULL;
101 assert(iface->lpVtbl == &DirectMusicDownloadedInstrument_Vtbl);
103 return impl_from_IDirectMusicDownloadedInstrument(iface);
106 static HRESULT DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(IDirectMusicDownloadedInstrument **instrument)
108 IDirectMusicDownloadedInstrumentImpl *object;
110 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
111 if (!object)
113 *instrument = NULL;
114 return E_OUTOFMEMORY;
117 object->IDirectMusicDownloadedInstrument_iface.lpVtbl = &DirectMusicDownloadedInstrument_Vtbl;
118 object->ref = 1;
120 *instrument = &object->IDirectMusicDownloadedInstrument_iface;
121 DMUSIC_LockModule();
123 return S_OK;
126 /* SynthPortImpl IDirectMusicPort IUnknown part follows: */
127 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_QueryInterface(LPDIRECTMUSICPORT iface, REFIID riid, LPVOID *ret_iface)
129 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
131 TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_dmguid(riid), ret_iface);
133 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirectMusicPort)) {
134 *ret_iface = &This->IDirectMusicPort_iface;
135 IDirectMusicPort_AddRef((LPDIRECTMUSICPORT)*ret_iface);
136 return S_OK;
137 } else if (IsEqualGUID(riid, &IID_IDirectMusicPortDownload)) {
138 *ret_iface = &This->IDirectMusicPortDownload_iface;
139 IDirectMusicPortDownload_AddRef((LPDIRECTMUSICPORTDOWNLOAD)*ret_iface);
140 return S_OK;
141 } else if (IsEqualGUID(riid, &IID_IDirectMusicThru)) {
142 *ret_iface = &This->IDirectMusicThru_iface;
143 IDirectMusicThru_AddRef((LPDIRECTMUSICTHRU)*ret_iface);
144 return S_OK;
147 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
149 return E_NOINTERFACE;
152 static ULONG WINAPI SynthPortImpl_IDirectMusicPort_AddRef(LPDIRECTMUSICPORT iface)
154 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
155 ULONG ref = InterlockedIncrement(&This->ref);
157 TRACE("(%p)->(): new ref = %u\n", This, ref);
159 DMUSIC_LockModule();
161 return ref;
164 static ULONG WINAPI SynthPortImpl_IDirectMusicPort_Release(LPDIRECTMUSICPORT iface)
166 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
167 ULONG ref = InterlockedDecrement(&This->ref);
169 TRACE("(%p)->(): new ref = %u\n", This, ref);
171 if (!ref)
173 IDirectMusicSynth_Activate(This->synth, FALSE);
174 IDirectMusicSynth_Close(This->synth);
175 IDirectMusicSynth_Release(This->synth);
176 IDirectMusicSynthSink_Release(This->synth_sink);
177 IReferenceClock_Release(This->pLatencyClock);
178 HeapFree(GetProcessHeap(), 0, This);
181 DMUSIC_UnlockModule();
183 return ref;
186 /* SynthPortImpl IDirectMusicPort interface follows: */
187 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_PlayBuffer(LPDIRECTMUSICPORT iface, LPDIRECTMUSICBUFFER buffer)
189 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
190 HRESULT hr;
191 REFERENCE_TIME time;
192 LPBYTE data;
193 DWORD size;
195 TRACE("(%p/%p)->(%p)\n", iface, This, buffer);
197 if (!buffer)
198 return E_POINTER;
200 hr = IDirectMusicBuffer_GetStartTime(buffer, &time);
202 if (SUCCEEDED(hr))
203 hr = IDirectMusicBuffer_GetRawBufferPtr(buffer, &data);
205 if (SUCCEEDED(hr))
206 hr = IDirectMusicBuffer_GetUsedBytes(buffer, &size);
208 if (SUCCEEDED(hr))
209 hr = IDirectMusicSynth_PlayBuffer(This->synth, time, data, size);
211 return hr;
214 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle(LPDIRECTMUSICPORT iface, HANDLE event)
216 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
218 FIXME("(%p/%p)->(%p): stub\n", iface, This, event);
220 return S_OK;
223 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_Read(LPDIRECTMUSICPORT iface, LPDIRECTMUSICBUFFER buffer)
225 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
227 FIXME("(%p/%p)->(%p): stub\n", iface, This, buffer);
229 return S_OK;
232 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_DownloadInstrument(LPDIRECTMUSICPORT iface, IDirectMusicInstrument* instrument, IDirectMusicDownloadedInstrument** downloaded_instrument, DMUS_NOTERANGE* note_ranges, DWORD num_note_ranges)
234 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
235 IDirectMusicInstrumentImpl *instrument_object;
236 HRESULT ret;
237 BOOL free;
238 HANDLE download;
239 DMUS_DOWNLOADINFO *info;
240 DMUS_OFFSETTABLE *offset_table;
241 DMUS_INSTRUMENT *instrument_info;
242 BYTE *data;
243 ULONG offset;
244 ULONG nb_regions;
245 ULONG size;
246 ULONG i;
248 TRACE("(%p/%p)->(%p, %p, %p, %d)\n", iface, This, instrument, downloaded_instrument, note_ranges, num_note_ranges);
250 if (!instrument || !downloaded_instrument || (num_note_ranges && !note_ranges))
251 return E_POINTER;
253 instrument_object = impl_from_IDirectMusicInstrument(instrument);
255 nb_regions = instrument_object->header.cRegions;
256 size = sizeof(DMUS_DOWNLOADINFO) + sizeof(ULONG) * (1 + nb_regions) + sizeof(DMUS_INSTRUMENT) + sizeof(DMUS_REGION) * nb_regions;
258 data = HeapAlloc(GetProcessHeap(), 0, size);
259 if (!data)
260 return E_OUTOFMEMORY;
262 info = (DMUS_DOWNLOADINFO*)data;
263 offset_table = (DMUS_OFFSETTABLE*)(data + sizeof(DMUS_DOWNLOADINFO));
264 offset = sizeof(DMUS_DOWNLOADINFO) + sizeof(ULONG) * (1 + nb_regions);
266 info->dwDLType = DMUS_DOWNLOADINFO_INSTRUMENT2;
267 info->dwDLId = 0;
268 info->dwNumOffsetTableEntries = 1 + instrument_object->header.cRegions;
269 info->cbSize = size;
271 offset_table->ulOffsetTable[0] = offset;
272 instrument_info = (DMUS_INSTRUMENT*)(data + offset);
273 offset += sizeof(DMUS_INSTRUMENT);
274 instrument_info->ulPatch = MIDILOCALE2Patch(&instrument_object->header.Locale);
275 instrument_info->ulFirstRegionIdx = 1;
276 instrument_info->ulGlobalArtIdx = 0; /* FIXME */
277 instrument_info->ulFirstExtCkIdx = 0; /* FIXME */
278 instrument_info->ulCopyrightIdx = 0; /* FIXME */
279 instrument_info->ulFlags = 0; /* FIXME */
281 for (i = 0; i < nb_regions; i++)
283 DMUS_REGION *region = (DMUS_REGION*)(data + offset);
285 offset_table->ulOffsetTable[1 + i] = offset;
286 offset += sizeof(DMUS_REGION);
287 region->RangeKey = instrument_object->regions[i].header.RangeKey;
288 region->RangeVelocity = instrument_object->regions[i].header.RangeVelocity;
289 region->fusOptions = instrument_object->regions[i].header.fusOptions;
290 region->usKeyGroup = instrument_object->regions[i].header.usKeyGroup;
291 region->ulRegionArtIdx = 0; /* FIXME */
292 region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0;
293 region->ulFirstExtCkIdx = 0; /* FIXME */
294 region->WaveLink = instrument_object->regions[i].wave_link;
295 region->WSMP = instrument_object->regions[i].wave_sample;
296 region->WLOOP[0] = instrument_object->regions[i].wave_loop;
299 ret = IDirectMusicSynth8_Download(This->synth, &download, (VOID*)data, &free);
301 if (SUCCEEDED(ret))
302 ret = DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(downloaded_instrument);
304 if (SUCCEEDED(ret))
306 IDirectMusicDownloadedInstrumentImpl *downloaded_object = impl_from_IDirectMusicDownloadedInstrument(*downloaded_instrument);
308 downloaded_object->data = data;
309 downloaded_object->downloaded = TRUE;
312 *downloaded_instrument = NULL;
313 HeapFree(GetProcessHeap(), 0, data);
315 return E_FAIL;
318 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_UnloadInstrument(LPDIRECTMUSICPORT iface, IDirectMusicDownloadedInstrument *downloaded_instrument)
320 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
321 IDirectMusicDownloadedInstrumentImpl *downloaded_object = unsafe_impl_from_IDirectMusicDownloadedInstrument(downloaded_instrument);
323 TRACE("(%p/%p)->(%p)\n", iface, This, downloaded_instrument);
325 if (!downloaded_instrument)
326 return E_POINTER;
328 if (!downloaded_object->downloaded)
329 return DMUS_E_NOT_DOWNLOADED_TO_PORT;
331 HeapFree(GetProcessHeap(), 0, downloaded_object->data);
332 downloaded_object->data = NULL;
333 downloaded_object->downloaded = FALSE;
335 return S_OK;
338 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetLatencyClock(LPDIRECTMUSICPORT iface, IReferenceClock** clock)
340 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
342 TRACE("(%p/%p)->(%p)\n", iface, This, clock);
344 *clock = This->pLatencyClock;
345 IReferenceClock_AddRef(*clock);
347 return S_OK;
350 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetRunningStats(LPDIRECTMUSICPORT iface, LPDMUS_SYNTHSTATS stats)
352 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
354 FIXME("(%p/%p)->(%p): stub\n", iface, This, stats);
356 return S_OK;
359 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_Compact(LPDIRECTMUSICPORT iface)
361 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
363 FIXME("(%p/%p)->(): stub\n", iface, This);
365 return S_OK;
368 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetCaps(LPDIRECTMUSICPORT iface, LPDMUS_PORTCAPS port_caps)
370 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
372 TRACE("(%p/%p)->(%p)\n", iface, This, port_caps);
374 *port_caps = This->caps;
376 return S_OK;
379 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_DeviceIoControl(LPDIRECTMUSICPORT iface, DWORD io_control_code, LPVOID in_buffer, DWORD in_buffer_size,
380 LPVOID out_buffer, DWORD out_buffer_size, LPDWORD bytes_returned, LPOVERLAPPED overlapped)
382 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
384 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);
386 return S_OK;
389 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetNumChannelGroups(LPDIRECTMUSICPORT iface, DWORD channel_groups)
391 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
393 FIXME("(%p/%p)->(%d): semi-stub\n", iface, This, channel_groups);
395 This->nrofgroups = channel_groups;
397 return S_OK;
400 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetNumChannelGroups(LPDIRECTMUSICPORT iface, LPDWORD channel_groups)
402 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
404 TRACE("(%p/%p)->(%p)\n", iface, This, channel_groups);
406 *channel_groups = This->nrofgroups;
408 return S_OK;
411 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_Activate(LPDIRECTMUSICPORT iface, BOOL active)
413 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
415 TRACE("(%p/%p)->(%d)\n", iface, This, active);
417 This->fActive = active;
419 return S_OK;
422 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetChannelPriority(LPDIRECTMUSICPORT iface, DWORD channel_group, DWORD channel, DWORD priority)
424 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
426 FIXME("(%p/%p)->(%d, %d, %d): semi-stub\n", iface, This, channel_group, channel, priority);
428 if (channel > 16)
430 WARN("isn't there supposed to be 16 channels (no. %d requested)?! (faking as it is ok)\n", channel);
431 /*return E_INVALIDARG;*/
434 return S_OK;
437 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetChannelPriority(LPDIRECTMUSICPORT iface, DWORD channel_group, DWORD channel, LPDWORD priority)
439 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
441 TRACE("(%p/%p)->(%u, %u, %p)\n", iface, This, channel_group, channel, priority);
443 *priority = This->group[channel_group - 1].channel[channel].priority;
445 return S_OK;
448 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_SetDirectSound(LPDIRECTMUSICPORT iface, LPDIRECTSOUND direct_sound, LPDIRECTSOUNDBUFFER direct_sound_buffer)
450 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
452 FIXME("(%p/%p)->(%p, %p): stub\n", iface, This, direct_sound, direct_sound_buffer);
454 return S_OK;
457 static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_GetFormat(LPDIRECTMUSICPORT iface, LPWAVEFORMATEX pWaveFormatEx, LPDWORD pdwWaveFormatExSize, LPDWORD pdwBufferSize)
459 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface);
460 WAVEFORMATEX format;
461 FIXME("(%p, %p, %p, %p): stub\n", This, pWaveFormatEx, pdwWaveFormatExSize, pdwBufferSize);
463 if (pWaveFormatEx == NULL)
465 if (pdwWaveFormatExSize)
466 *pdwWaveFormatExSize = sizeof(format);
467 else
468 return E_POINTER;
470 else
472 if (pdwWaveFormatExSize == NULL)
473 return E_POINTER;
475 /* Just fill this in with something that will not crash Direct Sound for now. */
476 /* It won't be used anyway until Performances are completed */
477 format.wFormatTag = WAVE_FORMAT_PCM;
478 format.nChannels = 2; /* This->params.dwAudioChannels; */
479 format.nSamplesPerSec = 44100; /* This->params.dwSampleRate; */
480 format.wBitsPerSample = 16; /* FIXME: check this */
481 format.nBlockAlign = (format.wBitsPerSample * format.nChannels) / 8;
482 format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
483 format.cbSize = 0;
485 if (*pdwWaveFormatExSize >= sizeof(format))
487 CopyMemory(pWaveFormatEx, &format, min(sizeof(format), *pdwWaveFormatExSize));
488 *pdwWaveFormatExSize = sizeof(format); /* FIXME check if this is set */
490 else
491 return E_POINTER; /* FIXME find right error */
494 if (pdwBufferSize)
495 *pdwBufferSize = 44100 * 2 * 2;
496 else
497 return E_POINTER;
499 return S_OK;
502 static const IDirectMusicPortVtbl SynthPortImpl_DirectMusicPort_Vtbl = {
503 /**** IDirectMusicPort IUnknown part methods ***/
504 SynthPortImpl_IDirectMusicPort_QueryInterface,
505 SynthPortImpl_IDirectMusicPort_AddRef,
506 SynthPortImpl_IDirectMusicPort_Release,
507 /**** IDirectMusicPort methods ***/
508 SynthPortImpl_IDirectMusicPort_PlayBuffer,
509 SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle,
510 SynthPortImpl_IDirectMusicPort_Read,
511 SynthPortImpl_IDirectMusicPort_DownloadInstrument,
512 SynthPortImpl_IDirectMusicPort_UnloadInstrument,
513 SynthPortImpl_IDirectMusicPort_GetLatencyClock,
514 SynthPortImpl_IDirectMusicPort_GetRunningStats,
515 SynthPortImpl_IDirectMusicPort_Compact,
516 SynthPortImpl_IDirectMusicPort_GetCaps,
517 SynthPortImpl_IDirectMusicPort_DeviceIoControl,
518 SynthPortImpl_IDirectMusicPort_SetNumChannelGroups,
519 SynthPortImpl_IDirectMusicPort_GetNumChannelGroups,
520 SynthPortImpl_IDirectMusicPort_Activate,
521 SynthPortImpl_IDirectMusicPort_SetChannelPriority,
522 SynthPortImpl_IDirectMusicPort_GetChannelPriority,
523 SynthPortImpl_IDirectMusicPort_SetDirectSound,
524 SynthPortImpl_IDirectMusicPort_GetFormat
527 /* SynthPortImpl IDirectMusicPortDownload IUnknown part follows: */
528 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_QueryInterface(LPDIRECTMUSICPORTDOWNLOAD iface, REFIID riid, LPVOID *ret_iface)
530 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
532 TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_dmguid(riid), ret_iface);
534 return IDirectMusicPort_QueryInterface(&This->IDirectMusicPort_iface, riid, ret_iface);
537 static ULONG WINAPI SynthPortImpl_IDirectMusicPortDownload_AddRef (LPDIRECTMUSICPORTDOWNLOAD iface)
539 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
541 TRACE("(%p/%p)->()\n", iface, This);
543 return IDirectMusicPort_AddRef(&This->IDirectMusicPort_iface);
546 static ULONG WINAPI SynthPortImpl_IDirectMusicPortDownload_Release(LPDIRECTMUSICPORTDOWNLOAD iface)
548 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
550 TRACE("(%p/%p)->()\n", iface, This);
552 return IDirectMusicPort_Release(&This->IDirectMusicPort_iface);
555 /* SynthPortImpl IDirectMusicPortDownload Interface follows: */
556 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_GetBuffer(LPDIRECTMUSICPORTDOWNLOAD iface, DWORD DLId, IDirectMusicDownload** IDMDownload)
558 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
560 FIXME("(%p/%p)->(%u, %p): stub\n", iface, This, DLId, IDMDownload);
562 if (!IDMDownload)
563 return E_POINTER;
565 return DMUSIC_CreateDirectMusicDownloadImpl(&IID_IDirectMusicDownload, (LPVOID*)IDMDownload, NULL);
568 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer(LPDIRECTMUSICPORTDOWNLOAD iface, DWORD size, IDirectMusicDownload** IDMDownload)
570 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
572 FIXME("(%p/%p)->(%u, %p): stub\n", iface, This, size, IDMDownload);
574 return S_OK;
577 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_GetDLId(LPDIRECTMUSICPORTDOWNLOAD iface, DWORD* start_DLId, DWORD count)
579 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
581 FIXME("(%p/%p)->(%p, %u): stub\n", iface, This, start_DLId, count);
583 return S_OK;
586 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_GetAppend (LPDIRECTMUSICPORTDOWNLOAD iface, DWORD* append)
588 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
590 FIXME("(%p/%p)->(%p): stub\n", iface, This, append);
592 return S_OK;
595 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_Download(LPDIRECTMUSICPORTDOWNLOAD iface, IDirectMusicDownload* IDMDownload)
597 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
599 FIXME("(%p/%p)->(%p): stub\n", iface, This, IDMDownload);
601 return S_OK;
604 static HRESULT WINAPI SynthPortImpl_IDirectMusicPortDownload_Unload(LPDIRECTMUSICPORTDOWNLOAD iface, IDirectMusicDownload* IDMDownload)
606 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPortDownload(iface);
608 FIXME("(%p/%p)->(%p): stub\n", iface, This, IDMDownload);
610 return S_OK;
613 static const IDirectMusicPortDownloadVtbl SynthPortImpl_DirectMusicPortDownload_Vtbl = {
614 /*** IDirectMusicPortDownload IUnknown part methods ***/
615 SynthPortImpl_IDirectMusicPortDownload_QueryInterface,
616 SynthPortImpl_IDirectMusicPortDownload_AddRef,
617 SynthPortImpl_IDirectMusicPortDownload_Release,
618 /*** IDirectMusicPortDownload methods ***/
619 SynthPortImpl_IDirectMusicPortDownload_GetBuffer,
620 SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer,
621 SynthPortImpl_IDirectMusicPortDownload_GetDLId,
622 SynthPortImpl_IDirectMusicPortDownload_GetAppend,
623 SynthPortImpl_IDirectMusicPortDownload_Download,
624 SynthPortImpl_IDirectMusicPortDownload_Unload
627 /* SynthPortImpl IDirectMusicThru IUnknown part follows: */
628 static HRESULT WINAPI SynthPortImpl_IDirectMusicThru_QueryInterface(LPDIRECTMUSICTHRU iface, REFIID riid, LPVOID *ret_iface)
630 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
632 TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_dmguid(riid), ret_iface);
634 return IDirectMusicPort_QueryInterface(&This->IDirectMusicPort_iface, riid, ret_iface);
637 static ULONG WINAPI SynthPortImpl_IDirectMusicThru_AddRef(LPDIRECTMUSICTHRU iface)
639 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
641 TRACE("(%p/%p)->()\n", iface, This);
643 return IDirectMusicPort_AddRef(&This->IDirectMusicPort_iface);
646 static ULONG WINAPI SynthPortImpl_IDirectMusicThru_Release(LPDIRECTMUSICTHRU iface)
648 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
650 TRACE("(%p/%p)->()\n", iface, This);
652 return IDirectMusicPort_Release(&This->IDirectMusicPort_iface);
655 /* SynthPortImpl IDirectMusicThru Interface follows: */
656 static HRESULT WINAPI SynthPortImpl_IDirectMusicThru_ThruChannel(LPDIRECTMUSICTHRU iface, DWORD source_channel_group, DWORD source_channel, DWORD destination_channel_group,
657 DWORD destination_channel, LPDIRECTMUSICPORT destination_port)
659 SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicThru(iface);
661 FIXME("(%p/%p)->(%d, %d, %d, %d, %p): stub\n", iface, This, source_channel_group, source_channel, destination_channel_group, destination_channel, destination_port);
663 return S_OK;
666 static const IDirectMusicThruVtbl SynthPortImpl_DirectMusicThru_Vtbl = {
667 /*** IDirectMusicThru IUnknown part methods */
668 SynthPortImpl_IDirectMusicThru_QueryInterface,
669 SynthPortImpl_IDirectMusicThru_AddRef,
670 SynthPortImpl_IDirectMusicThru_Release,
671 /*** IDirectMusicThru methods ***/
672 SynthPortImpl_IDirectMusicThru_ThruChannel
675 HRESULT DMUSIC_CreateSynthPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device)
677 SynthPortImpl *obj;
678 HRESULT hr = E_FAIL;
679 int i;
681 TRACE("(%p,%p,%p,%p,%p,%d)\n", guid, object, unkouter, port_params, port_caps, device);
683 *object = NULL;
685 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SynthPortImpl));
686 if (!obj)
687 return E_OUTOFMEMORY;
689 obj->IDirectMusicPort_iface.lpVtbl = &SynthPortImpl_DirectMusicPort_Vtbl;
690 obj->IDirectMusicPortDownload_iface.lpVtbl = &SynthPortImpl_DirectMusicPortDownload_Vtbl;
691 obj->IDirectMusicThru_iface.lpVtbl = &SynthPortImpl_DirectMusicThru_Vtbl;
692 obj->ref = 0; /* Will be inited by QueryInterface */
693 obj->fActive = FALSE;
694 obj->params = *port_params;
695 obj->caps = *port_caps;
697 hr = DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock, (LPVOID*)&obj->pLatencyClock, NULL);
698 if (hr != S_OK)
700 HeapFree(GetProcessHeap(), 0, obj);
701 return hr;
704 if (SUCCEEDED(hr))
705 hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth, (void**)&obj->synth);
707 if (SUCCEEDED(hr))
708 hr = CoCreateInstance(&CLSID_DirectMusicSynthSink, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynthSink, (void**)&obj->synth_sink);
710 if (SUCCEEDED(hr))
711 hr = IDirectMusicSynth_SetMasterClock(obj->synth, obj->pLatencyClock);
713 if (SUCCEEDED(hr))
714 hr = IDirectMusicSynthSink_SetMasterClock(obj->synth_sink, obj->pLatencyClock);
716 if (SUCCEEDED(hr))
717 hr = IDirectMusicSynth_SetSynthSink(obj->synth, obj->synth_sink);
719 if (SUCCEEDED(hr))
720 hr = IDirectMusicSynth_Open(obj->synth, port_params);
722 if (0)
724 if (port_params->dwValidParams & DMUS_PORTPARAMS_CHANNELGROUPS) {
725 obj->nrofgroups = port_params->dwChannelGroups;
726 /* Setting default priorities */
727 for (i = 0; i < obj->nrofgroups; i++) {
728 TRACE ("Setting default channel priorities on channel group %i\n", i + 1);
729 obj->group[i].channel[0].priority = DAUD_CHAN1_DEF_VOICE_PRIORITY;
730 obj->group[i].channel[1].priority = DAUD_CHAN2_DEF_VOICE_PRIORITY;
731 obj->group[i].channel[2].priority = DAUD_CHAN3_DEF_VOICE_PRIORITY;
732 obj->group[i].channel[3].priority = DAUD_CHAN4_DEF_VOICE_PRIORITY;
733 obj->group[i].channel[4].priority = DAUD_CHAN5_DEF_VOICE_PRIORITY;
734 obj->group[i].channel[5].priority = DAUD_CHAN6_DEF_VOICE_PRIORITY;
735 obj->group[i].channel[6].priority = DAUD_CHAN7_DEF_VOICE_PRIORITY;
736 obj->group[i].channel[7].priority = DAUD_CHAN8_DEF_VOICE_PRIORITY;
737 obj->group[i].channel[8].priority = DAUD_CHAN9_DEF_VOICE_PRIORITY;
738 obj->group[i].channel[9].priority = DAUD_CHAN10_DEF_VOICE_PRIORITY;
739 obj->group[i].channel[10].priority = DAUD_CHAN11_DEF_VOICE_PRIORITY;
740 obj->group[i].channel[11].priority = DAUD_CHAN12_DEF_VOICE_PRIORITY;
741 obj->group[i].channel[12].priority = DAUD_CHAN13_DEF_VOICE_PRIORITY;
742 obj->group[i].channel[13].priority = DAUD_CHAN14_DEF_VOICE_PRIORITY;
743 obj->group[i].channel[14].priority = DAUD_CHAN15_DEF_VOICE_PRIORITY;
744 obj->group[i].channel[15].priority = DAUD_CHAN16_DEF_VOICE_PRIORITY;
749 if (SUCCEEDED(hr))
750 return IDirectMusicPort_QueryInterface((LPDIRECTMUSICPORT)obj, guid, object);
752 if (obj->synth)
753 IDirectMusicSynth_Release(obj->synth);
754 if (obj->synth_sink)
755 IDirectMusicSynthSink_Release(obj->synth_sink);
756 if (obj->pLatencyClock)
757 IReferenceClock_Release(obj->pLatencyClock);
758 HeapFree(GetProcessHeap(), 0, obj);
760 return hr;
763 HRESULT DMUSIC_CreateMidiOutPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device)
765 TRACE("(%p,%p,%p,%p,%p,%d): stub\n", guid, object, unkouter, port_params, port_caps, device);
767 return E_NOTIMPL;
770 HRESULT DMUSIC_CreateMidiInPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device)
772 TRACE("(%p,%p,%p,%p,%p,%d): stub\n", guid, object, unkouter, port_params, port_caps, device);
774 return E_NOTIMPL;