From: Anton Baskanov baskanov@gmail.com
--- dlls/dmsynth/synth.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index a4196f29a8a..d8acc76d3f0 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -320,6 +320,13 @@ struct event BYTE midi[3]; };
+struct voice +{ + struct list entry; + fluid_voice_t *fluid_voice; + struct wave *wave; +}; + struct synth { IDirectMusicSynth8 IDirectMusicSynth8_iface; @@ -336,6 +343,7 @@ struct synth struct list instruments; struct list waves; struct list events; + struct list voices;
fluid_settings_t *fluid_settings; fluid_sfont_t *fluid_sfont; @@ -397,6 +405,7 @@ static ULONG WINAPI synth_Release(IDirectMusicSynth8 *iface) { struct instrument *instrument; struct event *event; + struct voice *voice; struct wave *wave; void *next;
@@ -418,6 +427,14 @@ static ULONG WINAPI synth_Release(IDirectMusicSynth8 *iface) free(event); }
+ LIST_FOR_EACH_ENTRY_SAFE(voice, next, &This->voices, struct voice, entry) + { + list_remove(&voice->entry); + if (voice->wave) + wave_release(voice->wave); + free(voice); + } + fluid_sfont_set_data(This->fluid_sfont, NULL); delete_fluid_sfont(This->fluid_sfont); This->fluid_sfont = NULL; @@ -1742,6 +1759,7 @@ static int synth_preset_noteon(fluid_preset_t *fluid_preset, fluid_synth_t *flui { struct articulation *articulation; struct wave *wave = region->wave; + struct voice *voice;
if (key < region->key_range.usLow || key > region->key_range.usHigh) continue; if (vel < region->vel_range.usLow || vel > region->vel_range.usHigh) continue; @@ -1763,6 +1781,28 @@ static int synth_preset_noteon(fluid_preset_t *fluid_preset, fluid_synth_t *flui return FLUID_FAILED; }
+ LIST_FOR_EACH_ENTRY(voice, &synth->voices, struct voice, entry) + { + if (voice->fluid_voice == fluid_voice) + break; + } + + if (&voice->entry == &synth->voices) + { + if (!(voice = calloc(1, sizeof(struct voice)))) + { + delete_fluid_sample(fluid_sample); + return FLUID_FAILED; + } + voice->fluid_voice = fluid_voice; + list_add_tail(&synth->voices, &voice->entry); + } + + if (voice->wave) + wave_release(voice->wave); + voice->wave = wave; + wave_addref(voice->wave); + set_default_voice_connections(fluid_voice); if (region->wave_sample.cSampleLoops) { @@ -1885,6 +1925,7 @@ HRESULT synth_create(IUnknown **ret_iface) list_init(&obj->instruments); list_init(&obj->waves); list_init(&obj->events); + list_init(&obj->voices);
if (!(obj->fluid_settings = new_fluid_settings())) goto failed; if (!(obj->fluid_sfont = new_fluid_sfont(synth_sfont_get_name, synth_sfont_get_preset,