dmusic: Use a struct list for instrument regions.
This commit is contained in:
parent
febe6a7810
commit
52d3f7ab09
3 changed files with 41 additions and 36 deletions
|
@ -71,13 +71,15 @@ typedef struct port_info {
|
|||
ULONG device;
|
||||
} port_info;
|
||||
|
||||
typedef struct instrument_region {
|
||||
struct region
|
||||
{
|
||||
struct list entry;
|
||||
RGNHEADER header;
|
||||
WAVELINK wave_link;
|
||||
WSMPL wave_sample;
|
||||
WLOOP wave_loop;
|
||||
BOOL loop_present;
|
||||
} instrument_region;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* ClassFactory
|
||||
|
@ -180,9 +182,9 @@ struct instrument
|
|||
WCHAR wszName[DMUS_MAX_NAME];
|
||||
/* instrument data */
|
||||
BOOL loaded;
|
||||
instrument_region *regions;
|
||||
|
||||
struct list articulations;
|
||||
struct list regions;
|
||||
};
|
||||
|
||||
static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface)
|
||||
|
|
|
@ -84,8 +84,7 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface)
|
|||
if (!ref)
|
||||
{
|
||||
struct articulation *articulation, *next_articulation;
|
||||
|
||||
free(This->regions);
|
||||
struct region *region, *next_region;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(articulation, next_articulation, &This->articulations, struct articulation, entry)
|
||||
{
|
||||
|
@ -93,6 +92,12 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface)
|
|||
free(articulation);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(region, next_region, &This->regions, struct region, entry)
|
||||
{
|
||||
list_remove(®ion->entry);
|
||||
free(region);
|
||||
}
|
||||
|
||||
free(This);
|
||||
}
|
||||
|
||||
|
@ -139,6 +144,7 @@ HRESULT instrument_create(IDirectMusicInstrument **ret_iface)
|
|||
instrument->IDirectMusicInstrument_iface.lpVtbl = &instrument_vtbl;
|
||||
instrument->ref = 1;
|
||||
list_init(&instrument->articulations);
|
||||
list_init(&instrument->regions);
|
||||
|
||||
TRACE("Created DirectMusicInstrument %p\n", instrument);
|
||||
*ret_iface = &instrument->IDirectMusicInstrument_iface;
|
||||
|
@ -186,18 +192,20 @@ static inline HRESULT advance_stream(IStream *stream, ULONG bytes)
|
|||
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;
|
||||
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)
|
||||
{
|
||||
ret = read_from_stream(stream, &chunk, sizeof(chunk));
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
if (FAILED(ret)) goto failed;
|
||||
|
||||
length = subtract_bytes(length, sizeof(chunk));
|
||||
|
||||
|
@ -207,8 +215,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
|
|||
TRACE("RGNH chunk (region header): %lu bytes\n", chunk.dwSize);
|
||||
|
||||
ret = read_from_stream(stream, ®ion->header, sizeof(region->header));
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
if (FAILED(ret)) goto failed;
|
||||
|
||||
length = subtract_bytes(length, sizeof(region->header));
|
||||
break;
|
||||
|
@ -217,16 +224,14 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
|
|||
TRACE("WSMP chunk (wave sample): %lu bytes\n", chunk.dwSize);
|
||||
|
||||
ret = read_from_stream(stream, ®ion->wave_sample, sizeof(region->wave_sample));
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
if (FAILED(ret)) goto failed;
|
||||
length = subtract_bytes(length, sizeof(region->wave_sample));
|
||||
|
||||
if (!(region->loop_present = (chunk.dwSize != sizeof(region->wave_sample))))
|
||||
break;
|
||||
|
||||
ret = read_from_stream(stream, ®ion->wave_loop, sizeof(region->wave_loop));
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
if (FAILED(ret)) goto failed;
|
||||
|
||||
length = subtract_bytes(length, sizeof(region->wave_loop));
|
||||
break;
|
||||
|
@ -235,8 +240,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
|
|||
TRACE("WLNK chunk (wave link): %lu bytes\n", chunk.dwSize);
|
||||
|
||||
ret = read_from_stream(stream, ®ion->wave_link, sizeof(region->wave_link));
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
if (FAILED(ret)) goto failed;
|
||||
|
||||
length = subtract_bytes(length, sizeof(region->wave_link));
|
||||
break;
|
||||
|
@ -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);
|
||||
|
||||
ret = advance_stream(stream, chunk.dwSize);
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
if (FAILED(ret)) goto failed;
|
||||
|
||||
length = subtract_bytes(length, chunk.dwSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail(&This->regions, ®ion->entry);
|
||||
return S_OK;
|
||||
|
||||
failed:
|
||||
free(region);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length)
|
||||
|
@ -287,7 +295,6 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
|
|||
struct instrument *This = impl_from_IDirectMusicInstrument(iface);
|
||||
HRESULT hr;
|
||||
DMUS_PRIVATE_CHUNK chunk;
|
||||
ULONG i = 0;
|
||||
ULONG length = 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)
|
|||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
}
|
||||
|
||||
This->regions = malloc(sizeof(*This->regions) * This->header.cRegions);
|
||||
if (!This->regions)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
while (length)
|
||||
{
|
||||
hr = read_from_stream(stream, &chunk, sizeof(chunk));
|
||||
|
@ -362,7 +365,7 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
|
|||
if (chunk.fccID == FOURCC_RGN)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -431,8 +434,5 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
|
|||
return S_OK;
|
||||
|
||||
error:
|
||||
free(This->regions);
|
||||
This->regions = NULL;
|
||||
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
}
|
||||
|
|
|
@ -267,6 +267,7 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi
|
|||
{
|
||||
struct synth_port *This = synth_from_IDirectMusicPort(iface);
|
||||
struct instrument *instrument_object;
|
||||
struct region *instrument_region;
|
||||
HRESULT ret;
|
||||
BOOL on_heap;
|
||||
HANDLE download;
|
||||
|
@ -312,22 +313,24 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi
|
|||
instrument_info->ulCopyrightIdx = 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);
|
||||
|
||||
offset_table->ulOffsetTable[1 + i] = offset;
|
||||
offset += sizeof(DMUS_REGION);
|
||||
region->RangeKey = instrument_object->regions[i].header.RangeKey;
|
||||
region->RangeVelocity = instrument_object->regions[i].header.RangeVelocity;
|
||||
region->fusOptions = instrument_object->regions[i].header.fusOptions;
|
||||
region->usKeyGroup = instrument_object->regions[i].header.usKeyGroup;
|
||||
region->RangeKey = instrument_region->header.RangeKey;
|
||||
region->RangeVelocity = instrument_region->header.RangeVelocity;
|
||||
region->fusOptions = instrument_region->header.fusOptions;
|
||||
region->usKeyGroup = instrument_region->header.usKeyGroup;
|
||||
region->ulRegionArtIdx = 0; /* FIXME */
|
||||
region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0;
|
||||
region->ulFirstExtCkIdx = 0; /* FIXME */
|
||||
region->WaveLink = instrument_object->regions[i].wave_link;
|
||||
region->WSMP = instrument_object->regions[i].wave_sample;
|
||||
region->WLOOP[0] = instrument_object->regions[i].wave_loop;
|
||||
region->WaveLink = instrument_region->wave_link;
|
||||
region->WSMP = instrument_region->wave_sample;
|
||||
region->WLOOP[0] = instrument_region->wave_loop;
|
||||
i++;
|
||||
}
|
||||
|
||||
ret = IDirectMusicSynth8_Download(This->synth, &download, (void*)data, &on_heap);
|
||||
|
|
Loading…
Add table
Reference in a new issue