From ee51a0c014f973a897654e95893eda39a768e7d9 Mon Sep 17 00:00:00 2001 From: Raphael Junqueira Date: Tue, 11 May 2004 04:27:23 +0000 Subject: [PATCH] - Many IDirectMusicSegment fixes (loading). - AudioPath crash fix (don't use DSound APIs if buffer is null). - Move generic functions to dmime_main.c for future reuse (from segment.c). - IDirectMusicTempoTrack loading (many tempo case must be handled). - IDirectMusicSegTriggerTrack loading implementation (now DMRF/DirectMusic References loading should be done). --- dlls/dmime/audiopath.c | 4 +- dlls/dmime/dmime_main.c | 103 +++++++++++++++ dlls/dmime/dmime_private.h | 3 + dlls/dmime/segment.c | 211 +++++++++++++---------------- dlls/dmime/segtriggertrack.c | 250 +++++++++++++++++++++++++++++++++-- dlls/dmime/tempotrack.c | 66 +++++++-- 6 files changed, 493 insertions(+), 144 deletions(-) diff --git a/dlls/dmime/audiopath.c b/dlls/dmime/audiopath.c index ebe7ed1cadc..5a332bf0bad 100644 --- a/dlls/dmime/audiopath.c +++ b/dlls/dmime/audiopath.c @@ -191,7 +191,9 @@ HRESULT WINAPI IDirectMusicAudioPathImpl_IDirectMusicAudioPath_Activate (LPDIREC } else { if (This->fActive) return S_OK; This->fActive = TRUE; - IDirectSoundBuffer_Stop(This->pDSBuffer); + if (NULL != This->pDSBuffer) { + IDirectSoundBuffer_Stop(This->pDSBuffer); + } } return S_OK; } diff --git a/dlls/dmime/dmime_main.c b/dlls/dmime/dmime_main.c index c6f18427ae7..7596ec081d2 100644 --- a/dlls/dmime/dmime_main.c +++ b/dlls/dmime/dmime_main.c @@ -20,6 +20,7 @@ #include "dmime_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dmime); +WINE_DECLARE_DEBUG_CHANNEL(dmfile); typedef struct { /* IUnknown fields */ @@ -1155,3 +1156,105 @@ const char *debugstr_DMUS_OBJECTDESC (LPDMUS_OBJECTDESC pDesc) { */ return "X"; } + +HRESULT IDirectMusicImpl_IPersistStream_ParseDescGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc) { + + switch (pChunk->fccID) { + case DMUS_FOURCC_GUID_CHUNK: { + TRACE_(dmfile)(": GUID chunk\n"); + pDesc->dwValidData |= DMUS_OBJ_OBJECT; + IStream_Read (pStm, &pDesc->guidObject, pChunk->dwSize, NULL); + break; + } + case DMUS_FOURCC_DATE_CHUNK: { + TRACE_(dmfile)(": file date chunk\n"); + pDesc->dwValidData |= DMUS_OBJ_DATE; + IStream_Read (pStm, &pDesc->ftDate, pChunk->dwSize, NULL); + break; + } + case DMUS_FOURCC_NAME_CHUNK: { + TRACE_(dmfile)(": name chunk\n"); + pDesc->dwValidData |= DMUS_OBJ_NAME; + IStream_Read (pStm, &pDesc->wszName, pChunk->dwSize, NULL); + break; + } + case DMUS_FOURCC_FILE_CHUNK: { + TRACE_(dmfile)(": file name chunk\n"); + pDesc->dwValidData |= DMUS_OBJ_FILENAME; + IStream_Read (pStm, &pDesc->wszFileName, pChunk->dwSize, NULL); + break; + } + case DMUS_FOURCC_VERSION_CHUNK: { + TRACE_(dmfile)(": version chunk\n"); + pDesc->dwValidData |= DMUS_OBJ_VERSION; + IStream_Read (pStm, &pDesc->vVersion, pChunk->dwSize, NULL); + break; + } + case DMUS_FOURCC_CATEGORY_CHUNK: { + TRACE_(dmfile)(": category chunk\n"); + pDesc->dwValidData |= DMUS_OBJ_CATEGORY; + IStream_Read (pStm, pDesc->wszCategory, pChunk->dwSize, NULL); + break; + } + default: + /* not handled */ + return S_FALSE; + } + + return S_OK; +} + +HRESULT IDirectMusicImpl_IPersistStream_ParseUNFOGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc) { + + LARGE_INTEGER liMove; /* used when skipping chunks */ + + /** + * don't ask me why, but M$ puts INFO elements in UNFO list sometimes + * (though strings seem to be valid unicode) + */ + switch (pChunk->fccID) { + + case mmioFOURCC('I','N','A','M'): + case DMUS_FOURCC_UNAM_CHUNK: { + TRACE_(dmfile)(": name chunk\n"); + pDesc->dwValidData |= DMUS_OBJ_NAME; + IStream_Read (pStm, pDesc->wszName, pChunk->dwSize, NULL); + + break; + } + + case mmioFOURCC('I','A','R','T'): + case DMUS_FOURCC_UART_CHUNK: { + TRACE_(dmfile)(": artist chunk (ignored)\n"); + liMove.QuadPart = pChunk->dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + case mmioFOURCC('I','C','O','P'): + case DMUS_FOURCC_UCOP_CHUNK: { + TRACE_(dmfile)(": copyright chunk (ignored)\n"); + liMove.QuadPart = pChunk->dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + case mmioFOURCC('I','S','B','J'): + case DMUS_FOURCC_USBJ_CHUNK: { + TRACE_(dmfile)(": subject chunk (ignored)\n"); + liMove.QuadPart = pChunk->dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + case mmioFOURCC('I','C','M','T'): + case DMUS_FOURCC_UCMT_CHUNK: { + TRACE_(dmfile)(": comment chunk (ignored)\n"); + liMove.QuadPart = pChunk->dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + default: + /* not handled */ + return S_FALSE; + } + + return S_OK; +} diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h index cebeba1efba..abaa066362a 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h @@ -960,4 +960,7 @@ extern const char *debugstr_DMUS_OBJ_FLAGS (DWORD flagmask); /* dump whole DMUS_OBJECTDESC struct */ extern const char *debugstr_DMUS_OBJECTDESC (LPDMUS_OBJECTDESC pDesc); +HRESULT IDirectMusicImpl_IPersistStream_ParseDescGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc); +HRESULT IDirectMusicImpl_IPersistStream_ParseUNFOGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc); + #endif /* __WINE_DMIME_PRIVATE_H */ diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c index e8e28bf0cac..aef5809b332 100644 --- a/dlls/dmime/segment.c +++ b/dlls/dmime/segment.c @@ -626,90 +626,6 @@ HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_IsDirty (LPPERSISTSTREAM return S_FALSE; } - -static HRESULT IDirectMusicImpl_IPersistStream_ParseDescGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc) { - - switch (pChunk->fccID) { - case DMUS_FOURCC_GUID_CHUNK: { - TRACE_(dmfile)(": GUID chunk\n"); - pDesc->dwValidData |= DMUS_OBJ_OBJECT; - IStream_Read (pStm, &pDesc->guidObject, pChunk->dwSize, NULL); - break; - } - case DMUS_FOURCC_VERSION_CHUNK: { - TRACE_(dmfile)(": version chunk\n"); - pDesc->dwValidData |= DMUS_OBJ_VERSION; - IStream_Read (pStm, &pDesc->vVersion, pChunk->dwSize, NULL); - break; - } - case DMUS_FOURCC_CATEGORY_CHUNK: { - TRACE_(dmfile)(": category chunk\n"); - pDesc->dwValidData |= DMUS_OBJ_CATEGORY; - IStream_Read (pStm, pDesc->wszCategory, pChunk->dwSize, NULL); - break; - } - default: - /* not handled */ - return S_FALSE; - } - - return S_OK; -} - -static HRESULT IDirectMusicImpl_IPersistStream_ParseUNFOGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc) { - - LARGE_INTEGER liMove; /* used when skipping chunks */ - - /** - * don't ask me why, but M$ puts INFO elements in UNFO list sometimes - * (though strings seem to be valid unicode) - */ - switch (pChunk->fccID) { - /* - case mmioFOURCC('I','N','A','M'): - case DMUS_FOURCC_UNAM_CHUNK: { - TRACE_(dmfile)(": name chunk\n"); - pDesc->dwValidData |= DMUS_OBJ_NAME; - IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL); - break; - } - */ - case mmioFOURCC('I','A','R','T'): - case DMUS_FOURCC_UART_CHUNK: { - TRACE_(dmfile)(": artist chunk (ignored)\n"); - liMove.QuadPart = pChunk->dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - case mmioFOURCC('I','C','O','P'): - case DMUS_FOURCC_UCOP_CHUNK: { - TRACE_(dmfile)(": copyright chunk (ignored)\n"); - liMove.QuadPart = pChunk->dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - case mmioFOURCC('I','S','B','J'): - case DMUS_FOURCC_USBJ_CHUNK: { - TRACE_(dmfile)(": subject chunk (ignored)\n"); - liMove.QuadPart = pChunk->dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - case mmioFOURCC('I','C','M','T'): - case DMUS_FOURCC_UCMT_CHUNK: { - TRACE_(dmfile)(": comment chunk (ignored)\n"); - liMove.QuadPart = pChunk->dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - default: - /* not handled */ - return S_FALSE; - } - - return S_OK; -} - static HRESULT IDirectMusicSegment8Impl_IPersistStream_LoadTrack (LPPERSISTSTREAM iface, IStream* pClonedStream, IDirectMusicTrack** ppTrack, DMUS_IO_TRACK_HEADER* pTrack_hdr) { @@ -797,12 +713,78 @@ static HRESULT IDirectMusicSegment8Impl_IPersistStream_ParseTrackForm (LPPERSIST TRACE_(dmfile)(": TRACK list\n"); + IStream_Clone (pStm, &pClonedStream); + + liMove.QuadPart = 0; + liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD)); + IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL); + + hr = IDirectMusicSegment8Impl_IPersistStream_LoadTrack (iface, pClonedStream, &pTrack, &track_hdr); + if (FAILED(hr)) { + ERR(": could not load track\n"); + return hr; + } + + hr = IDirectMusicSegment8Impl_IDirectMusicSegment8_InsertTrack ((LPDIRECTMUSICSEGMENT8)This->SegmentVtbl, pTrack, track_hdr.dwGroup); /* at dsPosition */ + if (FAILED(hr)) { + ERR(": could not insert track\n"); + return hr; + } + IDirectMusicTrack_Release(pTrack); pTrack = NULL; /* now we can release at as it inserted */ + IStream_Release (pClonedStream); + +#if 0 +#else + /* + do { + IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); + ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; + TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); + switch (Chunk.fccID) { + default: { + TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + } + + TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]); + } while (ListCount[0] < ListSize[0]); + */ + +#endif + + liMove.QuadPart = ListSize[0]; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + + /* + */ + } else { + TRACE_(dmfile)(": unknown (skipping)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + } + break; + } + + case FOURCC_RIFF: { + IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); + FIXME_(dmfile)(": RIFF chunk of type %s (behavior to check)\n", debugstr_fourcc(Chunk.fccID)); + + ListSize[0] = Chunk.dwSize - sizeof(FOURCC); + + if (Chunk.fccID == track_hdr.fccType && 0 == track_hdr.ckid) { + LPSTREAM pClonedStream = NULL; + + TRACE_(dmfile)(": TRACK RIFF\n"); + IStream_Clone (pStm, &pClonedStream); liMove.QuadPart = 0; liMove.QuadPart -= (sizeof(FOURCC) + sizeof(DWORD)); IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL); - + hr = IDirectMusicSegment8Impl_IPersistStream_LoadTrack (iface, pClonedStream, &pTrack, &track_hdr); if (FAILED(hr)) { ERR(": could not load track\n"); @@ -818,39 +800,18 @@ static HRESULT IDirectMusicSegment8Impl_IPersistStream_ParseTrackForm (LPPERSIST } IDirectMusicTrack_Release(pTrack); pTrack = NULL; /* now we can release at as it inserted */ - liMove.QuadPart = Chunk.dwSize; + /** now safe move the cursor */ + liMove.QuadPart = ListSize[0]; IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + + } else { + TRACE_(dmfile)(": unknown RIFF fmt (skipping)\n"); + liMove.QuadPart = ListSize[0]; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + } + break; + } - } else { - TRACE_(dmfile)(": unknown (skipping)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - } - break; - } - - case FOURCC_RIFF: { - IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); - FIXME_(dmfile)(": LIST chunk of type %s (behavior to check)", debugstr_fourcc(Chunk.fccID)); - ListSize[0] = Chunk.dwSize - sizeof(FOURCC); - ListCount[0] = 0; - if (Chunk.fccID == track_hdr.fccType && 0 == track_hdr.ckid) { - TRACE_(dmfile)(": TRACK RIFF\n"); - /* - hr = IDirectMusicSegment8Impl_IPersistStream_LoadTrack (iface, pStm, &pTrack, &track_hdr); - if (FAILED(hr)) return hr; - */ - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - - } else { - TRACE_(dmfile)(": unknown (skipping)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - } - break; - } - default: { if (0 == track_hdr.fccType && Chunk.fccID == track_hdr.ckid) { LPSTREAM pClonedStream = NULL; @@ -908,7 +869,7 @@ static HRESULT IDirectMusicSegment8Impl_IPersistStream_ParseTrackList (LPPERSIST return E_FAIL; } - ListSize[0] = Chunk.dwSize - sizeof(FOURCC); + ListSize[0] = pChunk->dwSize - sizeof(FOURCC); ListCount[0] = 0; do { @@ -976,8 +937,9 @@ static HRESULT IDirectMusicSegment8Impl_IPersistStream_ParseSegmentForm (LPPERSI if (hr == S_FALSE) { switch (Chunk.fccID) { case DMUS_FOURCC_SEGMENT_CHUNK: { - DWORD checkSz = 0; + DWORD checkSz = sizeof(FOURCC); FIXME_(dmfile)(": segment chunk\n"); +#if 1 /** DX 7 */ IStream_Read (pStm, &This->header.dwRepeats, sizeof(This->header.dwRepeats), NULL); checkSz += sizeof(This->header.dwRepeats); @@ -991,6 +953,12 @@ static HRESULT IDirectMusicSegment8Impl_IPersistStream_ParseSegmentForm (LPPERSI checkSz += sizeof(This->header.mtLoopEnd); IStream_Read (pStm, &This->header.dwResolution, sizeof(This->header.dwResolution), NULL); checkSz += sizeof(This->header.dwResolution); + TRACE_(dmfile)("dwRepeats: %lu\n", This->header.dwRepeats); + TRACE_(dmfile)("mtLength: %lu\n", This->header.mtLength); + TRACE_(dmfile)("mtPlayStart: %lu\n", This->header.mtPlayStart); + TRACE_(dmfile)("mtLoopStart: %lu\n", This->header.mtLoopStart); + TRACE_(dmfile)("mtLoopEnd: %lu\n", This->header.mtLoopEnd); + TRACE_(dmfile)("dwResolution: %lu\n", This->header.dwResolution); /** DX 8 */ if (Chunk.dwSize > checkSz) { IStream_Read (pStm, &This->header.rtLength, sizeof(This->header.rtLength), NULL); @@ -1007,7 +975,8 @@ static HRESULT IDirectMusicSegment8Impl_IPersistStream_ParseSegmentForm (LPPERSI IStream_Read (pStm, &This->header.rtPlayStart, sizeof(This->header.rtPlayStart), NULL); checkSz += sizeof(This->header.rtPlayStart); } - liMove.QuadPart = Chunk.dwSize - checkSz; +#endif + liMove.QuadPart = Chunk.dwSize - checkSz + sizeof(FOURCC); IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); break; } @@ -1081,7 +1050,7 @@ HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_Load (LPPERSISTSTREAM ifa LARGE_INTEGER liMove; /* used when skipping chunks */ - FIXME("(%p, %p): Loading not implemented yet\n", This, pStm); + FIXME("(%p, %p): Loading not fully implemented yet\n", This, pStm); IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); switch (Chunk.fccID) { @@ -1125,7 +1094,7 @@ HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_Load (LPPERSISTSTREAM ifa } HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) { - return E_NOTIMPL; + return E_NOTIMPL; } HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) { diff --git a/dlls/dmime/segtriggertrack.c b/dlls/dmime/segtriggertrack.c index af4d873d855..cec615de21d 100644 --- a/dlls/dmime/segtriggertrack.c +++ b/dlls/dmime/segtriggertrack.c @@ -209,39 +209,265 @@ ICOM_VTABLE(IDirectMusicTrack8) DirectMusicSegTriggerTrack_Track_Vtbl = { /* IDirectMusicSegTriggerTrack IPersistStream part: */ HRESULT WINAPI IDirectMusicSegTriggerTrack_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) { - ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); - return IDirectMusicSegTriggerTrack_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj); + ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); + return IDirectMusicSegTriggerTrack_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj); } ULONG WINAPI IDirectMusicSegTriggerTrack_IPersistStream_AddRef (LPPERSISTSTREAM iface) { - ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); - return IDirectMusicSegTriggerTrack_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); + ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); + return IDirectMusicSegTriggerTrack_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); } ULONG WINAPI IDirectMusicSegTriggerTrack_IPersistStream_Release (LPPERSISTSTREAM iface) { - ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); - return IDirectMusicSegTriggerTrack_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl); + ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); + return IDirectMusicSegTriggerTrack_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl); } HRESULT WINAPI IDirectMusicSegTriggerTrack_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) { - return E_NOTIMPL; + ICOM_THIS_MULTI(IDirectMusicSegment8Impl, PersistStreamVtbl, iface); + FIXME("(%p, %p): stub\n", This, pClassID); + return E_NOTIMPL; } HRESULT WINAPI IDirectMusicSegTriggerTrack_IPersistStream_IsDirty (LPPERSISTSTREAM iface) { - return E_NOTIMPL; + ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); + FIXME("(%p): stub, always S_FALSE\n", This); + return S_FALSE; } +static HRESULT IDirectMusicSegTriggerTrack_IPersistStream_ParseSegment (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, IDirectMusicSegTriggerTrack* This) { + + DMUS_PRIVATE_CHUNK Chunk; + DWORD ListSize[3], ListCount[3]; + LARGE_INTEGER liMove; /* used when skipping chunks */ + + if (pChunk->fccID != DMUS_FOURCC_SEGMENT_LIST) { + ERR_(dmfile)(": %s chunk should be a SEGMENT list\n", debugstr_fourcc (pChunk->fccID)); + return E_FAIL; + } + + ListSize[0] = pChunk->dwSize - sizeof(FOURCC); + ListCount[0] = 0; + + do { + IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); + ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; + TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); + switch (Chunk.fccID) { + case DMUS_FOURCC_SEGMENTITEM_CHUNK: { + TRACE_(dmfile)(": segment item chunk\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + case DMUS_FOURCC_SEGMENTITEMNAME_CHUNK: { + TRACE_(dmfile)(": segment item name chunk\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + case FOURCC_LIST: { + IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); + TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); + ListSize[1] = Chunk.dwSize - sizeof(FOURCC); + ListCount[1] = 0; + switch (Chunk.fccID) { + /** + * should be a DMRF (DirectMusic Reference) list @TODO + */ + default: { + TRACE_(dmfile)(": unknown (skipping)\n"); + liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + } + break; + } + default: { + TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + } + TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]); + } while (ListCount[0] < ListSize[0]); + + return S_OK; +} + +static HRESULT IDirectMusicSegTriggerTrack_IPersistStream_ParseSegmentsList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, IDirectMusicSegTriggerTrack* This) { + + HRESULT hr = E_FAIL; + DMUS_PRIVATE_CHUNK Chunk; + DWORD ListSize[3], ListCount[3]; + LARGE_INTEGER liMove; /* used when skipping chunks */ + + if (pChunk->fccID != DMUS_FOURCC_SEGMENTS_LIST) { + ERR_(dmfile)(": %s chunk should be a SEGMENTS list\n", debugstr_fourcc (pChunk->fccID)); + return E_FAIL; + } + + ListSize[0] = pChunk->dwSize - sizeof(FOURCC); + ListCount[0] = 0; + + do { + IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); + ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; + TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); + switch (Chunk.fccID) { + case FOURCC_LIST: { + IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); + TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); + ListSize[1] = Chunk.dwSize - sizeof(FOURCC); + ListCount[1] = 0; + switch (Chunk.fccID) { + case DMUS_FOURCC_SEGMENT_LIST: { + TRACE_(dmfile)(": SEGMENT list\n"); + hr = IDirectMusicSegTriggerTrack_IPersistStream_ParseSegment (iface, &Chunk, pStm, This); + if (FAILED(hr)) return hr; + break; + } + default: { + TRACE_(dmfile)(": unknown (skipping)\n"); + liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + } + break; + } + default: { + TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + } + TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]); + } while (ListCount[0] < ListSize[0]); + + return S_OK; +} + +static HRESULT IDirectMusicSegTriggerTrack_IPersistStream_ParseSegTrackList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, IDirectMusicSegTriggerTrack* This) { + + HRESULT hr = E_FAIL; + DMUS_PRIVATE_CHUNK Chunk; + DWORD ListSize[3], ListCount[3]; + LARGE_INTEGER liMove; /* used when skipping chunks */ + + if (pChunk->fccID != DMUS_FOURCC_SEGTRACK_LIST) { + ERR_(dmfile)(": %s chunk should be a TRACK list\n", debugstr_fourcc (pChunk->fccID)); + return E_FAIL; + } + + ListSize[0] = pChunk->dwSize - sizeof(FOURCC); + ListCount[0] = 0; + + do { + IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); + ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; + TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); + switch (Chunk.fccID) { + case DMUS_FOURCC_SEGTRACK_CHUNK: { + FIXME_(dmfile)(": segment trigger track chunk\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + case FOURCC_LIST: { + IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); + TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); + ListSize[1] = Chunk.dwSize - sizeof(FOURCC); + ListCount[1] = 0; + switch (Chunk.fccID) { + case DMUS_FOURCC_SEGMENTS_LIST: { + TRACE_(dmfile)(": SEGMENTS list\n"); + hr = IDirectMusicSegTriggerTrack_IPersistStream_ParseSegmentsList (iface, &Chunk, pStm, This); + if (FAILED(hr)) return hr; + break; + } + default: { + TRACE_(dmfile)(": unknown (skipping)\n"); + liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + } + break; + } + default: { + TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + break; + } + } + TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]); + } while (ListCount[0] < ListSize[0]); + + return S_OK; +} + + HRESULT WINAPI IDirectMusicSegTriggerTrack_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) { - FIXME(": Loading not implemented yet\n"); - return S_OK; + ICOM_THIS_MULTI(IDirectMusicSegTriggerTrack, PersistStreamVtbl, iface); + + DMUS_PRIVATE_CHUNK Chunk; + LARGE_INTEGER liMove; + HRESULT hr; + + FIXME("(%p, %p): Loading not fully implemented yet\n", This, pStm); + +#if 1 + IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); + TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); + switch (Chunk.fccID) { + case FOURCC_LIST: { + IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); + TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); + switch (Chunk.fccID) { + case DMUS_FOURCC_SEGTRACK_LIST: { + TRACE_(dmfile)(": segment trigger track list\n"); + hr = IDirectMusicSegTriggerTrack_IPersistStream_ParseSegTrackList (iface, &Chunk, pStm, This); + if (FAILED(hr)) return hr; + /* + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + */ + + break; + } + default: { + TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + return E_FAIL; + } + } + TRACE_(dmfile)(": reading finished\n"); + break; + } + default: { + TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */ + return E_FAIL; + } + } +#endif + + return S_OK; } HRESULT WINAPI IDirectMusicSegTriggerTrack_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) { - return E_NOTIMPL; + return E_NOTIMPL; } HRESULT WINAPI IDirectMusicSegTriggerTrack_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) { - return E_NOTIMPL; + return E_NOTIMPL; } ICOM_VTABLE(IPersistStream) DirectMusicSegTriggerTrack_PersistStream_Vtbl = { diff --git a/dlls/dmime/tempotrack.c b/dlls/dmime/tempotrack.c index a86b236b6d4..b55b32a9e77 100644 --- a/dlls/dmime/tempotrack.c +++ b/dlls/dmime/tempotrack.c @@ -214,31 +214,77 @@ ICOM_VTABLE(IDirectMusicTrack8) DirectMusicTempoTrack_Track_Vtbl = { /* IDirectMusicTempoTrack IPersistStream part: */ HRESULT WINAPI IDirectMusicTempoTrack_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) { - ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); - return IDirectMusicTempoTrack_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj); + ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); + return IDirectMusicTempoTrack_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj); } ULONG WINAPI IDirectMusicTempoTrack_IPersistStream_AddRef (LPPERSISTSTREAM iface) { - ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); - return IDirectMusicTempoTrack_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); + ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); + return IDirectMusicTempoTrack_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); } ULONG WINAPI IDirectMusicTempoTrack_IPersistStream_Release (LPPERSISTSTREAM iface) { - ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); - return IDirectMusicTempoTrack_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl); + ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); + return IDirectMusicTempoTrack_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl); } HRESULT WINAPI IDirectMusicTempoTrack_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) { - return E_NOTIMPL; + ICOM_THIS_MULTI(IDirectMusicSegment8Impl, PersistStreamVtbl, iface); + FIXME("(%p, %p): stub\n", This, pClassID); + return S_OK; } HRESULT WINAPI IDirectMusicTempoTrack_IPersistStream_IsDirty (LPPERSISTSTREAM iface) { - return E_NOTIMPL; + ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); + FIXME("(%p): stub, always S_FALSE\n", This); + return S_FALSE; } HRESULT WINAPI IDirectMusicTempoTrack_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) { - FIXME(": Loading not implemented yet\n"); - return S_OK; + ICOM_THIS_MULTI(IDirectMusicTempoTrack, PersistStreamVtbl, iface); + DMUS_PRIVATE_CHUNK Chunk; + DWORD StreamSize, StreamCount; + LARGE_INTEGER liMove; + DMUS_IO_TEMPO_ITEM item; + DWORD nItem = 0; + FIXME("(%p, %p): Loading not fully implemented yet\n", This, pStm); + +#if 1 + IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); + TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); + switch (Chunk.fccID) { + case DMUS_FOURCC_TEMPO_TRACK: { + TRACE_(dmfile)(": tempo track\n"); +#if 1 + IStream_Read (pStm, &StreamSize, sizeof(DWORD), NULL); + StreamSize -= sizeof(DWORD); + StreamCount = 0; + TRACE_(dmfile)(": items (size = %lu, chunkSize = %lu)\n", StreamSize, Chunk.dwSize - sizeof(DWORD)); + do { + IStream_Read (pStm, &item, sizeof(item), NULL); + ++nItem; + TRACE_(dmfile)("DMUS_IO_TEMPO_ITEM: item %ld\n", nItem); + TRACE_(dmfile)(" - lTime = %lu\n", item.lTime); + TRACE_(dmfile)(" - dblTempo = %g\n", item.dblTempo); + StreamCount += sizeof(item); + TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize); + } while (StreamCount < StreamSize); +#else + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); +#endif + break; + } + default: { + TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); + liMove.QuadPart = Chunk.dwSize; + IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); + return E_FAIL; + } + } +#endif + + return S_OK; } HRESULT WINAPI IDirectMusicTempoTrack_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {