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..13f0434f677 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)floor(attenuation * -65536. + 0.5);
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 13f0434f677..ce8894ac835 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 ce8894ac835..fe1862dd4b0 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 fe1862dd4b0..99232998f0b 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)floor(attenuation * -65536. + 0.5);
start_loop = generators->amount[SF_GEN_STARTLOOP_ADDRS_OFFSET].value;
Rémi Bernon (@rbernon) commented about dlls/dmusic/instrument.c:
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)floor(attenuation * -65536. + 0.5);
Is this really supposed to be rounding like that? It's kind of weird.
On Tue Nov 25 10:57:06 2025 +0000, Rémi Bernon wrote:
Is this really supposed to be rounding like that? It's kind of weird.
It's just rounding to a nearest integer. I can change it to a simple cast if it's confusing.
On Tue Nov 25 11:57:43 2025 +0000, Anton Baskanov wrote:
It's just rounding to a nearest integer. I can change it to a simple cast if it's confusing.
Well not exactly, it rounds (v + 0.5) towards -inf. If you actually want to round to nearest, you should use `round` I think.