Commit 858557f4 authored by Raphael Junqueira's avatar Raphael Junqueira Committed by Alexandre Julliard

- Parse DMStyle motifs (ie patterns) and bands (fill lists).

- Implement IDirectMusicSegment8::InsertTrack and IDirectMusicSegment8::RemoveTrack (now EnumTrack GetParam, and GetTrack should be easy to do).
parent 10227610
......@@ -144,6 +144,15 @@ extern HRESULT WINAPI DMUSIC_CreateDirectMusicTimeSigTrack (LPCGUID lpcGUID, LPV
extern HRESULT WINAPI DMUSIC_CreateDirectMusicWaveTrack (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter);
/*****************************************************************************
* Auxiliary definitions
*/
typedef struct _DMUS_PRIVATE_SEGMENT_TRACK {
struct list entry; /* for listing elements */
DWORD dwGroupBits;
IDirectMusicTrack* pTrack;
} DMUS_PRIVATE_SEGMENT_TRACK, *LPDMUS_PRIVATE_SEGMENT_TRACK;
/* some sort of aux. performance channel: as far as i can understand, these are
used to represent a particular midi channel in particular group at particular
group; so all we need to do is to fill it with parent port, group and midi
......@@ -266,7 +275,8 @@ struct IDirectMusicSegment8Impl {
/* IDirectMusicSegment8Impl fields */
LPDMUS_OBJECTDESC pDesc;
DMUS_IO_SEGMENT_HEADER header;
IDirectMusicGraph* pGraph;
IDirectMusicGraph* pGraph;
struct list Tracks;
};
/* IUnknown: */
......
......@@ -158,15 +158,64 @@ HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetTrackGroup (LPDI
}
HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_InsertTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD dwGroupBits) {
LPDMUS_PRIVATE_SEGMENT_TRACK pNewSegTrack;
ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
FIXME("(%p, %p, %ld): stub\n", This, pTrack, dwGroupBits);
struct list *pEntry;
DWORD i = 0;
LPDMUS_PRIVATE_SEGMENT_TRACK pIt = NULL;
TRACE("(%p, %p, %ld)\n", This, pTrack, dwGroupBits);
LIST_FOR_EACH (pEntry, &This->Tracks) {
i++;
pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_SEGMENT_TRACK, entry);
TRACE(" - #%lu: %p -> %ld,%p\n", i, pIt, pIt->dwGroupBits, pIt->pTrack);
if (NULL != pIt && pIt->pTrack == pTrack) {
ERR("(%p, %p): track is already in list\n", This, pTrack);
return E_FAIL;
}
}
pNewSegTrack = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_SEGMENT_TRACK));
if (NULL == pNewSegTrack) {
ERR(": no more memory\n");
return E_OUTOFMEMORY;
}
pNewSegTrack->dwGroupBits = dwGroupBits;
pNewSegTrack->pTrack = pTrack;
IDirectMusicTrack_Init(pTrack, iface);
IDirectMusicTrack_AddRef(pTrack);
list_add_tail (&This->Tracks, &pNewSegTrack->entry);
return S_OK;
}
HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_RemoveTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack) {
ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
struct list *pEntry;
DWORD i = 0;
LPDMUS_PRIVATE_SEGMENT_TRACK pIt = NULL;
FIXME("(%p, %p): stub\n", This, pTrack);
return S_OK;
LIST_FOR_EACH (pEntry, &This->Tracks) {
i++;
pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_SEGMENT_TRACK, entry);
if (pIt->pTrack == pTrack) {
TRACE("(%p, %p): track in list\n", This, pTrack);
list_remove(&pIt->entry);
IDirectMusicTrack_Init(pIt->pTrack, NULL);
IDirectMusicTrack_Release(pIt->pTrack);
HeapFree(GetProcessHeap(), 0, pIt);
return S_OK;
}
}
return S_FALSE;
}
HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_InitPlay (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicSegmentState** ppSegState, IDirectMusicPerformance* pPerformance, DWORD dwFlags) {
......@@ -655,7 +704,7 @@ static HRESULT IDirectMusicSegment8Impl_IPersistStream_LoadTrack (LPPERSISTSTREA
/* release all loading-related stuff */
IPersistStream_Release (pPersistStream);
hr = IDirectMusicSegment8Impl_IDirectMusicSegment8_InsertTrack ((LPDIRECTMUSICSEGMENT8)This->SegmentVtbl, *ppTrack, pTrack_hdr->dwGroup); /* at dsPosition */
hr = IDirectMusicSegment8Impl_IDirectMusicSegment8_InsertTrack ((LPDIRECTMUSICSEGMENT8)&This->SegmentVtbl, *ppTrack, pTrack_hdr->dwGroup); /* at dsPosition */
if (FAILED(hr)) {
ERR(": could not insert track\n");
return hr;
......@@ -1099,6 +1148,7 @@ HRESULT WINAPI DMUSIC_CreateDirectMusicSegmentImpl (LPCGUID lpcGUID, LPVOID* ppo
obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
memcpy (&obj->pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof (CLSID));
obj->ref = 0; /* will be inited by QueryInterface */
list_init (&obj->Tracks);
return IDirectMusicSegment8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);
}
......@@ -93,6 +93,22 @@ extern ICOM_VTABLE(IPersistStream) DirectMusicStyleTrack_PersistStream_Vtbl;
*/
extern HRESULT WINAPI DMUSIC_CreateDirectMusicStyleImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter);
/*****************************************************************************
* Auxiliary definitions
*/
typedef struct _DMUS_PRIVATE_STYLE_BAND {
struct list entry; /* for listing elements */
IDirectMusicBand* pBand;
} DMUS_PRIVATE_STYLE_BAND, *LPDMUS_PRIVATE_STYLE_BAND;
typedef struct _DMUS_PRIVATE_STYLE_MOTIF {
struct list entry; /* for listing elements */
DMUS_OBJECTDESC desc;
DMUS_IO_PATTERN pattern;
DMUS_IO_MOTIFSETTINGS settings;
IDirectMusicBand* pBand;
} DMUS_PRIVATE_STYLE_MOTIF, *LPDMUS_PRIVATE_STYLE_MOTIF;
extern HRESULT WINAPI DMUSIC_CreateDirectMusicAuditionTrack (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter);
extern HRESULT WINAPI DMUSIC_CreateDirectMusicChordTrack (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter);
extern HRESULT WINAPI DMUSIC_CreateDirectMusicCommandTrack (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter);
......@@ -115,6 +131,10 @@ struct IDirectMusicStyle8Impl {
/* IDirectMusicStyle8Impl fields */
LPDMUS_OBJECTDESC pDesc;
DMUS_IO_STYLE style;
/* data */
struct list Motifs;
struct list Bands;
};
/* IUnknown: */
......
......@@ -430,7 +430,36 @@ HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_IsDirty (LPPERSISTSTREAM if
return S_FALSE;
}
static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
static HRESULT IDirectMusicStyle8Impl_IPersistStream_LoadBand (LPPERSISTSTREAM iface, IStream* pClonedStream, IDirectMusicBand** ppBand) {
HRESULT hr = E_FAIL;
IPersistStream* pPersistStream = NULL;
hr = CoCreateInstance (&CLSID_DirectMusicBand, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicBand, (LPVOID*) ppBand);
if (FAILED(hr)) {
ERR(": could not create object\n");
return hr;
}
/* acquire PersistStream interface */
hr = IDirectMusicBand_QueryInterface (*ppBand, &IID_IPersistStream, (LPVOID*) &pPersistStream);
if (FAILED(hr)) {
ERR(": could not acquire IPersistStream\n");
return hr;
}
/* load */
hr = IPersistStream_Load (pPersistStream, pClonedStream);
if (FAILED(hr)) {
ERR(": failed to load object\n");
return hr;
}
/* release all loading-related stuff */
IPersistStream_Release (pPersistStream);
return S_OK;
}
static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif) {
/*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
HRESULT hr = E_FAIL;
DMUS_PRIVATE_CHUNK Chunk;
......@@ -457,7 +486,7 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (LPPERSIST
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));
......@@ -623,17 +652,19 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartList (LPPERSISTSTR
static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
/*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
HRESULT hr = E_FAIL;
DMUS_PRIVATE_CHUNK Chunk;
DWORD ListSize[3], ListCount[3];
LARGE_INTEGER liMove; /* used when skipping chunks */
DMUS_IO_PATTERN pattern;
DWORD dwRythm = 0;
DWORD dwRythm;
DMUS_OBJECTDESC desc;
IDirectMusicBand* pBand = NULL;
LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif = NULL;
memset(&pattern, 0, sizeof(pattern));
dwRythm = 0;
DM_STRUCT_INIT(&desc);
if (pChunk->fccID != DMUS_FOURCC_PATTERN_LIST) {
ERR_(dmfile)(": %s chunk should be a PATTERN list\n", debugstr_fourcc (pChunk->fccID));
......@@ -650,8 +681,20 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSIST
switch (Chunk.fccID) {
case DMUS_FOURCC_PATTERN_CHUNK: {
TRACE_(dmfile)(": Pattern chunk\n");
IStream_Read (pStm, &pattern, Chunk.dwSize, NULL);
/** alloc new motif entry */
pNewMotif = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_MOTIF));
list_add_tail (&This->Motifs, &pNewMotif->entry);
if (NULL == pNewMotif) {
ERR(": no more memory\n");
return E_OUTOFMEMORY;
}
IStream_Read (pStm, &pNewMotif->pattern, Chunk.dwSize, NULL);
/** TODO trace pattern */
/** reset all datas, as a new pattern begin */
dwRythm = 0;
DM_STRUCT_INIT(&pNewMotif->desc);
break;
}
case DMUS_FOURCC_RHYTHM_CHUNK: {
......@@ -665,8 +708,55 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSIST
}
case DMUS_FOURCC_MOTIFSETTINGS_CHUNK: {
TRACE_(dmfile)(": MotifSettigns chunk (skipping for now)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
IStream_Read (pStm, &pNewMotif->settings, Chunk.dwSize, NULL);
/** TODO trace settings */
break;
}
case FOURCC_RIFF: {
/**
* sould be embededs Bands into pattern
*/
IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
ListCount[1] = 0;
switch (Chunk.fccID) {
case DMUS_FOURCC_BAND_FORM: {
LPSTREAM pClonedStream = NULL;
TRACE_(dmfile)(": BAND RIFF\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 = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand);
if (FAILED(hr)) {
ERR(": could not load track\n");
return hr;
}
IStream_Release (pClonedStream);
pNewMotif->pBand = pBand;
IDirectMusicBand_AddRef(pBand);
IDirectMusicTrack_Release(pBand); pBand = NULL; /* now we can release at as it inserted */
/** now safe move the cursor */
liMove.QuadPart = ListSize[1];
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
liMove.QuadPart = ListSize[1];
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
break;
}
case FOURCC_LIST: {
......@@ -682,7 +772,7 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSIST
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &desc);
hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &pNewMotif->desc);
if (FAILED(hr)) return hr;
if (hr == S_FALSE) {
......@@ -701,7 +791,7 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSIST
}
case DMUS_FOURCC_PARTREF_LIST: {
TRACE_(dmfile)(": PartRef list\n");
hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (iface, &Chunk, pStm);
hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (iface, &Chunk, pStm, pNewMotif);
if (FAILED(hr)) return hr;
break;
}
......@@ -735,6 +825,8 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTST
DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
LARGE_INTEGER liMove; /* used when skipping chunks */
IDirectMusicBand* pBand = NULL;
if (pChunk->fccID != DMUS_FOURCC_STYLE_FORM) {
ERR_(dmfile)(": %s chunk should be a STYLE form\n", debugstr_fourcc (pChunk->fccID));
return E_FAIL;
......@@ -769,10 +861,10 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTST
ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
ListCount[0] = 0;
switch (Chunk.fccID) {
case DMUS_FOURCC_BAND_FORM: {
TRACE_(dmfile)(": BAND RIFF (TODO load it)\n");
/*
case DMUS_FOURCC_BAND_FORM: {
LPSTREAM pClonedStream = NULL;
LPDMUS_PRIVATE_STYLE_BAND pNewBand;
TRACE_(dmfile)(": BAND RIFF\n");
IStream_Clone (pStm, &pClonedStream);
......@@ -781,15 +873,24 @@ static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTST
liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD));
IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL);
hr = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand, &header);
hr = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand);
if (FAILED(hr)) {
ERR(": could not load track\n");
return hr;
}
IStream_Release (pClonedStream);
IDirectMusicTrack_Release(pBand); pBand = NULL;
*/
pNewBand = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_BAND));
if (NULL == pNewBand) {
ERR(": no more memory\n");
return E_OUTOFMEMORY;
}
pNewBand->pBand = pBand;
IDirectMusicBand_AddRef(pBand);
list_add_tail (&This->Bands, &pNewBand->entry);
IDirectMusicTrack_Release(pBand); pBand = NULL; /* now we can release at as it inserted */
/** now safe move the cursor */
liMove.QuadPart = ListSize[0];
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
......@@ -956,6 +1057,8 @@ HRESULT WINAPI DMUSIC_CreateDirectMusicStyleImpl (LPCGUID lpcGUID, LPVOID* ppobj
obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
memcpy (&obj->pDesc->guidClass, &CLSID_DirectMusicStyle, sizeof (CLSID));
obj->ref = 0; /* will be inited by QueryInterface */
list_init (&obj->Bands);
list_init (&obj->Motifs);
return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment