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 #include "wine/heap.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(dmusic
);
30 IDirectMusicPort IDirectMusicPort_iface
;
31 IDirectMusicPortDownload IDirectMusicPortDownload_iface
;
32 IDirectMusicThru IDirectMusicThru_iface
;
33 IKsControl IKsControl_iface
;
35 IDirectMusic8Impl
*parent
;
37 IDirectSoundBuffer
*dsbuffer
;
38 IDirectMusicSynth
*synth
;
39 IDirectMusicSynthSink
*synth_sink
;
41 DMUS_PORTPARAMS params
;
43 DMUSIC_PRIVATE_CHANNEL_GROUP group
[1];
46 static inline IDirectMusicDownloadedInstrumentImpl
* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument
*iface
)
48 return CONTAINING_RECORD(iface
, IDirectMusicDownloadedInstrumentImpl
, IDirectMusicDownloadedInstrument_iface
);
51 static inline struct synth_port
*synth_from_IDirectMusicPort(IDirectMusicPort
*iface
)
53 return CONTAINING_RECORD(iface
, struct synth_port
, IDirectMusicPort_iface
);
56 static inline struct synth_port
*synth_from_IDirectMusicPortDownload(IDirectMusicPortDownload
*iface
)
58 return CONTAINING_RECORD(iface
, struct synth_port
, IDirectMusicPortDownload_iface
);
61 static inline struct synth_port
*synth_from_IDirectMusicThru(IDirectMusicThru
*iface
)
63 return CONTAINING_RECORD(iface
, struct synth_port
, IDirectMusicThru_iface
);
66 static inline struct synth_port
*synth_from_IKsControl(IKsControl
*iface
)
68 return CONTAINING_RECORD(iface
, struct synth_port
, IKsControl_iface
);
71 /* IDirectMusicDownloadedInstrument IUnknown part follows: */
72 static HRESULT WINAPI
IDirectMusicDownloadedInstrumentImpl_QueryInterface(IDirectMusicDownloadedInstrument
*iface
, REFIID riid
, VOID
**ret_iface
)
74 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
76 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDirectMusicDownloadedInstrument
))
78 IDirectMusicDownloadedInstrument_AddRef(iface
);
83 WARN("(%p, %s, %p): not found\n", iface
, debugstr_dmguid(riid
), ret_iface
);
88 static ULONG WINAPI
IDirectMusicDownloadedInstrumentImpl_AddRef(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface
)
90 IDirectMusicDownloadedInstrumentImpl
*This
= impl_from_IDirectMusicDownloadedInstrument(iface
);
91 ULONG ref
= InterlockedIncrement(&This
->ref
);
93 TRACE("(%p): new ref = %lu\n", iface
, ref
);
98 static ULONG WINAPI
IDirectMusicDownloadedInstrumentImpl_Release(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface
)
100 IDirectMusicDownloadedInstrumentImpl
*This
= impl_from_IDirectMusicDownloadedInstrument(iface
);
101 ULONG ref
= InterlockedDecrement(&This
->ref
);
103 TRACE("(%p): new ref = %lu\n", iface
, ref
);
107 HeapFree(GetProcessHeap(), 0, This
->data
);
108 HeapFree(GetProcessHeap(), 0, This
);
109 DMUSIC_UnlockModule();
115 static const IDirectMusicDownloadedInstrumentVtbl DirectMusicDownloadedInstrument_Vtbl
= {
116 IDirectMusicDownloadedInstrumentImpl_QueryInterface
,
117 IDirectMusicDownloadedInstrumentImpl_AddRef
,
118 IDirectMusicDownloadedInstrumentImpl_Release
121 static inline IDirectMusicDownloadedInstrumentImpl
* unsafe_impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument
*iface
)
125 assert(iface
->lpVtbl
== &DirectMusicDownloadedInstrument_Vtbl
);
127 return impl_from_IDirectMusicDownloadedInstrument(iface
);
130 static HRESULT
DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(IDirectMusicDownloadedInstrument
**instrument
)
132 IDirectMusicDownloadedInstrumentImpl
*object
;
134 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
138 return E_OUTOFMEMORY
;
141 object
->IDirectMusicDownloadedInstrument_iface
.lpVtbl
= &DirectMusicDownloadedInstrument_Vtbl
;
144 *instrument
= &object
->IDirectMusicDownloadedInstrument_iface
;
150 static HRESULT WINAPI
synth_port_QueryInterface(IDirectMusicPort
*iface
, REFIID riid
, void **ret_iface
)
152 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
154 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
156 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirectMusicPort
))
157 *ret_iface
= &This
->IDirectMusicPort_iface
;
158 else if (IsEqualGUID(riid
, &IID_IDirectMusicPortDownload
))
159 *ret_iface
= &This
->IDirectMusicPortDownload_iface
;
160 else if (IsEqualGUID(riid
, &IID_IDirectMusicThru
))
161 *ret_iface
= &This
->IDirectMusicThru_iface
;
162 else if (IsEqualGUID(riid
, &IID_IKsControl
))
163 *ret_iface
= &This
->IKsControl_iface
;
165 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ret_iface
);
167 return E_NOINTERFACE
;
170 IUnknown_AddRef((IUnknown
*)*ret_iface
);
175 static ULONG WINAPI
synth_port_AddRef(IDirectMusicPort
*iface
)
177 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
178 ULONG ref
= InterlockedIncrement(&This
->ref
);
180 TRACE("(%p): new ref = %lu\n", This
, ref
);
187 static ULONG WINAPI
synth_port_Release(IDirectMusicPort
*iface
)
189 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
190 ULONG ref
= InterlockedDecrement(&This
->ref
);
192 TRACE("(%p): new ref = %lu\n", This
, ref
);
196 dmusic_remove_port(This
->parent
, iface
);
197 IDirectMusicSynthSink_Release(This
->synth_sink
);
198 IDirectMusicSynth_Activate(This
->synth
, FALSE
);
199 IDirectMusicSynth_Close(This
->synth
);
200 IDirectMusicSynth_Release(This
->synth
);
202 IDirectSoundBuffer_Release(This
->dsbuffer
);
204 IDirectSound_Release(This
->dsound
);
205 HeapFree(GetProcessHeap(), 0, This
);
208 DMUSIC_UnlockModule();
213 static HRESULT WINAPI
synth_port_PlayBuffer(IDirectMusicPort
*iface
, IDirectMusicBuffer
*buffer
)
215 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
221 TRACE("(%p, %p)\n", iface
, buffer
);
226 hr
= IDirectMusicBuffer_GetStartTime(buffer
, &time
);
229 hr
= IDirectMusicBuffer_GetRawBufferPtr(buffer
, &data
);
232 hr
= IDirectMusicBuffer_GetUsedBytes(buffer
, &size
);
235 hr
= IDirectMusicSynth_PlayBuffer(This
->synth
, time
, data
, size
);
240 static HRESULT WINAPI
synth_port_SetReadNotificationHandle(IDirectMusicPort
*iface
, HANDLE event
)
242 TRACE("(%p, %p): method not implemented\n", iface
, event
);
246 static HRESULT WINAPI
synth_port_Read(IDirectMusicPort
*iface
, IDirectMusicBuffer
*buffer
)
248 TRACE("(%p, %p): method not implemented\n", iface
, buffer
);
252 static HRESULT WINAPI
synth_port_DownloadInstrument(IDirectMusicPort
*iface
, IDirectMusicInstrument
*instrument
,
253 IDirectMusicDownloadedInstrument
**downloaded_instrument
, DMUS_NOTERANGE
*note_ranges
, DWORD num_note_ranges
)
255 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
256 IDirectMusicInstrumentImpl
*instrument_object
;
260 DMUS_DOWNLOADINFO
*info
;
261 DMUS_OFFSETTABLE
*offset_table
;
262 DMUS_INSTRUMENT
*instrument_info
;
269 TRACE("(%p, %p, %p, %p, %ld)\n", iface
, instrument
, downloaded_instrument
, note_ranges
, num_note_ranges
);
271 if (!instrument
|| !downloaded_instrument
|| (num_note_ranges
&& !note_ranges
))
274 instrument_object
= impl_from_IDirectMusicInstrument(instrument
);
276 nb_regions
= instrument_object
->header
.cRegions
;
277 size
= sizeof(DMUS_DOWNLOADINFO
) + sizeof(ULONG
) * (1 + nb_regions
) + sizeof(DMUS_INSTRUMENT
) + sizeof(DMUS_REGION
) * nb_regions
;
279 data
= HeapAlloc(GetProcessHeap(), 0, size
);
281 return E_OUTOFMEMORY
;
283 info
= (DMUS_DOWNLOADINFO
*)data
;
284 offset_table
= (DMUS_OFFSETTABLE
*)(data
+ sizeof(DMUS_DOWNLOADINFO
));
285 offset
= sizeof(DMUS_DOWNLOADINFO
) + sizeof(ULONG
) * (1 + nb_regions
);
287 info
->dwDLType
= DMUS_DOWNLOADINFO_INSTRUMENT2
;
289 info
->dwNumOffsetTableEntries
= 1 + instrument_object
->header
.cRegions
;
292 offset_table
->ulOffsetTable
[0] = offset
;
293 instrument_info
= (DMUS_INSTRUMENT
*)(data
+ offset
);
294 offset
+= sizeof(DMUS_INSTRUMENT
);
295 instrument_info
->ulPatch
= MIDILOCALE2Patch(&instrument_object
->header
.Locale
);
296 instrument_info
->ulFirstRegionIdx
= 1;
297 instrument_info
->ulGlobalArtIdx
= 0; /* FIXME */
298 instrument_info
->ulFirstExtCkIdx
= 0; /* FIXME */
299 instrument_info
->ulCopyrightIdx
= 0; /* FIXME */
300 instrument_info
->ulFlags
= 0; /* FIXME */
302 for (i
= 0; i
< nb_regions
; i
++)
304 DMUS_REGION
*region
= (DMUS_REGION
*)(data
+ offset
);
306 offset_table
->ulOffsetTable
[1 + i
] = offset
;
307 offset
+= sizeof(DMUS_REGION
);
308 region
->RangeKey
= instrument_object
->regions
[i
].header
.RangeKey
;
309 region
->RangeVelocity
= instrument_object
->regions
[i
].header
.RangeVelocity
;
310 region
->fusOptions
= instrument_object
->regions
[i
].header
.fusOptions
;
311 region
->usKeyGroup
= instrument_object
->regions
[i
].header
.usKeyGroup
;
312 region
->ulRegionArtIdx
= 0; /* FIXME */
313 region
->ulNextRegionIdx
= i
!= (nb_regions
- 1) ? (i
+ 2) : 0;
314 region
->ulFirstExtCkIdx
= 0; /* FIXME */
315 region
->WaveLink
= instrument_object
->regions
[i
].wave_link
;
316 region
->WSMP
= instrument_object
->regions
[i
].wave_sample
;
317 region
->WLOOP
[0] = instrument_object
->regions
[i
].wave_loop
;
320 ret
= IDirectMusicSynth8_Download(This
->synth
, &download
, (VOID
*)data
, &free
);
323 ret
= DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(downloaded_instrument
);
327 IDirectMusicDownloadedInstrumentImpl
*downloaded_object
= impl_from_IDirectMusicDownloadedInstrument(*downloaded_instrument
);
329 downloaded_object
->data
= data
;
330 downloaded_object
->downloaded
= TRUE
;
333 *downloaded_instrument
= NULL
;
334 HeapFree(GetProcessHeap(), 0, data
);
339 static HRESULT WINAPI
synth_port_UnloadInstrument(IDirectMusicPort
*iface
,
340 IDirectMusicDownloadedInstrument
*downloaded_instrument
)
342 IDirectMusicDownloadedInstrumentImpl
*downloaded_object
= unsafe_impl_from_IDirectMusicDownloadedInstrument(downloaded_instrument
);
344 TRACE("(%p, %p)\n", iface
, downloaded_instrument
);
346 if (!downloaded_instrument
)
349 if (!downloaded_object
->downloaded
)
350 return DMUS_E_NOT_DOWNLOADED_TO_PORT
;
352 HeapFree(GetProcessHeap(), 0, downloaded_object
->data
);
353 downloaded_object
->data
= NULL
;
354 downloaded_object
->downloaded
= FALSE
;
359 static HRESULT WINAPI
synth_port_GetLatencyClock(IDirectMusicPort
*iface
, IReferenceClock
**clock
)
361 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
363 TRACE("(%p, %p)\n", iface
, clock
);
365 return IDirectMusicSynth8_GetLatencyClock(This
->synth
, clock
);
368 static HRESULT WINAPI
synth_port_GetRunningStats(IDirectMusicPort
*iface
, DMUS_SYNTHSTATS
*stats
)
370 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
372 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, stats
);
377 static HRESULT WINAPI
synth_port_Compact(IDirectMusicPort
*iface
)
379 TRACE("(%p): method not implemented\n", iface
);
383 static HRESULT WINAPI
synth_port_GetCaps(IDirectMusicPort
*iface
, DMUS_PORTCAPS
*port_caps
)
385 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
387 TRACE("(%p, %p)\n", iface
, port_caps
);
389 return IDirectMusicSynth_GetPortCaps(This
->synth
, port_caps
);
392 static HRESULT WINAPI
synth_port_DeviceIoControl(IDirectMusicPort
*iface
, DWORD io_control_code
,
393 void *in_buffer
, DWORD in_buffer_size
, void *out_buffer
, DWORD out_buffer_size
,
394 DWORD
*bytes_returned
, OVERLAPPED
*overlapped
)
396 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
398 FIXME("(%p/%p, %ld, %p, %ld, %p, %ld, %p, %p): stub\n", iface
, This
, io_control_code
, in_buffer
, in_buffer_size
, out_buffer
, out_buffer_size
, bytes_returned
, overlapped
);
403 static HRESULT WINAPI
synth_port_SetNumChannelGroups(IDirectMusicPort
*iface
, DWORD channel_groups
)
405 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
407 FIXME("(%p, %ld): semi-stub\n", iface
, channel_groups
);
409 This
->nrofgroups
= channel_groups
;
414 static HRESULT WINAPI
synth_port_GetNumChannelGroups(IDirectMusicPort
*iface
, DWORD
*channel_groups
)
416 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
418 TRACE("(%p, %p)\n", iface
, channel_groups
);
420 *channel_groups
= This
->nrofgroups
;
425 static HRESULT WINAPI
synth_port_Activate(IDirectMusicPort
*iface
, BOOL active
)
427 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
429 FIXME("(%p/%p)->(%d): semi-stub\n", iface
, This
, active
);
431 if (This
->active
== active
)
435 /* Acquire the dsound */
437 IDirectSound_AddRef(This
->parent
->dsound
);
438 This
->dsound
= This
->parent
->dsound
;
440 IDirectSound_AddRef(This
->dsound
);
442 /* Release the dsound */
443 IDirectSound_Release(This
->dsound
);
444 IDirectSound_Release(This
->parent
->dsound
);
445 if (This
->dsound
== This
->parent
->dsound
)
449 This
->active
= active
;
454 static HRESULT WINAPI
synth_port_SetChannelPriority(IDirectMusicPort
*iface
, DWORD channel_group
,
455 DWORD channel
, DWORD priority
)
457 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
459 FIXME("(%p/%p, %ld, %ld, %ld): semi-stub\n", iface
, This
, channel_group
, channel
, priority
);
463 WARN("isn't there supposed to be 16 channels (no. %ld requested)?! (faking as it is ok)\n", channel
);
464 /*return E_INVALIDARG;*/
470 static HRESULT WINAPI
synth_port_GetChannelPriority(IDirectMusicPort
*iface
, DWORD channel_group
,
471 DWORD channel
, DWORD
*priority
)
473 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
475 TRACE("(%p, %lu, %lu, %p)\n", iface
, channel_group
, channel
, priority
);
477 *priority
= This
->group
[channel_group
- 1].channel
[channel
].priority
;
482 static HRESULT WINAPI
synth_port_SetDirectSound(IDirectMusicPort
*iface
, IDirectSound
*dsound
,
483 IDirectSoundBuffer
*dsbuffer
)
485 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
487 FIXME("(%p/%p)->(%p, %p): semi-stub\n", iface
, This
, dsound
, dsbuffer
);
490 return DMUS_E_DSOUND_ALREADY_SET
;
493 if (This
->dsound
!= This
->parent
->dsound
)
494 ERR("Not the same dsound in the port (%p) and parent dmusic (%p), expect trouble!\n",
495 This
->dsound
, This
->parent
->dsound
);
496 if (!IDirectSound_Release(This
->parent
->dsound
))
497 This
->parent
->dsound
= NULL
;
500 IDirectSoundBuffer_Release(This
->dsbuffer
);
502 This
->dsound
= dsound
;
503 This
->dsbuffer
= dsbuffer
;
506 IDirectSound_AddRef(This
->dsound
);
508 IDirectSoundBuffer_AddRef(This
->dsbuffer
);
513 static HRESULT WINAPI
synth_port_GetFormat(IDirectMusicPort
*iface
, WAVEFORMATEX
*format
,
514 DWORD
*fmtsize
, DWORD
*bufsize
)
516 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
519 TRACE("(%p, %p, %p, %p)\n", This
, format
, fmtsize
, bufsize
);
521 if (FAILED(hr
= IDirectMusicSynth_GetFormat(This
->synth
, format
, fmtsize
)))
525 hr
= IDirectMusicSynthSink_GetDesiredBufferSize(This
->synth_sink
, bufsize
);
530 static const IDirectMusicPortVtbl synth_port_vtbl
= {
531 /**** IDirectMusicPort IUnknown part methods ***/
532 synth_port_QueryInterface
,
535 /**** IDirectMusicPort methods ***/
536 synth_port_PlayBuffer
,
537 synth_port_SetReadNotificationHandle
,
539 synth_port_DownloadInstrument
,
540 synth_port_UnloadInstrument
,
541 synth_port_GetLatencyClock
,
542 synth_port_GetRunningStats
,
545 synth_port_DeviceIoControl
,
546 synth_port_SetNumChannelGroups
,
547 synth_port_GetNumChannelGroups
,
549 synth_port_SetChannelPriority
,
550 synth_port_GetChannelPriority
,
551 synth_port_SetDirectSound
,
555 static HRESULT WINAPI
synth_port_download_QueryInterface(IDirectMusicPortDownload
*iface
, REFIID riid
, void **ret_iface
)
557 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
559 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
561 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
564 static ULONG WINAPI
synth_port_download_AddRef(IDirectMusicPortDownload
*iface
)
566 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
568 TRACE("(%p)\n", iface
);
570 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
573 static ULONG WINAPI
synth_port_download_Release(IDirectMusicPortDownload
*iface
)
575 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
577 TRACE("(%p)\n", iface
);
579 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
582 static HRESULT WINAPI
synth_port_download_GetBuffer(IDirectMusicPortDownload
*iface
, DWORD DLId
,
583 IDirectMusicDownload
**IDMDownload
)
585 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
587 FIXME("(%p/%p, %lu, %p): stub\n", iface
, This
, DLId
, IDMDownload
);
592 return DMUSIC_CreateDirectMusicDownloadImpl(&IID_IDirectMusicDownload
, (LPVOID
*)IDMDownload
, NULL
);
595 static HRESULT WINAPI
synth_port_download_AllocateBuffer(IDirectMusicPortDownload
*iface
, DWORD size
,
596 IDirectMusicDownload
**IDMDownload
)
598 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
600 FIXME("(%p/%p, %lu, %p): stub\n", iface
, This
, size
, IDMDownload
);
605 static HRESULT WINAPI
synth_port_download_GetDLId(IDirectMusicPortDownload
*iface
, DWORD
*start_DLId
, DWORD count
)
607 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
609 FIXME("(%p/%p, %p, %lu): stub\n", iface
, This
, start_DLId
, count
);
614 static HRESULT WINAPI
synth_port_download_GetAppend(IDirectMusicPortDownload
*iface
, DWORD
*append
)
616 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
618 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, append
);
623 static HRESULT WINAPI
synth_port_download_Download(IDirectMusicPortDownload
*iface
, IDirectMusicDownload
*IDMDownload
)
625 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
627 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, IDMDownload
);
632 static HRESULT WINAPI
synth_port_download_Unload(IDirectMusicPortDownload
*iface
, IDirectMusicDownload
*IDMDownload
)
634 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
636 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, IDMDownload
);
641 static const IDirectMusicPortDownloadVtbl synth_port_download_vtbl
= {
642 /*** IDirectMusicPortDownload IUnknown part methods ***/
643 synth_port_download_QueryInterface
,
644 synth_port_download_AddRef
,
645 synth_port_download_Release
,
646 /*** IDirectMusicPortDownload methods ***/
647 synth_port_download_GetBuffer
,
648 synth_port_download_AllocateBuffer
,
649 synth_port_download_GetDLId
,
650 synth_port_download_GetAppend
,
651 synth_port_download_Download
,
652 synth_port_download_Unload
655 static HRESULT WINAPI
synth_port_thru_QueryInterface(IDirectMusicThru
*iface
, REFIID riid
, void **ret_iface
)
657 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
659 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
661 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
664 static ULONG WINAPI
synth_port_thru_AddRef(IDirectMusicThru
*iface
)
666 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
668 TRACE("(%p)\n", iface
);
670 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
673 static ULONG WINAPI
synth_port_thru_Release(IDirectMusicThru
*iface
)
675 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
677 TRACE("(%p)\n", iface
);
679 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
682 static HRESULT WINAPI
synth_port_thru_ThruChannel(IDirectMusicThru
*iface
, DWORD source_channel_group
,
683 DWORD source_channel
, DWORD destination_channel_group
, DWORD destination_channel
,
684 IDirectMusicPort
*destination_port
)
686 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
688 FIXME("(%p/%p, %ld, %ld, %ld, %ld, %p): stub\n", iface
, This
, source_channel_group
, source_channel
, destination_channel_group
, destination_channel
, destination_port
);
693 static const IDirectMusicThruVtbl synth_port_thru_vtbl
= {
694 /*** IDirectMusicThru IUnknown part methods */
695 synth_port_thru_QueryInterface
,
696 synth_port_thru_AddRef
,
697 synth_port_thru_Release
,
698 /*** IDirectMusicThru methods ***/
699 synth_port_thru_ThruChannel
702 static HRESULT WINAPI
IKsControlImpl_QueryInterface(IKsControl
*iface
, REFIID riid
,
705 struct synth_port
*This
= synth_from_IKsControl(iface
);
707 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
710 static ULONG WINAPI
IKsControlImpl_AddRef(IKsControl
*iface
)
712 struct synth_port
*This
= synth_from_IKsControl(iface
);
714 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
717 static ULONG WINAPI
IKsControlImpl_Release(IKsControl
*iface
)
719 struct synth_port
*This
= synth_from_IKsControl(iface
);
721 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
724 static HRESULT WINAPI
IKsControlImpl_KsProperty(IKsControl
*iface
, KSPROPERTY
*prop
,
725 ULONG prop_len
, void *data
, ULONG data_len
, ULONG
*ret_len
)
727 TRACE("(%p, %p, %lu, %p, %lu, %p)\n", iface
, prop
, prop_len
, data
, data_len
, ret_len
);
728 TRACE("prop = %s - %lu - %lu\n", debugstr_guid(&prop
->u
.s
.Set
), prop
->u
.s
.Id
, prop
->u
.s
.Flags
);
730 if (prop
->u
.s
.Flags
!= KSPROPERTY_TYPE_GET
)
732 FIXME("prop flags %lu not yet supported\n", prop
->u
.s
.Flags
);
736 if (data_len
< sizeof(DWORD
))
737 return E_NOT_SUFFICIENT_BUFFER
;
739 FIXME("Unknown property %s\n", debugstr_guid(&prop
->u
.s
.Set
));
740 *(DWORD
*)data
= FALSE
;
741 *ret_len
= sizeof(DWORD
);
746 static HRESULT WINAPI
IKsControlImpl_KsMethod(IKsControl
*iface
, KSMETHOD
*method
,
747 ULONG method_len
, void *data
, ULONG data_len
, ULONG
*ret_len
)
749 FIXME("(%p, %p, %lu, %p, %lu, %p): stub\n", iface
, method
, method_len
, data
, data_len
, ret_len
);
754 static HRESULT WINAPI
IKsControlImpl_KsEvent(IKsControl
*iface
, KSEVENT
*event
, ULONG event_len
,
755 void *data
, ULONG data_len
, ULONG
*ret_len
)
757 FIXME("(%p, %p, %lu, %p, %lu, %p): stub\n", iface
, event
, event_len
, data
, data_len
, ret_len
);
762 static const IKsControlVtbl ikscontrol_vtbl
= {
763 IKsControlImpl_QueryInterface
,
764 IKsControlImpl_AddRef
,
765 IKsControlImpl_Release
,
766 IKsControlImpl_KsProperty
,
767 IKsControlImpl_KsMethod
,
768 IKsControlImpl_KsEvent
771 HRESULT
synth_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*port_params
,
772 DMUS_PORTCAPS
*port_caps
, IDirectMusicPort
**port
)
774 struct synth_port
*obj
;
778 TRACE("(%p, %p)\n", port_params
, port
);
782 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*obj
));
784 return E_OUTOFMEMORY
;
786 obj
->IDirectMusicPort_iface
.lpVtbl
= &synth_port_vtbl
;
787 obj
->IDirectMusicPortDownload_iface
.lpVtbl
= &synth_port_download_vtbl
;
788 obj
->IDirectMusicThru_iface
.lpVtbl
= &synth_port_thru_vtbl
;
789 obj
->IKsControl_iface
.lpVtbl
= &ikscontrol_vtbl
;
791 obj
->parent
= parent
;
793 obj
->params
= *port_params
;
795 hr
= CoCreateInstance(&CLSID_DirectMusicSynth
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynth
,
796 (void **)&obj
->synth
);
799 hr
= CoCreateInstance(&CLSID_DirectMusicSynthSink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynthSink
, (void**)&obj
->synth_sink
);
802 hr
= IDirectMusicSynth_SetSynthSink(obj
->synth
, obj
->synth_sink
);
805 hr
= IDirectMusicSynth_SetMasterClock(obj
->synth
, obj
->parent
->master_clock
);
808 hr
= IDirectMusicSynth_Open(obj
->synth
, port_params
);
812 if (port_params
->dwValidParams
& DMUS_PORTPARAMS_CHANNELGROUPS
) {
813 obj
->nrofgroups
= port_params
->dwChannelGroups
;
814 /* Setting default priorities */
815 for (i
= 0; i
< obj
->nrofgroups
; i
++) {
816 TRACE ("Setting default channel priorities on channel group %i\n", i
+ 1);
817 obj
->group
[i
].channel
[0].priority
= DAUD_CHAN1_DEF_VOICE_PRIORITY
;
818 obj
->group
[i
].channel
[1].priority
= DAUD_CHAN2_DEF_VOICE_PRIORITY
;
819 obj
->group
[i
].channel
[2].priority
= DAUD_CHAN3_DEF_VOICE_PRIORITY
;
820 obj
->group
[i
].channel
[3].priority
= DAUD_CHAN4_DEF_VOICE_PRIORITY
;
821 obj
->group
[i
].channel
[4].priority
= DAUD_CHAN5_DEF_VOICE_PRIORITY
;
822 obj
->group
[i
].channel
[5].priority
= DAUD_CHAN6_DEF_VOICE_PRIORITY
;
823 obj
->group
[i
].channel
[6].priority
= DAUD_CHAN7_DEF_VOICE_PRIORITY
;
824 obj
->group
[i
].channel
[7].priority
= DAUD_CHAN8_DEF_VOICE_PRIORITY
;
825 obj
->group
[i
].channel
[8].priority
= DAUD_CHAN9_DEF_VOICE_PRIORITY
;
826 obj
->group
[i
].channel
[9].priority
= DAUD_CHAN10_DEF_VOICE_PRIORITY
;
827 obj
->group
[i
].channel
[10].priority
= DAUD_CHAN11_DEF_VOICE_PRIORITY
;
828 obj
->group
[i
].channel
[11].priority
= DAUD_CHAN12_DEF_VOICE_PRIORITY
;
829 obj
->group
[i
].channel
[12].priority
= DAUD_CHAN13_DEF_VOICE_PRIORITY
;
830 obj
->group
[i
].channel
[13].priority
= DAUD_CHAN14_DEF_VOICE_PRIORITY
;
831 obj
->group
[i
].channel
[14].priority
= DAUD_CHAN15_DEF_VOICE_PRIORITY
;
832 obj
->group
[i
].channel
[15].priority
= DAUD_CHAN16_DEF_VOICE_PRIORITY
;
838 *port
= &obj
->IDirectMusicPort_iface
;
843 IDirectMusicSynth_Release(obj
->synth
);
845 IDirectMusicSynthSink_Release(obj
->synth_sink
);
846 HeapFree(GetProcessHeap(), 0, obj
);
852 IDirectMusicPort IDirectMusicPort_iface
;
853 IDirectMusicThru IDirectMusicThru_iface
;
855 IReferenceClock
*clock
;
858 static inline struct midi_port
*impl_from_IDirectMusicPort(IDirectMusicPort
*iface
)
860 return CONTAINING_RECORD(iface
, struct midi_port
, IDirectMusicPort_iface
);
863 static HRESULT WINAPI
midi_IDirectMusicPort_QueryInterface(IDirectMusicPort
*iface
, REFIID riid
,
866 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
868 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
870 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDirectMusicPort
))
872 else if (IsEqualIID(riid
, &IID_IDirectMusicThru
))
873 *ret_iface
= &This
->IDirectMusicThru_iface
;
875 WARN("no interface for %s\n", debugstr_dmguid(riid
));
877 return E_NOINTERFACE
;
880 IUnknown_AddRef((IUnknown
*)*ret_iface
);
885 static ULONG WINAPI
midi_IDirectMusicPort_AddRef(IDirectMusicPort
*iface
)
887 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
888 ULONG ref
= InterlockedIncrement(&This
->ref
);
890 TRACE("(%p) ref = %lu\n", iface
, ref
);
895 static ULONG WINAPI
midi_IDirectMusicPort_Release(IDirectMusicPort
*iface
)
897 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
898 ULONG ref
= InterlockedDecrement(&This
->ref
);
900 TRACE("(%p) ref = %lu\n", iface
, ref
);
904 IReferenceClock_Release(This
->clock
);
911 static HRESULT WINAPI
midi_IDirectMusicPort_PlayBuffer(IDirectMusicPort
*iface
,
912 IDirectMusicBuffer
*buffer
)
914 FIXME("(%p, %p) stub!\n", iface
, buffer
);
919 static HRESULT WINAPI
midi_IDirectMusicPort_SetReadNotificationHandle(IDirectMusicPort
*iface
,
922 FIXME("(%p, %p) stub!\n", iface
, event
);
927 static HRESULT WINAPI
midi_IDirectMusicPort_Read(IDirectMusicPort
*iface
,
928 IDirectMusicBuffer
*buffer
)
930 FIXME("(%p, %p) stub!\n", iface
, buffer
);
935 static HRESULT WINAPI
midi_IDirectMusicPort_DownloadInstrument(IDirectMusicPort
*iface
,
936 IDirectMusicInstrument
*instrument
, IDirectMusicDownloadedInstrument
**downloaded
,
937 DMUS_NOTERANGE
*ranges
, DWORD num_ranges
)
939 FIXME("(%p, %p, %p, %p, %lu) stub!\n", iface
, instrument
, downloaded
, ranges
, num_ranges
);
944 static HRESULT WINAPI
midi_IDirectMusicPort_UnloadInstrument(IDirectMusicPort
*iface
,
945 IDirectMusicDownloadedInstrument
*downloaded
)
947 FIXME("(%p, %p) stub!\n", iface
, downloaded
);
952 static HRESULT WINAPI
midi_IDirectMusicPort_GetLatencyClock(IDirectMusicPort
*iface
,
953 IReferenceClock
**clock
)
955 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
957 TRACE("(%p, %p)\n", iface
, clock
);
962 *clock
= This
->clock
;
963 IReferenceClock_AddRef(*clock
);
968 static HRESULT WINAPI
midi_IDirectMusicPort_GetRunningStats(IDirectMusicPort
*iface
,
969 DMUS_SYNTHSTATS
*stats
)
971 FIXME("(%p, %p) stub!\n", iface
, stats
);
976 static HRESULT WINAPI
midi_IDirectMusicPort_Compact(IDirectMusicPort
*iface
)
978 FIXME("(%p) stub!\n", iface
);
983 static HRESULT WINAPI
midi_IDirectMusicPort_GetCaps(IDirectMusicPort
*iface
, DMUS_PORTCAPS
*caps
)
985 FIXME("(%p, %p) stub!\n", iface
, caps
);
990 static HRESULT WINAPI
midi_IDirectMusicPort_DeviceIoControl(IDirectMusicPort
*iface
,
991 DWORD io_control_code
, void *in
, DWORD size_in
, void *out
, DWORD size_out
, DWORD
*ret_len
,
992 OVERLAPPED
*overlapped
)
994 FIXME("(%p, %lu, %p, %lu, %p, %lu, %p, %p) stub!\n", iface
, io_control_code
, in
, size_in
, out
995 , size_out
, ret_len
, overlapped
);
1000 static HRESULT WINAPI
midi_IDirectMusicPort_SetNumChannelGroups(IDirectMusicPort
*iface
,
1003 FIXME("(%p, %lu) stub!\n", iface
, cgroups
);
1008 static HRESULT WINAPI
midi_IDirectMusicPort_GetNumChannelGroups(IDirectMusicPort
*iface
,
1011 FIXME("(%p, %p) stub!\n", iface
, cgroups
);
1016 static HRESULT WINAPI
midi_IDirectMusicPort_Activate(IDirectMusicPort
*iface
, BOOL active
)
1018 FIXME("(%p, %u) stub!\n", iface
, active
);
1023 static HRESULT WINAPI
midi_IDirectMusicPort_SetChannelPriority(IDirectMusicPort
*iface
,
1024 DWORD channel_group
, DWORD channel
, DWORD priority
)
1026 FIXME("(%p, %lu, %lu, %lu) stub!\n", iface
, channel_group
, channel
, priority
);
1031 static HRESULT WINAPI
midi_IDirectMusicPort_GetChannelPriority(IDirectMusicPort
*iface
,
1032 DWORD channel_group
, DWORD channel
, DWORD
*priority
)
1034 FIXME("(%p, %lu, %lu, %p) stub!\n", iface
, channel_group
, channel
, priority
);
1039 static HRESULT WINAPI
midi_IDirectMusicPort_SetDirectSound(IDirectMusicPort
*iface
,
1040 IDirectSound
*dsound
, IDirectSoundBuffer
*dsbuffer
)
1042 FIXME("(%p, %p, %p) stub!\n", iface
, dsound
, dsbuffer
);
1047 static HRESULT WINAPI
midi_IDirectMusicPort_GetFormat(IDirectMusicPort
*iface
, WAVEFORMATEX
*format
,
1048 DWORD
*format_size
, DWORD
*buffer_size
)
1050 FIXME("(%p, %p, %p, %p) stub!\n", iface
, format
, format_size
, buffer_size
);
1055 static const IDirectMusicPortVtbl midi_port_vtbl
= {
1056 midi_IDirectMusicPort_QueryInterface
,
1057 midi_IDirectMusicPort_AddRef
,
1058 midi_IDirectMusicPort_Release
,
1059 midi_IDirectMusicPort_PlayBuffer
,
1060 midi_IDirectMusicPort_SetReadNotificationHandle
,
1061 midi_IDirectMusicPort_Read
,
1062 midi_IDirectMusicPort_DownloadInstrument
,
1063 midi_IDirectMusicPort_UnloadInstrument
,
1064 midi_IDirectMusicPort_GetLatencyClock
,
1065 midi_IDirectMusicPort_GetRunningStats
,
1066 midi_IDirectMusicPort_Compact
,
1067 midi_IDirectMusicPort_GetCaps
,
1068 midi_IDirectMusicPort_DeviceIoControl
,
1069 midi_IDirectMusicPort_SetNumChannelGroups
,
1070 midi_IDirectMusicPort_GetNumChannelGroups
,
1071 midi_IDirectMusicPort_Activate
,
1072 midi_IDirectMusicPort_SetChannelPriority
,
1073 midi_IDirectMusicPort_GetChannelPriority
,
1074 midi_IDirectMusicPort_SetDirectSound
,
1075 midi_IDirectMusicPort_GetFormat
,
1078 static inline struct midi_port
*impl_from_IDirectMusicThru(IDirectMusicThru
*iface
)
1080 return CONTAINING_RECORD(iface
, struct midi_port
, IDirectMusicThru_iface
);
1083 static HRESULT WINAPI
midi_IDirectMusicThru_QueryInterface(IDirectMusicThru
*iface
, REFIID riid
,
1086 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1088 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
1091 static ULONG WINAPI
midi_IDirectMusicThru_AddRef(IDirectMusicThru
*iface
)
1093 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1095 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
1098 static ULONG WINAPI
midi_IDirectMusicThru_Release(IDirectMusicThru
*iface
)
1100 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1102 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
1105 static HRESULT WINAPI
midi_IDirectMusicThru_ThruChannel(IDirectMusicThru
*iface
, DWORD src_group
,
1106 DWORD src_channel
, DWORD dest_group
, DWORD dest_channel
, IDirectMusicPort
*dest_port
)
1108 FIXME("(%p, %lu, %lu, %lu, %lu, %p) stub!\n", iface
, src_group
, src_channel
, dest_group
,
1109 dest_channel
, dest_port
);
1114 static const IDirectMusicThruVtbl midi_thru_vtbl
= {
1115 midi_IDirectMusicThru_QueryInterface
,
1116 midi_IDirectMusicThru_AddRef
,
1117 midi_IDirectMusicThru_Release
,
1118 midi_IDirectMusicThru_ThruChannel
,
1121 static HRESULT
midi_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1122 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1124 struct midi_port
*obj
;
1127 if (!(obj
= heap_alloc_zero(sizeof(*obj
))))
1128 return E_OUTOFMEMORY
;
1130 obj
->IDirectMusicPort_iface
.lpVtbl
= &midi_port_vtbl
;
1131 obj
->IDirectMusicThru_iface
.lpVtbl
= &midi_thru_vtbl
;
1134 hr
= DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock
, (void **)&obj
->clock
, NULL
);
1136 HeapFree(GetProcessHeap(), 0, obj
);
1140 *port
= &obj
->IDirectMusicPort_iface
;
1145 HRESULT
midi_out_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1146 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1148 TRACE("(%p, %p, %p, %p)\n", parent
, params
, caps
, port
);
1150 return midi_port_create(parent
, params
, caps
, port
);
1153 HRESULT
midi_in_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1154 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1156 TRACE("(%p, %p, %p, %p)\n", parent
, params
, caps
, port
);
1158 return midi_port_create(parent
, params
, caps
, port
);