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
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
) ||
53 IsEqualIID(riid
, &IID_IDirectMusicDownloadedInstrument
) ||
54 IsEqualIID(riid
, &IID_IDirectMusicDownloadedInstrument8
))
56 IDirectMusicDownloadedInstrument_AddRef(iface
);
61 WARN("(%p, %s, %p): not found\n", iface
, debugstr_dmguid(riid
), ret_iface
);
66 static ULONG WINAPI
IDirectMusicDownloadedInstrumentImpl_AddRef(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface
)
68 IDirectMusicDownloadedInstrumentImpl
*This
= impl_from_IDirectMusicDownloadedInstrument(iface
);
69 ULONG ref
= InterlockedIncrement(&This
->ref
);
71 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
76 static ULONG WINAPI
IDirectMusicDownloadedInstrumentImpl_Release(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface
)
78 IDirectMusicDownloadedInstrumentImpl
*This
= impl_from_IDirectMusicDownloadedInstrument(iface
);
79 ULONG ref
= InterlockedDecrement(&This
->ref
);
81 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
85 HeapFree(GetProcessHeap(), 0, This
->data
);
86 HeapFree(GetProcessHeap(), 0, This
);
87 DMUSIC_UnlockModule();
93 static const IDirectMusicDownloadedInstrumentVtbl DirectMusicDownloadedInstrument_Vtbl
= {
94 IDirectMusicDownloadedInstrumentImpl_QueryInterface
,
95 IDirectMusicDownloadedInstrumentImpl_AddRef
,
96 IDirectMusicDownloadedInstrumentImpl_Release
99 static inline IDirectMusicDownloadedInstrumentImpl
* unsafe_impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument
*iface
)
103 assert(iface
->lpVtbl
== &DirectMusicDownloadedInstrument_Vtbl
);
105 return impl_from_IDirectMusicDownloadedInstrument(iface
);
108 static HRESULT
DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(IDirectMusicDownloadedInstrument
**instrument
)
110 IDirectMusicDownloadedInstrumentImpl
*object
;
112 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
116 return E_OUTOFMEMORY
;
119 object
->IDirectMusicDownloadedInstrument_iface
.lpVtbl
= &DirectMusicDownloadedInstrument_Vtbl
;
122 *instrument
= &object
->IDirectMusicDownloadedInstrument_iface
;
128 /* SynthPortImpl IDirectMusicPort IUnknown part follows: */
129 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_QueryInterface(LPDIRECTMUSICPORT iface
, REFIID riid
, LPVOID
*ret_iface
)
131 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
133 TRACE("(%p/%p)->(%s, %p)\n", iface
, This
, debugstr_dmguid(riid
), ret_iface
);
135 if (IsEqualIID (riid
, &IID_IUnknown
) ||
136 IsEqualGUID(riid
, &IID_IDirectMusicPort
) ||
137 IsEqualGUID(riid
, &IID_IDirectMusicPort8
)) {
138 *ret_iface
= &This
->IDirectMusicPort_iface
;
139 IDirectMusicPort_AddRef((LPDIRECTMUSICPORT
)*ret_iface
);
141 } else if (IsEqualGUID(riid
, &IID_IDirectMusicPortDownload
) ||
142 IsEqualGUID(riid
, &IID_IDirectMusicPortDownload8
)) {
143 *ret_iface
= &This
->IDirectMusicPortDownload_iface
;
144 IDirectMusicPortDownload_AddRef((LPDIRECTMUSICPORTDOWNLOAD
)*ret_iface
);
146 } else if (IsEqualGUID(riid
, &IID_IDirectMusicThru
) ||
147 IsEqualGUID(riid
, &IID_IDirectMusicThru8
)) {
148 *ret_iface
= &This
->IDirectMusicThru_iface
;
149 IDirectMusicThru_AddRef((LPDIRECTMUSICTHRU
)*ret_iface
);
153 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ret_iface
);
155 return E_NOINTERFACE
;
158 static ULONG WINAPI
SynthPortImpl_IDirectMusicPort_AddRef(LPDIRECTMUSICPORT iface
)
160 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
161 ULONG ref
= InterlockedIncrement(&This
->ref
);
163 TRACE("(%p)->(): new ref = %u\n", This
, ref
);
170 static ULONG WINAPI
SynthPortImpl_IDirectMusicPort_Release(LPDIRECTMUSICPORT iface
)
172 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
173 ULONG ref
= InterlockedDecrement(&This
->ref
);
175 TRACE("(%p)->(): new ref = %u\n", This
, ref
);
179 IDirectMusicSynth_Activate(This
->synth
, FALSE
);
180 IDirectMusicSynth_Close(This
->synth
);
181 IDirectMusicSynth_Release(This
->synth
);
182 IDirectMusicSynthSink_Release(This
->synth_sink
);
183 IReferenceClock_Release(This
->pLatencyClock
);
184 HeapFree(GetProcessHeap(), 0, This
);
187 DMUSIC_UnlockModule();
192 /* SynthPortImpl IDirectMusicPort interface follows: */
193 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_PlayBuffer(LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER buffer
)
195 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
201 TRACE("(%p/%p)->(%p)\n", iface
, This
, buffer
);
206 hr
= IDirectMusicBuffer_GetStartTime(buffer
, &time
);
209 hr
= IDirectMusicBuffer_GetRawBufferPtr(buffer
, &data
);
212 hr
= IDirectMusicBuffer_GetUsedBytes(buffer
, &size
);
215 hr
= IDirectMusicSynth_PlayBuffer(This
->synth
, time
, data
, size
);
220 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle(LPDIRECTMUSICPORT iface
, HANDLE event
)
222 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
224 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, event
);
229 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_Read(LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER buffer
)
231 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
233 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, buffer
);
238 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_DownloadInstrument(LPDIRECTMUSICPORT iface
, IDirectMusicInstrument
* instrument
, IDirectMusicDownloadedInstrument
** downloaded_instrument
, DMUS_NOTERANGE
* note_ranges
, DWORD num_note_ranges
)
240 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
241 IDirectMusicInstrumentImpl
*instrument_object
;
245 DMUS_DOWNLOADINFO
*info
;
246 DMUS_OFFSETTABLE
*offset_table
;
247 DMUS_INSTRUMENT
*instrument_info
;
254 TRACE("(%p/%p)->(%p, %p, %p, %d)\n", iface
, This
, instrument
, downloaded_instrument
, note_ranges
, num_note_ranges
);
256 if (!instrument
|| !downloaded_instrument
|| (num_note_ranges
&& !note_ranges
))
259 instrument_object
= impl_from_IDirectMusicInstrument(instrument
);
261 nb_regions
= instrument_object
->header
.cRegions
;
262 size
= sizeof(DMUS_DOWNLOADINFO
) + sizeof(ULONG
) * (1 + nb_regions
) + sizeof(DMUS_INSTRUMENT
) + sizeof(DMUS_REGION
) * nb_regions
;
264 data
= HeapAlloc(GetProcessHeap(), 0, size
);
266 return E_OUTOFMEMORY
;
268 info
= (DMUS_DOWNLOADINFO
*)data
;
269 offset_table
= (DMUS_OFFSETTABLE
*)(data
+ sizeof(DMUS_DOWNLOADINFO
));
270 offset
= sizeof(DMUS_DOWNLOADINFO
) + sizeof(ULONG
) * (1 + nb_regions
);
272 info
->dwDLType
= DMUS_DOWNLOADINFO_INSTRUMENT2
;
274 info
->dwNumOffsetTableEntries
= 1 + instrument_object
->header
.cRegions
;
277 offset_table
->ulOffsetTable
[0] = offset
;
278 instrument_info
= (DMUS_INSTRUMENT
*)(data
+ offset
);
279 offset
+= sizeof(DMUS_INSTRUMENT
);
280 instrument_info
->ulPatch
= MIDILOCALE2Patch(&instrument_object
->header
.Locale
);
281 instrument_info
->ulFirstRegionIdx
= 1;
282 instrument_info
->ulGlobalArtIdx
= 0; /* FIXME */
283 instrument_info
->ulFirstExtCkIdx
= 0; /* FIXME */
284 instrument_info
->ulCopyrightIdx
= 0; /* FIXME */
285 instrument_info
->ulFlags
= 0; /* FIXME */
287 for (i
= 0; i
< nb_regions
; i
++)
289 DMUS_REGION
*region
= (DMUS_REGION
*)(data
+ offset
);
291 offset_table
->ulOffsetTable
[1 + i
] = offset
;
292 offset
+= sizeof(DMUS_REGION
);
293 region
->RangeKey
= instrument_object
->regions
[i
].header
.RangeKey
;
294 region
->RangeVelocity
= instrument_object
->regions
[i
].header
.RangeVelocity
;
295 region
->fusOptions
= instrument_object
->regions
[i
].header
.fusOptions
;
296 region
->usKeyGroup
= instrument_object
->regions
[i
].header
.usKeyGroup
;
297 region
->ulRegionArtIdx
= 0; /* FIXME */
298 region
->ulNextRegionIdx
= i
!= (nb_regions
- 1) ? (i
+ 2) : 0;
299 region
->ulFirstExtCkIdx
= 0; /* FIXME */
300 region
->WaveLink
= instrument_object
->regions
[i
].wave_link
;
301 region
->WSMP
= instrument_object
->regions
[i
].wave_sample
;
302 region
->WLOOP
[0] = instrument_object
->regions
[i
].wave_loop
;
305 ret
= IDirectMusicSynth8_Download(This
->synth
, &download
, (VOID
*)data
, &free
);
308 ret
= DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(downloaded_instrument
);
312 IDirectMusicDownloadedInstrumentImpl
*downloaded_object
= impl_from_IDirectMusicDownloadedInstrument(*downloaded_instrument
);
314 downloaded_object
->data
= data
;
315 downloaded_object
->downloaded
= TRUE
;
318 *downloaded_instrument
= NULL
;
319 HeapFree(GetProcessHeap(), 0, data
);
324 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_UnloadInstrument(LPDIRECTMUSICPORT iface
, IDirectMusicDownloadedInstrument
*downloaded_instrument
)
326 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
327 IDirectMusicDownloadedInstrumentImpl
*downloaded_object
= unsafe_impl_from_IDirectMusicDownloadedInstrument(downloaded_instrument
);
329 TRACE("(%p/%p)->(%p)\n", iface
, This
, downloaded_instrument
);
331 if (!downloaded_instrument
)
334 if (!downloaded_object
->downloaded
)
335 return DMUS_E_NOT_DOWNLOADED_TO_PORT
;
337 HeapFree(GetProcessHeap(), 0, downloaded_object
->data
);
338 downloaded_object
->data
= NULL
;
339 downloaded_object
->downloaded
= FALSE
;
344 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetLatencyClock(LPDIRECTMUSICPORT iface
, IReferenceClock
** clock
)
346 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
348 TRACE("(%p/%p)->(%p)\n", iface
, This
, clock
);
350 *clock
= This
->pLatencyClock
;
351 IReferenceClock_AddRef(*clock
);
356 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetRunningStats(LPDIRECTMUSICPORT iface
, LPDMUS_SYNTHSTATS stats
)
358 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
360 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, stats
);
365 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_Compact(LPDIRECTMUSICPORT iface
)
367 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
369 FIXME("(%p/%p)->(): stub\n", iface
, This
);
374 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetCaps(LPDIRECTMUSICPORT iface
, LPDMUS_PORTCAPS port_caps
)
376 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
378 TRACE("(%p/%p)->(%p)\n", iface
, This
, port_caps
);
380 *port_caps
= This
->caps
;
385 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_DeviceIoControl(LPDIRECTMUSICPORT iface
, DWORD io_control_code
, LPVOID in_buffer
, DWORD in_buffer_size
,
386 LPVOID out_buffer
, DWORD out_buffer_size
, LPDWORD bytes_returned
, LPOVERLAPPED overlapped
)
388 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
390 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
);
395 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_SetNumChannelGroups(LPDIRECTMUSICPORT iface
, DWORD channel_groups
)
397 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
399 FIXME("(%p/%p)->(%d): semi-stub\n", iface
, This
, channel_groups
);
401 This
->nrofgroups
= channel_groups
;
406 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetNumChannelGroups(LPDIRECTMUSICPORT iface
, LPDWORD channel_groups
)
408 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
410 TRACE("(%p/%p)->(%p)\n", iface
, This
, channel_groups
);
412 *channel_groups
= This
->nrofgroups
;
417 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_Activate(LPDIRECTMUSICPORT iface
, BOOL active
)
419 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
421 TRACE("(%p/%p)->(%d)\n", iface
, This
, active
);
423 This
->fActive
= active
;
428 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_SetChannelPriority(LPDIRECTMUSICPORT iface
, DWORD channel_group
, DWORD channel
, DWORD priority
)
430 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
432 FIXME("(%p/%p)->(%d, %d, %d): semi-stub\n", iface
, This
, channel_group
, channel
, priority
);
436 WARN("isn't there supposed to be 16 channels (no. %d requested)?! (faking as it is ok)\n", channel
);
437 /*return E_INVALIDARG;*/
443 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetChannelPriority(LPDIRECTMUSICPORT iface
, DWORD channel_group
, DWORD channel
, LPDWORD priority
)
445 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
447 TRACE("(%p/%p)->(%u, %u, %p)\n", iface
, This
, channel_group
, channel
, priority
);
449 *priority
= This
->group
[channel_group
- 1].channel
[channel
].priority
;
454 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_SetDirectSound(LPDIRECTMUSICPORT iface
, LPDIRECTSOUND direct_sound
, LPDIRECTSOUNDBUFFER direct_sound_buffer
)
456 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
458 FIXME("(%p/%p)->(%p, %p): stub\n", iface
, This
, direct_sound
, direct_sound_buffer
);
463 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetFormat(LPDIRECTMUSICPORT iface
, LPWAVEFORMATEX pWaveFormatEx
, LPDWORD pdwWaveFormatExSize
, LPDWORD pdwBufferSize
)
465 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
467 FIXME("(%p, %p, %p, %p): stub\n", This
, pWaveFormatEx
, pdwWaveFormatExSize
, pdwBufferSize
);
469 if (pWaveFormatEx
== NULL
)
471 if (pdwWaveFormatExSize
)
472 *pdwWaveFormatExSize
= sizeof(format
);
478 if (pdwWaveFormatExSize
== NULL
)
481 /* Just fill this in with something that will not crash Direct Sound for now. */
482 /* It won't be used anyway until Performances are completed */
483 format
.wFormatTag
= WAVE_FORMAT_PCM
;
484 format
.nChannels
= 2; /* This->params.dwAudioChannels; */
485 format
.nSamplesPerSec
= 44100; /* This->params.dwSampleRate; */
486 format
.wBitsPerSample
= 16; /* FIXME: check this */
487 format
.nBlockAlign
= (format
.wBitsPerSample
* format
.nChannels
) / 8;
488 format
.nAvgBytesPerSec
= format
.nSamplesPerSec
* format
.nBlockAlign
;
491 if (*pdwWaveFormatExSize
>= sizeof(format
))
493 CopyMemory(pWaveFormatEx
, &format
, min(sizeof(format
), *pdwWaveFormatExSize
));
494 *pdwWaveFormatExSize
= sizeof(format
); /* FIXME check if this is set */
497 return E_POINTER
; /* FIXME find right error */
501 *pdwBufferSize
= 44100 * 2 * 2;
508 static const IDirectMusicPortVtbl SynthPortImpl_DirectMusicPort_Vtbl
= {
509 /**** IDirectMusicPort IUnknown part methods ***/
510 SynthPortImpl_IDirectMusicPort_QueryInterface
,
511 SynthPortImpl_IDirectMusicPort_AddRef
,
512 SynthPortImpl_IDirectMusicPort_Release
,
513 /**** IDirectMusicPort methods ***/
514 SynthPortImpl_IDirectMusicPort_PlayBuffer
,
515 SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle
,
516 SynthPortImpl_IDirectMusicPort_Read
,
517 SynthPortImpl_IDirectMusicPort_DownloadInstrument
,
518 SynthPortImpl_IDirectMusicPort_UnloadInstrument
,
519 SynthPortImpl_IDirectMusicPort_GetLatencyClock
,
520 SynthPortImpl_IDirectMusicPort_GetRunningStats
,
521 SynthPortImpl_IDirectMusicPort_Compact
,
522 SynthPortImpl_IDirectMusicPort_GetCaps
,
523 SynthPortImpl_IDirectMusicPort_DeviceIoControl
,
524 SynthPortImpl_IDirectMusicPort_SetNumChannelGroups
,
525 SynthPortImpl_IDirectMusicPort_GetNumChannelGroups
,
526 SynthPortImpl_IDirectMusicPort_Activate
,
527 SynthPortImpl_IDirectMusicPort_SetChannelPriority
,
528 SynthPortImpl_IDirectMusicPort_GetChannelPriority
,
529 SynthPortImpl_IDirectMusicPort_SetDirectSound
,
530 SynthPortImpl_IDirectMusicPort_GetFormat
533 /* SynthPortImpl IDirectMusicPortDownload IUnknown part follows: */
534 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_QueryInterface(LPDIRECTMUSICPORTDOWNLOAD iface
, REFIID riid
, LPVOID
*ret_iface
)
536 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
538 TRACE("(%p/%p)->(%s, %p)\n", iface
, This
, debugstr_dmguid(riid
), ret_iface
);
540 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
543 static ULONG WINAPI
SynthPortImpl_IDirectMusicPortDownload_AddRef (LPDIRECTMUSICPORTDOWNLOAD iface
)
545 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
547 TRACE("(%p/%p)->()\n", iface
, This
);
549 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
552 static ULONG WINAPI
SynthPortImpl_IDirectMusicPortDownload_Release(LPDIRECTMUSICPORTDOWNLOAD iface
)
554 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
556 TRACE("(%p/%p)->()\n", iface
, This
);
558 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
561 /* SynthPortImpl IDirectMusicPortDownload Interface follows: */
562 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_GetBuffer(LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD DLId
, IDirectMusicDownload
** IDMDownload
)
564 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
566 FIXME("(%p/%p)->(%u, %p): stub\n", iface
, This
, DLId
, IDMDownload
);
571 return DMUSIC_CreateDirectMusicDownloadImpl(&IID_IDirectMusicDownload
, (LPVOID
*)IDMDownload
, NULL
);
574 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer(LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD size
, IDirectMusicDownload
** IDMDownload
)
576 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
578 FIXME("(%p/%p)->(%u, %p): stub\n", iface
, This
, size
, IDMDownload
);
583 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_GetDLId(LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD
* start_DLId
, DWORD count
)
585 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
587 FIXME("(%p/%p)->(%p, %u): stub\n", iface
, This
, start_DLId
, count
);
592 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_GetAppend (LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD
* append
)
594 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
596 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, append
);
601 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_Download(LPDIRECTMUSICPORTDOWNLOAD iface
, IDirectMusicDownload
* IDMDownload
)
603 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
605 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, IDMDownload
);
610 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_Unload(LPDIRECTMUSICPORTDOWNLOAD iface
, IDirectMusicDownload
* IDMDownload
)
612 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
614 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, IDMDownload
);
619 static const IDirectMusicPortDownloadVtbl SynthPortImpl_DirectMusicPortDownload_Vtbl
= {
620 /*** IDirectMusicPortDownload IUnknown part methods ***/
621 SynthPortImpl_IDirectMusicPortDownload_QueryInterface
,
622 SynthPortImpl_IDirectMusicPortDownload_AddRef
,
623 SynthPortImpl_IDirectMusicPortDownload_Release
,
624 /*** IDirectMusicPortDownload methods ***/
625 SynthPortImpl_IDirectMusicPortDownload_GetBuffer
,
626 SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer
,
627 SynthPortImpl_IDirectMusicPortDownload_GetDLId
,
628 SynthPortImpl_IDirectMusicPortDownload_GetAppend
,
629 SynthPortImpl_IDirectMusicPortDownload_Download
,
630 SynthPortImpl_IDirectMusicPortDownload_Unload
633 /* SynthPortImpl IDirectMusicThru IUnknown part follows: */
634 static HRESULT WINAPI
SynthPortImpl_IDirectMusicThru_QueryInterface(LPDIRECTMUSICTHRU iface
, REFIID riid
, LPVOID
*ret_iface
)
636 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
638 TRACE("(%p/%p)->(%s, %p)\n", iface
, This
, debugstr_dmguid(riid
), ret_iface
);
640 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
643 static ULONG WINAPI
SynthPortImpl_IDirectMusicThru_AddRef(LPDIRECTMUSICTHRU iface
)
645 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
647 TRACE("(%p/%p)->()\n", iface
, This
);
649 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
652 static ULONG WINAPI
SynthPortImpl_IDirectMusicThru_Release(LPDIRECTMUSICTHRU iface
)
654 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
656 TRACE("(%p/%p)->()\n", iface
, This
);
658 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
661 /* SynthPortImpl IDirectMusicThru Interface follows: */
662 static HRESULT WINAPI
SynthPortImpl_IDirectMusicThru_ThruChannel(LPDIRECTMUSICTHRU iface
, DWORD source_channel_group
, DWORD source_channel
, DWORD destination_channel_group
,
663 DWORD destination_channel
, LPDIRECTMUSICPORT destination_port
)
665 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
667 FIXME("(%p/%p)->(%d, %d, %d, %d, %p): stub\n", iface
, This
, source_channel_group
, source_channel
, destination_channel_group
, destination_channel
, destination_port
);
672 static const IDirectMusicThruVtbl SynthPortImpl_DirectMusicThru_Vtbl
= {
673 /*** IDirectMusicThru IUnknown part methods */
674 SynthPortImpl_IDirectMusicThru_QueryInterface
,
675 SynthPortImpl_IDirectMusicThru_AddRef
,
676 SynthPortImpl_IDirectMusicThru_Release
,
677 /*** IDirectMusicThru methods ***/
678 SynthPortImpl_IDirectMusicThru_ThruChannel
681 HRESULT
DMUSIC_CreateSynthPortImpl(LPCGUID guid
, LPVOID
*object
, LPUNKNOWN unkouter
, LPDMUS_PORTPARAMS port_params
, LPDMUS_PORTCAPS port_caps
, DWORD device
)
687 TRACE("(%p,%p,%p,%p,%p,%d)\n", guid
, object
, unkouter
, port_params
, port_caps
, device
);
691 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SynthPortImpl
));
693 return E_OUTOFMEMORY
;
695 obj
->IDirectMusicPort_iface
.lpVtbl
= &SynthPortImpl_DirectMusicPort_Vtbl
;
696 obj
->IDirectMusicPortDownload_iface
.lpVtbl
= &SynthPortImpl_DirectMusicPortDownload_Vtbl
;
697 obj
->IDirectMusicThru_iface
.lpVtbl
= &SynthPortImpl_DirectMusicThru_Vtbl
;
698 obj
->ref
= 0; /* Will be inited by QueryInterface */
699 obj
->fActive
= FALSE
;
700 obj
->params
= *port_params
;
701 obj
->caps
= *port_caps
;
703 hr
= DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock
, (LPVOID
*)&obj
->pLatencyClock
, NULL
);
706 HeapFree(GetProcessHeap(), 0, obj
);
711 hr
= CoCreateInstance(&CLSID_DirectMusicSynth
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynth
, (void**)&obj
->synth
);
714 hr
= CoCreateInstance(&CLSID_DirectMusicSynthSink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynthSink
, (void**)&obj
->synth_sink
);
717 hr
= IDirectMusicSynth_SetMasterClock(obj
->synth
, obj
->pLatencyClock
);
720 hr
= IDirectMusicSynthSink_SetMasterClock(obj
->synth_sink
, obj
->pLatencyClock
);
723 hr
= IDirectMusicSynth_SetSynthSink(obj
->synth
, obj
->synth_sink
);
726 hr
= IDirectMusicSynth_Open(obj
->synth
, port_params
);
730 if (port_params
->dwValidParams
& DMUS_PORTPARAMS_CHANNELGROUPS
) {
731 obj
->nrofgroups
= port_params
->dwChannelGroups
;
732 /* Setting default priorities */
733 for (i
= 0; i
< obj
->nrofgroups
; i
++) {
734 TRACE ("Setting default channel priorities on channel group %i\n", i
+ 1);
735 obj
->group
[i
].channel
[0].priority
= DAUD_CHAN1_DEF_VOICE_PRIORITY
;
736 obj
->group
[i
].channel
[1].priority
= DAUD_CHAN2_DEF_VOICE_PRIORITY
;
737 obj
->group
[i
].channel
[2].priority
= DAUD_CHAN3_DEF_VOICE_PRIORITY
;
738 obj
->group
[i
].channel
[3].priority
= DAUD_CHAN4_DEF_VOICE_PRIORITY
;
739 obj
->group
[i
].channel
[4].priority
= DAUD_CHAN5_DEF_VOICE_PRIORITY
;
740 obj
->group
[i
].channel
[5].priority
= DAUD_CHAN6_DEF_VOICE_PRIORITY
;
741 obj
->group
[i
].channel
[6].priority
= DAUD_CHAN7_DEF_VOICE_PRIORITY
;
742 obj
->group
[i
].channel
[7].priority
= DAUD_CHAN8_DEF_VOICE_PRIORITY
;
743 obj
->group
[i
].channel
[8].priority
= DAUD_CHAN9_DEF_VOICE_PRIORITY
;
744 obj
->group
[i
].channel
[9].priority
= DAUD_CHAN10_DEF_VOICE_PRIORITY
;
745 obj
->group
[i
].channel
[10].priority
= DAUD_CHAN11_DEF_VOICE_PRIORITY
;
746 obj
->group
[i
].channel
[11].priority
= DAUD_CHAN12_DEF_VOICE_PRIORITY
;
747 obj
->group
[i
].channel
[12].priority
= DAUD_CHAN13_DEF_VOICE_PRIORITY
;
748 obj
->group
[i
].channel
[13].priority
= DAUD_CHAN14_DEF_VOICE_PRIORITY
;
749 obj
->group
[i
].channel
[14].priority
= DAUD_CHAN15_DEF_VOICE_PRIORITY
;
750 obj
->group
[i
].channel
[15].priority
= DAUD_CHAN16_DEF_VOICE_PRIORITY
;
756 return IDirectMusicPort_QueryInterface((LPDIRECTMUSICPORT
)obj
, guid
, object
);
759 IDirectMusicSynth_Release(obj
->synth
);
761 IDirectMusicSynthSink_Release(obj
->synth_sink
);
762 if (obj
->pLatencyClock
)
763 IReferenceClock_Release(obj
->pLatencyClock
);
764 HeapFree(GetProcessHeap(), 0, obj
);
769 HRESULT
DMUSIC_CreateMidiOutPortImpl(LPCGUID guid
, LPVOID
*object
, LPUNKNOWN unkouter
, LPDMUS_PORTPARAMS port_params
, LPDMUS_PORTCAPS port_caps
, DWORD device
)
771 TRACE("(%p,%p,%p,%p,%p,%d): stub\n", guid
, object
, unkouter
, port_params
, port_caps
, device
);
776 HRESULT
DMUSIC_CreateMidiInPortImpl(LPCGUID guid
, LPVOID
*object
, LPUNKNOWN unkouter
, LPDMUS_PORTPARAMS port_params
, LPDMUS_PORTCAPS port_caps
, DWORD device
)
778 TRACE("(%p,%p,%p,%p,%p,%d): stub\n", guid
, object
, unkouter
, port_params
, port_caps
, device
);