1 /* IDirectMusicChordTrack Implementation
3 * Copyright (C) 2003 Rok Mandeljc
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.
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.
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.
26 #include "wine/debug.h"
27 #include "wine/unicode.h"
29 #include "dmstyle_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(dmstyle
);
32 WINE_DECLARE_DEBUG_CHANNEL(dmfile
);
34 /*****************************************************************************
35 * IDirectMusicChordTrack implementation
37 /* IDirectMusicChordTrack IUnknown part: */
38 HRESULT WINAPI
IDirectMusicChordTrack_QueryInterface (LPDIRECTMUSICTRACK8 iface
, REFIID riid
, LPVOID
*ppobj
)
40 ICOM_THIS(IDirectMusicChordTrack
,iface
);
42 if (IsEqualIID (riid
, &IID_IUnknown
) ||
43 IsEqualIID (riid
, &IID_IDirectMusicTrack
) ||
44 IsEqualIID (riid
, &IID_IDirectMusicTrack8
)) {
45 IDirectMusicChordTrack_AddRef(iface
);
48 } else if (IsEqualIID (riid
, &IID_IPersistStream
)) {
49 IDirectMusicChordTrackStream_AddRef ((LPPERSISTSTREAM
)This
->pStream
);
50 *ppobj
= This
->pStream
;
54 WARN("(%p)->(%s,%p),not found\n", This
, debugstr_guid(riid
), ppobj
);
58 ULONG WINAPI
IDirectMusicChordTrack_AddRef (LPDIRECTMUSICTRACK8 iface
)
60 ICOM_THIS(IDirectMusicChordTrack
,iface
);
61 TRACE("(%p) : AddRef from %ld\n", This
, This
->ref
);
65 ULONG WINAPI
IDirectMusicChordTrack_Release (LPDIRECTMUSICTRACK8 iface
)
67 ICOM_THIS(IDirectMusicChordTrack
,iface
);
68 ULONG ref
= --This
->ref
;
69 TRACE("(%p) : ReleaseRef to %ld\n", This
, This
->ref
);
71 HeapFree(GetProcessHeap(), 0, This
);
76 /* IDirectMusicChordTrack IDirectMusicTrack part: */
77 HRESULT WINAPI
IDirectMusicChordTrack_Init (LPDIRECTMUSICTRACK8 iface
, IDirectMusicSegment
* pSegment
)
79 ICOM_THIS(IDirectMusicChordTrack
,iface
);
81 FIXME("(%p, %p): stub\n", This
, pSegment
);
86 HRESULT WINAPI
IDirectMusicChordTrack_InitPlay (LPDIRECTMUSICTRACK8 iface
, IDirectMusicSegmentState
* pSegmentState
, IDirectMusicPerformance
* pPerformance
, void** ppStateData
, DWORD dwVirtualTrack8ID
, DWORD dwFlags
)
88 ICOM_THIS(IDirectMusicChordTrack
,iface
);
90 FIXME("(%p, %p, %p, %p, %ld, %ld): stub\n", This
, pSegmentState
, pPerformance
, ppStateData
, dwVirtualTrack8ID
, dwFlags
);
95 HRESULT WINAPI
IDirectMusicChordTrack_EndPlay (LPDIRECTMUSICTRACK8 iface
, void* pStateData
)
97 ICOM_THIS(IDirectMusicChordTrack
,iface
);
99 FIXME("(%p, %p): stub\n", This
, pStateData
);
104 HRESULT WINAPI
IDirectMusicChordTrack_Play (LPDIRECTMUSICTRACK8 iface
, void* pStateData
, MUSIC_TIME mtStart
, MUSIC_TIME mtEnd
, MUSIC_TIME mtOffset
, DWORD dwFlags
, IDirectMusicPerformance
* pPerf
, IDirectMusicSegmentState
* pSegSt
, DWORD dwVirtualID
)
106 ICOM_THIS(IDirectMusicChordTrack
,iface
);
108 FIXME("(%p, %p, %ld, %ld, %ld, %ld, %p, %p, %ld): stub\n", This
, pStateData
, mtStart
, mtEnd
, mtOffset
, dwFlags
, pPerf
, pSegSt
, dwVirtualID
);
113 HRESULT WINAPI
IDirectMusicChordTrack_GetParam (LPDIRECTMUSICTRACK8 iface
, REFGUID rguidType
, MUSIC_TIME mtTime
, MUSIC_TIME
* pmtNext
, void* pParam
)
115 ICOM_THIS(IDirectMusicChordTrack
,iface
);
117 FIXME("(%p, %s, %ld, %p, %p): stub\n", This
, debugstr_guid(rguidType
), mtTime
, pmtNext
, pParam
);
122 HRESULT WINAPI
IDirectMusicChordTrack_SetParam (LPDIRECTMUSICTRACK8 iface
, REFGUID rguidType
, MUSIC_TIME mtTime
, void* pParam
)
124 ICOM_THIS(IDirectMusicChordTrack
,iface
);
126 FIXME("(%p, %s, %ld, %p): stub\n", This
, debugstr_guid(rguidType
), mtTime
, pParam
);
131 HRESULT WINAPI
IDirectMusicChordTrack_IsParamSupported (LPDIRECTMUSICTRACK8 iface
, REFGUID rguidType
)
133 ICOM_THIS(IDirectMusicChordTrack
,iface
);
135 TRACE("(%p, %s): ", This
, debugstr_guid(rguidType
));
136 if (IsEqualGUID (rguidType
, &GUID_BandParam
)
137 || IsEqualGUID (rguidType
, &GUID_ChordParam
)
138 || IsEqualGUID (rguidType
, &GUID_RhythmParam
)) {
139 TRACE("param supported\n");
143 TRACE("param unsupported\n");
144 return DMUS_E_TYPE_UNSUPPORTED
;
147 HRESULT WINAPI
IDirectMusicChordTrack_AddNotificationType (LPDIRECTMUSICTRACK8 iface
, REFGUID rguidNotificationType
)
149 ICOM_THIS(IDirectMusicChordTrack
,iface
);
151 FIXME("(%p, %s): stub\n", This
, debugstr_guid(rguidNotificationType
));
156 HRESULT WINAPI
IDirectMusicChordTrack_RemoveNotificationType (LPDIRECTMUSICTRACK8 iface
, REFGUID rguidNotificationType
)
158 ICOM_THIS(IDirectMusicChordTrack
,iface
);
160 FIXME("(%p, %s): stub\n", This
, debugstr_guid(rguidNotificationType
));
165 HRESULT WINAPI
IDirectMusicChordTrack_Clone (LPDIRECTMUSICTRACK8 iface
, MUSIC_TIME mtStart
, MUSIC_TIME mtEnd
, IDirectMusicTrack
** ppTrack
)
167 ICOM_THIS(IDirectMusicChordTrack
,iface
);
169 FIXME("(%p, %ld, %ld, %p): stub\n", This
, mtStart
, mtEnd
, ppTrack
);
174 /* IDirectMusicChordTrack IDirectMusicTrack8 part: */
175 HRESULT WINAPI
IDirectMusicChordTrack_PlayEx (LPDIRECTMUSICTRACK8 iface
, void* pStateData
, REFERENCE_TIME rtStart
, REFERENCE_TIME rtEnd
, REFERENCE_TIME rtOffset
, DWORD dwFlags
, IDirectMusicPerformance
* pPerf
, IDirectMusicSegmentState
* pSegSt
, DWORD dwVirtualID
)
177 ICOM_THIS(IDirectMusicChordTrack
,iface
);
179 FIXME("(%p, %p, %lli, %lli, %lli, %ld, %p, %p, %ld): stub\n", This
, pStateData
, rtStart
, rtEnd
, rtOffset
, dwFlags
, pPerf
, pSegSt
, dwVirtualID
);
184 HRESULT WINAPI
IDirectMusicChordTrack_GetParamEx (LPDIRECTMUSICTRACK8 iface
, REFGUID rguidType
, REFERENCE_TIME rtTime
, REFERENCE_TIME
* prtNext
, void* pParam
, void* pStateData
, DWORD dwFlags
)
186 ICOM_THIS(IDirectMusicChordTrack
,iface
);
188 FIXME("(%p, %s, %lli, %p, %p, %p, %ld): stub\n", This
, debugstr_guid(rguidType
), rtTime
, prtNext
, pParam
, pStateData
, dwFlags
);
193 HRESULT WINAPI
IDirectMusicChordTrack_SetParamEx (LPDIRECTMUSICTRACK8 iface
, REFGUID rguidType
, REFERENCE_TIME rtTime
, void* pParam
, void* pStateData
, DWORD dwFlags
)
195 ICOM_THIS(IDirectMusicChordTrack
,iface
);
197 FIXME("(%p, %s, %lli, %p, %p, %ld): stub\n", This
, debugstr_guid(rguidType
), rtTime
, pParam
, pStateData
, dwFlags
);
202 HRESULT WINAPI
IDirectMusicChordTrack_Compose (LPDIRECTMUSICTRACK8 iface
, IUnknown
* pContext
, DWORD dwTrackGroup
, IDirectMusicTrack
** ppResultTrack
)
204 ICOM_THIS(IDirectMusicChordTrack
,iface
);
206 FIXME("(%p, %p, %ld, %p): stub\n", This
, pContext
, dwTrackGroup
, ppResultTrack
);
211 HRESULT WINAPI
IDirectMusicChordTrack_Join (LPDIRECTMUSICTRACK8 iface
, IDirectMusicTrack
* pNewTrack
, MUSIC_TIME mtJoin
, IUnknown
* pContext
, DWORD dwTrackGroup
, IDirectMusicTrack
** ppResultTrack
)
213 ICOM_THIS(IDirectMusicChordTrack
,iface
);
215 FIXME("(%p, %p, %ld, %p, %ld, %p): stub\n", This
, pNewTrack
, mtJoin
, pContext
, dwTrackGroup
, ppResultTrack
);
220 ICOM_VTABLE(IDirectMusicTrack8
) DirectMusicChordTrack_Vtbl
=
222 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
223 IDirectMusicChordTrack_QueryInterface
,
224 IDirectMusicChordTrack_AddRef
,
225 IDirectMusicChordTrack_Release
,
226 IDirectMusicChordTrack_Init
,
227 IDirectMusicChordTrack_InitPlay
,
228 IDirectMusicChordTrack_EndPlay
,
229 IDirectMusicChordTrack_Play
,
230 IDirectMusicChordTrack_GetParam
,
231 IDirectMusicChordTrack_SetParam
,
232 IDirectMusicChordTrack_IsParamSupported
,
233 IDirectMusicChordTrack_AddNotificationType
,
234 IDirectMusicChordTrack_RemoveNotificationType
,
235 IDirectMusicChordTrack_Clone
,
236 IDirectMusicChordTrack_PlayEx
,
237 IDirectMusicChordTrack_GetParamEx
,
238 IDirectMusicChordTrack_SetParamEx
,
239 IDirectMusicChordTrack_Compose
,
240 IDirectMusicChordTrack_Join
243 /* for ClassFactory */
244 HRESULT WINAPI
DMUSIC_CreateDirectMusicChordTrack (LPCGUID lpcGUID
, LPDIRECTMUSICTRACK8
*ppTrack
, LPUNKNOWN pUnkOuter
)
246 IDirectMusicChordTrack
* track
;
248 if (IsEqualIID (lpcGUID
, &IID_IDirectMusicTrack
)
249 || IsEqualIID (lpcGUID
, &IID_IDirectMusicTrack8
)) {
250 track
= HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicChordTrack
));
252 *ppTrack
= (LPDIRECTMUSICTRACK8
) NULL
;
253 return E_OUTOFMEMORY
;
255 track
->lpVtbl
= &DirectMusicChordTrack_Vtbl
;
257 track
->pStream
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicChordTrackStream
));
258 track
->pStream
->lpVtbl
= &DirectMusicChordTrackStream_Vtbl
;
259 track
->pStream
->ref
= 1;
260 track
->pStream
->pParentTrack
= track
;
261 *ppTrack
= (LPDIRECTMUSICTRACK8
) track
;
265 WARN("No interface found\n");
266 return E_NOINTERFACE
;
270 /*****************************************************************************
271 * IDirectMusicChordTrackStream implementation
273 /* IDirectMusicChordTrackStream IUnknown part follow: */
274 HRESULT WINAPI
IDirectMusicChordTrackStream_QueryInterface (LPPERSISTSTREAM iface
, REFIID riid
, LPVOID
*ppobj
)
276 ICOM_THIS(IDirectMusicChordTrackStream
,iface
);
278 if (IsEqualGUID(riid
, &IID_IUnknown
)
279 || IsEqualGUID(riid
, &IID_IPersistStream
)) {
280 IDirectMusicChordTrackStream_AddRef(iface
);
285 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppobj
);
286 return E_NOINTERFACE
;
289 ULONG WINAPI
IDirectMusicChordTrackStream_AddRef (LPPERSISTSTREAM iface
)
291 ICOM_THIS(IDirectMusicChordTrackStream
,iface
);
292 TRACE("(%p) : AddRef from %ld\n", This
, This
->ref
);
293 return ++(This
->ref
);
296 ULONG WINAPI
IDirectMusicChordTrackStream_Release (LPPERSISTSTREAM iface
)
298 ICOM_THIS(IDirectMusicChordTrackStream
,iface
);
299 ULONG ref
= --This
->ref
;
300 TRACE("(%p) : ReleaseRef to %ld\n", This
, This
->ref
);
302 HeapFree(GetProcessHeap(), 0, This
);
307 /* IDirectMusicChordTrackStream IPersist part: */
308 HRESULT WINAPI
IDirectMusicChordTrackStream_GetClassID (LPPERSISTSTREAM iface
, CLSID
* pClassID
)
313 /* IDirectMusicChordTrackStream IPersistStream part: */
314 HRESULT WINAPI
IDirectMusicChordTrackStream_IsDirty (LPPERSISTSTREAM iface
)
319 HRESULT WINAPI
IDirectMusicChordTrackStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
)
321 ICOM_THIS(IDirectMusicChordTrackStream
,iface
);
323 DWORD chunkSize
, dwSizeOfStruct
, ListSize
[1], ListCount
[1];
324 LARGE_INTEGER liMove
; /* used when skipping chunks */
325 IDirectMusicChordTrack
* pTrack
= This
->pParentTrack
; /* that's where we load data to */
326 DMUS_IO_CHORD tempChord
; /* temporary, used for reading data */
329 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
330 IStream_Read (pStm
, &chunkSize
, sizeof(DWORD
), NULL
);
331 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
334 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
335 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(chunkID
));
336 ListSize
[0] = chunkSize
- sizeof(FOURCC
);
339 case DMUS_FOURCC_CHORDTRACK_LIST
: {
340 TRACE_(dmfile
)(": chord track list\n");
342 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
343 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
344 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
345 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
347 case DMUS_FOURCC_CHORDTRACKHEADER_CHUNK
: {
348 TRACE_(dmfile
)(": chord track header chunk\n");
349 IStream_Read (pStm
, &pTrack
->dwHeader
, chunkSize
, NULL
);
350 TRACE_(dmfile
)(": (READ): header: chord root = %i; chord scale = %i\n", (pTrack
->dwHeader
&& 0xFF000000) >> 24, pTrack
->dwHeader
&& 0x00FFFFFF);
353 case DMUS_FOURCC_CHORDTRACKBODY_CHUNK
: {
354 TRACE_(dmfile
)(": chord track body chunk\n");
355 /* make space for one more structure */
356 /* pTrack->dwChordKeys++; */ /* moved at the end for correct counting */
357 /* FIXME: scheme with HeapReAlloc doesn't work so.. */
358 /* pTrack->pChordKeys = HeapReAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, pTrack->pChordKeys, sizeof(DMUS_CHORD_KEY) * pTrack->dwChordKeys); */
359 /* pTrack->pChordKeysTime = HeapReAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, pTrack->pChordKeysTime, sizeof(MUSIC_TIME) *pTrack->dwChordKeys); */
360 /* load size of DMUS_IO_CHORD */
361 IStream_Read (pStm
, &dwSizeOfStruct
, sizeof(DWORD
), NULL
);
362 if (dwSizeOfStruct
!= sizeof(DMUS_IO_CHORD
)) {
363 TRACE_(dmfile
)(": declared size of struct (=%ld) != actual size (=%i); loading failed\n", dwSizeOfStruct
, sizeof(DMUS_IO_CHORD
));
366 /* reset temporary storage and fill it with data */
367 ZeroMemory (&tempChord
, sizeof(DMUS_IO_CHORD
));
368 IStream_Read (pStm
, &tempChord
, dwSizeOfStruct
, NULL
);
369 /* copy data to final destination */
370 strncpyW (pTrack
->pChordKeys
[pTrack
->dwChordKeys
].wszName
, tempChord
.wszName
, 16);
371 /*pTrack->pChordKeys[pTrack->dwChordKeys].wszName = tempChord.wszName; */
372 pTrack
->pChordKeys
[pTrack
->dwChordKeys
].wMeasure
= tempChord
.wMeasure
;
373 pTrack
->pChordKeys
[pTrack
->dwChordKeys
].bBeat
= tempChord
.bBeat
;
374 pTrack
->pChordKeys
[pTrack
->dwChordKeys
].bFlags
= tempChord
.bFlags
;
375 /* this one is my invention */
376 pTrack
->pChordKeysTime
[pTrack
->dwChordKeys
] = tempChord
.mtTime
;
377 /* FIXME: are these two are derived from header? */
378 pTrack
->pChordKeys
[pTrack
->dwChordKeys
].dwScale
= pTrack
->dwHeader
&& 0x00FFFFFF;
379 pTrack
->pChordKeys
[pTrack
->dwChordKeys
].bKey
= (pTrack
->dwHeader
&& 0xFF000000) >> 24;
380 /* now here comes number of subchords */
381 IStream_Read (pStm
, &tempSubChords
, sizeof(DWORD
), NULL
);
382 pTrack
->pChordKeys
[pTrack
->dwChordKeys
].bSubChordCount
= tempSubChords
;
383 /* load size of DMUS_IO_SUBCHORD */
384 IStream_Read (pStm
, &dwSizeOfStruct
, sizeof(DWORD
), NULL
);
385 if (dwSizeOfStruct
!= sizeof(DMUS_IO_SUBCHORD
)) {
386 TRACE_(dmfile
)(": declared size of struct (=%ld) != actual size (=%i); loading failed\n", dwSizeOfStruct
, sizeof(DMUS_IO_SUBCHORD
));
389 IStream_Read (pStm
, pTrack
->pChordKeys
[pTrack
->dwChordKeys
].SubChordList
, dwSizeOfStruct
* tempSubChords
, NULL
);
390 /* well, this should be it :) */
391 pTrack
->dwChordKeys
++;
395 TRACE_(dmfile
)(": unknown chunk (skipping)\n");
396 liMove
.QuadPart
= chunkSize
;
397 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip this chunk */
401 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
402 } while (ListCount
[0] < ListSize
[0]);
406 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
407 liMove
.QuadPart
= ListSize
[0];
408 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
412 /* in the end, let's see what we got */
413 TRACE_(dmfile
)(": reading finished\n");
414 if (TRACE_ON(dmfile
)) {
416 TRACE_(dmfile
)(": (READ): number of chord keys in track = %ld\n", pTrack
->dwChordKeys
);
417 for (i
= 0; i
< pTrack
->dwChordKeys
; i
++) {
418 TRACE_(dmfile
)(": (READ): chord key[%i]: associated mtTime = %li\n", i
, pTrack
->pChordKeysTime
[i
]);
419 TRACE_(dmfile
)(": (READ): chord key[%i]: wszName = %s; wMeasure = %d; bBeat = %i; dwScale = %ld; \
420 bKey = %i; bFlags = %i; bSubChordCount = %i\n", i
, debugstr_w (pTrack
->pChordKeys
[i
].wszName
), \
421 pTrack
->pChordKeys
[i
].wMeasure
, pTrack
->pChordKeys
[i
].bBeat
, pTrack
->pChordKeys
[i
].dwScale
, \
422 pTrack
->pChordKeys
[i
].bKey
, pTrack
->pChordKeys
[i
].bFlags
, pTrack
->pChordKeys
[i
].bSubChordCount
);
423 for (j
= 0; j
< pTrack
->pChordKeys
[i
].bSubChordCount
; j
++) {
424 TRACE_(dmfile
)(": (READ): chord key[%i]: subchord[%i]: dwChordPattern = %ld; \
425 dwScalePattern = %ld; dwInversionPoints = %ld; dwLevels = %ld; bChordRoot = %i; \
426 bScaleRoot = %i\n", i
, j
, pTrack
->pChordKeys
[i
].SubChordList
[j
].dwChordPattern
, \
427 pTrack
->pChordKeys
[i
].SubChordList
[j
].dwScalePattern
, pTrack
->pChordKeys
[i
].SubChordList
[j
].dwInversionPoints
, \
428 pTrack
->pChordKeys
[i
].SubChordList
[j
].dwLevels
, pTrack
->pChordKeys
[i
].SubChordList
[j
].bChordRoot
, \
429 pTrack
->pChordKeys
[i
].SubChordList
[j
].bScaleRoot
);
436 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
437 liMove
.QuadPart
= chunkSize
;
438 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
446 HRESULT WINAPI
IDirectMusicChordTrackStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
)
451 HRESULT WINAPI
IDirectMusicChordTrackStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
)
456 ICOM_VTABLE(IPersistStream
) DirectMusicChordTrackStream_Vtbl
=
458 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
459 IDirectMusicChordTrackStream_QueryInterface
,
460 IDirectMusicChordTrackStream_AddRef
,
461 IDirectMusicChordTrackStream_Release
,
462 IDirectMusicChordTrackStream_GetClassID
,
463 IDirectMusicChordTrackStream_IsDirty
,
464 IDirectMusicChordTrackStream_Load
,
465 IDirectMusicChordTrackStream_Save
,
466 IDirectMusicChordTrackStream_GetSizeMax