Ramp sound FX parameters over a time on the audio clock
A pitch sweep counted down in On update or On fixed update runs in game time, while the sound runs on the clock of the audio device. A short sound magnifies any offset between the two, so the sweep came out different on every play and most of all on the first. - Set sound FX parameters has a new input time in seconds. The values run evenly to their target in that time, scheduled on the audio clock with linearRampToValueAtTime or exponentialRampToValueAtTime. - Evenly in their own unit: a pitch in semitones and a gain in decibels, an EQ band and a Mix share linearly in their value. - A time of 0 or below keeps the quick glide of about 0.1 s. - Each change starts from where the voice is now. Whatever was still planned is dropped, so a change never queues behind an older one. Firefox lacks cancelAndHoldAtTime, there the value is held by hand. - A voice still waiting on its bytes starts a timed change with the sound, so the whole sweep is heard. Tests: - node-catalog: time is handed on, a time below 0 is a quick glide. - sound-library: semitones and decibels ramp in their own steps, a timed change on a waiting voice starts with the sound. - sound-library + node-catalog + soundfx: 419 tests, green. - e2e 34 on melektaus-atx: ALL PASSED, 31 checks. A 2 s ramp from depth 7 to -5 read speed 0.979, 0.926 and 0.778 half a second on. - Counter-check: folding a timed change on a waiting voice into its start values fails the new test. - The gate did not run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ed2b58b3c0
commit
501a1524ed
9 files changed
+154
-29
No files matched your search
@@ -2032,7 +2032,19 @@ const CASES: Record<string, Case[]> = {
|
||||
name: 'hands the numbers of the bundle to the voice it is given',
|
||||
inputs: { voice: 4, fxParams: { depth: 3, label: 'x' } },
|
||||
next: 'exec',
|
||||
after: (ctx) => expect(ctx.tuned).toEqual([{ voice: 4, fxParams: { depth: 3 } }]),
|
||||
after: (ctx) => expect(ctx.tuned).toEqual([{ voice: 4, fxParams: { depth: 3 }, time: 0 }]),
|
||||
},
|
||||
{
|
||||
name: 'hands on the time the values take to get there',
|
||||
inputs: { voice: 4, fxParams: { depth: -64 }, time: 1.28 },
|
||||
next: 'exec',
|
||||
after: (ctx) => expect(ctx.tuned).toEqual([{ voice: 4, fxParams: { depth: -64 }, time: 1.28 }]),
|
||||
},
|
||||
{
|
||||
name: 'a time below 0 is a quick glide',
|
||||
inputs: { voice: 4, fxParams: { depth: 3 }, time: -2 },
|
||||
next: 'exec',
|
||||
after: (ctx) => expect(ctx.tuned).toEqual([{ voice: 4, fxParams: { depth: 3 }, time: 0 }]),
|
||||
},
|
||||
{
|
||||
name: 'voice 0 – nothing was played – reaches nothing, and the flow carries on',
|
||||
@@ -2119,6 +2131,7 @@ const EVENT_NODES: Record<string, string> = {
|
||||
OnStart: 'graph.test.ts',
|
||||
OnEnable: 'behavior-events.test.ts',
|
||||
OnUpdate: 'graph.test.ts',
|
||||
OnFixedUpdate: 'fixed-update.test.ts',
|
||||
OnDisable: 'behavior-events.test.ts',
|
||||
OnDestroy: 'behavior-events.test.ts',
|
||||
OnKeyDown: 'behavior-events.test.ts',
|
||||
@@ -2131,7 +2144,6 @@ const EVENT_NODES: Record<string, string> = {
|
||||
OnClick: 'nodes.test.ts',
|
||||
OnMouseWheel: 'clip-areas.test.ts',
|
||||
OnAnimationFinished: 'animation.test.ts',
|
||||
OnFixedUpdate: 'fixed-update.test.ts',
|
||||
OnStateEntered: 'state-machine.test.ts',
|
||||
OnStateExited: 'state-machine.test.ts',
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user