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
);
30 IDirectMusicDownload
*download
;
36 IDirectMusicPort IDirectMusicPort_iface
;
37 IDirectMusicPortDownload IDirectMusicPortDownload_iface
;
38 IDirectMusicThru IDirectMusicThru_iface
;
39 IKsControl IKsControl_iface
;
41 IDirectMusic8Impl
*parent
;
43 IDirectSoundBuffer
*dsbuffer
;
44 IDirectMusicSynth
*synth
;
45 IDirectMusicSynthSink
*synth_sink
;
47 DMUS_PORTPARAMS params
;
49 DMUSIC_PRIVATE_CHANNEL_GROUP group
[1];
51 struct list downloads
;
55 static inline struct synth_port
*synth_from_IDirectMusicPort(IDirectMusicPort
*iface
)
57 return CONTAINING_RECORD(iface
, struct synth_port
, IDirectMusicPort_iface
);
60 static inline struct synth_port
*synth_from_IDirectMusicPortDownload(IDirectMusicPortDownload
*iface
)
62 return CONTAINING_RECORD(iface
, struct synth_port
, IDirectMusicPortDownload_iface
);
65 static inline struct synth_port
*synth_from_IDirectMusicThru(IDirectMusicThru
*iface
)
67 return CONTAINING_RECORD(iface
, struct synth_port
, IDirectMusicThru_iface
);
70 static inline struct synth_port
*synth_from_IKsControl(IKsControl
*iface
)
72 return CONTAINING_RECORD(iface
, struct synth_port
, IKsControl_iface
);
75 static HRESULT WINAPI
synth_port_QueryInterface(IDirectMusicPort
*iface
, REFIID riid
, void **ret_iface
)
77 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
79 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
81 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirectMusicPort
))
82 *ret_iface
= &This
->IDirectMusicPort_iface
;
83 else if (IsEqualGUID(riid
, &IID_IDirectMusicPortDownload
))
84 *ret_iface
= &This
->IDirectMusicPortDownload_iface
;
85 else if (IsEqualGUID(riid
, &IID_IDirectMusicThru
))
86 *ret_iface
= &This
->IDirectMusicThru_iface
;
87 else if (IsEqualGUID(riid
, &IID_IKsControl
))
88 *ret_iface
= &This
->IKsControl_iface
;
90 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ret_iface
);
95 IUnknown_AddRef((IUnknown
*)*ret_iface
);
100 static ULONG WINAPI
synth_port_AddRef(IDirectMusicPort
*iface
)
102 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
103 ULONG ref
= InterlockedIncrement(&This
->ref
);
105 TRACE("(%p): new ref = %lu\n", This
, ref
);
110 static ULONG WINAPI
synth_port_Release(IDirectMusicPort
*iface
)
112 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
113 ULONG ref
= InterlockedDecrement(&This
->ref
);
115 TRACE("(%p): new ref = %lu\n", This
, ref
);
119 struct download_entry
*entry
, *next
;
121 LIST_FOR_EACH_ENTRY_SAFE(entry
, next
, &This
->downloads
, struct download_entry
, entry
)
123 list_remove(&entry
->entry
);
124 IDirectMusicDownload_Release(entry
->download
);
128 dmusic_remove_port(This
->parent
, iface
);
129 IDirectMusicSynthSink_Release(This
->synth_sink
);
130 IDirectMusicSynth_Activate(This
->synth
, FALSE
);
131 IDirectMusicSynth_Close(This
->synth
);
132 IDirectMusicSynth_Release(This
->synth
);
134 IDirectSoundBuffer_Release(This
->dsbuffer
);
136 IDirectSound_Release(This
->dsound
);
143 static HRESULT WINAPI
synth_port_PlayBuffer(IDirectMusicPort
*iface
, IDirectMusicBuffer
*buffer
)
145 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
151 TRACE("(%p, %p)\n", iface
, buffer
);
156 hr
= IDirectMusicBuffer_GetStartTime(buffer
, &time
);
159 hr
= IDirectMusicBuffer_GetRawBufferPtr(buffer
, &data
);
162 hr
= IDirectMusicBuffer_GetUsedBytes(buffer
, &size
);
165 hr
= IDirectMusicSynth_PlayBuffer(This
->synth
, time
, data
, size
);
170 static HRESULT WINAPI
synth_port_SetReadNotificationHandle(IDirectMusicPort
*iface
, HANDLE event
)
172 TRACE("(%p, %p): method not implemented\n", iface
, event
);
176 static HRESULT WINAPI
synth_port_Read(IDirectMusicPort
*iface
, IDirectMusicBuffer
*buffer
)
178 TRACE("(%p, %p): method not implemented\n", iface
, buffer
);
182 static HRESULT WINAPI
synth_port_DownloadInstrument(IDirectMusicPort
*iface
, IDirectMusicInstrument
*instrument
,
183 IDirectMusicDownloadedInstrument
**downloaded_instrument
, DMUS_NOTERANGE
*note_ranges
, DWORD num_note_ranges
)
185 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
187 TRACE("(%p, %p, %p, %p, %ld)\n", iface
, instrument
, downloaded_instrument
, note_ranges
, num_note_ranges
);
189 if (!instrument
|| !downloaded_instrument
|| (num_note_ranges
&& !note_ranges
))
192 return instrument_download_to_port(instrument
, &This
->IDirectMusicPortDownload_iface
, downloaded_instrument
);
195 static HRESULT WINAPI
synth_port_UnloadInstrument(IDirectMusicPort
*iface
,
196 IDirectMusicDownloadedInstrument
*downloaded_instrument
)
198 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
200 TRACE("(%p, %p)\n", iface
, downloaded_instrument
);
202 if (!downloaded_instrument
)
205 return instrument_unload_from_port(downloaded_instrument
, &This
->IDirectMusicPortDownload_iface
);
208 static HRESULT WINAPI
synth_port_GetLatencyClock(IDirectMusicPort
*iface
, IReferenceClock
**clock
)
210 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
212 TRACE("(%p, %p)\n", iface
, clock
);
214 return IDirectMusicSynth8_GetLatencyClock(This
->synth
, clock
);
217 static HRESULT WINAPI
synth_port_GetRunningStats(IDirectMusicPort
*iface
, DMUS_SYNTHSTATS
*stats
)
219 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
221 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, stats
);
226 static HRESULT WINAPI
synth_port_Compact(IDirectMusicPort
*iface
)
228 TRACE("(%p): method not implemented\n", iface
);
232 static HRESULT WINAPI
synth_port_GetCaps(IDirectMusicPort
*iface
, DMUS_PORTCAPS
*port_caps
)
234 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
236 TRACE("(%p, %p)\n", iface
, port_caps
);
238 return IDirectMusicSynth_GetPortCaps(This
->synth
, port_caps
);
241 static HRESULT WINAPI
synth_port_DeviceIoControl(IDirectMusicPort
*iface
, DWORD io_control_code
,
242 void *in_buffer
, DWORD in_buffer_size
, void *out_buffer
, DWORD out_buffer_size
,
243 DWORD
*bytes_returned
, OVERLAPPED
*overlapped
)
245 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
247 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
);
252 static HRESULT WINAPI
synth_port_SetNumChannelGroups(IDirectMusicPort
*iface
, DWORD channel_groups
)
254 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
256 FIXME("(%p, %ld): semi-stub\n", iface
, channel_groups
);
258 This
->nrofgroups
= channel_groups
;
263 static HRESULT WINAPI
synth_port_GetNumChannelGroups(IDirectMusicPort
*iface
, DWORD
*channel_groups
)
265 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
267 TRACE("(%p, %p)\n", iface
, channel_groups
);
269 *channel_groups
= This
->nrofgroups
;
274 static HRESULT WINAPI
synth_port_Activate(IDirectMusicPort
*iface
, BOOL active
)
276 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
279 TRACE("(%p/%p)->(%d)\n", iface
, This
, active
);
281 if (This
->active
== active
) return S_FALSE
;
285 if (!This
->dsound
&& FAILED(hr
= IDirectMusicPort_SetDirectSound(iface
,
286 This
->parent
->dsound
, NULL
)))
288 if (FAILED(hr
= IDirectMusicSynthSink_SetDirectSound(This
->synth_sink
,
289 This
->dsound
, This
->dsbuffer
)))
292 if (FAILED(hr
= IDirectMusicSynth_Activate(This
->synth
, active
)))
298 if (FAILED(hr
= IDirectMusicSynth_Activate(This
->synth
, FALSE
))) return hr
;
299 This
->active
= FALSE
;
301 if (FAILED(hr
= IDirectMusicSynthSink_SetDirectSound(This
->synth_sink
, NULL
, NULL
)))
303 hr
= IDirectMusicPort_SetDirectSound(iface
, NULL
, NULL
);
309 static HRESULT WINAPI
synth_port_SetChannelPriority(IDirectMusicPort
*iface
, DWORD channel_group
,
310 DWORD channel
, DWORD priority
)
312 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
314 FIXME("(%p/%p, %ld, %ld, %ld): semi-stub\n", iface
, This
, channel_group
, channel
, priority
);
318 WARN("isn't there supposed to be 16 channels (no. %ld requested)?! (faking as it is ok)\n", channel
);
319 /*return E_INVALIDARG;*/
325 static HRESULT WINAPI
synth_port_GetChannelPriority(IDirectMusicPort
*iface
, DWORD channel_group
,
326 DWORD channel
, DWORD
*priority
)
328 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
330 TRACE("(%p, %lu, %lu, %p)\n", iface
, channel_group
, channel
, priority
);
332 *priority
= This
->group
[channel_group
- 1].channel
[channel
].priority
;
337 static HRESULT WINAPI
synth_port_SetDirectSound(IDirectMusicPort
*iface
, IDirectSound
*dsound
,
338 IDirectSoundBuffer
*dsbuffer
)
340 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
342 FIXME("(%p/%p)->(%p, %p): semi-stub\n", iface
, This
, dsound
, dsbuffer
);
345 return DMUS_E_DSOUND_ALREADY_SET
;
348 if (This
->dsound
!= This
->parent
->dsound
)
349 ERR("Not the same dsound in the port (%p) and parent dmusic (%p), expect trouble!\n",
350 This
->dsound
, This
->parent
->dsound
);
351 if (!IDirectSound_Release(This
->parent
->dsound
))
352 This
->parent
->dsound
= NULL
;
355 IDirectSoundBuffer_Release(This
->dsbuffer
);
357 This
->dsound
= dsound
;
358 This
->dsbuffer
= dsbuffer
;
361 IDirectSound_AddRef(This
->dsound
);
363 IDirectSoundBuffer_AddRef(This
->dsbuffer
);
368 static HRESULT WINAPI
synth_port_GetFormat(IDirectMusicPort
*iface
, WAVEFORMATEX
*format
,
369 DWORD
*fmtsize
, DWORD
*bufsize
)
371 struct synth_port
*This
= synth_from_IDirectMusicPort(iface
);
374 TRACE("(%p, %p, %p, %p)\n", This
, format
, fmtsize
, bufsize
);
376 if (FAILED(hr
= IDirectMusicSynth_GetFormat(This
->synth
, format
, fmtsize
)))
380 hr
= IDirectMusicSynthSink_GetDesiredBufferSize(This
->synth_sink
, bufsize
);
385 static const IDirectMusicPortVtbl synth_port_vtbl
= {
386 /**** IDirectMusicPort IUnknown part methods ***/
387 synth_port_QueryInterface
,
390 /**** IDirectMusicPort methods ***/
391 synth_port_PlayBuffer
,
392 synth_port_SetReadNotificationHandle
,
394 synth_port_DownloadInstrument
,
395 synth_port_UnloadInstrument
,
396 synth_port_GetLatencyClock
,
397 synth_port_GetRunningStats
,
400 synth_port_DeviceIoControl
,
401 synth_port_SetNumChannelGroups
,
402 synth_port_GetNumChannelGroups
,
404 synth_port_SetChannelPriority
,
405 synth_port_GetChannelPriority
,
406 synth_port_SetDirectSound
,
410 static HRESULT WINAPI
synth_port_download_QueryInterface(IDirectMusicPortDownload
*iface
, REFIID riid
, void **ret_iface
)
412 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
414 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
416 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
419 static ULONG WINAPI
synth_port_download_AddRef(IDirectMusicPortDownload
*iface
)
421 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
423 TRACE("(%p)\n", iface
);
425 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
428 static ULONG WINAPI
synth_port_download_Release(IDirectMusicPortDownload
*iface
)
430 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
432 TRACE("(%p)\n", iface
);
434 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
437 static HRESULT WINAPI
synth_port_download_GetBuffer(IDirectMusicPortDownload
*iface
, DWORD id
,
438 IDirectMusicDownload
**download
)
440 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
441 struct download_entry
*entry
;
443 TRACE("(%p/%p, %lu, %p)\n", iface
, This
, id
, download
);
445 if (!download
) return E_POINTER
;
446 if (id
>= This
->next_dlid
) return DMUS_E_INVALID_DOWNLOADID
;
448 LIST_FOR_EACH_ENTRY(entry
, &This
->downloads
, struct download_entry
, entry
)
452 *download
= entry
->download
;
453 IDirectMusicDownload_AddRef(entry
->download
);
458 return DMUS_E_NOT_DOWNLOADED_TO_PORT
;
461 static HRESULT WINAPI
synth_port_download_AllocateBuffer(IDirectMusicPortDownload
*iface
, DWORD size
,
462 IDirectMusicDownload
**download
)
464 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
466 TRACE("(%p/%p, %lu, %p)\n", iface
, This
, size
, download
);
468 if (!download
) return E_POINTER
;
469 if (!size
) return E_INVALIDARG
;
471 return download_create(size
, download
);
474 static HRESULT WINAPI
synth_port_download_GetDLId(IDirectMusicPortDownload
*iface
, DWORD
*first
, DWORD count
)
476 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
478 TRACE("(%p/%p, %p, %lu)\n", iface
, This
, first
, count
);
480 if (!first
) return E_POINTER
;
481 if (!count
) return E_INVALIDARG
;
483 *first
= This
->next_dlid
;
484 This
->next_dlid
+= count
;
489 static HRESULT WINAPI
synth_port_download_GetAppend(IDirectMusicPortDownload
*iface
, DWORD
*append
)
491 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
493 FIXME("(%p/%p)->(%p): stub\n", iface
, This
, append
);
498 static HRESULT WINAPI
synth_port_download_Download(IDirectMusicPortDownload
*iface
, IDirectMusicDownload
*download
)
500 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
501 struct download_entry
*entry
;
502 DMUS_DOWNLOADINFO
*info
;
508 TRACE("(%p/%p)->(%p)\n", iface
, This
, download
);
510 if (!download
) return E_POINTER
;
512 LIST_FOR_EACH_ENTRY(entry
, &This
->downloads
, struct download_entry
, entry
)
513 if (entry
->download
== download
) return DMUS_E_ALREADY_DOWNLOADED
;
515 if (!(entry
= malloc(sizeof(*entry
)))) return E_OUTOFMEMORY
;
516 if (SUCCEEDED(hr
= IDirectMusicDownload_GetBuffer(download
, (void **)&info
, &size
))
517 && SUCCEEDED(hr
= IDirectMusicSynth_Download(This
->synth
, &handle
, info
, &can_free
)))
519 entry
->download
= download
;
520 IDirectMusicDownload_AddRef(download
);
521 entry
->id
= info
->dwDLId
;
522 entry
->handle
= handle
;
523 list_add_tail(&This
->downloads
, &entry
->entry
);
526 if (FAILED(hr
)) free(entry
);
530 static HRESULT WINAPI
synth_port_download_Unload(IDirectMusicPortDownload
*iface
, IDirectMusicDownload
*download
)
532 struct synth_port
*This
= synth_from_IDirectMusicPortDownload(iface
);
533 struct download_entry
*entry
;
536 TRACE("(%p/%p)->(%p)\n", iface
, This
, download
);
538 if (!download
) return E_POINTER
;
540 LIST_FOR_EACH_ENTRY(entry
, &This
->downloads
, struct download_entry
, entry
)
542 if (entry
->download
== download
)
544 list_remove(&entry
->entry
);
545 IDirectMusicDownload_Release(entry
->download
);
546 handle
= entry
->handle
;
552 if (!handle
) return S_OK
;
553 return IDirectMusicSynth_Unload(This
->synth
, handle
, NULL
, NULL
);
556 static const IDirectMusicPortDownloadVtbl synth_port_download_vtbl
= {
557 /*** IDirectMusicPortDownload IUnknown part methods ***/
558 synth_port_download_QueryInterface
,
559 synth_port_download_AddRef
,
560 synth_port_download_Release
,
561 /*** IDirectMusicPortDownload methods ***/
562 synth_port_download_GetBuffer
,
563 synth_port_download_AllocateBuffer
,
564 synth_port_download_GetDLId
,
565 synth_port_download_GetAppend
,
566 synth_port_download_Download
,
567 synth_port_download_Unload
570 static HRESULT WINAPI
synth_port_thru_QueryInterface(IDirectMusicThru
*iface
, REFIID riid
, void **ret_iface
)
572 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
574 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
576 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
579 static ULONG WINAPI
synth_port_thru_AddRef(IDirectMusicThru
*iface
)
581 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
583 TRACE("(%p)\n", iface
);
585 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
588 static ULONG WINAPI
synth_port_thru_Release(IDirectMusicThru
*iface
)
590 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
592 TRACE("(%p)\n", iface
);
594 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
597 static HRESULT WINAPI
synth_port_thru_ThruChannel(IDirectMusicThru
*iface
, DWORD source_channel_group
,
598 DWORD source_channel
, DWORD destination_channel_group
, DWORD destination_channel
,
599 IDirectMusicPort
*destination_port
)
601 struct synth_port
*This
= synth_from_IDirectMusicThru(iface
);
603 FIXME("(%p/%p, %ld, %ld, %ld, %ld, %p): stub\n", iface
, This
, source_channel_group
, source_channel
, destination_channel_group
, destination_channel
, destination_port
);
608 static const IDirectMusicThruVtbl synth_port_thru_vtbl
= {
609 /*** IDirectMusicThru IUnknown part methods */
610 synth_port_thru_QueryInterface
,
611 synth_port_thru_AddRef
,
612 synth_port_thru_Release
,
613 /*** IDirectMusicThru methods ***/
614 synth_port_thru_ThruChannel
617 static HRESULT WINAPI
IKsControlImpl_QueryInterface(IKsControl
*iface
, REFIID riid
,
620 struct synth_port
*This
= synth_from_IKsControl(iface
);
622 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
625 static ULONG WINAPI
IKsControlImpl_AddRef(IKsControl
*iface
)
627 struct synth_port
*This
= synth_from_IKsControl(iface
);
629 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
632 static ULONG WINAPI
IKsControlImpl_Release(IKsControl
*iface
)
634 struct synth_port
*This
= synth_from_IKsControl(iface
);
636 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
639 static HRESULT WINAPI
IKsControlImpl_KsProperty(IKsControl
*iface
, KSPROPERTY
*prop
,
640 ULONG prop_len
, void *data
, ULONG data_len
, ULONG
*ret_len
)
642 TRACE("(%p, %p, %lu, %p, %lu, %p)\n", iface
, prop
, prop_len
, data
, data_len
, ret_len
);
643 TRACE("prop = %s - %lu - %lu\n", debugstr_guid(&prop
->Set
), prop
->Id
, prop
->Flags
);
645 if (prop
->Flags
!= KSPROPERTY_TYPE_GET
)
647 FIXME("prop flags %lu not yet supported\n", prop
->Flags
);
651 if (data_len
< sizeof(DWORD
))
652 return E_NOT_SUFFICIENT_BUFFER
;
654 FIXME("Unknown property %s\n", debugstr_guid(&prop
->Set
));
655 *(DWORD
*)data
= FALSE
;
656 *ret_len
= sizeof(DWORD
);
661 static HRESULT WINAPI
IKsControlImpl_KsMethod(IKsControl
*iface
, KSMETHOD
*method
,
662 ULONG method_len
, void *data
, ULONG data_len
, ULONG
*ret_len
)
664 FIXME("(%p, %p, %lu, %p, %lu, %p): stub\n", iface
, method
, method_len
, data
, data_len
, ret_len
);
669 static HRESULT WINAPI
IKsControlImpl_KsEvent(IKsControl
*iface
, KSEVENT
*event
, ULONG event_len
,
670 void *data
, ULONG data_len
, ULONG
*ret_len
)
672 FIXME("(%p, %p, %lu, %p, %lu, %p): stub\n", iface
, event
, event_len
, data
, data_len
, ret_len
);
677 static const IKsControlVtbl ikscontrol_vtbl
= {
678 IKsControlImpl_QueryInterface
,
679 IKsControlImpl_AddRef
,
680 IKsControlImpl_Release
,
681 IKsControlImpl_KsProperty
,
682 IKsControlImpl_KsMethod
,
683 IKsControlImpl_KsEvent
686 HRESULT
synth_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*port_params
,
687 DMUS_PORTCAPS
*port_caps
, IDirectMusicPort
**port
)
689 struct synth_port
*obj
;
693 TRACE("(%p, %p)\n", port_params
, port
);
697 obj
= calloc(1, sizeof(*obj
));
699 return E_OUTOFMEMORY
;
701 obj
->IDirectMusicPort_iface
.lpVtbl
= &synth_port_vtbl
;
702 obj
->IDirectMusicPortDownload_iface
.lpVtbl
= &synth_port_download_vtbl
;
703 obj
->IDirectMusicThru_iface
.lpVtbl
= &synth_port_thru_vtbl
;
704 obj
->IKsControl_iface
.lpVtbl
= &ikscontrol_vtbl
;
706 obj
->parent
= parent
;
708 obj
->params
= *port_params
;
709 list_init(&obj
->downloads
);
711 hr
= CoCreateInstance(&CLSID_DirectMusicSynth
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynth
,
712 (void **)&obj
->synth
);
715 hr
= CoCreateInstance(&CLSID_DirectMusicSynthSink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicSynthSink
, (void**)&obj
->synth_sink
);
718 hr
= IDirectMusicSynth_SetSynthSink(obj
->synth
, obj
->synth_sink
);
721 hr
= IDirectMusicSynth_SetMasterClock(obj
->synth
, obj
->parent
->master_clock
);
724 hr
= IDirectMusicSynthSink_SetMasterClock(obj
->synth_sink
, obj
->parent
->master_clock
);
727 hr
= IDirectMusicSynth_Open(obj
->synth
, port_params
);
731 if (port_params
->dwValidParams
& DMUS_PORTPARAMS_CHANNELGROUPS
) {
732 obj
->nrofgroups
= port_params
->dwChannelGroups
;
733 /* Setting default priorities */
734 for (i
= 0; i
< obj
->nrofgroups
; i
++) {
735 TRACE ("Setting default channel priorities on channel group %i\n", i
+ 1);
736 obj
->group
[i
].channel
[0].priority
= DAUD_CHAN1_DEF_VOICE_PRIORITY
;
737 obj
->group
[i
].channel
[1].priority
= DAUD_CHAN2_DEF_VOICE_PRIORITY
;
738 obj
->group
[i
].channel
[2].priority
= DAUD_CHAN3_DEF_VOICE_PRIORITY
;
739 obj
->group
[i
].channel
[3].priority
= DAUD_CHAN4_DEF_VOICE_PRIORITY
;
740 obj
->group
[i
].channel
[4].priority
= DAUD_CHAN5_DEF_VOICE_PRIORITY
;
741 obj
->group
[i
].channel
[5].priority
= DAUD_CHAN6_DEF_VOICE_PRIORITY
;
742 obj
->group
[i
].channel
[6].priority
= DAUD_CHAN7_DEF_VOICE_PRIORITY
;
743 obj
->group
[i
].channel
[7].priority
= DAUD_CHAN8_DEF_VOICE_PRIORITY
;
744 obj
->group
[i
].channel
[8].priority
= DAUD_CHAN9_DEF_VOICE_PRIORITY
;
745 obj
->group
[i
].channel
[9].priority
= DAUD_CHAN10_DEF_VOICE_PRIORITY
;
746 obj
->group
[i
].channel
[10].priority
= DAUD_CHAN11_DEF_VOICE_PRIORITY
;
747 obj
->group
[i
].channel
[11].priority
= DAUD_CHAN12_DEF_VOICE_PRIORITY
;
748 obj
->group
[i
].channel
[12].priority
= DAUD_CHAN13_DEF_VOICE_PRIORITY
;
749 obj
->group
[i
].channel
[13].priority
= DAUD_CHAN14_DEF_VOICE_PRIORITY
;
750 obj
->group
[i
].channel
[14].priority
= DAUD_CHAN15_DEF_VOICE_PRIORITY
;
751 obj
->group
[i
].channel
[15].priority
= DAUD_CHAN16_DEF_VOICE_PRIORITY
;
757 *port
= &obj
->IDirectMusicPort_iface
;
762 IDirectMusicSynth_Release(obj
->synth
);
764 IDirectMusicSynthSink_Release(obj
->synth_sink
);
771 IDirectMusicPort IDirectMusicPort_iface
;
772 IDirectMusicThru IDirectMusicThru_iface
;
774 IReferenceClock
*clock
;
777 static inline struct midi_port
*impl_from_IDirectMusicPort(IDirectMusicPort
*iface
)
779 return CONTAINING_RECORD(iface
, struct midi_port
, IDirectMusicPort_iface
);
782 static HRESULT WINAPI
midi_IDirectMusicPort_QueryInterface(IDirectMusicPort
*iface
, REFIID riid
,
785 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
787 TRACE("(%p, %s, %p)\n", iface
, debugstr_dmguid(riid
), ret_iface
);
789 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDirectMusicPort
))
791 else if (IsEqualIID(riid
, &IID_IDirectMusicThru
))
792 *ret_iface
= &This
->IDirectMusicThru_iface
;
794 WARN("no interface for %s\n", debugstr_dmguid(riid
));
796 return E_NOINTERFACE
;
799 IUnknown_AddRef((IUnknown
*)*ret_iface
);
804 static ULONG WINAPI
midi_IDirectMusicPort_AddRef(IDirectMusicPort
*iface
)
806 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
807 ULONG ref
= InterlockedIncrement(&This
->ref
);
809 TRACE("(%p) ref = %lu\n", iface
, ref
);
814 static ULONG WINAPI
midi_IDirectMusicPort_Release(IDirectMusicPort
*iface
)
816 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
817 ULONG ref
= InterlockedDecrement(&This
->ref
);
819 TRACE("(%p) ref = %lu\n", iface
, ref
);
823 IReferenceClock_Release(This
->clock
);
830 static HRESULT WINAPI
midi_IDirectMusicPort_PlayBuffer(IDirectMusicPort
*iface
,
831 IDirectMusicBuffer
*buffer
)
833 FIXME("(%p, %p) stub!\n", iface
, buffer
);
838 static HRESULT WINAPI
midi_IDirectMusicPort_SetReadNotificationHandle(IDirectMusicPort
*iface
,
841 FIXME("(%p, %p) stub!\n", iface
, event
);
846 static HRESULT WINAPI
midi_IDirectMusicPort_Read(IDirectMusicPort
*iface
,
847 IDirectMusicBuffer
*buffer
)
849 FIXME("(%p, %p) stub!\n", iface
, buffer
);
854 static HRESULT WINAPI
midi_IDirectMusicPort_DownloadInstrument(IDirectMusicPort
*iface
,
855 IDirectMusicInstrument
*instrument
, IDirectMusicDownloadedInstrument
**downloaded
,
856 DMUS_NOTERANGE
*ranges
, DWORD num_ranges
)
858 FIXME("(%p, %p, %p, %p, %lu) stub!\n", iface
, instrument
, downloaded
, ranges
, num_ranges
);
863 static HRESULT WINAPI
midi_IDirectMusicPort_UnloadInstrument(IDirectMusicPort
*iface
,
864 IDirectMusicDownloadedInstrument
*downloaded
)
866 FIXME("(%p, %p) stub!\n", iface
, downloaded
);
871 static HRESULT WINAPI
midi_IDirectMusicPort_GetLatencyClock(IDirectMusicPort
*iface
,
872 IReferenceClock
**clock
)
874 struct midi_port
*This
= impl_from_IDirectMusicPort(iface
);
876 TRACE("(%p, %p)\n", iface
, clock
);
881 *clock
= This
->clock
;
882 IReferenceClock_AddRef(*clock
);
887 static HRESULT WINAPI
midi_IDirectMusicPort_GetRunningStats(IDirectMusicPort
*iface
,
888 DMUS_SYNTHSTATS
*stats
)
890 FIXME("(%p, %p) stub!\n", iface
, stats
);
895 static HRESULT WINAPI
midi_IDirectMusicPort_Compact(IDirectMusicPort
*iface
)
897 FIXME("(%p) stub!\n", iface
);
902 static HRESULT WINAPI
midi_IDirectMusicPort_GetCaps(IDirectMusicPort
*iface
, DMUS_PORTCAPS
*caps
)
904 FIXME("(%p, %p) stub!\n", iface
, caps
);
909 static HRESULT WINAPI
midi_IDirectMusicPort_DeviceIoControl(IDirectMusicPort
*iface
,
910 DWORD io_control_code
, void *in
, DWORD size_in
, void *out
, DWORD size_out
, DWORD
*ret_len
,
911 OVERLAPPED
*overlapped
)
913 FIXME("(%p, %lu, %p, %lu, %p, %lu, %p, %p) stub!\n", iface
, io_control_code
, in
, size_in
, out
914 , size_out
, ret_len
, overlapped
);
919 static HRESULT WINAPI
midi_IDirectMusicPort_SetNumChannelGroups(IDirectMusicPort
*iface
,
922 FIXME("(%p, %lu) stub!\n", iface
, cgroups
);
927 static HRESULT WINAPI
midi_IDirectMusicPort_GetNumChannelGroups(IDirectMusicPort
*iface
,
930 FIXME("(%p, %p) stub!\n", iface
, cgroups
);
935 static HRESULT WINAPI
midi_IDirectMusicPort_Activate(IDirectMusicPort
*iface
, BOOL active
)
937 FIXME("(%p, %u) stub!\n", iface
, active
);
942 static HRESULT WINAPI
midi_IDirectMusicPort_SetChannelPriority(IDirectMusicPort
*iface
,
943 DWORD channel_group
, DWORD channel
, DWORD priority
)
945 FIXME("(%p, %lu, %lu, %lu) stub!\n", iface
, channel_group
, channel
, priority
);
950 static HRESULT WINAPI
midi_IDirectMusicPort_GetChannelPriority(IDirectMusicPort
*iface
,
951 DWORD channel_group
, DWORD channel
, DWORD
*priority
)
953 FIXME("(%p, %lu, %lu, %p) stub!\n", iface
, channel_group
, channel
, priority
);
958 static HRESULT WINAPI
midi_IDirectMusicPort_SetDirectSound(IDirectMusicPort
*iface
,
959 IDirectSound
*dsound
, IDirectSoundBuffer
*dsbuffer
)
961 FIXME("(%p, %p, %p) stub!\n", iface
, dsound
, dsbuffer
);
966 static HRESULT WINAPI
midi_IDirectMusicPort_GetFormat(IDirectMusicPort
*iface
, WAVEFORMATEX
*format
,
967 DWORD
*format_size
, DWORD
*buffer_size
)
969 FIXME("(%p, %p, %p, %p) stub!\n", iface
, format
, format_size
, buffer_size
);
974 static const IDirectMusicPortVtbl midi_port_vtbl
= {
975 midi_IDirectMusicPort_QueryInterface
,
976 midi_IDirectMusicPort_AddRef
,
977 midi_IDirectMusicPort_Release
,
978 midi_IDirectMusicPort_PlayBuffer
,
979 midi_IDirectMusicPort_SetReadNotificationHandle
,
980 midi_IDirectMusicPort_Read
,
981 midi_IDirectMusicPort_DownloadInstrument
,
982 midi_IDirectMusicPort_UnloadInstrument
,
983 midi_IDirectMusicPort_GetLatencyClock
,
984 midi_IDirectMusicPort_GetRunningStats
,
985 midi_IDirectMusicPort_Compact
,
986 midi_IDirectMusicPort_GetCaps
,
987 midi_IDirectMusicPort_DeviceIoControl
,
988 midi_IDirectMusicPort_SetNumChannelGroups
,
989 midi_IDirectMusicPort_GetNumChannelGroups
,
990 midi_IDirectMusicPort_Activate
,
991 midi_IDirectMusicPort_SetChannelPriority
,
992 midi_IDirectMusicPort_GetChannelPriority
,
993 midi_IDirectMusicPort_SetDirectSound
,
994 midi_IDirectMusicPort_GetFormat
,
997 static inline struct midi_port
*impl_from_IDirectMusicThru(IDirectMusicThru
*iface
)
999 return CONTAINING_RECORD(iface
, struct midi_port
, IDirectMusicThru_iface
);
1002 static HRESULT WINAPI
midi_IDirectMusicThru_QueryInterface(IDirectMusicThru
*iface
, REFIID riid
,
1005 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1007 return IDirectMusicPort_QueryInterface(&This
->IDirectMusicPort_iface
, riid
, ret_iface
);
1010 static ULONG WINAPI
midi_IDirectMusicThru_AddRef(IDirectMusicThru
*iface
)
1012 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1014 return IDirectMusicPort_AddRef(&This
->IDirectMusicPort_iface
);
1017 static ULONG WINAPI
midi_IDirectMusicThru_Release(IDirectMusicThru
*iface
)
1019 struct midi_port
*This
= impl_from_IDirectMusicThru(iface
);
1021 return IDirectMusicPort_Release(&This
->IDirectMusicPort_iface
);
1024 static HRESULT WINAPI
midi_IDirectMusicThru_ThruChannel(IDirectMusicThru
*iface
, DWORD src_group
,
1025 DWORD src_channel
, DWORD dest_group
, DWORD dest_channel
, IDirectMusicPort
*dest_port
)
1027 FIXME("(%p, %lu, %lu, %lu, %lu, %p) stub!\n", iface
, src_group
, src_channel
, dest_group
,
1028 dest_channel
, dest_port
);
1033 static const IDirectMusicThruVtbl midi_thru_vtbl
= {
1034 midi_IDirectMusicThru_QueryInterface
,
1035 midi_IDirectMusicThru_AddRef
,
1036 midi_IDirectMusicThru_Release
,
1037 midi_IDirectMusicThru_ThruChannel
,
1040 static HRESULT
midi_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1041 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1043 struct midi_port
*obj
;
1046 if (!(obj
= calloc(1, sizeof(*obj
))))
1047 return E_OUTOFMEMORY
;
1049 obj
->IDirectMusicPort_iface
.lpVtbl
= &midi_port_vtbl
;
1050 obj
->IDirectMusicThru_iface
.lpVtbl
= &midi_thru_vtbl
;
1053 hr
= DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock
, (void **)&obj
->clock
, NULL
);
1059 *port
= &obj
->IDirectMusicPort_iface
;
1064 HRESULT
midi_out_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1065 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1067 TRACE("(%p, %p, %p, %p)\n", parent
, params
, caps
, port
);
1069 return midi_port_create(parent
, params
, caps
, port
);
1072 HRESULT
midi_in_port_create(IDirectMusic8Impl
*parent
, DMUS_PORTPARAMS
*params
,
1073 DMUS_PORTCAPS
*caps
, IDirectMusicPort
**port
)
1075 TRACE("(%p, %p, %p, %p)\n", parent
, params
, caps
, port
);
1077 return midi_port_create(parent
, params
, caps
, port
);