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