diff --git a/packages/alphatab/src/synth/synthesis/Region.ts b/packages/alphatab/src/synth/synthesis/Region.ts index a706584676..5f4b835c60 100644 --- a/packages/alphatab/src/synth/synthesis/Region.ts +++ b/packages/alphatab/src/synth/synthesis/Region.ts @@ -333,7 +333,7 @@ export class Region { this.loopStart += TypeConversions.int16ToUint32(amount.shortAmount) * 32768; break; case GenOperators.InitialAttenuation: - this.attenuation += amount.shortAmount * 0.1; + this.attenuation = amount.shortAmount * 0.1; break; case GenOperators.EndloopAddrsCoarseOffset: this.loopEnd += TypeConversions.int16ToUint32(amount.shortAmount) * 32768; diff --git a/packages/alphatab/test/audio/AlphaSynth.test.ts b/packages/alphatab/test/audio/AlphaSynth.test.ts index 030c9c82f8..cf184c69ae 100644 --- a/packages/alphatab/test/audio/AlphaSynth.test.ts +++ b/packages/alphatab/test/audio/AlphaSynth.test.ts @@ -19,8 +19,9 @@ import type { Score } from '@coderline/alphatab/model/Score'; import { Settings } from '@coderline/alphatab/Settings'; import { AlphaSynth } from '@coderline/alphatab/synth/AlphaSynth'; import { AudioExportOptions } from '@coderline/alphatab/synth/IAudioExporter'; -import { Hydra } from '@coderline/alphatab/synth/soundfont/Hydra'; +import { Hydra, HydraGenAmount } from '@coderline/alphatab/synth/soundfont/Hydra'; import { SynthConstants } from '@coderline/alphatab/synth/SynthConstants'; +import { GenOperators, Region } from '@coderline/alphatab/synth/synthesis/Region'; import { TinySoundFont } from '@coderline/alphatab/synth/synthesis/TinySoundFont'; import { Mdct } from '@coderline/alphatab/synth/vorbis/Mdct'; import { VorbisDecoder } from '@coderline/alphatab/synth/vorbis/VorbisDecoder'; @@ -522,4 +523,19 @@ describe('AlphaSynthTests', () => { await testPlaythrough(midi); }); + + it('soundfont-attenuation-local-overrides-global', () => { + const attenuation = GenOperators.InitialAttenuation as number; + const amount = (v: number) => + new HydraGenAmount(ByteBuffer.fromBuffer(new Uint8Array([v & 0xff, (v >> 8) & 0xff]))); + const globalZone = new Region(); + globalZone.clear(true); + globalZone.operator(attenuation, amount(100)); + const localZone = new Region(globalZone); + expect(localZone.attenuation).toBeCloseTo(10); + localZone.operator(attenuation, amount(60)); + expect(localZone.attenuation).toBeCloseTo(6); + localZone.operator(attenuation, amount(0)); + expect(localZone.attenuation).toBe(0); + }); });