From 7f629f7f542a14cdd0a58ac2af8bb26d7d0d2d32 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Bernon?= Date: Mon, 16 Oct 2023 19:44:37 +0200 Subject: [PATCH] dmsynth: Convert modulator values from DLS2 to SF2 convention. --- dlls/dmsynth/synth.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/dlls/dmsynth/synth.c b/dlls/dmsynth/synth.c index 45940e25b59..cb1858f3ce4 100644 --- a/dlls/dmsynth/synth.c +++ b/dlls/dmsynth/synth.c @@ -1336,6 +1336,7 @@ static BOOL gen_from_connection(const CONNECTION *conn, UINT *gen) static BOOL set_gen_from_connection(fluid_voice_t *fluid_voice, const CONNECTION *conn) { + double value; UINT gen; if (conn->usControl != CONN_SRC_NONE) return FALSE; @@ -1388,7 +1389,16 @@ static BOOL set_gen_from_connection(fluid_voice_t *fluid_voice, const CONNECTION return FALSE; } - fluid_voice_gen_set(fluid_voice, gen, conn->lScale); + /* SF2 / FluidSynth use 0.1% as "Sustain Level" unit, DLS2 uses percent, meaning is also reversed */ + if (gen == GEN_MODENVSUSTAIN || gen == GEN_VOLENVSUSTAIN) value = 1000 - conn->lScale * 10 / 65536.; + /* FIXME: SF2 and FluidSynth use 1200 * log2(f / 8.176) for absolute freqs, + * whereas DLS2 uses (1200 * log2(f / 440.) + 6900) * 65536. The values + * are very close but not strictly identical and we may need a conversion. + */ + else if (conn->lScale == 0x80000000) value = -32768; + else value = conn->lScale / 65536.; + fluid_voice_gen_set(fluid_voice, gen, value); + return TRUE; } @@ -1431,6 +1441,7 @@ static BOOL add_mod_from_connection(fluid_voice_t *fluid_voice, const CONNECTION { fluid_mod_t *mod; UINT gen = -1; + double value; switch (MAKELONG(conn->usSource, conn->usDestination)) { @@ -1460,7 +1471,17 @@ static BOOL add_mod_from_connection(fluid_voice_t *fluid_voice, const CONNECTION fluid_mod_set_source1(mod, src1, flags1); fluid_mod_set_source2(mod, src2, flags2); fluid_mod_set_dest(mod, gen); - fluid_mod_set_amount(mod, conn->lScale); + + /* SF2 / FluidSynth use 0.1% as "Sustain Level" unit, DLS2 uses percent, meaning is also reversed */ + if (gen == GEN_MODENVSUSTAIN || gen == GEN_VOLENVSUSTAIN) value = 1000 - conn->lScale * 10 / 65536.; + /* FIXME: SF2 and FluidSynth use 1200 * log2(f / 8.176) for absolute freqs, + * whereas DLS2 uses (1200 * log2(f / 440.) + 6900) * 65536. The values + * are very close but not strictly identical and we may need a conversion. + */ + else if (conn->lScale == 0x80000000) value = -32768; + else value = conn->lScale / 65536.; + fluid_mod_set_amount(mod, value); + fluid_voice_add_mod(fluid_voice, mod, FLUID_VOICE_OVERWRITE); return TRUE; -- 2.11.4.GIT