Hello Alistair,
this patch produces heavy -Wformat warnings in the TRACEs. And does this code work? You're not parsing anything out with dmobj_parsedescriptor() as it gets as 'supported' only DMUS_OBJ_CLASS.
But please hold off on fixing those issues.
I need to finally create a generic Reference List 'DMRF' parser. We have a few places that need it and some implementations IDirectMusicUtils_IPersistStream_ParseReference(). I did start before but it always ended in a 'git reset --hard'... But here it is net new code so no other stuff that needs to be fixed first. I should be able to get it done over the weekend.
bye michael
On 5/6/20 8:33 AM, Alistair Leslie-Hughes wrote:
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com
dlls/dmime/dmime_private.h | 7 ++ dlls/dmime/wavetrack.c | 196 ++++++++++++++++++++++++++++++++++++- 2 files changed, 201 insertions(+), 2 deletions(-)
diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h index 9759039a03e9..f7431e882f42 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h @@ -86,6 +86,13 @@ typedef struct _DMUS_PRIVATE_TEMPO_ITEM { DMUS_IO_TEMPO_ITEM item; } DMUS_PRIVATE_TEMPO_ITEM, *LPDMUS_PRIVATE_TEMPO_ITEM;
+struct wave_item {
- struct list entry; /* for listing elements */
- DMUS_IO_WAVE_TRACK_HEADER header;
- IDirectMusicObject *object;
+};
typedef struct _DMUS_PRIVATE_SEGMENT_ITEM { struct list entry; /* for listing elements */ DMUS_IO_SEGMENT_ITEM_HEADER header; diff --git a/dlls/dmime/wavetrack.c b/dlls/dmime/wavetrack.c index 1c6b08b52355..23406e0794d0 100644 --- a/dlls/dmime/wavetrack.c +++ b/dlls/dmime/wavetrack.c @@ -20,6 +20,8 @@ #include "dmime_private.h" #include "dmobject.h"
+#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
/***************************************************************************** @@ -32,6 +34,8 @@ typedef struct IDirectMusicWaveTrack { IDirectMusicTrack8 IDirectMusicTrack8_iface; struct dmobject dmobj; /* IPersistStream only */ LONG ref;
- struct list items;
} IDirectMusicWaveTrack;
/* IDirectMusicWaveTrack IDirectMusicTrack8 part: */ @@ -40,6 +44,11 @@ static inline IDirectMusicWaveTrack *impl_from_IDirectMusicTrack8(IDirectMusicTr return CONTAINING_RECORD(iface, IDirectMusicWaveTrack, IDirectMusicTrack8_iface); }
+static inline IDirectMusicWaveTrack *impl_from_IPersistStream(IPersistStream *iface) +{
- return CONTAINING_RECORD(iface, IDirectMusicWaveTrack, dmobj.IPersistStream_iface);
+}
static HRESULT WINAPI wave_track_QueryInterface(IDirectMusicTrack8 *iface, REFIID riid, void **ret_iface) { @@ -81,6 +90,19 @@ static ULONG WINAPI wave_track_Release(IDirectMusicTrack8 *iface) TRACE("(%p) ref=%d\n", This, ref);
if (!ref) {
struct list *cursor, *cursor2;struct wave_item *item;LIST_FOR_EACH_SAFE(cursor, cursor2, &This->items) {item = LIST_ENTRY(cursor, struct wave_item, entry);list_remove(cursor);if (item->object)IDirectMusicObject_Release(item->object);heap_free(item);} }HeapFree(GetProcessHeap(), 0, This); DMIME_UnlockModule();@@ -280,10 +302,179 @@ static const IDirectMusicTrack8Vtbl dmtrack8_vtbl = { wave_track_Join };
+static HRESULT parse_wave_item(IDirectMusicWaveTrack *This, IStream *stream,
struct chunk_entry *wave, struct wave_item *item)+{
- HRESULT hr;
- struct chunk_entry chunk = {.parent = wave};
- if (FAILED(hr = stream_next_chunk(stream, &chunk)))
return hr;- if(chunk.id == FOURCC_LIST && chunk.type == DMUS_FOURCC_WAVE_LIST)
- {
struct chunk_entry child = {.parent = &chunk};DMUS_IO_WAVE_ITEM_HEADER header;if (FAILED(hr = stream_next_chunk(stream, &child)))return hr;if(child.id != DMUS_FOURCC_WAVEITEM_CHUNK)return DMUS_E_UNSUPPORTED_STREAM;if (FAILED(hr = stream_chunk_get_data(stream, &child, &header, child.size))) {WARN("Failed to read data of %s\n", debugstr_chunk(&child));return hr;}TRACE("Found DMUS_IO_WAVE_ITEM_HEADER\n");TRACE(" - lVolume %d\n", header.lVolume);TRACE(" - dwVariations %d\n", header.dwVariations);TRACE(" - rtTime %d\n", header.rtTime);TRACE(" - rtStartOffset %d\n", header.rtStartOffset);TRACE(" - rtReserved %d\n", header.rtReserved);TRACE(" - rtDuration %d\n", header.rtDuration);TRACE(" - dwLoopStart %d\n", header.dwLoopStart);TRACE(" - dwLoopEnd %d\n", header.dwLoopEnd);TRACE(" - dwFlags 0x%08x\n", header.dwFlags);TRACE(" - wVolumeRange %d\n", header.wVolumeRange);TRACE(" - wPitchRange %d\n", header.wPitchRange);if (FAILED(hr = stream_next_chunk(stream, &child)))return hr;if(child.id == FOURCC_LIST && child.type == DMUS_FOURCC_REF_LIST){struct chunk_entry dmrf = {.parent = &child};IDirectMusicGetLoader *getloader;IDirectMusicLoader *loader;DMUS_IO_REFERENCE reference;if (FAILED(hr = stream_next_chunk(stream, &dmrf)))return hr;if(dmrf.id != DMUS_FOURCC_REF_CHUNK)return DMUS_E_UNSUPPORTED_STREAM;if (FAILED(hr = stream_chunk_get_data(stream, &dmrf, &reference, dmrf.size))) {WARN("Failed to read data of %s\n", debugstr_chunk(&dmrf));return hr;}TRACE("REFERENCE guidClassID %s, dwValidData 0x%08x\n", debugstr_dmguid(&reference.guidClassID),reference.dwValidData);This->dmobj.desc.guidClass = reference.guidClassID;This->dmobj.desc.dwValidData = DMUS_OBJ_CLASS;hr = dmobj_parsedescriptor(stream, &child, &This->dmobj.desc, reference.dwValidData);if (FAILED(hr))return hr;dump_DMUS_OBJECTDESC(&This->dmobj.desc);hr = IStream_QueryInterface (stream, &IID_IDirectMusicGetLoader, (void**)&getloader);if (FAILED(hr))return hr;hr = IDirectMusicGetLoader_GetLoader (getloader, &loader);if (FAILED(hr))return hr;IDirectMusicGetLoader_Release (getloader);hr = IDirectMusicLoader_GetObject (loader, &This->dmobj.desc, &IID_IDirectMusicObject,(void**)&item->object);IDirectMusicLoader_Release (loader);}- }
- else
hr = DMUS_E_UNSUPPORTED_STREAM;- return SUCCEEDED(hr) ? S_OK : hr;
+}
+static HRESULT parse_wavetrack_list(IDirectMusicWaveTrack *This, IStream *stream,
struct chunk_entry *wave)+{
- HRESULT hr;
- struct chunk_entry chunk = {.parent = wave};
- struct wave_item *item = NULL;
- TRACE("Parsing segment form in %p: %s\n", stream, debugstr_chunk(wave));
- if (FAILED(hr = stream_next_chunk(stream, &chunk)))
return hr;- if (chunk.id != DMUS_FOURCC_WAVETRACK_CHUNK)
return DMUS_E_UNSUPPORTED_STREAM;- item = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(struct wave_item));
- if (!item)
return E_OUTOFMEMORY;- list_add_tail (&This->items, &item->entry);
- if (FAILED(hr = stream_next_chunk(stream, &chunk)))
return hr;- if (chunk.id == FOURCC_LIST && chunk.type == DMUS_FOURCC_WAVEPART_LIST)
- {
struct chunk_entry child = {.parent = wave};DMUS_IO_WAVE_PART_HEADER header;if (FAILED(hr = stream_next_chunk(stream, &child)))return hr;if (child.id != DMUS_FOURCC_WAVEPART_CHUNK)return DMUS_E_UNSUPPORTED_STREAM;if (FAILED(hr = stream_chunk_get_data(stream, &child, &header, child.size))) {WARN("Failed to read data of %s\n", debugstr_chunk(&child));return hr;}TRACE("Found DMUS_IO_WAVE_PART_HEADER\n");TRACE(" - lVolume %d\n", header.lVolume);TRACE(" - dwVariations %d\n", header.dwVariations);TRACE(" - dwPChannel %d\n", header.dwPChannel);TRACE(" - dwLockToPart %d\n", header.dwLockToPart);TRACE(" - dwFlags 0x%08x\n", header.dwFlags);TRACE(" - dwIndex %d\n", header.dwIndex);if (FAILED(hr = stream_next_chunk(stream, &child)))return hr;if(child.id != FOURCC_LIST || child.type != DMUS_FOURCC_WAVEITEM_LIST)return DMUS_E_UNSUPPORTED_STREAM;hr = parse_wave_item(This, stream, &child, item);- }
- else
hr = DMUS_E_UNSUPPORTED_STREAM;- return SUCCEEDED(hr) ? S_OK : hr;
+}
static HRESULT WINAPI wave_IPersistStream_Load(IPersistStream *iface, IStream *stream) {
- FIXME(": Loading not implemented yet\n");
- return S_OK;
- IDirectMusicWaveTrack *This = impl_from_IPersistStream(iface);
- HRESULT hr;
- struct chunk_entry chunk = {0};
- TRACE("%p, %p\n", This, stream);
- if (!stream)
return E_POINTER;- if ((hr = stream_get_chunk(stream, &chunk) != S_OK))
return hr;- if (chunk.id == FOURCC_LIST && chunk.type == DMUS_FOURCC_WAVETRACK_LIST)
hr = parse_wavetrack_list(This, stream, &chunk);- else
hr = DMUS_E_UNSUPPORTED_STREAM;- return hr;
}
static const IPersistStreamVtbl persiststream_vtbl = { @@ -313,6 +504,7 @@ HRESULT WINAPI create_dmwavetrack(REFIID lpcGUID, void **ppobj) dmobject_init(&track->dmobj, &CLSID_DirectMusicWaveTrack, (IUnknown *)&track->IDirectMusicTrack8_iface); track->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
list_init(&track->items);
DMIME_LockModule(); hr = IDirectMusicTrack8_QueryInterface(&track->IDirectMusicTrack8_iface, lpcGUID, ppobj);