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
);
29 typedef struct SynthPortImpl
{
30 IDirectMusicPort IDirectMusicPort_iface
;
31 IDirectMusicPortDownload IDirectMusicPortDownload_iface
;
32 IDirectMusicThru IDirectMusicThru_iface
;
33 IKsControl IKsControl_iface
;
35 IDirectMusic8Impl
*parent
;
37 IDirectSoundBuffer
*dsbuffer
;
38 IReferenceClock
*pLatencyClock
;
39 IDirectMusicSynth
*synth
;
40 IDirectMusicSynthSink
*synth_sink
;
43 DMUS_PORTPARAMS params
;
45 DMUSIC_PRIVATE_CHANNEL_GROUP group
[1];
48 static inline IDirectMusicDownloadedInstrumentImpl
* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument
*iface
)
50 return CONTAINING_RECORD(iface
, IDirectMusicDownloadedInstrumentImpl
, IDirectMusicDownloadedInstrument_iface
);
53 static inline SynthPortImpl
*impl_from_SynthPortImpl_IDirectMusicPort(IDirectMusicPort
*iface
)
55 return CONTAINING_RECORD(iface
, SynthPortImpl
, IDirectMusicPort_iface
);
58 static inline SynthPortImpl
*impl_from_SynthPortImpl_IDirectMusicPortDownload(IDirectMusicPortDownload
*iface
)
60 return CONTAINING_RECORD(iface
, SynthPortImpl
, IDirectMusicPortDownload_iface
);
63 static inline SynthPortImpl
*impl_from_SynthPortImpl_IDirectMusicThru(IDirectMusicThru
*iface
)
65 return CONTAINING_RECORD(iface
, SynthPortImpl
, IDirectMusicThru_iface
);
68 static inline SynthPortImpl
*impl_from_IKsControl(IKsControl
*iface
)
70 return CONTAINING_RECORD(iface
, SynthPortImpl
, IKsControl_iface
);
73 /* IDirectMusicDownloadedInstrument IUnknown part follows: */
74 static HRESULT WINAPI
IDirectMusicDownloadedInstrumentImpl_QueryInterface(IDirectMusicDownloadedInstrument
*iface
, REFIID riid
, VOID
**ret_iface
)
76 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
78 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDirectMusicDownloadedInstrument
))
80 IDirectMusicDownloadedInstrument_AddRef(iface
);
85 WARN("(%p, %s, %p): not found\n", iface
, debugstr_dmguid(riid
), ret_iface
);
90 static ULONG WINAPI
IDirectMusicDownloadedInstrumentImpl_AddRef(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface
)
92 IDirectMusicDownloadedInstrumentImpl
*This
= impl_from_IDirectMusicDownloadedInstrument(iface
);
93 ULONG ref
= InterlockedIncrement(&This
->ref
);
95 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
100 static ULONG WINAPI
IDirectMusicDownloadedInstrumentImpl_Release(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface
)
102 IDirectMusicDownloadedInstrumentImpl
*This
= impl_from_IDirectMusicDownloadedInstrument(iface
);
103 ULONG ref
= InterlockedDecrement(&This
->ref
);
105 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
109 HeapFree(GetProcessHeap(), 0, This
->data
);
110 HeapFree(GetProcessHeap(), 0, This
);
111 DMUSIC_UnlockModule();
117 static const IDirectMusicDownloadedInstrumentVtbl DirectMusicDownloadedInstrument_Vtbl
= {
118 IDirectMusicDownloadedInstrumentImpl_QueryInterface
,
119 IDirectMusicDownloadedInstrumentImpl_AddRef
,
120 IDirectMusicDownloadedInstrumentImpl_Release
123 static inline IDirectMusicDownloadedInstrumentImpl
* unsafe_impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument
*iface
)
127 assert(iface
->lpVtbl
== &DirectMusicDownloadedInstrument_Vtbl
);
129 return impl_from_IDirectMusicDownloadedInstrument(iface
);
132 static HRESULT
DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(IDirectMusicDownloadedInstrument
**instrument
)
134 IDirectMusicDownloadedInstrumentImpl
*object
;
136 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
140 return E_OUTOFMEMORY
;
143 object
->IDirectMusicDownloadedInstrument_iface
.lpVtbl
= &DirectMusicDownloadedInstrument_Vtbl
;
146 *instrument
= &object
->IDirectMusicDownloadedInstrument_iface
;
152 /* SynthPortImpl IDirectMusicPort IUnknown part follows: */
153 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_QueryInterface(LPDIRECTMUSICPORT iface
, REFIID riid
, LPVOID
*ret_iface
)
155 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
157 TRACE("(%p/%p)->(%s, %p)\n", iface
, This
, debugstr_dmguid(riid
), ret_iface
);
159 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirectMusicPort
))
160 *ret_iface
= &This
->IDirectMusicPort_iface
;
161 else if (IsEqualGUID(riid
, &IID_IDirectMusicPortDownload
))
162 *ret_iface
= &This
->IDirectMusicPortDownload_iface
;
163 else if (IsEqualGUID(riid
, &IID_IDirectMusicThru
))
164 *ret_iface
= &This
->IDirectMusicThru_iface
;
165 else if (IsEqualGUID(riid
, &IID_IKsControl
))
166 *ret_iface
= &This
->IKsControl_iface
;
168 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ret_iface
);
170 return E_NOINTERFACE
;
173 IUnknown_AddRef((IUnknown
*)*ret_iface
);
178 static ULONG WINAPI
SynthPortImpl_IDirectMusicPort_AddRef(LPDIRECTMUSICPORT iface
)
180 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
181 ULONG ref
= InterlockedIncrement(&This
->ref
);
183 TRACE("(%p)->(): new ref = %u\n", This
, ref
);
190 static ULONG WINAPI
SynthPortImpl_IDirectMusicPort_Release(LPDIRECTMUSICPORT iface
)
192 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
193 ULONG ref
= InterlockedDecrement(&This
->ref
);
195 TRACE("(%p)->(): new ref = %u\n", This
, ref
);
199 dmusic_remove_port(This
->parent
, iface
);
200 IDirectMusicSynth_Activate(This
->synth
, FALSE
);
201 IDirectMusicSynth_Close(This
->synth
);
202 IDirectMusicSynth_Release(This
->synth
);
203 IDirectMusicSynthSink_Release(This
->synth_sink
);
204 IReferenceClock_Release(This
->pLatencyClock
);
206 IDirectSoundBuffer_Release(This
->dsbuffer
);
208 IDirectSound_Release(This
->dsound
);
209 HeapFree(GetProcessHeap(), 0, This
);
212 DMUSIC_UnlockModule();
217 /* SynthPortImpl IDirectMusicPort interface follows: */
218 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_PlayBuffer(LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER buffer
)
220 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
226 TRACE("(%p/%p)->(%p)\n", iface
, This
, buffer
);
231 hr
= IDirectMusicBuffer_GetStartTime(buffer
, &time
);
234 hr
= IDirectMusicBuffer_GetRawBufferPtr(buffer
, &data
);
237 hr
= IDirectMusicBuffer_GetUsedBytes(buffer
, &size
);
240 hr
= IDirectMusicSynth_PlayBuffer(This
->synth
, time
, data
, size
);
245 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle(LPDIRECTMUSICPORT iface
, HANDLE event
)
247 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
249 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, event
);
254 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_Read(LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER buffer
)
256 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
258 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, buffer
);
263 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_DownloadInstrument(LPDIRECTMUSICPORT iface
, IDirectMusicInstrument
* instrument
, IDirectMusicDownloadedInstrument
** downloaded_instrument
, DMUS_NOTERANGE
* note_ranges
, DWORD num_note_ranges
)
265 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
266 IDirectMusicInstrumentImpl
*instrument_object
;
270 DMUS_DOWNLOADINFO
*info
;
271 DMUS_OFFSETTABLE
*offset_table
;
272 DMUS_INSTRUMENT
*instrument_info
;
279 TRACE("(%p/%p)->(%p, %p, %p, %d)\n", iface
, This
, instrument
, downloaded_instrument
, note_ranges
, num_note_ranges
);
281 if (!instrument
|| !downloaded_instrument
|| (num_note_ranges
&& !note_ranges
))
284 instrument_object
= impl_from_IDirectMusicInstrument(instrument
);
286 nb_regions
= instrument_object
->header
.cRegions
;
287 size
= sizeof(DMUS_DOWNLOADINFO
) + sizeof(ULONG
) * (1 + nb_regions
) + sizeof(DMUS_INSTRUMENT
) + sizeof(DMUS_REGION
) * nb_regions
;
289 data
= HeapAlloc(GetProcessHeap(), 0, size
);
291 return E_OUTOFMEMORY
;
293 info
= (DMUS_DOWNLOADINFO
*)data
;
294 offset_table
= (DMUS_OFFSETTABLE
*)(data
+ sizeof(DMUS_DOWNLOADINFO
));
295 offset
= sizeof(DMUS_DOWNLOADINFO
) + sizeof(ULONG
) * (1 + nb_regions
);
297 info
->dwDLType
= DMUS_DOWNLOADINFO_INSTRUMENT2
;
299 info
->dwNumOffsetTableEntries
= 1 + instrument_object
->header
.cRegions
;
302 offset_table
->ulOffsetTable
[0] = offset
;
303 instrument_info
= (DMUS_INSTRUMENT
*)(data
+ offset
);
304 offset
+= sizeof(DMUS_INSTRUMENT
);
305 instrument_info
->ulPatch
= MIDILOCALE2Patch(&instrument_object
->header
.Locale
);
306 instrument_info
->ulFirstRegionIdx
= 1;
307 instrument_info
->ulGlobalArtIdx
= 0; /* FIXME */
308 instrument_info
->ulFirstExtCkIdx
= 0; /* FIXME */
309 instrument_info
->ulCopyrightIdx
= 0; /* FIXME */
310 instrument_info
->ulFlags
= 0; /* FIXME */
312 for (i
= 0; i
< nb_regions
; i
++)
314 DMUS_REGION
*region
= (DMUS_REGION
*)(data
+ offset
);
316 offset_table
->ulOffsetTable
[1 + i
] = offset
;
317 offset
+= sizeof(DMUS_REGION
);
318 region
->RangeKey
= instrument_object
->regions
[i
].header
.RangeKey
;
319 region
->RangeVelocity
= instrument_object
->regions
[i
].header
.RangeVelocity
;
320 region
->fusOptions
= instrument_object
->regions
[i
].header
.fusOptions
;
321 region
->usKeyGroup
= instrument_object
->regions
[i
].header
.usKeyGroup
;
322 region
->ulRegionArtIdx
= 0; /* FIXME */
323 region
->ulNextRegionIdx
= i
!= (nb_regions
- 1) ? (i
+ 2) : 0;
324 region
->ulFirstExtCkIdx
= 0; /* FIXME */
325 region
->WaveLink
= instrument_object
->regions
[i
].wave_link
;
326 region
->WSMP
= instrument_object
->regions
[i
].wave_sample
;
327 region
->WLOOP
[0] = instrument_object
->regions
[i
].wave_loop
;
330 ret
= IDirectMusicSynth8_Download(This
->synth
, &download
, (VOID
*)data
, &free
);
333 ret
= DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(downloaded_instrument
);
337 IDirectMusicDownloadedInstrumentImpl
*downloaded_object
= impl_from_IDirectMusicDownloadedInstrument(*downloaded_instrument
);
339 downloaded_object
->data
= data
;
340 downloaded_object
->downloaded
= TRUE
;
343 *downloaded_instrument
= NULL
;
344 HeapFree(GetProcessHeap(), 0, data
);
349 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_UnloadInstrument(LPDIRECTMUSICPORT iface
, IDirectMusicDownloadedInstrument
*downloaded_instrument
)
351 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
352 IDirectMusicDownloadedInstrumentImpl
*downloaded_object
= unsafe_impl_from_IDirectMusicDownloadedInstrument(downloaded_instrument
);
354 TRACE("(%p/%p)->(%p)\n", iface
, This
, downloaded_instrument
);
356 if (!downloaded_instrument
)
359 if (!downloaded_object
->downloaded
)
360 return DMUS_E_NOT_DOWNLOADED_TO_PORT
;
362 HeapFree(GetProcessHeap(), 0, downloaded_object
->data
);
363 downloaded_object
->data
= NULL
;
364 downloaded_object
->downloaded
= FALSE
;
369 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetLatencyClock(LPDIRECTMUSICPORT iface
, IReferenceClock
** clock
)
371 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
373 TRACE("(%p/%p)->(%p)\n", iface
, This
, clock
);
375 *clock
= This
->pLatencyClock
;
376 IReferenceClock_AddRef(*clock
);
381 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetRunningStats(LPDIRECTMUSICPORT iface
, LPDMUS_SYNTHSTATS stats
)
383 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
385 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, stats
);
390 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_Compact(LPDIRECTMUSICPORT iface
)
392 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
394 FIXME("(%p/%p)->(): stub\n", iface
, This
);
399 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetCaps(LPDIRECTMUSICPORT iface
, LPDMUS_PORTCAPS port_caps
)
401 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
403 TRACE("(%p/%p)->(%p)\n", iface
, This
, port_caps
);
405 *port_caps
= This
->caps
;
410 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_DeviceIoControl(LPDIRECTMUSICPORT iface
, DWORD io_control_code
, LPVOID in_buffer
, DWORD in_buffer_size
,
411 LPVOID out_buffer
, DWORD out_buffer_size
, LPDWORD bytes_returned
, LPOVERLAPPED overlapped
)
413 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
415 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
);
420 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_SetNumChannelGroups(LPDIRECTMUSICPORT iface
, DWORD channel_groups
)
422 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
424 FIXME("(%p/%p)->(%d): semi-stub\n", iface
, This
, channel_groups
);
426 This
->nrofgroups
= channel_groups
;
431 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetNumChannelGroups(LPDIRECTMUSICPORT iface
, LPDWORD channel_groups
)
433 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
435 TRACE("(%p/%p)->(%p)\n", iface
, This
, channel_groups
);
437 *channel_groups
= This
->nrofgroups
;
442 static HRESULT WINAPI
synth_dmport_Activate(IDirectMusicPort
*iface
, BOOL active
)
444 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
446 FIXME("(%p/%p)->(%d): semi-stub\n", iface
, This
, active
);
448 if (This
->active
== active
)
452 /* Acquire the dsound */
454 IDirectSound_AddRef(This
->parent
->dsound
);
455 This
->dsound
= This
->parent
->dsound
;
457 IDirectSound_AddRef(This
->dsound
);
459 /* Release the dsound */
460 IDirectSound_Release(This
->dsound
);
461 IDirectSound_Release(This
->parent
->dsound
);
462 if (This
->dsound
== This
->parent
->dsound
)
466 This
->active
= active
;
471 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_SetChannelPriority(LPDIRECTMUSICPORT iface
, DWORD channel_group
, DWORD channel
, DWORD priority
)
473 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
475 FIXME("(%p/%p)->(%d, %d, %d): semi-stub\n", iface
, This
, channel_group
, channel
, priority
);
479 WARN("isn't there supposed to be 16 channels (no. %d requested)?! (faking as it is ok)\n", channel
);
480 /*return E_INVALIDARG;*/
486 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetChannelPriority(LPDIRECTMUSICPORT iface
, DWORD channel_group
, DWORD channel
, LPDWORD priority
)
488 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
490 TRACE("(%p/%p)->(%u, %u, %p)\n", iface
, This
, channel_group
, channel
, priority
);
492 *priority
= This
->group
[channel_group
- 1].channel
[channel
].priority
;
497 static HRESULT WINAPI
synth_dmport_SetDirectSound(IDirectMusicPort
*iface
, IDirectSound
*dsound
,
498 IDirectSoundBuffer
*dsbuffer
)
500 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
502 FIXME("(%p/%p)->(%p, %p): semi-stub\n", iface
, This
, dsound
, dsbuffer
);
505 return DMUS_E_DSOUND_ALREADY_SET
;
508 if (This
->dsound
!= This
->parent
->dsound
)
509 ERR("Not the same dsound in the port (%p) and parent dmusic (%p), expect trouble!\n",
510 This
->dsound
, This
->parent
->dsound
);
511 if (!IDirectSound_Release(This
->parent
->dsound
))
512 This
->parent
->dsound
= NULL
;
515 IDirectSoundBuffer_Release(This
->dsbuffer
);
517 This
->dsound
= dsound
;
518 This
->dsbuffer
= dsbuffer
;
521 IDirectSound_AddRef(This
->dsound
);
523 IDirectSoundBuffer_AddRef(This
->dsbuffer
);
528 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPort_GetFormat(LPDIRECTMUSICPORT iface
, LPWAVEFORMATEX pWaveFormatEx
, LPDWORD pdwWaveFormatExSize
, LPDWORD pdwBufferSize
)
530 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPort(iface
);
532 FIXME("(%p, %p, %p, %p): stub\n", This
, pWaveFormatEx
, pdwWaveFormatExSize
, pdwBufferSize
);
534 if (pWaveFormatEx
== NULL
)
536 if (pdwWaveFormatExSize
)
537 *pdwWaveFormatExSize
= sizeof(format
);
543 if (pdwWaveFormatExSize
== NULL
)
546 /* Just fill this in with something that will not crash Direct Sound for now. */
547 /* It won't be used anyway until Performances are completed */
548 format
.wFormatTag
= WAVE_FORMAT_PCM
;
549 format
.nChannels
= 2; /* This->params.dwAudioChannels; */
550 format
.nSamplesPerSec
= 44100; /* This->params.dwSampleRate; */
551 format
.wBitsPerSample
= 16; /* FIXME: check this */
552 format
.nBlockAlign
= (format
.wBitsPerSample
* format
.nChannels
) / 8;
553 format
.nAvgBytesPerSec
= format
.nSamplesPerSec
* format
.nBlockAlign
;
556 if (*pdwWaveFormatExSize
>= sizeof(format
))
558 CopyMemory(pWaveFormatEx
, &format
, min(sizeof(format
), *pdwWaveFormatExSize
));
559 *pdwWaveFormatExSize
= sizeof(format
); /* FIXME check if this is set */
562 return E_POINTER
; /* FIXME find right error */
566 *pdwBufferSize
= 44100 * 2 * 2;
573 static const IDirectMusicPortVtbl SynthPortImpl_DirectMusicPort_Vtbl
= {
574 /**** IDirectMusicPort IUnknown part methods ***/
575 SynthPortImpl_IDirectMusicPort_QueryInterface
,
576 SynthPortImpl_IDirectMusicPort_AddRef
,
577 SynthPortImpl_IDirectMusicPort_Release
,
578 /**** IDirectMusicPort methods ***/
579 SynthPortImpl_IDirectMusicPort_PlayBuffer
,
580 SynthPortImpl_IDirectMusicPort_SetReadNotificationHandle
,
581 SynthPortImpl_IDirectMusicPort_Read
,
582 SynthPortImpl_IDirectMusicPort_DownloadInstrument
,
583 SynthPortImpl_IDirectMusicPort_UnloadInstrument
,
584 SynthPortImpl_IDirectMusicPort_GetLatencyClock
,
585 SynthPortImpl_IDirectMusicPort_GetRunningStats
,
586 SynthPortImpl_IDirectMusicPort_Compact
,
587 SynthPortImpl_IDirectMusicPort_GetCaps
,
588 SynthPortImpl_IDirectMusicPort_DeviceIoControl
,
589 SynthPortImpl_IDirectMusicPort_SetNumChannelGroups
,
590 SynthPortImpl_IDirectMusicPort_GetNumChannelGroups
,
591 synth_dmport_Activate
,
592 SynthPortImpl_IDirectMusicPort_SetChannelPriority
,
593 SynthPortImpl_IDirectMusicPort_GetChannelPriority
,
594 synth_dmport_SetDirectSound
,
595 SynthPortImpl_IDirectMusicPort_GetFormat
598 /* SynthPortImpl IDirectMusicPortDownload IUnknown part follows: */
599 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_QueryInterface(LPDIRECTMUSICPORTDOWNLOAD iface
, REFIID riid
, LPVOID
*ret_iface
)
601 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
603 TRACE("(%p/%p)->(%s, %p)\n", iface
, This
, debugstr_dmguid(riid
), ret_iface
);
605 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
608 static ULONG WINAPI
SynthPortImpl_IDirectMusicPortDownload_AddRef (LPDIRECTMUSICPORTDOWNLOAD iface
)
610 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
612 TRACE("(%p/%p)->()\n", iface
, This
);
614 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
617 static ULONG WINAPI
SynthPortImpl_IDirectMusicPortDownload_Release(LPDIRECTMUSICPORTDOWNLOAD iface
)
619 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
621 TRACE("(%p/%p)->()\n", iface
, This
);
623 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
626 /* SynthPortImpl IDirectMusicPortDownload Interface follows: */
627 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_GetBuffer(LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD DLId
, IDirectMusicDownload
** IDMDownload
)
629 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
631 FIXME("(%p/%p)->(%u, %p): stub\n", iface
, This
, DLId
, IDMDownload
);
636 return DMUSIC_CreateDirectMusicDownloadImpl(&IID_IDirectMusicDownload
, (LPVOID
*)IDMDownload
, NULL
);
639 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer(LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD size
, IDirectMusicDownload
** IDMDownload
)
641 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
643 FIXME("(%p/%p)->(%u, %p): stub\n", iface
, This
, size
, IDMDownload
);
648 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_GetDLId(LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD
* start_DLId
, DWORD count
)
650 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
652 FIXME("(%p/%p)->(%p, %u): stub\n", iface
, This
, start_DLId
, count
);
657 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_GetAppend (LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD
* append
)
659 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
661 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, append
);
666 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_Download(LPDIRECTMUSICPORTDOWNLOAD iface
, IDirectMusicDownload
* IDMDownload
)
668 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
670 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, IDMDownload
);
675 static HRESULT WINAPI
SynthPortImpl_IDirectMusicPortDownload_Unload(LPDIRECTMUSICPORTDOWNLOAD iface
, IDirectMusicDownload
* IDMDownload
)
677 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicPortDownload(iface
);
679 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, IDMDownload
);
684 static const IDirectMusicPortDownloadVtbl SynthPortImpl_DirectMusicPortDownload_Vtbl
= {
685 /*** IDirectMusicPortDownload IUnknown part methods ***/
686 SynthPortImpl_IDirectMusicPortDownload_QueryInterface
,
687 SynthPortImpl_IDirectMusicPortDownload_AddRef
,
688 SynthPortImpl_IDirectMusicPortDownload_Release
,
689 /*** IDirectMusicPortDownload methods ***/
690 SynthPortImpl_IDirectMusicPortDownload_GetBuffer
,
691 SynthPortImpl_IDirectMusicPortDownload_AllocateBuffer
,
692 SynthPortImpl_IDirectMusicPortDownload_GetDLId
,
693 SynthPortImpl_IDirectMusicPortDownload_GetAppend
,
694 SynthPortImpl_IDirectMusicPortDownload_Download
,
695 SynthPortImpl_IDirectMusicPortDownload_Unload
698 /* SynthPortImpl IDirectMusicThru IUnknown part follows: */
699 static HRESULT WINAPI
SynthPortImpl_IDirectMusicThru_QueryInterface(LPDIRECTMUSICTHRU iface
, REFIID riid
, LPVOID
*ret_iface
)
701 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
703 TRACE("(%p/%p)->(%s, %p)\n", iface
, This
, debugstr_dmguid(riid
), ret_iface
);
705 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
708 static ULONG WINAPI
SynthPortImpl_IDirectMusicThru_AddRef(LPDIRECTMUSICTHRU iface
)
710 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
712 TRACE("(%p/%p)->()\n", iface
, This
);
714 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
717 static ULONG WINAPI
SynthPortImpl_IDirectMusicThru_Release(LPDIRECTMUSICTHRU iface
)
719 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
721 TRACE("(%p/%p)->()\n", iface
, This
);
723 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
726 /* SynthPortImpl IDirectMusicThru Interface follows: */
727 static HRESULT WINAPI
SynthPortImpl_IDirectMusicThru_ThruChannel(LPDIRECTMUSICTHRU iface
, DWORD source_channel_group
, DWORD source_channel
, DWORD destination_channel_group
,
728 DWORD destination_channel
, LPDIRECTMUSICPORT destination_port
)
730 SynthPortImpl
*This
= impl_from_SynthPortImpl_IDirectMusicThru(iface
);
732 FIXME("(%p/%p)->(%d, %d, %d, %d, %p): stub\n", iface
, This
, source_channel_group
, source_channel
, destination_channel_group
, destination_channel
, destination_port
);
737 static const IDirectMusicThruVtbl SynthPortImpl_DirectMusicThru_Vtbl
= {
738 /*** IDirectMusicThru IUnknown part methods */
739 SynthPortImpl_IDirectMusicThru_QueryInterface
,
740 SynthPortImpl_IDirectMusicThru_AddRef
,
741 SynthPortImpl_IDirectMusicThru_Release
,
742 /*** IDirectMusicThru methods ***/
743 SynthPortImpl_IDirectMusicThru_ThruChannel
746 static HRESULT WINAPI
IKsControlImpl_QueryInterface(IKsControl
*iface
, REFIID riid
,
749 SynthPortImpl
*This
= impl_from_IKsControl(iface
);
751 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
754 static ULONG WINAPI
IKsControlImpl_AddRef(IKsControl
*iface
)
756 SynthPortImpl
*This
= impl_from_IKsControl(iface
);
758 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
761 static ULONG WINAPI
IKsControlImpl_Release(IKsControl
*iface
)
763 SynthPortImpl
*This
= impl_from_IKsControl(iface
);
765 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
768 static HRESULT WINAPI
IKsControlImpl_KsProperty(IKsControl
*iface
, KSPROPERTY
*prop
,
769 ULONG prop_len
, void *data
, ULONG data_len
, ULONG
*ret_len
)
771 TRACE("(%p)->(%p, %u, %p, %u, %p)\n", iface
, prop
, prop_len
, data
, data_len
, ret_len
);
772 TRACE("prop = %s - %u - %u\n", debugstr_guid(&prop
->u
.s
.Set
), prop
->u
.s
.Id
, prop
->u
.s
.Flags
);
774 if (prop
->u
.s
.Flags
!= KSPROPERTY_TYPE_GET
)
776 FIXME("prop flags %u not yet supported\n", prop
->u
.s
.Flags
);
780 if (data_len
< sizeof(DWORD
))
781 return E_NOT_SUFFICIENT_BUFFER
;
783 FIXME("Unknown property %s\n", debugstr_guid(&prop
->u
.s
.Set
));
784 *(DWORD
*)data
= FALSE
;
785 *ret_len
= sizeof(DWORD
);
790 static HRESULT WINAPI
IKsControlImpl_KsMethod(IKsControl
*iface
, KSMETHOD
*method
,
791 ULONG method_len
, void *data
, ULONG data_len
, ULONG
*ret_len
)
793 FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface
, method
, method_len
, data
, data_len
, ret_len
);
798 static HRESULT WINAPI
IKsControlImpl_KsEvent(IKsControl
*iface
, KSEVENT
*event
, ULONG event_len
,
799 void *data
, ULONG data_len
, ULONG
*ret_len
)
801 FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface
, event
, event_len
, data
, data_len
, ret_len
);
806 static const IKsControlVtbl ikscontrol_vtbl
= {
807 IKsControlImpl_QueryInterface
,
808 IKsControlImpl_AddRef
,
809 IKsControlImpl_Release
,
810 IKsControlImpl_KsProperty
,
811 IKsControlImpl_KsMethod
,
812 IKsControlImpl_KsEvent
815 HRESULT
synth_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*port_params
,
816 DMUS_PORTCAPS
*port_caps
, IDirectMusicPort
**port
)
822 TRACE("(%p, %p, %p)\n", port_params
, port_caps
, port
);
826 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SynthPortImpl
));
828 return E_OUTOFMEMORY
;
830 obj
->IDirectMusicPort_iface
.lpVtbl
= &SynthPortImpl_DirectMusicPort_Vtbl
;
831 obj
->IDirectMusicPortDownload_iface
.lpVtbl
= &SynthPortImpl_DirectMusicPortDownload_Vtbl
;
832 obj
->IDirectMusicThru_iface
.lpVtbl
= &SynthPortImpl_DirectMusicThru_Vtbl
;
833 obj
->IKsControl_iface
.lpVtbl
= &ikscontrol_vtbl
;
835 obj
->parent
= parent
;
837 obj
->params
= *port_params
;
838 obj
->caps
= *port_caps
;
840 hr
= DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock
, (LPVOID
*)&obj
->pLatencyClock
, NULL
);
843 HeapFree(GetProcessHeap(), 0, obj
);
848 hr
= CoCreateInstance(&CLSID_DirectMusicSynth
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynth
, (void**)&obj
->synth
);
851 hr
= CoCreateInstance(&CLSID_DirectMusicSynthSink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynthSink
, (void**)&obj
->synth_sink
);
854 hr
= IDirectMusicSynth_SetMasterClock(obj
->synth
, obj
->pLatencyClock
);
857 hr
= IDirectMusicSynthSink_SetMasterClock(obj
->synth_sink
, obj
->pLatencyClock
);
860 hr
= IDirectMusicSynth_SetSynthSink(obj
->synth
, obj
->synth_sink
);
863 hr
= IDirectMusicSynth_Open(obj
->synth
, port_params
);
867 if (port_params
->dwValidParams
& DMUS_PORTPARAMS_CHANNELGROUPS
) {
868 obj
->nrofgroups
= port_params
->dwChannelGroups
;
869 /* Setting default priorities */
870 for (i
= 0; i
< obj
->nrofgroups
; i
++) {
871 TRACE ("Setting default channel priorities on channel group %i\n", i
+ 1);
872 obj
->group
[i
].channel
[0].priority
= DAUD_CHAN1_DEF_VOICE_PRIORITY
;
873 obj
->group
[i
].channel
[1].priority
= DAUD_CHAN2_DEF_VOICE_PRIORITY
;
874 obj
->group
[i
].channel
[2].priority
= DAUD_CHAN3_DEF_VOICE_PRIORITY
;
875 obj
->group
[i
].channel
[3].priority
= DAUD_CHAN4_DEF_VOICE_PRIORITY
;
876 obj
->group
[i
].channel
[4].priority
= DAUD_CHAN5_DEF_VOICE_PRIORITY
;
877 obj
->group
[i
].channel
[5].priority
= DAUD_CHAN6_DEF_VOICE_PRIORITY
;
878 obj
->group
[i
].channel
[6].priority
= DAUD_CHAN7_DEF_VOICE_PRIORITY
;
879 obj
->group
[i
].channel
[7].priority
= DAUD_CHAN8_DEF_VOICE_PRIORITY
;
880 obj
->group
[i
].channel
[8].priority
= DAUD_CHAN9_DEF_VOICE_PRIORITY
;
881 obj
->group
[i
].channel
[9].priority
= DAUD_CHAN10_DEF_VOICE_PRIORITY
;
882 obj
->group
[i
].channel
[10].priority
= DAUD_CHAN11_DEF_VOICE_PRIORITY
;
883 obj
->group
[i
].channel
[11].priority
= DAUD_CHAN12_DEF_VOICE_PRIORITY
;
884 obj
->group
[i
].channel
[12].priority
= DAUD_CHAN13_DEF_VOICE_PRIORITY
;
885 obj
->group
[i
].channel
[13].priority
= DAUD_CHAN14_DEF_VOICE_PRIORITY
;
886 obj
->group
[i
].channel
[14].priority
= DAUD_CHAN15_DEF_VOICE_PRIORITY
;
887 obj
->group
[i
].channel
[15].priority
= DAUD_CHAN16_DEF_VOICE_PRIORITY
;
893 *port
= &obj
->IDirectMusicPort_iface
;
898 IDirectMusicSynth_Release(obj
->synth
);
900 IDirectMusicSynthSink_Release(obj
->synth_sink
);
901 if (obj
->pLatencyClock
)
902 IReferenceClock_Release(obj
->pLatencyClock
);
903 HeapFree(GetProcessHeap(), 0, obj
);
909 IDirectMusicPort IDirectMusicPort_iface
;
910 IDirectMusicThru IDirectMusicThru_iface
;
912 IReferenceClock
*clock
;
915 static inline struct midi_port
*impl_from_IDirectMusicPort(IDirectMusicPort
*iface
)
917 return CONTAINING_RECORD(iface
, struct midi_port
, IDirectMusicPort_iface
);
920 static HRESULT WINAPI
midi_IDirectMusicPort_QueryInterface(IDirectMusicPort
*iface
, REFIID riid
,
923 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
925 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
927 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDirectMusicPort
))
929 else if (IsEqualIID(riid
, &IID_IDirectMusicThru
))
930 *ret_iface
= &This
->IDirectMusicThru_iface
;
932 WARN("no interface for %s\n", debugstr_dmguid(riid
));
934 return E_NOINTERFACE
;
937 IUnknown_AddRef((IUnknown
*)*ret_iface
);
942 static ULONG WINAPI
midi_IDirectMusicPort_AddRef(IDirectMusicPort
*iface
)
944 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
945 ULONG ref
= InterlockedIncrement(&This
->ref
);
947 TRACE("(%p) ref = %u\n", iface
, ref
);
952 static ULONG WINAPI
midi_IDirectMusicPort_Release(IDirectMusicPort
*iface
)
954 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
955 ULONG ref
= InterlockedDecrement(&This
->ref
);
957 TRACE("(%p) ref = %u\n", iface
, ref
);
961 IReferenceClock_Release(This
->clock
);
968 static HRESULT WINAPI
midi_IDirectMusicPort_PlayBuffer(IDirectMusicPort
*iface
,
969 IDirectMusicBuffer
*buffer
)
971 FIXME("(%p, %p) stub!\n", iface
, buffer
);
976 static HRESULT WINAPI
midi_IDirectMusicPort_SetReadNotificationHandle(IDirectMusicPort
*iface
,
979 FIXME("(%p, %p) stub!\n", iface
, event
);
984 static HRESULT WINAPI
midi_IDirectMusicPort_Read(IDirectMusicPort
*iface
,
985 IDirectMusicBuffer
*buffer
)
987 FIXME("(%p, %p) stub!\n", iface
, buffer
);
992 static HRESULT WINAPI
midi_IDirectMusicPort_DownloadInstrument(IDirectMusicPort
*iface
,
993 IDirectMusicInstrument
*instrument
, IDirectMusicDownloadedInstrument
**downloaded
,
994 DMUS_NOTERANGE
*ranges
, DWORD num_ranges
)
996 FIXME("(%p, %p, %p, %p, %u) stub!\n", iface
, instrument
, downloaded
, ranges
, num_ranges
);
1001 static HRESULT WINAPI
midi_IDirectMusicPort_UnloadInstrument(IDirectMusicPort
*iface
,
1002 IDirectMusicDownloadedInstrument
*downloaded
)
1004 FIXME("(%p, %p) stub!\n", iface
, downloaded
);
1009 static HRESULT WINAPI
midi_IDirectMusicPort_GetLatencyClock(IDirectMusicPort
*iface
,
1010 IReferenceClock
**clock
)
1012 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
1014 TRACE("(%p, %p)\n", iface
, clock
);
1019 *clock
= This
->clock
;
1020 IReferenceClock_AddRef(*clock
);
1025 static HRESULT WINAPI
midi_IDirectMusicPort_GetRunningStats(IDirectMusicPort
*iface
,
1026 DMUS_SYNTHSTATS
*stats
)
1028 FIXME("(%p, %p) stub!\n", iface
, stats
);
1033 static HRESULT WINAPI
midi_IDirectMusicPort_Compact(IDirectMusicPort
*iface
)
1035 FIXME("(%p) stub!\n", iface
);
1040 static HRESULT WINAPI
midi_IDirectMusicPort_GetCaps(IDirectMusicPort
*iface
, DMUS_PORTCAPS
*caps
)
1042 FIXME("(%p, %p) stub!\n", iface
, caps
);
1047 static HRESULT WINAPI
midi_IDirectMusicPort_DeviceIoControl(IDirectMusicPort
*iface
,
1048 DWORD io_control_code
, void *in
, DWORD size_in
, void *out
, DWORD size_out
, DWORD
*ret_len
,
1049 OVERLAPPED
*overlapped
)
1051 FIXME("(%p, %u, %p, %u, %p, %u, %p, %p) stub!\n", iface
, io_control_code
, in
, size_in
, out
1052 , size_out
, ret_len
, overlapped
);
1057 static HRESULT WINAPI
midi_IDirectMusicPort_SetNumChannelGroups(IDirectMusicPort
*iface
,
1060 FIXME("(%p, %u) stub!\n", iface
, cgroups
);
1065 static HRESULT WINAPI
midi_IDirectMusicPort_GetNumChannelGroups(IDirectMusicPort
*iface
,
1068 FIXME("(%p, %p) stub!\n", iface
, cgroups
);
1073 static HRESULT WINAPI
midi_IDirectMusicPort_Activate(IDirectMusicPort
*iface
, BOOL active
)
1075 FIXME("(%p, %u) stub!\n", iface
, active
);
1080 static HRESULT WINAPI
midi_IDirectMusicPort_SetChannelPriority(IDirectMusicPort
*iface
,
1081 DWORD channel_group
, DWORD channel
, DWORD priority
)
1083 FIXME("(%p, %u, %u, %u) stub!\n", iface
, channel_group
, channel
, priority
);
1088 static HRESULT WINAPI
midi_IDirectMusicPort_GetChannelPriority(IDirectMusicPort
*iface
,
1089 DWORD channel_group
, DWORD channel
, DWORD
*priority
)
1091 FIXME("(%p, %u, %u, %p) stub!\n", iface
, channel_group
, channel
, priority
);
1096 static HRESULT WINAPI
midi_IDirectMusicPort_SetDirectSound(IDirectMusicPort
*iface
,
1097 IDirectSound
*dsound
, IDirectSoundBuffer
*dsbuffer
)
1099 FIXME("(%p, %p, %p) stub!\n", iface
, dsound
, dsbuffer
);
1104 static HRESULT WINAPI
midi_IDirectMusicPort_GetFormat(IDirectMusicPort
*iface
, WAVEFORMATEX
*format
,
1105 DWORD
*format_size
, DWORD
*buffer_size
)
1107 FIXME("(%p, %p, %p, %p) stub!\n", iface
, format
, format_size
, buffer_size
);
1112 static const IDirectMusicPortVtbl midi_port_vtbl
= {
1113 midi_IDirectMusicPort_QueryInterface
,
1114 midi_IDirectMusicPort_AddRef
,
1115 midi_IDirectMusicPort_Release
,
1116 midi_IDirectMusicPort_PlayBuffer
,
1117 midi_IDirectMusicPort_SetReadNotificationHandle
,
1118 midi_IDirectMusicPort_Read
,
1119 midi_IDirectMusicPort_DownloadInstrument
,
1120 midi_IDirectMusicPort_UnloadInstrument
,
1121 midi_IDirectMusicPort_GetLatencyClock
,
1122 midi_IDirectMusicPort_GetRunningStats
,
1123 midi_IDirectMusicPort_Compact
,
1124 midi_IDirectMusicPort_GetCaps
,
1125 midi_IDirectMusicPort_DeviceIoControl
,
1126 midi_IDirectMusicPort_SetNumChannelGroups
,
1127 midi_IDirectMusicPort_GetNumChannelGroups
,
1128 midi_IDirectMusicPort_Activate
,
1129 midi_IDirectMusicPort_SetChannelPriority
,
1130 midi_IDirectMusicPort_GetChannelPriority
,
1131 midi_IDirectMusicPort_SetDirectSound
,
1132 midi_IDirectMusicPort_GetFormat
,
1135 static inline struct midi_port
*impl_from_IDirectMusicThru(IDirectMusicThru
*iface
)
1137 return CONTAINING_RECORD(iface
, struct midi_port
, IDirectMusicThru_iface
);
1140 static HRESULT WINAPI
midi_IDirectMusicThru_QueryInterface(IDirectMusicThru
*iface
, REFIID riid
,
1143 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1145 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
1148 static ULONG WINAPI
midi_IDirectMusicThru_AddRef(IDirectMusicThru
*iface
)
1150 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1152 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
1155 static ULONG WINAPI
midi_IDirectMusicThru_Release(IDirectMusicThru
*iface
)
1157 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1159 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
1162 static HRESULT WINAPI
midi_IDirectMusicThru_ThruChannel(IDirectMusicThru
*iface
, DWORD src_group
,
1163 DWORD src_channel
, DWORD dest_group
, DWORD dest_channel
, IDirectMusicPort
*dest_port
)
1165 FIXME("(%p, %u, %u, %u, %u, %p) stub!\n", iface
, src_group
, src_channel
, dest_group
,
1166 dest_channel
, dest_port
);
1171 static const IDirectMusicThruVtbl midi_thru_vtbl
= {
1172 midi_IDirectMusicThru_QueryInterface
,
1173 midi_IDirectMusicThru_AddRef
,
1174 midi_IDirectMusicThru_Release
,
1175 midi_IDirectMusicThru_ThruChannel
,
1178 static HRESULT
midi_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1179 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1181 struct midi_port
*obj
;
1184 if (!(obj
= heap_alloc_zero(sizeof(*obj
))))
1185 return E_OUTOFMEMORY
;
1187 obj
->IDirectMusicPort_iface
.lpVtbl
= &midi_port_vtbl
;
1188 obj
->IDirectMusicThru_iface
.lpVtbl
= &midi_thru_vtbl
;
1191 hr
= DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock
, (void **)&obj
->clock
, NULL
);
1193 HeapFree(GetProcessHeap(), 0, obj
);
1197 *port
= &obj
->IDirectMusicPort_iface
;
1202 HRESULT
midi_out_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1203 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1205 TRACE("(%p, %p, %p, %p)\n", parent
, params
, caps
, port
);
1207 return midi_port_create(parent
, params
, caps
, port
);
1210 HRESULT
midi_in_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1211 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1213 TRACE("(%p, %p, %p, %p)\n", parent
, params
, caps
, port
);
1215 return midi_port_create(parent
, params
, caps
, port
);