- 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).
This commit is contained in:
parent
1022761090
commit
858557f4b7
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue