mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 14:14:09 +00:00
dmusic: Allocate and parse instruments in a single pass.
This commit is contained in:
parent
01127ce474
commit
ff4cb785cb
|
@ -115,7 +115,6 @@ static HRESULT WINAPI collection_GetInstrument(IDirectMusicCollection *iface,
|
|||
if (patch == inst_patch) {
|
||||
*instrument = inst_entry->pInstrument;
|
||||
IDirectMusicInstrument_AddRef(inst_entry->pInstrument);
|
||||
instrument_load(inst_entry->pInstrument, This->pStm);
|
||||
TRACE(": returning instrument %p\n", *instrument);
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -212,7 +211,6 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface,
|
|||
DMUS_PRIVATE_CHUNK chunk;
|
||||
DWORD StreamSize, StreamCount, ListSize[2], ListCount[2];
|
||||
LARGE_INTEGER liMove; /* used when skipping chunks */
|
||||
ULARGE_INTEGER dlibInstrumentPosition;
|
||||
|
||||
IStream_AddRef(stream); /* add count for later references */
|
||||
This->pStm = stream;
|
||||
|
@ -374,68 +372,12 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface,
|
|||
ListCount[1] = 0;
|
||||
switch (chunk.fccID) {
|
||||
case FOURCC_INS: {
|
||||
DMUS_PRIVATE_INSTRUMENTENTRY *new_instrument = calloc(1, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY));
|
||||
DMUS_PRIVATE_INSTRUMENTENTRY *entry = calloc(1, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY));
|
||||
TRACE_(dmfile)(": instrument list\n");
|
||||
/* Only way to create this one... even M$ does it discretely */
|
||||
instrument_create(&new_instrument->pInstrument);
|
||||
{
|
||||
struct instrument *instrument = impl_from_IDirectMusicInstrument(new_instrument->pInstrument);
|
||||
/* Store offset and length, they will be needed when loading the instrument */
|
||||
liMove.QuadPart = 0;
|
||||
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &dlibInstrumentPosition);
|
||||
instrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart;
|
||||
instrument->length = ListSize[1];
|
||||
do {
|
||||
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
|
||||
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
|
||||
TRACE_(dmfile)(": %s chunk (size = %#04lx)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
|
||||
switch (chunk.fccID) {
|
||||
case FOURCC_INSH: {
|
||||
TRACE_(dmfile)(": instrument header chunk\n");
|
||||
IStream_Read(stream, &instrument->header, chunk.dwSize, NULL);
|
||||
break;
|
||||
}
|
||||
case FOURCC_DLID: {
|
||||
TRACE_(dmfile)(": DLID (GUID) chunk\n");
|
||||
IStream_Read(stream, &instrument->id, chunk.dwSize, NULL);
|
||||
break;
|
||||
}
|
||||
case FOURCC_LIST: {
|
||||
IStream_Read(stream, &chunk.fccID, sizeof(FOURCC), NULL);
|
||||
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunk.fccID));
|
||||
switch (chunk.fccID) {
|
||||
default: {
|
||||
TRACE_(dmfile)(": unknown (skipping)\n");
|
||||
liMove.QuadPart = chunk.dwSize - sizeof(FOURCC);
|
||||
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
|
||||
liMove.QuadPart = chunk.dwSize;
|
||||
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
TRACE_(dmfile)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]);
|
||||
} while (ListCount[1] < ListSize[1]);
|
||||
/* DEBUG: dumps whole instrument object tree: */
|
||||
if (TRACE_ON(dmusic)) {
|
||||
TRACE("*** IDirectMusicInstrument (%p) ***\n", instrument);
|
||||
if (!IsEqualGUID(&instrument->id, &GUID_NULL))
|
||||
TRACE(" - GUID = %s\n", debugstr_dmguid(&instrument->id));
|
||||
TRACE(" - Instrument header:\n");
|
||||
TRACE(" - cRegions: %ld\n", instrument->header.cRegions);
|
||||
TRACE(" - Locale:\n");
|
||||
TRACE(" - ulBank: %ld\n", instrument->header.Locale.ulBank);
|
||||
TRACE(" - ulInstrument: %ld\n", instrument->header.Locale.ulInstrument);
|
||||
TRACE(" => dwPatch: %ld\n", MIDILOCALE2Patch(&instrument->header.Locale));
|
||||
}
|
||||
list_add_tail(&This->Instruments, &new_instrument->entry);
|
||||
}
|
||||
liMove.QuadPart = -12;
|
||||
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
|
||||
if (FAILED(instrument_create_from_stream(stream, &entry->pInstrument))) free(entry);
|
||||
else list_add_tail(&This->Instruments, &entry->entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ extern HRESULT DMUSIC_CreateReferenceClockImpl (LPCGUID lpcGUID, LPVOID* ppobj,
|
|||
|
||||
extern HRESULT download_create(DWORD size, IDirectMusicDownload **ret_iface);
|
||||
|
||||
extern HRESULT instrument_create(IDirectMusicInstrument **ret_iface);
|
||||
extern HRESULT instrument_create_from_stream(IStream *stream, IDirectMusicInstrument **ret_iface);
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirectMusic8Impl implementation structure
|
||||
|
@ -175,13 +175,10 @@ struct instrument
|
|||
IDirectMusicInstrument IDirectMusicInstrument_iface;
|
||||
LONG ref;
|
||||
|
||||
LARGE_INTEGER liInstrumentPosition; /* offset in a stream where instrument chunk can be found */
|
||||
ULONG length; /* Length of the instrument in the stream */
|
||||
GUID id;
|
||||
INSTHEADER header;
|
||||
WCHAR wszName[DMUS_MAX_NAME];
|
||||
/* instrument data */
|
||||
BOOL loaded;
|
||||
|
||||
struct list articulations;
|
||||
struct list regions;
|
||||
|
@ -192,8 +189,6 @@ static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicIn
|
|||
return CONTAINING_RECORD(iface, struct instrument, IDirectMusicInstrument_iface);
|
||||
}
|
||||
|
||||
extern HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream);
|
||||
|
||||
/*****************************************************************************
|
||||
* Misc.
|
||||
*/
|
||||
|
|
|
@ -135,7 +135,7 @@ static const IDirectMusicInstrumentVtbl instrument_vtbl =
|
|||
instrument_SetPatch,
|
||||
};
|
||||
|
||||
HRESULT instrument_create(IDirectMusicInstrument **ret_iface)
|
||||
static HRESULT instrument_create(IDirectMusicInstrument **ret_iface)
|
||||
{
|
||||
struct instrument *instrument;
|
||||
|
||||
|
@ -277,8 +277,11 @@ static HRESULT parse_ins_chunk(struct instrument *This, IStream *stream, struct
|
|||
switch (MAKE_IDTYPE(chunk.id, chunk.type))
|
||||
{
|
||||
case FOURCC_INSH:
|
||||
hr = stream_chunk_get_data(stream, &chunk, &This->header, sizeof(This->header));
|
||||
break;
|
||||
|
||||
case FOURCC_DLID:
|
||||
/* Instrument header and id are already set so just skip */
|
||||
hr = stream_chunk_get_data(stream, &chunk, &This->id, sizeof(This->id));
|
||||
break;
|
||||
|
||||
case MAKE_IDTYPE(FOURCC_LIST, FOURCC_LRGN):
|
||||
|
@ -300,24 +303,17 @@ static HRESULT parse_ins_chunk(struct instrument *This, IStream *stream, struct
|
|||
return hr;
|
||||
}
|
||||
|
||||
/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */
|
||||
HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
|
||||
HRESULT instrument_create_from_stream(IStream *stream, IDirectMusicInstrument **ret_iface)
|
||||
{
|
||||
struct instrument *This = impl_from_IDirectMusicInstrument(iface);
|
||||
struct chunk_entry chunk = {0};
|
||||
IDirectMusicInstrument *iface;
|
||||
struct instrument *This;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p, %p): offset = 0x%s, length = %lu)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length);
|
||||
TRACE("(%p, %p)\n", stream, ret_iface);
|
||||
|
||||
if (This->loaded)
|
||||
return S_OK;
|
||||
|
||||
hr = IStream_Seek(stream, This->liInstrumentPosition, STREAM_SEEK_SET, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("IStream_Seek failed: %08lx\n", hr);
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
}
|
||||
if (FAILED(hr = instrument_create(&iface))) return hr;
|
||||
This = impl_from_IDirectMusicInstrument(iface);
|
||||
|
||||
if ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
|
||||
{
|
||||
|
@ -329,16 +325,32 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
|
|||
|
||||
default:
|
||||
WARN("Invalid instrument chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
|
||||
goto error;
|
||||
hr = E_INVALIDARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr)) goto error;
|
||||
|
||||
This->loaded = TRUE;
|
||||
if (TRACE_ON(dmusic))
|
||||
{
|
||||
TRACE("Created DirectMusicInstrument (%p) ***\n", This);
|
||||
if (!IsEqualGUID(&This->id, &GUID_NULL))
|
||||
TRACE(" - GUID = %s\n", debugstr_dmguid(&This->id));
|
||||
TRACE(" - Instrument header:\n");
|
||||
TRACE(" - cRegions: %ld\n", This->header.cRegions);
|
||||
TRACE(" - Locale:\n");
|
||||
TRACE(" - ulBank: %ld\n", This->header.Locale.ulBank);
|
||||
TRACE(" - ulInstrument: %ld\n", This->header.Locale.ulInstrument);
|
||||
TRACE(" => dwPatch: %ld\n", MIDILOCALE2Patch(&This->header.Locale));
|
||||
}
|
||||
|
||||
*ret_iface = iface;
|
||||
return S_OK;
|
||||
|
||||
error:
|
||||
IDirectMusicInstrument_Release(iface);
|
||||
|
||||
stream_skip_chunk(stream, &chunk);
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue