From: Anton Baskanov baskanov@gmail.com
Fixes out-of-tune Harmonica from gm.dls. --- dlls/dmsynth/synth.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index 4fabdcdda87..31adf3df1c1 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -1772,8 +1772,11 @@ static int synth_preset_noteon(fluid_preset_t *fluid_preset, fluid_synth_t *flui else FIXME("Unsupported loop type %lu\n", loop->ulType);
- fluid_voice_gen_set(fluid_voice, GEN_STARTLOOPADDROFS, loop->ulStart); - fluid_voice_gen_set(fluid_voice, GEN_ENDLOOPADDROFS, loop->ulStart + loop->ulLength); + /* When copy_data is TRUE, fluid_sample_set_sound_data() adds + * 8-frame padding around the sample data. Offset the loop points + * to compensate for this. */ + fluid_voice_gen_set(fluid_voice, GEN_STARTLOOPADDROFS, 8 + loop->ulStart); + fluid_voice_gen_set(fluid_voice, GEN_ENDLOOPADDROFS, 8 + loop->ulStart + loop->ulLength); } LIST_FOR_EACH_ENTRY(articulation, &instrument->articulations, struct articulation, entry) add_voice_connections(fluid_voice, &articulation->list, articulation->connections);
From: Anton Baskanov baskanov@gmail.com
--- dlls/dmsynth/synth.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index 31adf3df1c1..2b0c5b45ea5 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -1080,6 +1080,9 @@ static HRESULT WINAPI synth_Render(IDirectMusicSynth8 *iface, short *buffer, case MIDI_PROGRAM_CHANGE: fluid_synth_program_change(This->fluid_synth, chan, event->midi[1]); break; + case MIDI_PITCH_BEND_CHANGE: + fluid_synth_pitch_bend(This->fluid_synth, chan, event->midi[1] | (event->midi[2] << 7)); + break; default: FIXME("MIDI event not implemented: %#x %#x %#x\n", event->midi[0], event->midi[1], event->midi[2]); break;
From: Anton Baskanov baskanov@gmail.com
Fixes pitch bend scale. --- dlls/dmsynth/synth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index 2b0c5b45ea5..72696cca856 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -1563,7 +1563,7 @@ static void add_voice_connections(fluid_voice_t *fluid_voice, const CONNECTIONLI if (!mod_from_connection(conn->usSource, (conn->usTransform >> 10) & 0x3f, &src1, &flags1)) continue; - if (!mod_from_connection(conn->usControl, (conn->usControl >> 4) & 0x3f, + if (!mod_from_connection(conn->usControl, (conn->usTransform >> 4) & 0x3f, &src2, &flags2)) continue; add_mod_from_connection(fluid_voice, conn, src1, flags1, src2, flags2);
From: Anton Baskanov baskanov@gmail.com
Fixes modulation wheel effects. --- dlls/dmsynth/synth.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index 72696cca856..ee1ec1aad06 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -1497,9 +1497,9 @@ static BOOL mod_from_connection(USHORT source, USHORT transform, UINT *fluid_sou return TRUE; }
-static BOOL add_mod_from_connection(fluid_voice_t *fluid_voice, const CONNECTION *conn, - UINT src1, UINT flags1, UINT src2, UINT flags2) +static BOOL add_mod_from_connection(fluid_voice_t *fluid_voice, const CONNECTION *conn) { + UINT src1 = FLUID_MOD_NONE, flags1 = 0, src2 = FLUID_MOD_NONE, flags2 = 0; fluid_mod_t *mod; UINT gen = -1; double value; @@ -1520,10 +1520,15 @@ static BOOL add_mod_from_connection(fluid_voice_t *fluid_voice, const CONNECTION
if (conn->usControl != CONN_SRC_NONE && gen != -1) { - src1 = src2; - flags1 = flags2; - src2 = 0; - flags2 = 0; + if (!mod_from_connection(conn->usControl, (conn->usTransform >> 4) & 0x3f, &src1, &flags1)) + return FALSE; + } + else + { + if (!mod_from_connection(conn->usSource, (conn->usTransform >> 10) & 0x3f, &src1, &flags1)) + return FALSE; + if (!mod_from_connection(conn->usControl, (conn->usTransform >> 4) & 0x3f, &src2, &flags2)) + return FALSE; }
if (gen == -1 && !gen_from_connection(conn, &gen)) return FALSE; @@ -1555,18 +1560,11 @@ static void add_voice_connections(fluid_voice_t *fluid_voice, const CONNECTIONLI
for (i = 0; i < list->cConnections; i++) { - UINT src1 = FLUID_MOD_NONE, flags1 = 0, src2 = FLUID_MOD_NONE, flags2 = 0; const CONNECTION *conn = connections + i;
if (set_gen_from_connection(fluid_voice, conn)) continue;
- if (!mod_from_connection(conn->usSource, (conn->usTransform >> 10) & 0x3f, - &src1, &flags1)) - continue; - if (!mod_from_connection(conn->usControl, (conn->usTransform >> 4) & 0x3f, - &src2, &flags2)) - continue; - add_mod_from_connection(fluid_voice, conn, src1, flags1, src2, flags2); + add_mod_from_connection(fluid_voice, conn); } }
From: Anton Baskanov baskanov@gmail.com
--- dlls/dmsynth/synth.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index ee1ec1aad06..f6565c7a36d 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -565,6 +565,10 @@ static HRESULT WINAPI synth_Open(IDirectMusicSynth8 *iface, DMUS_PORTPARAMS *par }
fluid_settings_setnum(This->fluid_settings, "synth.sample-rate", actual.dwSampleRate); + fluid_settings_setint(This->fluid_settings, "synth.reverb.active", + !!(actual.dwEffectFlags & DMUS_EFFECT_REVERB)); + fluid_settings_setint(This->fluid_settings, "synth.chorus.active", + !!(actual.dwEffectFlags & DMUS_EFFECT_CHORUS)); if (!(This->fluid_synth = new_fluid_synth(This->fluid_settings))) return E_OUTOFMEMORY; if ((id = fluid_synth_add_sfont(This->fluid_synth, This->fluid_sfont)) == FLUID_FAILED) WARN("Failed to add fluid_sfont to fluid_synth\n");
Rémi Bernon (@rbernon) commented about dlls/dmsynth/synth.c:
return TRUE;
}
-static BOOL add_mod_from_connection(fluid_voice_t *fluid_voice, const CONNECTION *conn,
Maybe we should remove the BOOL return, doesn't look useful after all.
Rémi Bernon (@rbernon) commented about dlls/dmsynth/synth.c:
else FIXME("Unsupported loop type %lu\n", loop->ulType);
fluid_voice_gen_set(fluid_voice, GEN_STARTLOOPADDROFS, loop->ulStart);
fluid_voice_gen_set(fluid_voice, GEN_ENDLOOPADDROFS, loop->ulStart + loop->ulLength);
/* When copy_data is TRUE, fluid_sample_set_sound_data() adds
* 8-frame padding around the sample data. Offset the loop points
* to compensate for this. */
fluid_voice_gen_set(fluid_voice, GEN_STARTLOOPADDROFS, 8 + loop->ulStart);
fluid_voice_gen_set(fluid_voice, GEN_ENDLOOPADDROFS, 8 + loop->ulStart + loop->ulLength);
Maybe we should not use copy_data? Adding a reference to the wave and releasing from a sample->notify callback. I even suspect (but it needs to be confirmed) that we're leaking fluid_samples at the moment, and that we should free them from the callback too.
I'm not able to test it with FFVIII until next week, but I think it looks alright so that might not be necessary.
On Mon Oct 30 09:55:23 2023 +0000, Rémi Bernon wrote:
Maybe we should not use copy_data? Adding a reference to the wave and releasing from a sample->notify callback. I even suspect (but it needs to be confirmed) that we're leaking fluid_samples at the moment, and that we should free them from the callback too.
Correct me if I'm wrong, but it looks like there's no way to set `sample->notify` through FluidSynth API. As an alternative, we could create FluidSynth samples in `synth_download_wave()` and use `GEN_OVERRIDEROOTKEY` and `GEN_FINETUNE` to set region-specific parameters, but we'd need to handle unloading of samples that are still playing.
Note also that according to `fluid_sample_set_sound_data()` docs, when copy_data is `FALSE` we should provide the 8-frame padding ourselves, so the loop point offset will still be necessary.