From 52d3f7ab09f8b4920c71eaa0c385f13f4bf1fa2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Thu, 31 Aug 2023 21:36:18 +0200 Subject: [PATCH] dmusic: Use a struct list for instrument regions. --- dlls/dmusic/dmusic_private.h | 8 +++--- dlls/dmusic/instrument.c | 50 ++++++++++++++++++------------------ dlls/dmusic/port.c | 19 ++++++++------ 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index bdc86b6883c..3fb32d73691 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -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) diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index a65826976f3..bcd2ef58265 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -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; } diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c index 95a02704a5f..a5ff9bac16e 100644 --- a/dlls/dmusic/port.c +++ b/dlls/dmusic/port.c @@ -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);