-- v2: dmusic: Take sample correction into account. dmusic: Add an 8 dB attenuation to normalize SF2 instrument volume. dmusic: Add IIR filter resonance hump compensation. dmusic: Set attenuation based on SF_GEN_INITIAL_ATTENUATION.
From: Anton Baskanov baskanov@gmail.com
--- dlls/dmusic/instrument.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index 1710cbc690d..2c7bfc7862a 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -576,7 +576,7 @@ static HRESULT instrument_add_soundfont_region(struct instrument *This, struct s
unity_note = generators->amount[SF_GEN_OVERRIDING_ROOT_KEY].value; if (unity_note == (WORD)-1) unity_note = sample->original_key; - region->wave_sample.usUnityNote = unity_note; + region->wave_sample.usUnityNote = unity_note - (SHORT)generators->amount[SF_GEN_COARSE_TUNE].value; region->wave_sample.sFineTune = generators->amount[SF_GEN_FINE_TUNE].value; region->wave_sample.lAttenuation = sample->correction;
From: Anton Baskanov baskanov@gmail.com
--- dlls/dmusic/instrument.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index 2c7bfc7862a..a5da7d0fdbb 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <math.h> + #include "dmusic_private.h" #include "soundfont.h" #include "dls2.h" @@ -563,6 +565,7 @@ static HRESULT instrument_add_soundfont_region(struct instrument *This, struct s UINT start_loop, end_loop, unity_note, sample_index = generators->amount[SF_GEN_SAMPLE_ID].value; struct sf_sample *sample = soundfont->shdr + sample_index; struct region *region; + double attenuation;
if (!(region = calloc(1, sizeof(*region)))) return E_OUTOFMEMORY; list_init(®ion->articulations); @@ -574,11 +577,15 @@ static HRESULT instrument_add_soundfont_region(struct instrument *This, struct s
region->wave_link.ulTableIndex = sample_index;
+ /* SF2 implementation for the original hardware applies a factor of 0.4 to + * the attenuation value. Although this does not comply with the SF2 spec, + * most soundfonts expect this behavior. */ + attenuation = (SHORT)generators->amount[SF_GEN_INITIAL_ATTENUATION].value * 0.4; unity_note = generators->amount[SF_GEN_OVERRIDING_ROOT_KEY].value; if (unity_note == (WORD)-1) unity_note = sample->original_key; region->wave_sample.usUnityNote = unity_note - (SHORT)generators->amount[SF_GEN_COARSE_TUNE].value; region->wave_sample.sFineTune = generators->amount[SF_GEN_FINE_TUNE].value; - region->wave_sample.lAttenuation = sample->correction; + region->wave_sample.lAttenuation = (LONG)round(attenuation * -65536.);
start_loop = generators->amount[SF_GEN_STARTLOOP_ADDRS_OFFSET].value; start_loop += generators->amount[SF_GEN_STARTLOOP_ADDRS_COARSE_OFFSET].value * 32768;
From: Anton Baskanov baskanov@gmail.com
--- dlls/dmusic/instrument.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index a5da7d0fdbb..bfef3975da9 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -581,6 +581,10 @@ static HRESULT instrument_add_soundfont_region(struct instrument *This, struct s * the attenuation value. Although this does not comply with the SF2 spec, * most soundfonts expect this behavior. */ attenuation = (SHORT)generators->amount[SF_GEN_INITIAL_ATTENUATION].value * 0.4; + /* Normally, FluidSynth adds a resonance hump compensation in + * fluid_iir_filter_q_from_dB, but as DLS has no such compensation, it's + * disabled in the budled version of FluidSynth. Add it back here. */ + attenuation += -15.05; unity_note = generators->amount[SF_GEN_OVERRIDING_ROOT_KEY].value; if (unity_note == (WORD)-1) unity_note = sample->original_key; region->wave_sample.usUnityNote = unity_note - (SHORT)generators->amount[SF_GEN_COARSE_TUNE].value;
From: Anton Baskanov baskanov@gmail.com
--- dlls/dmusic/instrument.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index bfef3975da9..d95edcc934d 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -585,6 +585,11 @@ static HRESULT instrument_add_soundfont_region(struct instrument *This, struct s * fluid_iir_filter_q_from_dB, but as DLS has no such compensation, it's * disabled in the budled version of FluidSynth. Add it back here. */ attenuation += -15.05; + /* Add some attenuation to normalize the volume. The value was determined + * experimentally by comparing instruments from SF2 soundfonts to the + * gm.dls equivalents. The value is approximate, as there is some volume + * variation from instrument to instrument. */ + attenuation += 80.; unity_note = generators->amount[SF_GEN_OVERRIDING_ROOT_KEY].value; if (unity_note == (WORD)-1) unity_note = sample->original_key; region->wave_sample.usUnityNote = unity_note - (SHORT)generators->amount[SF_GEN_COARSE_TUNE].value;
From: Anton Baskanov baskanov@gmail.com
--- dlls/dmusic/instrument.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index d95edcc934d..40c43277243 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -593,7 +593,7 @@ static HRESULT instrument_add_soundfont_region(struct instrument *This, struct s unity_note = generators->amount[SF_GEN_OVERRIDING_ROOT_KEY].value; if (unity_note == (WORD)-1) unity_note = sample->original_key; region->wave_sample.usUnityNote = unity_note - (SHORT)generators->amount[SF_GEN_COARSE_TUNE].value; - region->wave_sample.sFineTune = generators->amount[SF_GEN_FINE_TUNE].value; + region->wave_sample.sFineTune = sample->correction + generators->amount[SF_GEN_FINE_TUNE].value; region->wave_sample.lAttenuation = (LONG)round(attenuation * -65536.);
start_loop = generators->amount[SF_GEN_STARTLOOP_ADDRS_OFFSET].value;
On Tue Nov 25 17:09:11 2025 +0000, Anton Baskanov wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9583/diffs?diff_id=227434&start_sha=838ced8dc3ed1cc22fe98fa094250e6ab1d4aa32#10f65150261f79fd17205ded12c05be754cd4053_597_597)
Done.
v2: - Use `round(x)` instead of `floor(x + 0.5)`.
This merge request was approved by Rémi Bernon.
This merge request was approved by Michael Stefaniuc.
All the test failures are unrelated to DMusic.