Fix one ugly bug (horrible cast) into dmusic code to get Unreal2
[wine] / dlls / dmime / performance.c
1 /* IDirectMusicPerformance Implementation
2  *
3  * Copyright (C) 2003-2004 Rok Mandeljc
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
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
13  * GNU Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include "dmime_private.h"
21
22 WINE_DEFAULT_DEBUG_CHANNEL(dmime);
23
24 /* IDirectMusicPerformance8 IUnknown part: */
25 HRESULT WINAPI IDirectMusicPerformance8Impl_QueryInterface (LPDIRECTMUSICPERFORMANCE8 iface, REFIID riid, LPVOID *ppobj) {
26         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
27         TRACE("(%p, %s,%p)\n", This, debugstr_dmguid(riid), ppobj);
28
29         if (IsEqualIID (riid, &IID_IUnknown) || 
30             IsEqualIID (riid, &IID_IDirectMusicPerformance) ||
31             IsEqualIID (riid, &IID_IDirectMusicPerformance8)) {
32                 IDirectMusicPerformance8Impl_AddRef(iface);
33                 *ppobj = This;
34                 return S_OK;
35         }
36         
37         WARN("(%p, %s,%p): not found\n", This, debugstr_dmguid(riid), ppobj);
38         return E_NOINTERFACE;
39 }
40
41 ULONG WINAPI IDirectMusicPerformance8Impl_AddRef (LPDIRECTMUSICPERFORMANCE8 iface) {
42         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
43         TRACE("(%p): AddRef from %ld\n", This, This->ref);
44         return ++(This->ref);
45 }
46
47 ULONG WINAPI IDirectMusicPerformance8Impl_Release (LPDIRECTMUSICPERFORMANCE8 iface) {
48         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
49         ULONG ref = --This->ref;
50         TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
51         if (ref == 0) {
52                 HeapFree(GetProcessHeap(), 0, This);
53         }
54         return ref;
55 }
56
57 /* IDirectMusicPerformanceImpl IDirectMusicPerformance Interface part: */
58 HRESULT WINAPI IDirectMusicPerformance8Impl_Init (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusic** ppDirectMusic, LPDIRECTSOUND pDirectSound, HWND hWnd) {
59         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
60
61         FIXME("(iface = %p, dmusic = %p, dsound = %p, hwnd = %p)\n", This, ppDirectMusic, pDirectSound, hWnd);
62         if (This->pDirectMusic || This->pDirectSound)
63           return DMUS_E_ALREADY_INITED;
64         
65         if (NULL != pDirectSound) {
66           This->pDirectSound = (IDirectSound*) pDirectSound;
67           IDirectSound_AddRef((LPDIRECTSOUND) This->pDirectSound);
68         } else {
69           DirectSoundCreate8(&IID_IDirectSound8, (LPDIRECTSOUND8*) &This->pDirectSound, NULL);
70           /** 
71            * as seen in msdn
72            * 
73            *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directX/htm/idirectmusicperformance8initaudio.asp
74            */
75           if (NULL != hWnd) {
76             IDirectSound8_SetCooperativeLevel(This->pDirectSound, hWnd, DSSCL_PRIORITY);
77           } else {
78             /* how to get the ForeGround window handle ? */
79             /*IDirectSound8_SetCooperativeLevel(This->pDirectSound, hWnd, DSSCL_PRIORITY);*/
80           }
81           if (!This->pDirectSound)
82             return DSERR_NODRIVER;
83         }
84
85         if (NULL != ppDirectMusic && NULL != *ppDirectMusic) {
86           /* app creates it's own dmusic object and gives it to performance */
87           This->pDirectMusic = (IDirectMusic8*) *ppDirectMusic;
88           IDirectMusic8_AddRef((LPDIRECTMUSIC8) This->pDirectMusic);
89         } else {
90           /* app allows the performance to initialise itfself and needs a pointer to object*/
91           CoCreateInstance (&CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusic8, (void**)&This->pDirectMusic);
92           if (ppDirectMusic) {
93             *ppDirectMusic = (LPDIRECTMUSIC) This->pDirectMusic;
94             IDirectMusic8_AddRef((LPDIRECTMUSIC8) *ppDirectMusic);
95           }
96         }
97         
98         return S_OK;
99 }
100
101 HRESULT WINAPI IDirectMusicPerformance8Impl_PlaySegment (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicSegment* pSegment, DWORD dwFlags, __int64 i64StartTime, IDirectMusicSegmentState** ppSegmentState) {
102         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
103         FIXME("(%p, %p, %ld, %lli, %p): stub\n", This, pSegment, dwFlags, i64StartTime, ppSegmentState);
104         return S_OK;
105 }
106
107 HRESULT WINAPI IDirectMusicPerformance8Impl_Stop (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicSegment* pSegment, IDirectMusicSegmentState* pSegmentState, MUSIC_TIME mtTime, DWORD dwFlags) {
108         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
109         FIXME("(%p, %p, %p, %ld, %ld): stub\n", This, pSegment, pSegmentState, mtTime, dwFlags);
110         return S_OK;
111 }
112
113 HRESULT WINAPI IDirectMusicPerformance8Impl_GetSegmentState (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicSegmentState** ppSegmentState, MUSIC_TIME mtTime) {
114         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
115         FIXME("(%p,%p, %ld): stub\n", This, ppSegmentState, mtTime);
116         return S_OK;
117 }
118
119 HRESULT WINAPI IDirectMusicPerformance8Impl_SetPrepareTime (LPDIRECTMUSICPERFORMANCE8 iface, DWORD dwMilliSeconds) {
120         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
121         FIXME("(%p, %ld): stub\n", This, dwMilliSeconds);
122         return S_OK;
123 }
124
125 HRESULT WINAPI IDirectMusicPerformance8Impl_GetPrepareTime (LPDIRECTMUSICPERFORMANCE8 iface, DWORD* pdwMilliSeconds) {
126         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
127         FIXME("(%p, %p): stub\n", This, pdwMilliSeconds);
128         return S_OK;
129 }
130
131 HRESULT WINAPI IDirectMusicPerformance8Impl_SetBumperLength (LPDIRECTMUSICPERFORMANCE8 iface, DWORD dwMilliSeconds) {
132         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
133         FIXME("(%p, %ld): stub\n", This, dwMilliSeconds);
134         return S_OK;
135 }
136
137 HRESULT WINAPI IDirectMusicPerformance8Impl_GetBumperLength (LPDIRECTMUSICPERFORMANCE8 iface, DWORD* pdwMilliSeconds) {
138         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
139         FIXME("(%p, %p): stub\n", This, pdwMilliSeconds);
140         return S_OK;
141 }
142
143 HRESULT WINAPI IDirectMusicPerformance8Impl_SendPMsg (LPDIRECTMUSICPERFORMANCE8 iface, DMUS_PMSG* pPMSG) {
144         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
145         FIXME("(%p, %p): stub\n", This, pPMSG);
146         return S_OK;
147 }
148
149 HRESULT WINAPI IDirectMusicPerformance8Impl_MusicToReferenceTime (LPDIRECTMUSICPERFORMANCE8 iface, MUSIC_TIME mtTime, REFERENCE_TIME* prtTime) {
150         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
151         FIXME("(%p, %ld, %p): stub\n", This, mtTime, prtTime);
152         return S_OK;
153 }
154
155 HRESULT WINAPI IDirectMusicPerformance8Impl_ReferenceToMusicTime (LPDIRECTMUSICPERFORMANCE8 iface, REFERENCE_TIME rtTime, MUSIC_TIME* pmtTime) {
156         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
157         FIXME("(%p, %lli, %p): stub\n", This, rtTime, pmtTime);
158         return S_OK;
159 }
160
161 HRESULT WINAPI IDirectMusicPerformance8Impl_IsPlaying (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicSegment* pSegment, IDirectMusicSegmentState* pSegState) {
162         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
163         FIXME("(%p, %p, %p): stub\n", This, pSegment, pSegState);
164         return S_OK;
165 }
166
167 HRESULT WINAPI IDirectMusicPerformance8Impl_GetTime (LPDIRECTMUSICPERFORMANCE8 iface, REFERENCE_TIME* prtNow, MUSIC_TIME* pmtNow) {
168         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
169         FIXME("(%p, %p, %p): stub\n", This, prtNow, pmtNow);    
170         return S_OK;
171 }
172
173 HRESULT WINAPI IDirectMusicPerformance8Impl_AllocPMsg (LPDIRECTMUSICPERFORMANCE8 iface, ULONG cb, DMUS_PMSG** ppPMSG) {
174         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
175         FIXME("(%p, %ld, %p): stub\n", This, cb, ppPMSG);
176         return S_OK;
177 }
178
179 HRESULT WINAPI IDirectMusicPerformance8Impl_FreePMsg (LPDIRECTMUSICPERFORMANCE8 iface, DMUS_PMSG* pPMSG) {
180         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
181         FIXME("(%p, %p): stub\n", This, pPMSG);
182         return S_OK;
183 }
184
185 HRESULT WINAPI IDirectMusicPerformance8Impl_GetGraph (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicGraph** ppGraph) {
186         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
187         FIXME("(%p, %p): to check\n", This, ppGraph);
188         if (NULL != This->pToolGraph) {
189           *ppGraph = (LPDIRECTMUSICGRAPH) This->pToolGraph; 
190           IDirectMusicGraph_AddRef((LPDIRECTMUSICGRAPH) *ppGraph);
191         }
192         return S_OK;
193 }
194
195 HRESULT WINAPI IDirectMusicPerformance8Impl_SetGraph (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicGraph* pGraph) {
196         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
197
198         FIXME("(%p, %p): to check\n", This, pGraph);
199
200         if (NULL != This->pToolGraph) {
201           /* Todo clean buffers and tools before */
202           IDirectMusicGraph_Release((LPDIRECTMUSICGRAPH) This->pToolGraph);
203         }
204         This->pToolGraph = pGraph;
205         if (NULL != This->pToolGraph) {
206           IDirectMusicGraph_AddRef((LPDIRECTMUSICGRAPH) This->pToolGraph);
207         }
208         return S_OK;
209 }
210
211 HRESULT WINAPI IDirectMusicPerformance8Impl_SetNotificationHandle (LPDIRECTMUSICPERFORMANCE8 iface, HANDLE hNotification, REFERENCE_TIME rtMinimum) {
212         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
213         FIXME("(%p, %p, %lli): stub\n", This, hNotification, rtMinimum);
214         return S_OK;
215 }
216
217 HRESULT WINAPI IDirectMusicPerformance8Impl_GetNotificationPMsg (LPDIRECTMUSICPERFORMANCE8 iface, DMUS_NOTIFICATION_PMSG** ppNotificationPMsg) {
218         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
219         FIXME("(%p, %p): stub\n", This, ppNotificationPMsg);
220         return S_OK;
221 }
222
223 HRESULT WINAPI IDirectMusicPerformance8Impl_AddNotificationType (LPDIRECTMUSICPERFORMANCE8 iface, REFGUID rguidNotificationType) {
224         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
225         FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
226         return S_OK;
227 }
228
229 HRESULT WINAPI IDirectMusicPerformance8Impl_RemoveNotificationType (LPDIRECTMUSICPERFORMANCE8 iface, REFGUID rguidNotificationType) {
230         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
231         FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
232         return S_OK;
233 }
234
235 HRESULT WINAPI IDirectMusicPerformance8Impl_AddPort (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicPort* pPort) {
236         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
237         FIXME("(%p, %p): stub\n", This, pPort);
238         IDirectMusicPort_AddRef (pPort);
239         return S_OK;
240 }
241
242 HRESULT WINAPI IDirectMusicPerformance8Impl_RemovePort (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicPort* pPort) {
243         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
244         FIXME("(%p, %p): stub\n", This, pPort);
245         IDirectMusicPort_Release (pPort);
246         return S_OK;
247 }
248
249 HRESULT WINAPI IDirectMusicPerformance8Impl_AssignPChannelBlock (LPDIRECTMUSICPERFORMANCE8 iface, DWORD dwBlockNum, IDirectMusicPort* pPort, DWORD dwGroup) {
250         int i, j, range /* min value in range */;
251         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
252
253         FIXME("(%p, %ld, %p, %ld): semi-stub\n", This, dwBlockNum, pPort, dwGroup-1);
254         range = 16 * dwBlockNum;
255         j = 0;
256                 
257         for (i = range; i < range+16; i++) {
258                 /*TRACE("Setting PChannel[%i] to port %p, group %ld, MIDI port %i\n", i, pPort, dwGroup-1, j); */
259                 This->PChannel[i].port = pPort; 
260                 This->PChannel[i].group = dwGroup - 1; /* first index is always zero */
261                 This->PChannel[i].channel = j; /* FIXME: should this be assigned? */
262                 j++;
263         }
264
265         return S_OK;
266 }
267
268 HRESULT WINAPI IDirectMusicPerformance8Impl_AssignPChannel (LPDIRECTMUSICPERFORMANCE8 iface, DWORD dwPChannel, IDirectMusicPort* pPort, DWORD dwGroup, DWORD dwMChannel) {
269         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
270
271         TRACE("(%p, %ld, %p, %ld, %ld)\n", This, dwPChannel, pPort, dwGroup, dwMChannel);
272         This->PChannel[dwPChannel].port = pPort; 
273         This->PChannel[dwPChannel].group = dwGroup; 
274         This->PChannel[dwPChannel].channel = dwMChannel;
275
276         return S_OK;
277 }
278
279 HRESULT WINAPI IDirectMusicPerformance8Impl_PChannelInfo (LPDIRECTMUSICPERFORMANCE8 iface, DWORD dwPChannel, IDirectMusicPort** ppPort, DWORD* pdwGroup, DWORD* pdwMChannel) {
280         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
281         FIXME("(%p, %ld, %p, %p, %p): stub\n", This, dwPChannel, ppPort, pdwGroup, pdwMChannel);
282         return S_OK;
283 }
284
285 HRESULT WINAPI IDirectMusicPerformance8Impl_DownloadInstrument (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicInstrument* pInst, DWORD dwPChannel, IDirectMusicDownloadedInstrument** ppDownInst, DMUS_NOTERANGE* pNoteRanges, DWORD dwNumNoteRanges, IDirectMusicPort** ppPort, DWORD* pdwGroup, DWORD* pdwMChannel) {
286         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
287         FIXME("(%p, %p, %ld, %p, %p, %ld, %p, %p, %p): stub\n", This, pInst, dwPChannel, ppDownInst, pNoteRanges, dwNumNoteRanges, ppPort, pdwGroup, pdwMChannel);
288         return S_OK;
289 }
290
291 HRESULT WINAPI IDirectMusicPerformance8Impl_Invalidate (LPDIRECTMUSICPERFORMANCE8 iface, MUSIC_TIME mtTime, DWORD dwFlags) {
292         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
293         FIXME("(%p, %ld, %ld): stub\n", This, mtTime, dwFlags);
294         return S_OK;
295 }
296
297 HRESULT WINAPI IDirectMusicPerformance8Impl_GetParam (LPDIRECTMUSICPERFORMANCE8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam) {
298         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
299         FIXME("(%p, %s, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
300         return S_OK;
301 }
302
303 HRESULT WINAPI IDirectMusicPerformance8Impl_SetParam (LPDIRECTMUSICPERFORMANCE8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void* pParam) {
304         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
305         FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
306         return S_OK;
307 }
308
309 HRESULT WINAPI IDirectMusicPerformance8Impl_GetGlobalParam (LPDIRECTMUSICPERFORMANCE8 iface, REFGUID rguidType, void* pParam, DWORD dwSize) {
310         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
311
312         TRACE("(%p, %s, %p, %ld): stub\n", This, debugstr_dmguid(rguidType), pParam, dwSize);
313         
314         if (IsEqualGUID (rguidType, &GUID_PerfAutoDownload))
315                 memcpy(pParam, &This->fAutoDownload, sizeof(&This->fAutoDownload));
316         if (IsEqualGUID (rguidType, &GUID_PerfMasterGrooveLevel))
317                 memcpy(pParam, &This->cMasterGrooveLevel, sizeof(&This->cMasterGrooveLevel));
318         if (IsEqualGUID (rguidType, &GUID_PerfMasterTempo))
319                 memcpy(pParam, &This->fMasterTempo, sizeof(&This->fMasterTempo));
320         if (IsEqualGUID (rguidType, &GUID_PerfMasterVolume))
321                 memcpy(pParam, &This->lMasterVolume, sizeof(&This->lMasterVolume));
322
323         return S_OK;
324 }
325
326 HRESULT WINAPI IDirectMusicPerformance8Impl_SetGlobalParam (LPDIRECTMUSICPERFORMANCE8 iface, REFGUID rguidType, void* pParam, DWORD dwSize) {
327         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
328
329         TRACE("(%p, %s, %p, %ld)\n", This, debugstr_dmguid(rguidType), pParam, dwSize);
330         
331         if (IsEqualGUID (rguidType, &GUID_PerfAutoDownload)) {
332                 memcpy(&This->fAutoDownload, pParam, dwSize);
333                 TRACE("=> AutoDownload set to %d\n", This->fAutoDownload);
334         }
335         if (IsEqualGUID (rguidType, &GUID_PerfMasterGrooveLevel)) {
336                 memcpy(&This->cMasterGrooveLevel, pParam, dwSize);
337                 TRACE("=> MasterGrooveLevel set to %i\n", This->cMasterGrooveLevel);
338         }
339         if (IsEqualGUID (rguidType, &GUID_PerfMasterTempo)) {
340                 memcpy(&This->fMasterTempo, pParam, dwSize);
341                 TRACE("=> MasterTempo set to %f\n", This->fMasterTempo);
342         }
343         if (IsEqualGUID (rguidType, &GUID_PerfMasterVolume)) {
344                 memcpy(&This->lMasterVolume, pParam, dwSize);
345                 TRACE("=> MasterVolume set to %li\n", This->lMasterVolume);
346         }
347
348         return S_OK;
349 }
350
351 HRESULT WINAPI IDirectMusicPerformance8Impl_GetLatencyTime (LPDIRECTMUSICPERFORMANCE8 iface, REFERENCE_TIME* prtTime) {
352         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
353         FIXME("(%p, %p): stub\n", This, prtTime);
354         return S_OK;
355 }
356
357 HRESULT WINAPI IDirectMusicPerformance8Impl_GetQueueTime (LPDIRECTMUSICPERFORMANCE8 iface, REFERENCE_TIME* prtTime) {
358         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
359         FIXME("(%p, %p): stub\n", This, prtTime);
360         return S_OK;
361 }
362
363 HRESULT WINAPI IDirectMusicPerformance8Impl_AdjustTime (LPDIRECTMUSICPERFORMANCE8 iface, REFERENCE_TIME rtAmount) {
364         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
365         FIXME("(%p, %lli): stub\n", This, rtAmount);
366         return S_OK;
367 }
368
369 HRESULT WINAPI IDirectMusicPerformance8Impl_CloseDown (LPDIRECTMUSICPERFORMANCE8 iface) {
370         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
371         FIXME("(%p): stub\n", This);
372         return S_OK;
373 }
374
375 HRESULT WINAPI IDirectMusicPerformance8Impl_GetResolvedTime (LPDIRECTMUSICPERFORMANCE8 iface, REFERENCE_TIME rtTime, REFERENCE_TIME* prtResolved, DWORD dwTimeResolveFlags) {
376         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
377         FIXME("(%p, %lli, %p, %ld): stub\n", This, rtTime, prtResolved, dwTimeResolveFlags);
378         return S_OK;
379 }
380
381 HRESULT WINAPI IDirectMusicPerformance8Impl_MIDIToMusic (LPDIRECTMUSICPERFORMANCE8 iface, BYTE bMIDIValue, DMUS_CHORD_KEY* pChord, BYTE bPlayMode, BYTE bChordLevel, WORD* pwMusicValue) {
382         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
383         FIXME("(%p, %d, %p, %d, %d, %p): stub\n", This, bMIDIValue, pChord, bPlayMode, bChordLevel, pwMusicValue);
384         return S_OK;
385 }
386
387 HRESULT WINAPI IDirectMusicPerformance8Impl_MusicToMIDI (LPDIRECTMUSICPERFORMANCE8 iface, WORD wMusicValue, DMUS_CHORD_KEY* pChord, BYTE bPlayMode, BYTE bChordLevel, BYTE* pbMIDIValue) {
388         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
389         FIXME("(%p, %d, %p, %d, %d, %p): stub\n", This, wMusicValue, pChord, bPlayMode, bChordLevel, pbMIDIValue);
390         return S_OK;
391 }
392
393 HRESULT WINAPI IDirectMusicPerformance8Impl_TimeToRhythm (LPDIRECTMUSICPERFORMANCE8 iface, MUSIC_TIME mtTime, DMUS_TIMESIGNATURE* pTimeSig, WORD* pwMeasure, BYTE* pbBeat, BYTE* pbGrid, short* pnOffset) {
394         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
395         FIXME("(%p, %ld, %p, %p, %p, %p, %p): stub\n", This, mtTime, pTimeSig, pwMeasure, pbBeat, pbGrid, pnOffset);
396         return S_OK;
397 }
398
399 HRESULT WINAPI IDirectMusicPerformance8Impl_RhythmToTime (LPDIRECTMUSICPERFORMANCE8 iface, WORD wMeasure, BYTE bBeat, BYTE bGrid, short nOffset, DMUS_TIMESIGNATURE* pTimeSig, MUSIC_TIME* pmtTime) {
400         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
401         FIXME("(%p, %d, %d, %d, %i, %p, %p): stub\n", This, wMeasure, bBeat, bGrid, nOffset, pTimeSig, pmtTime);
402         return S_OK;
403 }
404
405 /* IDirectMusicPerformance8 Interface part follow: */
406 HRESULT WINAPI IDirectMusicPerformance8ImplInitAudio (LPDIRECTMUSICPERFORMANCE8 iface, 
407                                                       IDirectMusic** ppDirectMusic, 
408                                                       IDirectSound** ppDirectSound, 
409                                                       HWND hWnd, 
410                                                       DWORD dwDefaultPathType, 
411                                                       DWORD dwPChannelCount, 
412                                                       DWORD dwFlags, 
413                                                       DMUS_AUDIOPARAMS* pParams) {
414         IDirectSound* dsound;
415         HRESULT hr = S_OK;
416         
417         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
418         FIXME("(%p, %p, %p, %p, %lx, %lu, %lx, %p): to check\n", This, ppDirectMusic, ppDirectSound, hWnd, dwDefaultPathType, dwPChannelCount, dwFlags, pParams);
419
420         if (This->pDirectMusic || This->pDirectSound)
421           return DMUS_E_ALREADY_INITED;
422
423         if (NULL != ppDirectSound && NULL != *ppDirectSound) {
424           dsound = *ppDirectSound;
425         } else {
426           DirectSoundCreate8 (&IID_IDirectSound8, (LPDIRECTSOUND8*) &dsound, NULL);
427           if (!dsound)
428             return DSERR_NODRIVER;
429           if (ppDirectSound)
430             *ppDirectSound = dsound;  
431         }
432         
433         IDirectMusicPerformance8Impl_Init(iface, ppDirectMusic, dsound, hWnd);
434
435         /* Init increases the ref count of the dsound object. Decremente it if the app don't want a pointer to the object. */
436         if (!ppDirectSound)
437           IDirectSound_Release(This->pDirectSound);
438         
439         /* as seen in msdn we need params init before audio path creation */
440         if (NULL != pParams) {
441           memcpy(&This->pParams, pParams, sizeof(DMUS_AUDIOPARAMS));
442         } else {
443           /**
444            * TODO, how can i fill the struct 
445            * as seen at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directX/htm/dmusaudioparams.asp
446            */
447           This->pParams.dwSize = sizeof(DMUS_AUDIOPARAMS);
448           This->pParams.fInitNow = FALSE;
449           This->pParams.dwValidData = DMUS_AUDIOPARAMS_FEATURES | DMUS_AUDIOPARAMS_VOICES | DMUS_AUDIOPARAMS_SAMPLERATE | DMUS_AUDIOPARAMS_DEFAULTSYNTH;
450           This->pParams.dwVoices = 64;
451           This->pParams.dwSampleRate = (DWORD) 22.050; 
452           This->pParams.dwFeatures = dwFlags;
453           This->pParams.clsidDefaultSynth = CLSID_DirectMusicSynthSink;
454         }
455         hr = IDirectMusicPerformance8ImplCreateStandardAudioPath(iface, dwDefaultPathType, dwPChannelCount, FALSE, (IDirectMusicAudioPath**) &This->pDefaultPath);
456
457         return hr;
458 }
459
460 HRESULT WINAPI IDirectMusicPerformance8ImplPlaySegmentEx (LPDIRECTMUSICPERFORMANCE8 iface, IUnknown* pSource, WCHAR* pwzSegmentName, IUnknown* pTransition, DWORD dwFlags, __int64 i64StartTime, IDirectMusicSegmentState** ppSegmentState, IUnknown* pFrom, IUnknown* pAudioPath) {
461         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
462         FIXME("(%p, %p, %p, %p, %ld, %lli, %p, %p, %p): stub\n", This, pSource, pwzSegmentName, pTransition, dwFlags, i64StartTime, ppSegmentState, pFrom, pAudioPath);
463         return S_OK;
464 }
465
466 HRESULT WINAPI IDirectMusicPerformance8ImplStopEx (LPDIRECTMUSICPERFORMANCE8 iface, IUnknown* pObjectToStop, __int64 i64StopTime, DWORD dwFlags) {
467         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
468         FIXME("(%p, %p, %lli, %ld): stub\n", This, pObjectToStop, i64StopTime, dwFlags);
469         return S_OK;
470 }
471
472 HRESULT WINAPI IDirectMusicPerformance8ImplClonePMsg (LPDIRECTMUSICPERFORMANCE8 iface, DMUS_PMSG* pSourcePMSG, DMUS_PMSG** ppCopyPMSG) {
473         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
474         FIXME("(%p, %p, %p): stub\n", This, pSourcePMSG, ppCopyPMSG);
475         return S_OK;
476 }
477
478 HRESULT WINAPI IDirectMusicPerformance8ImplCreateAudioPath (LPDIRECTMUSICPERFORMANCE8 iface, IUnknown* pSourceConfig, BOOL fActivate, IDirectMusicAudioPath** ppNewPath) {
479         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
480         FIXME("(%p, %p, %d, %p): stub\n", This, pSourceConfig, fActivate, ppNewPath);
481         return S_OK;
482 }
483
484 /**
485  * see  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directX/htm/standardaudiopaths.asp
486  */
487 HRESULT WINAPI IDirectMusicPerformance8ImplCreateStandardAudioPath (LPDIRECTMUSICPERFORMANCE8 iface, DWORD dwType, DWORD dwPChannelCount, BOOL fActivate, IDirectMusicAudioPath** ppNewPath) {
488         IDirectMusicAudioPathImpl *default_path;
489         IDirectMusicAudioPath *pPath;
490         DSBUFFERDESC desc;
491         WAVEFORMATEX format;
492         LPDIRECTSOUNDBUFFER8 buffer;
493         HRESULT hr = S_OK;
494
495         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
496         
497         FIXME("(%p)->(%ld, %ld, %d, %p): semi-stub\n", This, dwType, dwPChannelCount, fActivate, ppNewPath);
498
499         if (NULL == ppNewPath) {
500           return E_POINTER;
501         }
502         
503         DMUSIC_CreateDirectMusicAudioPathImpl (&IID_IDirectMusicAudioPath, (LPVOID*)&pPath, NULL);
504         default_path = (IDirectMusicAudioPathImpl*)((char*)(pPath) - offsetof(IDirectMusicAudioPathImpl,AudioPathVtbl));
505         default_path->pPerf = (IDirectMusicPerformance8*) This;
506         
507         /* Secondary buffer description */
508         format.wFormatTag = WAVE_FORMAT_PCM;
509         format.nChannels = 1;
510         format.nSamplesPerSec = 44000;
511         format.nAvgBytesPerSec = 44000*2;
512         format.nBlockAlign = 2;
513         format.wBitsPerSample = 16;
514         format.cbSize = 0;
515         
516         desc.dwSize = sizeof(desc);
517         desc.dwFlags = DSBCAPS_CTRLFX | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS;
518         desc.dwBufferBytes = DSBSIZE_MIN;
519         desc.dwReserved = 0;
520         desc.lpwfxFormat = &format;
521         desc.guid3DAlgorithm = GUID_NULL;
522         
523         switch(dwType) {
524         case DMUS_APATH_DYNAMIC_3D:
525                 desc.dwFlags |= DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_MUTE3DATMAXDISTANCE;
526                 break;
527         case DMUS_APATH_DYNAMIC_MONO:
528                 desc.dwFlags |= DSBCAPS_CTRLFREQUENCY;
529                 break;
530         case DMUS_APATH_SHARED_STEREOPLUSREVERB:
531                 /* normally we havet to create 2 buffers (one for music other for reverb) 
532                  * in this case. See msdn
533                  */
534         case DMUS_APATH_DYNAMIC_STEREO:
535                 desc.dwFlags |= DSBCAPS_CTRLFREQUENCY;
536                 format.nChannels = 2;
537                 format.nBlockAlign *= 2;
538                 format.nAvgBytesPerSec *=2;
539                 break;
540         default:
541                 HeapFree(GetProcessHeap(), 0, default_path); 
542                 *ppNewPath = NULL;
543                 return E_INVALIDARG;
544                 break;
545         }
546
547         /* FIXME: Should we create one secondary buffer for each PChannel? */
548         hr = IDirectSound8_CreateSoundBuffer ((LPDIRECTSOUND8) This->pDirectSound, &desc, &buffer, NULL);
549         if (FAILED(hr)) {
550                 HeapFree(GetProcessHeap(), 0, default_path); 
551                 *ppNewPath = NULL;
552                 return DSERR_BUFFERLOST;
553         }
554         default_path->pDSBuffer = (IDirectSoundBuffer*) buffer;
555
556         /* Update description for creating primary buffer */
557         desc.dwFlags |= DSBCAPS_PRIMARYBUFFER;
558         desc.dwBufferBytes = 0;
559         desc.lpwfxFormat = NULL;
560
561         hr = IDirectSound8_CreateSoundBuffer ((LPDIRECTSOUND8) This->pDirectSound, &desc, &buffer, NULL);
562         if (FAILED(hr)) {
563                 IDirectSoundBuffer_Release(default_path->pDSBuffer);
564                 HeapFree(GetProcessHeap(), 0, default_path); 
565                 *ppNewPath = NULL;
566                 return DSERR_BUFFERLOST;
567         }
568         default_path->pPrimary = (IDirectSoundBuffer*) buffer;
569
570         *ppNewPath = (LPDIRECTMUSICAUDIOPATH) pPath;
571         
572         TRACE(" returning IDirectMusicPerformance interface at %p.\n", *ppNewPath);
573
574         return S_OK;
575 }
576
577 HRESULT WINAPI IDirectMusicPerformance8ImplSetDefaultAudioPath (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicAudioPath* pAudioPath) {
578         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
579
580         FIXME("(%p, %p): semi-stub\n", This, pAudioPath);
581         if (NULL != This->pDefaultPath) {
582                 IDirectMusicAudioPath_Release((LPDIRECTMUSICAUDIOPATH) This->pDefaultPath);
583                 ((IDirectMusicAudioPathImpl*) This->pDefaultPath)->pPerf = NULL;
584                 This->pDefaultPath = NULL;
585         }
586         This->pDefaultPath = pAudioPath;
587         if (NULL != This->pDefaultPath) {
588                 IDirectMusicAudioPath_AddRef((LPDIRECTMUSICAUDIOPATH) This->pDefaultPath);
589                 ((IDirectMusicAudioPathImpl*) This->pDefaultPath)->pPerf = (IDirectMusicPerformance8*) This;
590         }
591         
592         return S_OK;
593 }
594
595 HRESULT WINAPI IDirectMusicPerformance8ImplGetDefaultAudioPath (LPDIRECTMUSICPERFORMANCE8 iface, IDirectMusicAudioPath** ppAudioPath) {
596     ICOM_THIS(IDirectMusicPerformance8Impl,iface);
597
598         FIXME("(%p, %p): semi-stub\n", This, ppAudioPath);
599
600         if (NULL != This->pDefaultPath) {
601           *ppAudioPath = (LPDIRECTMUSICAUDIOPATH) This->pDefaultPath;
602           IDirectMusicAudioPath_AddRef(*ppAudioPath);
603         } else {
604           *ppAudioPath = NULL;
605         }
606         return S_OK;
607 }
608
609 HRESULT WINAPI IDirectMusicPerformance8ImplGetParamEx (LPDIRECTMUSICPERFORMANCE8 iface, REFGUID rguidType, DWORD dwTrackID, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam) {
610         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
611
612         FIXME("(%p, %s, %ld, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_dmguid(rguidType), dwTrackID, dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
613
614         return S_OK;
615 }
616
617 ICOM_VTABLE(IDirectMusicPerformance8) DirectMusicPerformance8_Vtbl = {
618     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
619         IDirectMusicPerformance8Impl_QueryInterface,
620         IDirectMusicPerformance8Impl_AddRef,
621         IDirectMusicPerformance8Impl_Release,
622         IDirectMusicPerformance8Impl_Init,
623         IDirectMusicPerformance8Impl_PlaySegment,
624         IDirectMusicPerformance8Impl_Stop,
625         IDirectMusicPerformance8Impl_GetSegmentState,
626         IDirectMusicPerformance8Impl_SetPrepareTime,
627         IDirectMusicPerformance8Impl_GetPrepareTime,
628         IDirectMusicPerformance8Impl_SetBumperLength,
629         IDirectMusicPerformance8Impl_GetBumperLength,
630         IDirectMusicPerformance8Impl_SendPMsg,
631         IDirectMusicPerformance8Impl_MusicToReferenceTime,
632         IDirectMusicPerformance8Impl_ReferenceToMusicTime,
633         IDirectMusicPerformance8Impl_IsPlaying,
634         IDirectMusicPerformance8Impl_GetTime,
635         IDirectMusicPerformance8Impl_AllocPMsg,
636         IDirectMusicPerformance8Impl_FreePMsg,
637         IDirectMusicPerformance8Impl_GetGraph,
638         IDirectMusicPerformance8Impl_SetGraph,
639         IDirectMusicPerformance8Impl_SetNotificationHandle,
640         IDirectMusicPerformance8Impl_GetNotificationPMsg,
641         IDirectMusicPerformance8Impl_AddNotificationType,
642         IDirectMusicPerformance8Impl_RemoveNotificationType,
643         IDirectMusicPerformance8Impl_AddPort,
644         IDirectMusicPerformance8Impl_RemovePort,
645         IDirectMusicPerformance8Impl_AssignPChannelBlock,
646         IDirectMusicPerformance8Impl_AssignPChannel,
647         IDirectMusicPerformance8Impl_PChannelInfo,
648         IDirectMusicPerformance8Impl_DownloadInstrument,
649         IDirectMusicPerformance8Impl_Invalidate,
650         IDirectMusicPerformance8Impl_GetParam,
651         IDirectMusicPerformance8Impl_SetParam,
652         IDirectMusicPerformance8Impl_GetGlobalParam,
653         IDirectMusicPerformance8Impl_SetGlobalParam,
654         IDirectMusicPerformance8Impl_GetLatencyTime,
655         IDirectMusicPerformance8Impl_GetQueueTime,
656         IDirectMusicPerformance8Impl_AdjustTime,
657         IDirectMusicPerformance8Impl_CloseDown,
658         IDirectMusicPerformance8Impl_GetResolvedTime,
659         IDirectMusicPerformance8Impl_MIDIToMusic,
660         IDirectMusicPerformance8Impl_MusicToMIDI,
661         IDirectMusicPerformance8Impl_TimeToRhythm,
662         IDirectMusicPerformance8Impl_RhythmToTime,
663         IDirectMusicPerformance8ImplInitAudio,
664         IDirectMusicPerformance8ImplPlaySegmentEx,
665         IDirectMusicPerformance8ImplStopEx,
666         IDirectMusicPerformance8ImplClonePMsg,
667         IDirectMusicPerformance8ImplCreateAudioPath,
668         IDirectMusicPerformance8ImplCreateStandardAudioPath,
669         IDirectMusicPerformance8ImplSetDefaultAudioPath,
670         IDirectMusicPerformance8ImplGetDefaultAudioPath,
671         IDirectMusicPerformance8ImplGetParamEx
672 };
673
674 /* for ClassFactory */
675 HRESULT WINAPI DMUSIC_CreateDirectMusicPerformanceImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter) {
676         IDirectMusicPerformance8Impl *obj;
677
678         TRACE("(%p,%p,%p)\n", lpcGUID, ppobj, pUnkOuter);
679
680         obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicPerformance8Impl));
681         if (NULL == obj)        {
682                 *ppobj = (LPDIRECTMUSICPERFORMANCE8)NULL;
683                 return E_OUTOFMEMORY;
684         }
685         obj->lpVtbl = &DirectMusicPerformance8_Vtbl;
686         obj->ref = 1;
687         obj->pDirectMusic = NULL;
688         obj->pDirectSound = NULL;
689         obj->pDefaultPath = NULL;
690         
691         return IDirectMusicPerformance8Impl_QueryInterface ((LPDIRECTMUSICPERFORMANCE8)obj, lpcGUID, ppobj);
692 }