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;