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
) || IsEqualGUID(riid
, &IID_IDirectMusicPort
)) {
30 IUnknown_AddRef(iface
);
34 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ppobj
);
38 static ULONG WINAPI
IDirectMusicPortImpl_AddRef (LPDIRECTMUSICPORT iface
) {
39 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
40 ULONG refCount
= InterlockedIncrement(&This
->ref
);
42 TRACE("(%p)->(ref before=%u)\n", This
, refCount
- 1);
49 static ULONG WINAPI
IDirectMusicPortImpl_Release (LPDIRECTMUSICPORT iface
) {
50 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
51 ULONG refCount
= InterlockedDecrement(&This
->ref
);
53 TRACE("(%p)->(ref before=%u)\n", This
, refCount
+ 1);
56 HeapFree(GetProcessHeap(), 0, This
);
59 DMUSIC_UnlockModule();
64 /* IDirectMusicPortImpl IDirectMusicPort part: */
65 static HRESULT WINAPI
IDirectMusicPortImpl_PlayBuffer (LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER pBuffer
) {
66 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
67 FIXME("(%p, %p): stub\n", This
, pBuffer
);
71 static HRESULT WINAPI
IDirectMusicPortImpl_SetReadNotificationHandle (LPDIRECTMUSICPORT iface
, HANDLE hEvent
) {
72 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
73 FIXME("(%p, %p): stub\n", This
, hEvent
);
77 static HRESULT WINAPI
IDirectMusicPortImpl_Read (LPDIRECTMUSICPORT iface
, LPDIRECTMUSICBUFFER pBuffer
) {
78 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
79 FIXME("(%p, %p): stub\n", This
, pBuffer
);
83 static HRESULT WINAPI
IDirectMusicPortImpl_DownloadInstrument (LPDIRECTMUSICPORT iface
, IDirectMusicInstrument
* pInstrument
, IDirectMusicDownloadedInstrument
** ppDownloadedInstrument
, DMUS_NOTERANGE
* pNoteRanges
, DWORD dwNumNoteRanges
) {
84 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
85 FIXME("(%p, %p, %p, %p, %d): stub\n", This
, pInstrument
, ppDownloadedInstrument
, pNoteRanges
, dwNumNoteRanges
);
89 static HRESULT WINAPI
IDirectMusicPortImpl_UnloadInstrument (LPDIRECTMUSICPORT iface
, IDirectMusicDownloadedInstrument
*pDownloadedInstrument
) {
90 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
91 FIXME("(%p, %p): stub\n", This
, pDownloadedInstrument
);
95 static HRESULT WINAPI
IDirectMusicPortImpl_GetLatencyClock (LPDIRECTMUSICPORT iface
, IReferenceClock
** ppClock
) {
96 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
97 TRACE("(%p, %p)\n", This
, ppClock
);
98 *ppClock
= This
->pLatencyClock
;
99 IReferenceClock_AddRef (*ppClock
);
103 static HRESULT WINAPI
IDirectMusicPortImpl_GetRunningStats (LPDIRECTMUSICPORT iface
, LPDMUS_SYNTHSTATS pStats
) {
104 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
105 FIXME("(%p, %p): stub\n", This
, pStats
);
109 static HRESULT WINAPI
IDirectMusicPortImpl_Compact (LPDIRECTMUSICPORT iface
) {
110 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
111 FIXME("(%p): stub\n", This
);
115 static HRESULT WINAPI
IDirectMusicPortImpl_GetCaps (LPDIRECTMUSICPORT iface
, LPDMUS_PORTCAPS pPortCaps
) {
116 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
117 TRACE("(%p, %p)\n", This
, pPortCaps
);
118 *pPortCaps
= This
->caps
;
122 static HRESULT WINAPI
IDirectMusicPortImpl_DeviceIoControl (LPDIRECTMUSICPORT iface
, DWORD dwIoControlCode
, LPVOID lpInBuffer
, DWORD nInBufferSize
, LPVOID lpOutBuffer
, DWORD nOutBufferSize
, LPDWORD lpBytesReturned
, LPOVERLAPPED lpOverlapped
) {
123 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
124 FIXME("(%p, %d, %p, %d, %p, %d, %p, %p): stub\n", This
, dwIoControlCode
, lpInBuffer
, nInBufferSize
, lpOutBuffer
, nOutBufferSize
, lpBytesReturned
, lpOverlapped
);
128 static HRESULT WINAPI
IDirectMusicPortImpl_SetNumChannelGroups (LPDIRECTMUSICPORT iface
, DWORD dwChannelGroups
) {
129 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
130 FIXME("(%p, %d): semi-stub\n", This
, dwChannelGroups
);
131 This
->nrofgroups
= dwChannelGroups
;
135 static HRESULT WINAPI
IDirectMusicPortImpl_GetNumChannelGroups (LPDIRECTMUSICPORT iface
, LPDWORD pdwChannelGroups
) {
136 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
137 TRACE("(%p, %p)\n", This
, pdwChannelGroups
);
138 *pdwChannelGroups
= This
->nrofgroups
;
142 HRESULT WINAPI
IDirectMusicPortImpl_Activate (LPDIRECTMUSICPORT iface
, BOOL fActive
) {
143 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
144 TRACE("(%p, %d)\n", This
, fActive
);
145 This
->fActive
= fActive
;
149 static HRESULT WINAPI
IDirectMusicPortImpl_SetChannelPriority (LPDIRECTMUSICPORT iface
, DWORD dwChannelGroup
, DWORD dwChannel
, DWORD dwPriority
) {
150 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
151 FIXME("(%p, %d, %d, %d): semi-stub\n", This
, dwChannelGroup
, dwChannel
, dwPriority
);
152 if (dwChannel
> 16) {
153 WARN("isn't there supposed to be 16 channels (no. %d requested)?! (faking as it is ok)\n", dwChannel
);
154 /*return E_INVALIDARG;*/
159 static HRESULT WINAPI
IDirectMusicPortImpl_GetChannelPriority (LPDIRECTMUSICPORT iface
, DWORD dwChannelGroup
, DWORD dwChannel
, LPDWORD pdwPriority
) {
160 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
161 TRACE("(%p, %d, %d, %p)\n", This
, dwChannelGroup
, dwChannel
, pdwPriority
);
162 *pdwPriority
= This
->group
[dwChannelGroup
-1].channel
[dwChannel
].priority
;
166 static HRESULT WINAPI
IDirectMusicPortImpl_SetDirectSound (LPDIRECTMUSICPORT iface
, LPDIRECTSOUND pDirectSound
, LPDIRECTSOUNDBUFFER pDirectSoundBuffer
) {
167 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
168 FIXME("(%p, %p, %p): stub\n", This
, pDirectSound
, pDirectSoundBuffer
);
172 static HRESULT WINAPI
IDirectMusicPortImpl_GetFormat (LPDIRECTMUSICPORT iface
, LPWAVEFORMATEX pWaveFormatEx
, LPDWORD pdwWaveFormatExSize
, LPDWORD pdwBufferSize
) {
173 IDirectMusicPortImpl
*This
= (IDirectMusicPortImpl
*)iface
;
175 FIXME("(%p, %p, %p, %p): stub\n", This
, pWaveFormatEx
, pdwWaveFormatExSize
, pdwBufferSize
);
177 if (pWaveFormatEx
== NULL
)
179 if (pdwWaveFormatExSize
)
180 *pdwWaveFormatExSize
= sizeof(format
);
186 if (pdwWaveFormatExSize
== NULL
)
189 /* Just fill this in with something that will not crash Direct Sound for now. */
190 /* It won't be used anyway until Performances are completed */
191 format
.wFormatTag
= WAVE_FORMAT_PCM
;
192 format
.nChannels
= 2; /* This->params.dwAudioChannels; */
193 format
.nSamplesPerSec
= 44100; /* This->params.dwSampleRate; */
194 format
.wBitsPerSample
= 16; /* FIXME: check this */
195 format
.nBlockAlign
= (format
.wBitsPerSample
* format
.nChannels
) / 8;
196 format
.nAvgBytesPerSec
= format
.nSamplesPerSec
* format
.nBlockAlign
;
199 if (*pdwWaveFormatExSize
>= sizeof(format
))
201 CopyMemory(pWaveFormatEx
, &format
, min(sizeof(format
), *pdwWaveFormatExSize
));
202 *pdwWaveFormatExSize
= sizeof(format
); /* FIXME check if this is set */
205 return E_POINTER
; /* FIXME find right error */
209 *pdwBufferSize
= 44100 * 2 * 2;
216 const IDirectMusicPortVtbl DirectMusicPort_Vtbl
= {
217 IDirectMusicPortImpl_QueryInterface
,
218 IDirectMusicPortImpl_AddRef
,
219 IDirectMusicPortImpl_Release
,
220 IDirectMusicPortImpl_PlayBuffer
,
221 IDirectMusicPortImpl_SetReadNotificationHandle
,
222 IDirectMusicPortImpl_Read
,
223 IDirectMusicPortImpl_DownloadInstrument
,
224 IDirectMusicPortImpl_UnloadInstrument
,
225 IDirectMusicPortImpl_GetLatencyClock
,
226 IDirectMusicPortImpl_GetRunningStats
,
227 IDirectMusicPortImpl_Compact
,
228 IDirectMusicPortImpl_GetCaps
,
229 IDirectMusicPortImpl_DeviceIoControl
,
230 IDirectMusicPortImpl_SetNumChannelGroups
,
231 IDirectMusicPortImpl_GetNumChannelGroups
,
232 IDirectMusicPortImpl_Activate
,
233 IDirectMusicPortImpl_SetChannelPriority
,
234 IDirectMusicPortImpl_GetChannelPriority
,
235 IDirectMusicPortImpl_SetDirectSound
,
236 IDirectMusicPortImpl_GetFormat
239 HRESULT WINAPI
DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID
, LPVOID
*ppobj
, LPUNKNOWN pUnkOuter
, LPDMUS_PORTPARAMS pPortParams
, LPDMUS_PORTCAPS pPortCaps
) {
240 IDirectMusicPortImpl
*obj
;
243 TRACE("(%p,%p,%p)\n", lpcGUID
, ppobj
, pUnkOuter
);
245 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicPortImpl
));
247 *ppobj
= (LPDIRECTMUSICPORT
) NULL
;
248 return E_OUTOFMEMORY
;
250 obj
->lpVtbl
= &DirectMusicPort_Vtbl
;
251 obj
->ref
= 0; /* will be inited by QueryInterface */
252 obj
->fActive
= FALSE
;
253 obj
->params
= *pPortParams
;
254 obj
->caps
= *pPortCaps
;
255 obj
->pDirectSound
= NULL
;
256 obj
->pLatencyClock
= NULL
;
257 hr
= DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock
, (LPVOID
*)&obj
->pLatencyClock
, NULL
);
260 if (pPortParams
->dwValidParams
& DMUS_PORTPARAMS_CHANNELGROUPS
) {
261 obj
->nrofgroups
= pPortParams
->dwChannelGroups
;
262 /* setting default priorities */
263 for (j
= 0; j
< obj
->nrofgroups
; j
++) {
264 TRACE ("Setting default channel priorities on channel group %i\n", j
+ 1);
265 obj
->group
[j
].channel
[0].priority
= DAUD_CHAN1_DEF_VOICE_PRIORITY
;
266 obj
->group
[j
].channel
[1].priority
= DAUD_CHAN2_DEF_VOICE_PRIORITY
;
267 obj
->group
[j
].channel
[2].priority
= DAUD_CHAN3_DEF_VOICE_PRIORITY
;
268 obj
->group
[j
].channel
[3].priority
= DAUD_CHAN4_DEF_VOICE_PRIORITY
;
269 obj
->group
[j
].channel
[4].priority
= DAUD_CHAN5_DEF_VOICE_PRIORITY
;
270 obj
->group
[j
].channel
[5].priority
= DAUD_CHAN6_DEF_VOICE_PRIORITY
;
271 obj
->group
[j
].channel
[6].priority
= DAUD_CHAN7_DEF_VOICE_PRIORITY
;
272 obj
->group
[j
].channel
[7].priority
= DAUD_CHAN8_DEF_VOICE_PRIORITY
;
273 obj
->group
[j
].channel
[8].priority
= DAUD_CHAN9_DEF_VOICE_PRIORITY
;
274 obj
->group
[j
].channel
[9].priority
= DAUD_CHAN10_DEF_VOICE_PRIORITY
;
275 obj
->group
[j
].channel
[10].priority
= DAUD_CHAN11_DEF_VOICE_PRIORITY
;
276 obj
->group
[j
].channel
[11].priority
= DAUD_CHAN12_DEF_VOICE_PRIORITY
;
277 obj
->group
[j
].channel
[12].priority
= DAUD_CHAN13_DEF_VOICE_PRIORITY
;
278 obj
->group
[j
].channel
[13].priority
= DAUD_CHAN14_DEF_VOICE_PRIORITY
;
279 obj
->group
[j
].channel
[14].priority
= DAUD_CHAN15_DEF_VOICE_PRIORITY
;
280 obj
->group
[j
].channel
[15].priority
= DAUD_CHAN16_DEF_VOICE_PRIORITY
;
285 return IDirectMusicPortImpl_QueryInterface ((LPDIRECTMUSICPORT
)obj
, lpcGUID
, ppobj
);