dmusic: Implement IDirectMusicObject interface on wave objects.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55792
This commit is contained in:
Rémi Bernon 2023-10-17 11:46:17 +02:00 committed by Alexandre Julliard
parent b1bfc52676
commit dc0431b819

View file

@ -32,6 +32,7 @@ C_ASSERT(sizeof(struct sample) == offsetof(struct sample, loops[0]));
struct wave
{
IUnknown IUnknown_iface;
struct dmobject dmobj;
LONG ref;
struct sample *sample;
@ -58,6 +59,20 @@ static HRESULT WINAPI wave_QueryInterface(IUnknown *iface, REFIID riid, void **r
return S_OK;
}
if (IsEqualIID(riid, &IID_IDirectMusicObject))
{
*ret_iface = &This->dmobj.IDirectMusicObject_iface;
IDirectMusicObject_AddRef(&This->dmobj.IDirectMusicObject_iface);
return S_OK;
}
if (IsEqualIID(riid, &IID_IPersistStream))
{
*ret_iface = &This->dmobj.IPersistStream_iface;
IDirectMusicObject_AddRef(&This->dmobj.IPersistStream_iface);
return S_OK;
}
WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
*ret_iface = NULL;
return E_NOINTERFACE;
@ -96,18 +111,6 @@ static const IUnknownVtbl unknown_vtbl =
wave_Release,
};
static HRESULT wave_create(IUnknown **ret_iface)
{
struct wave *obj;
if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY;
obj->IUnknown_iface.lpVtbl = &unknown_vtbl;
obj->ref = 1;
*ret_iface = &obj->IUnknown_iface;
return S_OK;
}
static HRESULT parse_wsmp_chunk(struct wave *This, IStream *stream, struct chunk_entry *chunk)
{
struct sample *sample;
@ -167,6 +170,110 @@ static HRESULT parse_wave_chunk(struct wave *This, IStream *stream, struct chunk
return hr;
}
static HRESULT WINAPI wave_object_ParseDescriptor(IDirectMusicObject *iface,
IStream *stream, DMUS_OBJECTDESC *desc)
{
struct chunk_entry chunk = {0};
HRESULT hr;
TRACE("(%p, %p, %p)\n", iface, stream, desc);
if (!stream || !desc) return E_POINTER;
if ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
{
switch (MAKE_IDTYPE(chunk.id, chunk.type))
{
case MAKE_IDTYPE(FOURCC_RIFF, mmioFOURCC('W','A','V','E')):
hr = dmobj_parsedescriptor(stream, &chunk, desc,
DMUS_OBJ_NAME_INFO | DMUS_OBJ_OBJECT | DMUS_OBJ_VERSION);
break;
default:
WARN("Invalid wave chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
hr = DMUS_E_CHUNKNOTFOUND;
break;
}
}
if (FAILED(hr)) return hr;
TRACE("returning descriptor:\n");
dump_DMUS_OBJECTDESC(desc);
return S_OK;
}
static const IDirectMusicObjectVtbl wave_object_vtbl =
{
dmobj_IDirectMusicObject_QueryInterface,
dmobj_IDirectMusicObject_AddRef,
dmobj_IDirectMusicObject_Release,
dmobj_IDirectMusicObject_GetDescriptor,
dmobj_IDirectMusicObject_SetDescriptor,
wave_object_ParseDescriptor,
};
static inline struct wave *impl_from_IPersistStream(IPersistStream *iface)
{
return CONTAINING_RECORD(iface, struct wave, dmobj.IPersistStream_iface);
}
static HRESULT WINAPI wave_persist_stream_Load(IPersistStream *iface, IStream *stream)
{
struct wave *This = impl_from_IPersistStream(iface);
struct chunk_entry chunk = {0};
HRESULT hr;
TRACE("(%p, %p)\n", This, stream);
if (!stream) return E_POINTER;
if ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
{
switch (MAKE_IDTYPE(chunk.id, chunk.type))
{
case MAKE_IDTYPE(FOURCC_RIFF, mmioFOURCC('W','A','V','E')):
hr = parse_wave_chunk(This, stream, &chunk);
break;
default:
WARN("Invalid wave chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
hr = DMUS_E_UNSUPPORTED_STREAM;
break;
}
}
stream_skip_chunk(stream, &chunk);
return hr;
}
static const IPersistStreamVtbl wave_persist_stream_vtbl =
{
dmobj_IPersistStream_QueryInterface,
dmobj_IPersistStream_AddRef,
dmobj_IPersistStream_Release,
dmobj_IPersistStream_GetClassID,
unimpl_IPersistStream_IsDirty,
wave_persist_stream_Load,
unimpl_IPersistStream_Save,
unimpl_IPersistStream_GetSizeMax,
};
static HRESULT wave_create(IUnknown **ret_iface)
{
struct wave *obj;
if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY;
obj->IUnknown_iface.lpVtbl = &unknown_vtbl;
obj->ref = 1;
dmobject_init(&obj->dmobj, &CLSID_DirectSoundWave, &obj->IUnknown_iface);
obj->dmobj.IDirectMusicObject_iface.lpVtbl = &wave_object_vtbl;
obj->dmobj.IPersistStream_iface.lpVtbl = &wave_persist_stream_vtbl;
*ret_iface = &obj->IUnknown_iface;
return S_OK;
}
HRESULT wave_create_from_chunk(IStream *stream, struct chunk_entry *parent, IUnknown **ret_iface)
{
struct wave *This;