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