dmusic: Implement IDirectMusicObject interface on wave objects.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55792
This commit is contained in:
parent
b1bfc52676
commit
dc0431b819
1 changed files with 119 additions and 12 deletions
|
@ -32,6 +32,7 @@ C_ASSERT(sizeof(struct sample) == offsetof(struct sample, loops[0]));
|
||||||
struct wave
|
struct wave
|
||||||
{
|
{
|
||||||
IUnknown IUnknown_iface;
|
IUnknown IUnknown_iface;
|
||||||
|
struct dmobject dmobj;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
struct sample *sample;
|
struct sample *sample;
|
||||||
|
@ -58,6 +59,20 @@ static HRESULT WINAPI wave_QueryInterface(IUnknown *iface, REFIID riid, void **r
|
||||||
return S_OK;
|
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);
|
WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
|
||||||
*ret_iface = NULL;
|
*ret_iface = NULL;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
|
@ -96,18 +111,6 @@ static const IUnknownVtbl unknown_vtbl =
|
||||||
wave_Release,
|
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)
|
static HRESULT parse_wsmp_chunk(struct wave *This, IStream *stream, struct chunk_entry *chunk)
|
||||||
{
|
{
|
||||||
struct sample *sample;
|
struct sample *sample;
|
||||||
|
@ -167,6 +170,110 @@ static HRESULT parse_wave_chunk(struct wave *This, IStream *stream, struct chunk
|
||||||
return hr;
|
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)
|
HRESULT wave_create_from_chunk(IStream *stream, struct chunk_entry *parent, IUnknown **ret_iface)
|
||||||
{
|
{
|
||||||
struct wave *This;
|
struct wave *This;
|
||||||
|
|
Loading…
Add table
Reference in a new issue