dmusic: Add support for loading articulations.

This commit is contained in:
Christian Costa 2013-01-22 08:35:56 +01:00 committed by Alexandre Julliard
parent c90a1e5e21
commit 2562969804
2 changed files with 75 additions and 1 deletions

View file

@ -85,6 +85,11 @@ typedef struct instrument_region {
BOOL loop_present;
} instrument_region;
typedef struct instrument_articulation {
CONNECTIONLIST connections_list;
CONNECTION *connections;
} instrument_articulation;
/*****************************************************************************
* ClassFactory
*/
@ -245,6 +250,8 @@ struct IDirectMusicInstrumentImpl {
/* instrument data */
BOOL loaded;
instrument_region *regions;
ULONG nb_articulations;
instrument_articulation *articulations;
};
static inline IDirectMusicInstrumentImpl *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface)

View file

@ -76,7 +76,12 @@ static ULONG WINAPI IDirectMusicInstrumentImpl_Release(LPDIRECTMUSICINSTRUMENT i
if (!ref)
{
ULONG i;
HeapFree(GetProcessHeap(), 0, This->regions);
for (i = 0; i < This->nb_articulations; i++)
HeapFree(GetProcessHeap(), 0, This->articulations->connections);
HeapFree(GetProcessHeap(), 0, This->articulations);
HeapFree(GetProcessHeap(), 0, This);
}
@ -243,6 +248,42 @@ static HRESULT load_region(IDirectMusicInstrumentImpl *This, IStream *stream, in
return S_OK;
}
static HRESULT load_articulation(IDirectMusicInstrumentImpl *This, IStream *stream, ULONG length)
{
HRESULT ret;
instrument_articulation *articulation;
if (!This->articulations)
This->articulations = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->articulations));
else
This->articulations = HeapReAlloc(GetProcessHeap(), 0, This->articulations, sizeof(*This->articulations) * (This->nb_articulations + 1));
if (!This->articulations)
return E_OUTOFMEMORY;
articulation = &This->articulations[This->nb_articulations];
ret = read_from_stream(stream, &articulation->connections_list, sizeof(CONNECTIONLIST));
if (FAILED(ret))
return ret;
articulation->connections = HeapAlloc(GetProcessHeap(), 0, sizeof(CONNECTION) * articulation->connections_list.cConnections);
if (!articulation->connections)
return E_OUTOFMEMORY;
ret = read_from_stream(stream, articulation->connections, sizeof(CONNECTION) * articulation->connections_list.cConnections);
if (FAILED(ret))
{
HeapFree(GetProcessHeap(), 0, articulation->connections);
return ret;
}
subtract_bytes(length, sizeof(CONNECTIONLIST) + sizeof(CONNECTION) * articulation->connections_list.cConnections);
This->nb_articulations++;
return S_OK;
}
/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */
HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, IStream *stream)
{
@ -323,7 +364,7 @@ HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, ISt
if (chunk.fccID == FOURCC_RGN)
{
TRACE("RGN chunk (region list): %u bytes\n", chunk.dwSize);
TRACE("RGN chunk (region): %u bytes\n", chunk.dwSize);
hr = load_region(This, stream, &This->regions[i++], chunk.dwSize - sizeof(chunk.fccID));
}
else
@ -338,6 +379,32 @@ HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, ISt
}
break;
case FOURCC_LART:
TRACE("LART chunk (articulations list): %u bytes\n", size);
while (size)
{
hr = read_from_stream(stream, &chunk, sizeof(chunk));
if (FAILED(hr))
goto error;
if (chunk.fccID == FOURCC_ART1)
{
TRACE("ART1 chunk (level 1 articulation): %u bytes\n", chunk.dwSize);
hr = load_articulation(This, stream, chunk.dwSize);
}
else
{
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
hr = advance_stream(stream, chunk.dwSize);
}
if (FAILED(hr))
goto error;
size = subtract_bytes(size, chunk.dwSize + sizeof(chunk));
}
break;
default:
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);