Module: wine Branch: master Commit: 24c00250c4a5e95a1b7b30e6ce396ee05a1bccbb URL: https://gitlab.winehq.org/wine/wine/-/commit/24c00250c4a5e95a1b7b30e6ce396ee...
Author: Anton Baskanov baskanov@gmail.com Date: Thu Nov 2 14:16:50 2023 +0700
dmsynth: Move instrument search to synth_preset_noteon().
This allows loaded instruments to take effect without a subsequent program change. In particular, when there is no program change at all, this allows the default Acoustic Grand Piano or Standard drum set to play. As a side effect, this disables FluidSynth fallback logic for missing presets.
---
dlls/dmsynth/synth.c | 53 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index 51271e48b2a..d11ca0f2f5d 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -288,11 +288,6 @@ struct instrument struct synth *synth; };
-static void instrument_addref(struct instrument *instrument) -{ - InterlockedIncrement(&instrument->ref); -} - static void instrument_release(struct instrument *instrument) { ULONG ref = InterlockedDecrement(&instrument->ref); @@ -327,7 +322,7 @@ struct preset
fluid_preset_t *fluid_preset;
- struct instrument *instrument; + struct synth *synth; };
struct event @@ -637,7 +632,6 @@ static HRESULT WINAPI synth_Close(IDirectMusicSynth8 *iface) LIST_FOR_EACH_ENTRY_SAFE(preset, next, &This->presets, struct preset, entry) { list_remove(&preset->entry); - instrument_release(preset->instrument); delete_fluid_preset(preset->fluid_preset); free(preset); } @@ -1785,13 +1779,28 @@ static void set_default_voice_connections(fluid_voice_t *fluid_voice) static int synth_preset_noteon(fluid_preset_t *fluid_preset, fluid_synth_t *fluid_synth, int chan, int key, int vel) { struct preset *preset = fluid_preset_get_data(fluid_preset); - struct instrument *instrument = preset->instrument; - struct synth *synth = instrument->synth; + struct synth *synth = preset->synth; + struct instrument *instrument; fluid_voice_t *fluid_voice; struct region *region;
TRACE("(%p, %p, %u, %u, %u)\n", fluid_preset, fluid_synth, chan, key, vel);
+ EnterCriticalSection(&synth->cs); + + LIST_FOR_EACH_ENTRY(instrument, &synth->instruments, struct instrument, entry) + { + if (preset->bank == 128 && instrument->patch == (0x80000000 | preset->patch)) break; + else if (instrument->patch == ((preset->bank << 8) | preset->patch)) break; + } + + if (&instrument->entry == &synth->instruments) + { + WARN("Could not find instrument with patch %#x\n", preset->patch); + LeaveCriticalSection(&synth->cs); + return FLUID_FAILED; + } + LIST_FOR_EACH_ENTRY(region, &instrument->regions, struct region, entry) { struct articulation *articulation; @@ -1804,6 +1813,7 @@ static int synth_preset_noteon(fluid_preset_t *fluid_preset, fluid_synth_t *flui if (!(fluid_voice = fluid_synth_alloc_voice(synth->fluid_synth, wave->fluid_sample, chan, key, vel))) { WARN("Failed to allocate FluidSynth voice\n"); + LeaveCriticalSection(&synth->cs); return FLUID_FAILED; }
@@ -1819,7 +1829,10 @@ static int synth_preset_noteon(fluid_preset_t *fluid_preset, fluid_synth_t *flui if (&voice->entry == &synth->voices) { if (!(voice = calloc(1, sizeof(struct voice)))) + { + LeaveCriticalSection(&synth->cs); return FLUID_FAILED; + } voice->fluid_voice = fluid_voice; list_add_tail(&synth->voices, &voice->entry); } @@ -1852,9 +1865,12 @@ static int synth_preset_noteon(fluid_preset_t *fluid_preset, fluid_synth_t *flui LIST_FOR_EACH_ENTRY(articulation, ®ion->articulations, struct articulation, entry) add_voice_connections(fluid_voice, &articulation->list, articulation->connections); fluid_synth_start_voice(synth->fluid_synth, fluid_voice); + LeaveCriticalSection(&synth->cs); return FLUID_OK; }
+ LeaveCriticalSection(&synth->cs); + WARN("Failed to find instrument matching note / velocity\n"); return FLUID_FAILED; } @@ -1871,7 +1887,6 @@ static const char *synth_sfont_get_name(fluid_sfont_t *fluid_sfont) static fluid_preset_t *synth_sfont_get_preset(fluid_sfont_t *fluid_sfont, int bank, int patch) { struct synth *synth = fluid_sfont_get_data(fluid_sfont); - struct instrument *instrument; fluid_preset_t *fluid_preset; struct preset *preset;
@@ -1888,19 +1903,6 @@ static fluid_preset_t *synth_sfont_get_preset(fluid_sfont_t *fluid_sfont, int ba } }
- LIST_FOR_EACH_ENTRY(instrument, &synth->instruments, struct instrument, entry) - { - if (bank == 128 && instrument->patch == (0x80000000 | patch)) break; - else if (instrument->patch == ((bank << 8) | patch)) break; - } - - if (&instrument->entry == &synth->instruments) - { - WARN("Could not find instrument with patch %#x\n", patch); - LeaveCriticalSection(&synth->cs); - return NULL; - } - if (!(fluid_preset = new_fluid_preset(fluid_sfont, synth_preset_get_name, synth_preset_get_bank, synth_preset_get_num, synth_preset_noteon, synth_preset_free))) { @@ -1918,12 +1920,11 @@ static fluid_preset_t *synth_sfont_get_preset(fluid_sfont_t *fluid_sfont, int ba preset->bank = bank; preset->patch = patch; preset->fluid_preset = fluid_preset; - preset->instrument = instrument; + preset->synth = synth; fluid_preset_set_data(fluid_preset, preset); - instrument_addref(instrument); list_add_tail(&synth->presets, &preset->entry);
- TRACE("Created fluid_preset %p for instrument %p\n", fluid_preset, instrument); + TRACE("Created fluid_preset %p\n", fluid_preset);
LeaveCriticalSection(&synth->cs);