From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmsynth/synth.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index ee47852a3e5..b8457c67f2b 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -73,6 +73,26 @@ static void dump_dmus_region(DMUS_REGION *region) } }
+static void dump_connectionlist(CONNECTIONLIST *list) +{ + CONNECTION *connections = (CONNECTION *)(list + 1); + UINT i; + + TRACE("CONNECTIONLIST:\n"); + TRACE(" - cbSize = %lu", list->cbSize); + TRACE(" - cConnections = %lu", list->cConnections); + + for (i = 0; i < list->cConnections; i++) + { + TRACE("- CONNECTION[%u]:\n", i); + TRACE(" - usSource = %u\n", connections[i].usSource); + TRACE(" - usControl = %u\n", connections[i].usControl); + TRACE(" - usDestination = %u\n", connections[i].usDestination); + TRACE(" - usTransform = %u\n", connections[i].usTransform); + TRACE(" - lScale = %lu\n", connections[i].lScale); + } +} + static void dump_dmus_wave(DMUS_WAVE *wave) { TRACE("DMUS_WAVE:\n"); @@ -111,6 +131,13 @@ static void wave_release(struct wave *wave) if (!ref) free(wave); }
+struct articulation +{ + struct list entry; + UINT connections_count; + CONNECTION connections[]; +}; + struct region { struct list entry; @@ -120,6 +147,8 @@ struct region UINT flags; UINT group;
+ struct list articulations; + struct wave *wave; WAVELINK wave_link; WSMPL wave_sample; @@ -128,6 +157,15 @@ struct region
static void region_destroy(struct region *region) { + struct articulation *articulation; + void *next; + + LIST_FOR_EACH_ENTRY_SAFE(articulation, next, ®ion->articulations, struct articulation, entry) + { + list_remove(&articulation->entry); + free(articulation); + } + wave_release(region->wave); free(region); } @@ -141,6 +179,7 @@ struct instrument UINT patch; UINT flags; struct list regions; + struct list articulations;
struct synth *synth; }; @@ -151,6 +190,7 @@ static void instrument_release(struct instrument *instrument)
if (!ref) { + struct articulation *articulation; struct region *region; void *next;
@@ -160,6 +200,12 @@ static void instrument_release(struct instrument *instrument) region_destroy(region); }
+ LIST_FOR_EACH_ENTRY_SAFE(articulation, next, &instrument->articulations, struct articulation, entry) + { + list_remove(&articulation->entry); + free(articulation); + } + free(instrument); } } @@ -365,6 +411,44 @@ static HRESULT WINAPI synth_SetNumChannelGroups(IDirectMusicSynth8 *iface, return S_OK; }
+static HRESULT synth_download_articulation2(struct synth *This, ULONG *offsets, BYTE *data, + UINT index, struct list *list) +{ + DMUS_ARTICULATION2 *articulation_info; + struct articulation *articulation; + CONNECTIONLIST *connections_list; + CONNECTION *connections; + + for (; index; index = articulation_info->ulNextArtIdx) + { + articulation_info = (DMUS_ARTICULATION2 *)(data + offsets[index]); + if (articulation_info->ulFirstExtCkIdx) FIXME("Articulation extensions not implemented\n"); + + connections_list = (CONNECTIONLIST *)(data + offsets[articulation_info->ulArtIdx]); + connections = (CONNECTION *)connections_list + 1; + if (TRACE_ON(dmsynth)) dump_connectionlist(connections_list); + + if (!(articulation = calloc(1, offsetof(struct articulation, connections[connections_list->cConnections])))) return E_OUTOFMEMORY; + articulation->connections_count = connections_list->cConnections; + memcpy(articulation->connections, connections, connections_list->cConnections * sizeof(*connections)); + list_add_tail(list, &articulation->entry); + } + + return S_OK; +} + +static HRESULT synth_download_articulation(struct synth *This, DMUS_DOWNLOADINFO *info, ULONG *offsets, BYTE *data, + UINT index, struct list *list) +{ + if (info->dwDLType == DMUS_DOWNLOADINFO_INSTRUMENT2) + return synth_download_articulation2(This, offsets, data, index, list); + else + { + FIXME("DMUS_ARTICPARAMS support not implemented\n"); + return S_OK; + } +} + static struct wave *synth_find_wave_from_id(struct synth *This, DWORD id) { struct wave *wave; @@ -410,6 +494,7 @@ static HRESULT synth_download_instrument(struct synth *This, DMUS_DOWNLOADINFO * instrument->patch = instrument_info->ulPatch; instrument->flags = instrument_info->ulFlags; list_init(&instrument->regions); + list_init(&instrument->articulations); instrument->synth = This;
for (index = instrument_info->ulFirstRegionIdx; index; index = region_info->ulNextRegionIdx) @@ -426,6 +511,7 @@ static HRESULT synth_download_instrument(struct synth *This, DMUS_DOWNLOADINFO * region->wave_link = region_info->WaveLink; region->wave_sample = region_info->WSMP; memcpy(region->wave_loops, region_info->WLOOP, region_info->WSMP.cSampleLoops * sizeof(WLOOP)); + list_init(®ion->articulations);
if (!(region->wave = synth_find_wave_from_id(This, region->wave_link.ulTableIndex))) { @@ -435,8 +521,16 @@ static HRESULT synth_download_instrument(struct synth *This, DMUS_DOWNLOADINFO * }
list_add_tail(&instrument->regions, ®ion->entry); + + if (region_info->ulRegionArtIdx && FAILED(synth_download_articulation(This, info, offsets, data, + region_info->ulRegionArtIdx, ®ion->articulations))) + goto error; }
+ if (FAILED(synth_download_articulation(This, info, offsets, data, + instrument_info->ulGlobalArtIdx, &instrument->articulations))) + goto error; + list_add_tail(&This->instruments, &instrument->entry); *ret_handle = instrument;