1 /* IDirectMusicPort Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "dmusic_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(dmusic
);
24 /* IDirectMusicPortImpl IUnknown part: */
25 static HRESULT WINAPI
IDirectMusicPortImpl_QueryInterface (LPDIRECTMUSICPORT iface
, REFIID riid
, LPVOID
*ppobj
) {
26 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
27 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
29 if (IsEqualIID (riid
, &IID_IUnknown
) ||
30 IsEqualGUID(riid
, &IID_IDirectMusicPort
) ||
31 IsEqualGUID(riid
, &IID_IDirectMusicPort8
) ||
32 IsEqualGUID(riid
, &IID_IDirectMusicPortDownload
) ||
33 IsEqualGUID(riid
, &IID_IDirectMusicPortDownload8
) ||
34 IsEqualGUID(riid
, &IID_IDirectMusicThru
) ||
35 IsEqualGUID(riid
, &IID_IDirectMusicThru8
)) {
36 IUnknown_AddRef(iface
);
40 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ppobj
);
44 static ULONG WINAPI
IDirectMusicPortImpl_AddRef (LPDIRECTMUSICPORT iface
) {
45 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
46 ULONG refCount
= InterlockedIncrement(&This
->ref
);
48 TRACE("(%p)->(ref before=%u)\n", This
, refCount
- 1);
55 static ULONG WINAPI
IDirectMusicPortImpl_Release (LPDIRECTMUSICPORT iface
) {
56 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
57 ULONG refCount
= InterlockedDecrement(&This
->ref
);
59 TRACE("(%p)->(ref before=%u)\n", This
, refCount
+ 1);
62 HeapFree(GetProcessHeap(), 0, This
);
65 DMUSIC_UnlockModule();
70 /* IDirectMusicPortImpl IDirectMusicPort part: */
71 static HRESULT WINAPI
IDirectMusicPortImpl_PlayBuffer (LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER pBuffer
) {
72 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
73 FIXME("(%p, %p): stub\n", This
, pBuffer
);
77 static HRESULT WINAPI
IDirectMusicPortImpl_SetReadNotificationHandle (LPDIRECTMUSICPORT iface
, HANDLE hEvent
) {
78 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
79 FIXME("(%p, %p): stub\n", This
, hEvent
);
83 static HRESULT WINAPI
IDirectMusicPortImpl_Read (LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER pBuffer
) {
84 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
85 FIXME("(%p, %p): stub\n", This
, pBuffer
);
89 static HRESULT WINAPI
IDirectMusicPortImpl_DownloadInstrument (LPDIRECTMUSICPORT iface
, IDirectMusicInstrument
* pInstrument
, IDirectMusicDownloadedInstrument
** ppDownloadedInstrument
, DMUS_NOTERANGE
* pNoteRanges
, DWORD dwNumNoteRanges
) {
90 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
91 FIXME("(%p, %p, %p, %p, %d): stub\n", This
, pInstrument
, ppDownloadedInstrument
, pNoteRanges
, dwNumNoteRanges
);
95 static HRESULT WINAPI
IDirectMusicPortImpl_UnloadInstrument (LPDIRECTMUSICPORT iface
, IDirectMusicDownloadedInstrument
*pDownloadedInstrument
) {
96 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
97 FIXME("(%p, %p): stub\n", This
, pDownloadedInstrument
);
101 static HRESULT WINAPI
IDirectMusicPortImpl_GetLatencyClock (LPDIRECTMUSICPORT iface
, IReferenceClock
** ppClock
) {
102 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
103 TRACE("(%p, %p)\n", This
, ppClock
);
104 *ppClock
= This
->pLatencyClock
;
105 IReferenceClock_AddRef (*ppClock
);
109 static HRESULT WINAPI
IDirectMusicPortImpl_GetRunningStats (LPDIRECTMUSICPORT iface
, LPDMUS_SYNTHSTATS pStats
) {
110 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
111 FIXME("(%p, %p): stub\n", This
, pStats
);
115 static HRESULT WINAPI
IDirectMusicPortImpl_Compact (LPDIRECTMUSICPORT iface
) {
116 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
117 FIXME("(%p): stub\n", This
);
121 static HRESULT WINAPI
IDirectMusicPortImpl_GetCaps (LPDIRECTMUSICPORT iface
, LPDMUS_PORTCAPS pPortCaps
) {
122 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
123 TRACE("(%p, %p)\n", This
, pPortCaps
);
124 *pPortCaps
= This
->caps
;
128 static HRESULT WINAPI
IDirectMusicPortImpl_DeviceIoControl (LPDIRECTMUSICPORT iface
, DWORD dwIoControlCode
, LPVOID lpInBuffer
, DWORD nInBufferSize
, LPVOID lpOutBuffer
, DWORD nOutBufferSize
, LPDWORD lpBytesReturned
, LPOVERLAPPED lpOverlapped
) {
129 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
130 FIXME("(%p, %d, %p, %d, %p, %d, %p, %p): stub\n", This
, dwIoControlCode
, lpInBuffer
, nInBufferSize
, lpOutBuffer
, nOutBufferSize
, lpBytesReturned
, lpOverlapped
);
134 static HRESULT WINAPI
IDirectMusicPortImpl_SetNumChannelGroups (LPDIRECTMUSICPORT iface
, DWORD dwChannelGroups
) {
135 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
136 FIXME("(%p, %d): semi-stub\n", This
, dwChannelGroups
);
137 This
->nrofgroups
= dwChannelGroups
;
141 static HRESULT WINAPI
IDirectMusicPortImpl_GetNumChannelGroups (LPDIRECTMUSICPORT iface
, LPDWORD pdwChannelGroups
) {
142 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
143 TRACE("(%p, %p)\n", This
, pdwChannelGroups
);
144 *pdwChannelGroups
= This
->nrofgroups
;
148 HRESULT WINAPI
IDirectMusicPortImpl_Activate (LPDIRECTMUSICPORT iface
, BOOL fActive
) {
149 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
150 TRACE("(%p, %d)\n", This
, fActive
);
151 This
->fActive
= fActive
;
155 static HRESULT WINAPI
IDirectMusicPortImpl_SetChannelPriority (LPDIRECTMUSICPORT iface
, DWORD dwChannelGroup
, DWORD dwChannel
, DWORD dwPriority
) {
156 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
157 FIXME("(%p, %d, %d, %d): semi-stub\n", This
, dwChannelGroup
, dwChannel
, dwPriority
);
158 if (dwChannel
> 16) {
159 WARN("isn't there supposed to be 16 channels (no. %d requested)?! (faking as it is ok)\n", dwChannel
);
160 /*return E_INVALIDARG;*/
165 static HRESULT WINAPI
IDirectMusicPortImpl_GetChannelPriority (LPDIRECTMUSICPORT iface
, DWORD dwChannelGroup
, DWORD dwChannel
, LPDWORD pdwPriority
) {
166 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
167 TRACE("(%p, %d, %d, %p)\n", This
, dwChannelGroup
, dwChannel
, pdwPriority
);
168 *pdwPriority
= This
->group
[dwChannelGroup
-1].channel
[dwChannel
].priority
;
172 static HRESULT WINAPI
IDirectMusicPortImpl_SetDirectSound (LPDIRECTMUSICPORT iface
, LPDIRECTSOUND pDirectSound
, LPDIRECTSOUNDBUFFER pDirectSoundBuffer
) {
173 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
174 FIXME("(%p, %p, %p): stub\n", This
, pDirectSound
, pDirectSoundBuffer
);
178 static HRESULT WINAPI
IDirectMusicPortImpl_GetFormat (LPDIRECTMUSICPORT iface
, LPWAVEFORMATEX pWaveFormatEx
, LPDWORD pdwWaveFormatExSize
, LPDWORD pdwBufferSize
) {
179 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
181 FIXME("(%p, %p, %p, %p): stub\n", This
, pWaveFormatEx
, pdwWaveFormatExSize
, pdwBufferSize
);
183 if (pWaveFormatEx
== NULL
)
185 if (pdwWaveFormatExSize
)
186 *pdwWaveFormatExSize
= sizeof(format
);
192 if (pdwWaveFormatExSize
== NULL
)
195 /* Just fill this in with something that will not crash Direct Sound for now. */
196 /* It won't be used anyway until Performances are completed */
197 format
.wFormatTag
= WAVE_FORMAT_PCM
;
198 format
.nChannels
= 2; /* This->params.dwAudioChannels; */
199 format
.nSamplesPerSec
= 44100; /* This->params.dwSampleRate; */
200 format
.wBitsPerSample
= 16; /* FIXME: check this */
201 format
.nBlockAlign
= (format
.wBitsPerSample
* format
.nChannels
) / 8;
202 format
.nAvgBytesPerSec
= format
.nSamplesPerSec
* format
.nBlockAlign
;
205 if (*pdwWaveFormatExSize
>= sizeof(format
))
207 CopyMemory(pWaveFormatEx
, &format
, min(sizeof(format
), *pdwWaveFormatExSize
));
208 *pdwWaveFormatExSize
= sizeof(format
); /* FIXME check if this is set */
211 return E_POINTER
; /* FIXME find right error */
215 *pdwBufferSize
= 44100 * 2 * 2;
222 static const IDirectMusicPortVtbl DirectMusicPort_Vtbl
= {
223 IDirectMusicPortImpl_QueryInterface
,
224 IDirectMusicPortImpl_AddRef
,
225 IDirectMusicPortImpl_Release
,
226 IDirectMusicPortImpl_PlayBuffer
,
227 IDirectMusicPortImpl_SetReadNotificationHandle
,
228 IDirectMusicPortImpl_Read
,
229 IDirectMusicPortImpl_DownloadInstrument
,
230 IDirectMusicPortImpl_UnloadInstrument
,
231 IDirectMusicPortImpl_GetLatencyClock
,
232 IDirectMusicPortImpl_GetRunningStats
,
233 IDirectMusicPortImpl_Compact
,
234 IDirectMusicPortImpl_GetCaps
,
235 IDirectMusicPortImpl_DeviceIoControl
,
236 IDirectMusicPortImpl_SetNumChannelGroups
,
237 IDirectMusicPortImpl_GetNumChannelGroups
,
238 IDirectMusicPortImpl_Activate
,
239 IDirectMusicPortImpl_SetChannelPriority
,
240 IDirectMusicPortImpl_GetChannelPriority
,
241 IDirectMusicPortImpl_SetDirectSound
,
242 IDirectMusicPortImpl_GetFormat
245 /* IDirectMusicPortDownload IUnknown parts follow: */
246 static HRESULT WINAPI
IDirectMusicPortDownloadImpl_QueryInterface (LPDIRECTMUSICPORTDOWNLOAD iface
, REFIID riid
, LPVOID
*ppobj
) {
247 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpDownloadVtbl
, iface
);
248 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, debugstr_dmguid(riid
), ppobj
);
249 return IUnknown_QueryInterface((IUnknown
*)&(This
->lpVtbl
), riid
, ppobj
);
252 static ULONG WINAPI
IDirectMusicPortDownloadImpl_AddRef (LPDIRECTMUSICPORTDOWNLOAD iface
) {
253 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpDownloadVtbl
, iface
);
254 TRACE("(%p/%p)->()\n", This
, iface
);
255 return IUnknown_AddRef((IUnknown
*)&(This
->lpVtbl
));
258 static ULONG WINAPI
IDirectMusicPortDownloadImpl_Release (LPDIRECTMUSICPORTDOWNLOAD iface
) {
259 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpDownloadVtbl
, iface
);
260 TRACE("(%p/%p)->()\n", This
, iface
);
261 return IUnknown_Release((IUnknown
*)&(This
->lpVtbl
));
264 /* IDirectMusicPortDownload Interface follow: */
265 static HRESULT WINAPI
IDirectMusicPortDownloadImpl_GetBuffer (LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD dwDLId
, IDirectMusicDownload
** ppIDMDownload
) {
266 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpDownloadVtbl
, iface
);
267 FIXME("(%p/%p)->(%d, %p): stub\n", This
, iface
, dwDLId
, ppIDMDownload
);
271 static HRESULT WINAPI
IDirectMusicPortDownloadImpl_AllocateBuffer (LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD dwSize
, IDirectMusicDownload
** ppIDMDownload
) {
272 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpDownloadVtbl
, iface
);
273 FIXME("(%p/%p)->(%d, %p): stub\n", This
, iface
, dwSize
, ppIDMDownload
);
277 static HRESULT WINAPI
IDirectMusicPortDownloadImpl_GetDLId (LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD
* pdwStartDLId
, DWORD dwCount
) {
278 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpDownloadVtbl
, iface
);
279 FIXME("(%p/%p)->(%p, %d): stub\n", This
, iface
, pdwStartDLId
, dwCount
);
283 static HRESULT WINAPI
IDirectMusicPortDownloadImpl_GetAppend (LPDIRECTMUSICPORTDOWNLOAD iface
, DWORD
* pdwAppend
) {
284 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
285 FIXME("(%p/%p)->(%p): stub\n", This
, iface
, pdwAppend
);
289 static HRESULT WINAPI
IDirectMusicPortDownloadImpl_Download (LPDIRECTMUSICPORTDOWNLOAD iface
, IDirectMusicDownload
* pIDMDownload
) {
290 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
291 FIXME("(%p/%p)->(%p): stub\n", This
, iface
, pIDMDownload
);
295 static HRESULT WINAPI
IDirectMusicPortDownloadImpl_Unload (LPDIRECTMUSICPORTDOWNLOAD iface
, IDirectMusicDownload
* pIDMDownload
) {
296 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
297 FIXME("(%p/%p)->(%p): stub\n", This
, iface
, pIDMDownload
);
301 static const IDirectMusicPortDownloadVtbl DirectMusicPortDownload_Vtbl
= {
302 IDirectMusicPortDownloadImpl_QueryInterface
,
303 IDirectMusicPortDownloadImpl_AddRef
,
304 IDirectMusicPortDownloadImpl_Release
,
305 IDirectMusicPortDownloadImpl_GetBuffer
,
306 IDirectMusicPortDownloadImpl_AllocateBuffer
,
307 IDirectMusicPortDownloadImpl_GetDLId
,
308 IDirectMusicPortDownloadImpl_GetAppend
,
309 IDirectMusicPortDownloadImpl_Download
,
310 IDirectMusicPortDownloadImpl_Unload
313 /* IDirectMusicThru IUnknown parts follow: */
314 static HRESULT WINAPI
IDirectMusicThruImpl_QueryInterface (LPDIRECTMUSICTHRU iface
, REFIID riid
, LPVOID
*ppobj
) {
315 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpThruVtbl
, iface
);
316 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, debugstr_dmguid(riid
), ppobj
);
317 return IUnknown_QueryInterface((IUnknown
*)&(This
->lpVtbl
), riid
, ppobj
);
320 static ULONG WINAPI
IDirectMusicThruImpl_AddRef (LPDIRECTMUSICTHRU iface
) {
321 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpThruVtbl
, iface
);
322 TRACE("(%p/%p)->()\n", This
, iface
);
323 return IUnknown_AddRef((IUnknown
*)&(This
->lpVtbl
));
326 static ULONG WINAPI
IDirectMusicThruImpl_Release (LPDIRECTMUSICTHRU iface
) {
327 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpThruVtbl
, iface
);
328 TRACE("(%p/%p)->()\n", This
, iface
);
329 return IUnknown_Release((IUnknown
*)&(This
->lpVtbl
));
332 /* IDirectMusicThru Interface follow: */
333 static HRESULT WINAPI
IDirectMusicThruImpl_ThruChannel (LPDIRECTMUSICTHRU iface
, DWORD dwSourceChannelGroup
, DWORD dwSourceChannel
, DWORD dwDestinationChannelGroup
, DWORD dwDestinationChannel
, LPDIRECTMUSICPORT pDestinationPort
) {
334 ICOM_THIS_MULTI(IDirectMusicPortImpl
, lpThruVtbl
, iface
);
335 FIXME("(%p/%p)->(%d, %d, %d, %d, %p): stub\n", This
, iface
, dwSourceChannelGroup
, dwSourceChannel
, dwDestinationChannelGroup
, dwDestinationChannel
, pDestinationPort
);
339 static const IDirectMusicThruVtbl DirectMusicThru_Vtbl
= {
340 IDirectMusicThruImpl_QueryInterface
,
341 IDirectMusicThruImpl_AddRef
,
342 IDirectMusicThruImpl_Release
,
343 IDirectMusicThruImpl_ThruChannel
346 HRESULT WINAPI
DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID
, LPVOID
*ppobj
, LPUNKNOWN pUnkOuter
, LPDMUS_PORTPARAMS pPortParams
, LPDMUS_PORTCAPS pPortCaps
) {
347 IDirectMusicPortImpl
*obj
;
350 TRACE("(%p,%p,%p)\n", lpcGUID
, ppobj
, pUnkOuter
);
352 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicPortImpl
));
355 return E_OUTOFMEMORY
;
357 obj
->lpVtbl
= &DirectMusicPort_Vtbl
;
358 obj
->lpDownloadVtbl
= &DirectMusicPortDownload_Vtbl
;
359 obj
->lpThruVtbl
= &DirectMusicThru_Vtbl
;
360 obj
->ref
= 0; /* will be inited by QueryInterface */
361 obj
->fActive
= FALSE
;
362 obj
->params
= *pPortParams
;
363 obj
->caps
= *pPortCaps
;
364 obj
->pDirectSound
= NULL
;
365 obj
->pLatencyClock
= NULL
;
366 hr
= DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock
, (LPVOID
*)&obj
->pLatencyClock
, NULL
);
369 if (pPortParams
->dwValidParams
& DMUS_PORTPARAMS_CHANNELGROUPS
) {
370 obj
->nrofgroups
= pPortParams
->dwChannelGroups
;
371 /* setting default priorities */
372 for (j
= 0; j
< obj
->nrofgroups
; j
++) {
373 TRACE ("Setting default channel priorities on channel group %i\n", j
+ 1);
374 obj
->group
[j
].channel
[0].priority
= DAUD_CHAN1_DEF_VOICE_PRIORITY
;
375 obj
->group
[j
].channel
[1].priority
= DAUD_CHAN2_DEF_VOICE_PRIORITY
;
376 obj
->group
[j
].channel
[2].priority
= DAUD_CHAN3_DEF_VOICE_PRIORITY
;
377 obj
->group
[j
].channel
[3].priority
= DAUD_CHAN4_DEF_VOICE_PRIORITY
;
378 obj
->group
[j
].channel
[4].priority
= DAUD_CHAN5_DEF_VOICE_PRIORITY
;
379 obj
->group
[j
].channel
[5].priority
= DAUD_CHAN6_DEF_VOICE_PRIORITY
;
380 obj
->group
[j
].channel
[6].priority
= DAUD_CHAN7_DEF_VOICE_PRIORITY
;
381 obj
->group
[j
].channel
[7].priority
= DAUD_CHAN8_DEF_VOICE_PRIORITY
;
382 obj
->group
[j
].channel
[8].priority
= DAUD_CHAN9_DEF_VOICE_PRIORITY
;
383 obj
->group
[j
].channel
[9].priority
= DAUD_CHAN10_DEF_VOICE_PRIORITY
;
384 obj
->group
[j
].channel
[10].priority
= DAUD_CHAN11_DEF_VOICE_PRIORITY
;
385 obj
->group
[j
].channel
[11].priority
= DAUD_CHAN12_DEF_VOICE_PRIORITY
;
386 obj
->group
[j
].channel
[12].priority
= DAUD_CHAN13_DEF_VOICE_PRIORITY
;
387 obj
->group
[j
].channel
[13].priority
= DAUD_CHAN14_DEF_VOICE_PRIORITY
;
388 obj
->group
[j
].channel
[14].priority
= DAUD_CHAN15_DEF_VOICE_PRIORITY
;
389 obj
->group
[j
].channel
[15].priority
= DAUD_CHAN16_DEF_VOICE_PRIORITY
;
394 return IDirectMusicPortImpl_QueryInterface ((LPDIRECTMUSICPORT
)obj
, lpcGUID
, ppobj
);