Commit 52d3f7ab authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dmusic: Use a struct list for instrument regions.

parent febe6a78
...@@ -71,13 +71,15 @@ typedef struct port_info { ...@@ -71,13 +71,15 @@ typedef struct port_info {
ULONG device; ULONG device;
} port_info; } port_info;
typedef struct instrument_region { struct region
{
struct list entry;
RGNHEADER header; RGNHEADER header;
WAVELINK wave_link; WAVELINK wave_link;
WSMPL wave_sample; WSMPL wave_sample;
WLOOP wave_loop; WLOOP wave_loop;
BOOL loop_present; BOOL loop_present;
} instrument_region; };
/***************************************************************************** /*****************************************************************************
* ClassFactory * ClassFactory
...@@ -180,9 +182,9 @@ struct instrument ...@@ -180,9 +182,9 @@ struct instrument
WCHAR wszName[DMUS_MAX_NAME]; WCHAR wszName[DMUS_MAX_NAME];
/* instrument data */ /* instrument data */
BOOL loaded; BOOL loaded;
instrument_region *regions;
struct list articulations; struct list articulations;
struct list regions;
}; };
static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface) static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface)
......
...@@ -84,8 +84,7 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface) ...@@ -84,8 +84,7 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface)
if (!ref) if (!ref)
{ {
struct articulation *articulation, *next_articulation; struct articulation *articulation, *next_articulation;
struct region *region, *next_region;
free(This->regions);
LIST_FOR_EACH_ENTRY_SAFE(articulation, next_articulation, &This->articulations, struct articulation, entry) LIST_FOR_EACH_ENTRY_SAFE(articulation, next_articulation, &This->articulations, struct articulation, entry)
{ {
...@@ -93,6 +92,12 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface) ...@@ -93,6 +92,12 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface)
free(articulation); free(articulation);
} }
LIST_FOR_EACH_ENTRY_SAFE(region, next_region, &This->regions, struct region, entry)
{
list_remove(&region->entry);
free(region);
}
free(This); free(This);
} }
...@@ -139,6 +144,7 @@ HRESULT instrument_create(IDirectMusicInstrument **ret_iface) ...@@ -139,6 +144,7 @@ HRESULT instrument_create(IDirectMusicInstrument **ret_iface)
instrument->IDirectMusicInstrument_iface.lpVtbl = &instrument_vtbl; instrument->IDirectMusicInstrument_iface.lpVtbl = &instrument_vtbl;
instrument->ref = 1; instrument->ref = 1;
list_init(&instrument->articulations); list_init(&instrument->articulations);
list_init(&instrument->regions);
TRACE("Created DirectMusicInstrument %p\n", instrument); TRACE("Created DirectMusicInstrument %p\n", instrument);
*ret_iface = &instrument->IDirectMusicInstrument_iface; *ret_iface = &instrument->IDirectMusicInstrument_iface;
...@@ -186,18 +192,20 @@ static inline HRESULT advance_stream(IStream *stream, ULONG bytes) ...@@ -186,18 +192,20 @@ static inline HRESULT advance_stream(IStream *stream, ULONG bytes)
return ret; return ret;
} }
static HRESULT load_region(struct instrument *This, IStream *stream, instrument_region *region, ULONG length) static HRESULT load_region(struct instrument *This, IStream *stream, ULONG length)
{ {
struct region *region;
HRESULT ret; HRESULT ret;
DMUS_PRIVATE_CHUNK chunk; DMUS_PRIVATE_CHUNK chunk;
TRACE("(%p, %p, %p, %lu)\n", This, stream, region, length); TRACE("(%p, %p, %lu)\n", This, stream, length);
if (!(region = malloc(sizeof(*region)))) return E_OUTOFMEMORY;
while (length) while (length)
{ {
ret = read_from_stream(stream, &chunk, sizeof(chunk)); ret = read_from_stream(stream, &chunk, sizeof(chunk));
if (FAILED(ret)) if (FAILED(ret)) goto failed;
return ret;
length = subtract_bytes(length, sizeof(chunk)); length = subtract_bytes(length, sizeof(chunk));
...@@ -207,8 +215,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ ...@@ -207,8 +215,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
TRACE("RGNH chunk (region header): %lu bytes\n", chunk.dwSize); TRACE("RGNH chunk (region header): %lu bytes\n", chunk.dwSize);
ret = read_from_stream(stream, &region->header, sizeof(region->header)); ret = read_from_stream(stream, &region->header, sizeof(region->header));
if (FAILED(ret)) if (FAILED(ret)) goto failed;
return ret;
length = subtract_bytes(length, sizeof(region->header)); length = subtract_bytes(length, sizeof(region->header));
break; break;
...@@ -217,16 +224,14 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ ...@@ -217,16 +224,14 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
TRACE("WSMP chunk (wave sample): %lu bytes\n", chunk.dwSize); TRACE("WSMP chunk (wave sample): %lu bytes\n", chunk.dwSize);
ret = read_from_stream(stream, &region->wave_sample, sizeof(region->wave_sample)); ret = read_from_stream(stream, &region->wave_sample, sizeof(region->wave_sample));
if (FAILED(ret)) if (FAILED(ret)) goto failed;
return ret;
length = subtract_bytes(length, sizeof(region->wave_sample)); length = subtract_bytes(length, sizeof(region->wave_sample));
if (!(region->loop_present = (chunk.dwSize != sizeof(region->wave_sample)))) if (!(region->loop_present = (chunk.dwSize != sizeof(region->wave_sample))))
break; break;
ret = read_from_stream(stream, &region->wave_loop, sizeof(region->wave_loop)); ret = read_from_stream(stream, &region->wave_loop, sizeof(region->wave_loop));
if (FAILED(ret)) if (FAILED(ret)) goto failed;
return ret;
length = subtract_bytes(length, sizeof(region->wave_loop)); length = subtract_bytes(length, sizeof(region->wave_loop));
break; break;
...@@ -235,8 +240,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ ...@@ -235,8 +240,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
TRACE("WLNK chunk (wave link): %lu bytes\n", chunk.dwSize); TRACE("WLNK chunk (wave link): %lu bytes\n", chunk.dwSize);
ret = read_from_stream(stream, &region->wave_link, sizeof(region->wave_link)); ret = read_from_stream(stream, &region->wave_link, sizeof(region->wave_link));
if (FAILED(ret)) if (FAILED(ret)) goto failed;
return ret;
length = subtract_bytes(length, sizeof(region->wave_link)); length = subtract_bytes(length, sizeof(region->wave_link));
break; break;
...@@ -245,15 +249,19 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ ...@@ -245,15 +249,19 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
TRACE("Unknown chunk %s (skipping): %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); TRACE("Unknown chunk %s (skipping): %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
ret = advance_stream(stream, chunk.dwSize); ret = advance_stream(stream, chunk.dwSize);
if (FAILED(ret)) if (FAILED(ret)) goto failed;
return ret;
length = subtract_bytes(length, chunk.dwSize); length = subtract_bytes(length, chunk.dwSize);
break; break;
} }
} }
list_add_tail(&This->regions, &region->entry);
return S_OK; return S_OK;
failed:
free(region);
return ret;
} }
static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length) static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length)
...@@ -287,7 +295,6 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) ...@@ -287,7 +295,6 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
struct instrument *This = impl_from_IDirectMusicInstrument(iface); struct instrument *This = impl_from_IDirectMusicInstrument(iface);
HRESULT hr; HRESULT hr;
DMUS_PRIVATE_CHUNK chunk; DMUS_PRIVATE_CHUNK chunk;
ULONG i = 0;
ULONG length = This->length; ULONG length = This->length;
TRACE("(%p, %p): offset = 0x%s, length = %lu)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length); TRACE("(%p, %p): offset = 0x%s, length = %lu)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length);
...@@ -302,10 +309,6 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) ...@@ -302,10 +309,6 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
return DMUS_E_UNSUPPORTED_STREAM; return DMUS_E_UNSUPPORTED_STREAM;
} }
This->regions = malloc(sizeof(*This->regions) * This->header.cRegions);
if (!This->regions)
return E_OUTOFMEMORY;
while (length) while (length)
{ {
hr = read_from_stream(stream, &chunk, sizeof(chunk)); hr = read_from_stream(stream, &chunk, sizeof(chunk));
...@@ -362,7 +365,7 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) ...@@ -362,7 +365,7 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
if (chunk.fccID == FOURCC_RGN) if (chunk.fccID == FOURCC_RGN)
{ {
TRACE("RGN chunk (region): %lu bytes\n", chunk.dwSize); TRACE("RGN chunk (region): %lu bytes\n", chunk.dwSize);
hr = load_region(This, stream, &This->regions[i++], chunk.dwSize - sizeof(chunk.fccID)); hr = load_region(This, stream, chunk.dwSize - sizeof(chunk.fccID));
} }
else else
{ {
...@@ -431,8 +434,5 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) ...@@ -431,8 +434,5 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
return S_OK; return S_OK;
error: error:
free(This->regions);
This->regions = NULL;
return DMUS_E_UNSUPPORTED_STREAM; return DMUS_E_UNSUPPORTED_STREAM;
} }
...@@ -267,6 +267,7 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi ...@@ -267,6 +267,7 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi
{ {
struct synth_port *This = synth_from_IDirectMusicPort(iface); struct synth_port *This = synth_from_IDirectMusicPort(iface);
struct instrument *instrument_object; struct instrument *instrument_object;
struct region *instrument_region;
HRESULT ret; HRESULT ret;
BOOL on_heap; BOOL on_heap;
HANDLE download; HANDLE download;
...@@ -312,22 +313,24 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi ...@@ -312,22 +313,24 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi
instrument_info->ulCopyrightIdx = 0; /* FIXME */ instrument_info->ulCopyrightIdx = 0; /* FIXME */
instrument_info->ulFlags = 0; /* FIXME */ instrument_info->ulFlags = 0; /* FIXME */
for (i = 0; i < nb_regions; i++) i = 0;
LIST_FOR_EACH_ENTRY(instrument_region, &instrument_object->regions, struct region, entry)
{ {
DMUS_REGION *region = (DMUS_REGION*)(data + offset); DMUS_REGION *region = (DMUS_REGION*)(data + offset);
offset_table->ulOffsetTable[1 + i] = offset; offset_table->ulOffsetTable[1 + i] = offset;
offset += sizeof(DMUS_REGION); offset += sizeof(DMUS_REGION);
region->RangeKey = instrument_object->regions[i].header.RangeKey; region->RangeKey = instrument_region->header.RangeKey;
region->RangeVelocity = instrument_object->regions[i].header.RangeVelocity; region->RangeVelocity = instrument_region->header.RangeVelocity;
region->fusOptions = instrument_object->regions[i].header.fusOptions; region->fusOptions = instrument_region->header.fusOptions;
region->usKeyGroup = instrument_object->regions[i].header.usKeyGroup; region->usKeyGroup = instrument_region->header.usKeyGroup;
region->ulRegionArtIdx = 0; /* FIXME */ region->ulRegionArtIdx = 0; /* FIXME */
region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0; region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0;
region->ulFirstExtCkIdx = 0; /* FIXME */ region->ulFirstExtCkIdx = 0; /* FIXME */
region->WaveLink = instrument_object->regions[i].wave_link; region->WaveLink = instrument_region->wave_link;
region->WSMP = instrument_object->regions[i].wave_sample; region->WSMP = instrument_region->wave_sample;
region->WLOOP[0] = instrument_object->regions[i].wave_loop; region->WLOOP[0] = instrument_region->wave_loop;
i++;
} }
ret = IDirectMusicSynth8_Download(This->synth, &download, (void*)data, &on_heap); ret = IDirectMusicSynth8_Download(This->synth, &download, (void*)data, &on_heap);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment