Keep both sounds full at the middle of a Mix with a curve #331
A Mix crossfaded: at 0.5 each sound was at half. Layering two sounds in an instrument now goes through a Mix (076c564), so the user asked for a second curve where each side stays full up to the middle and only fades on the other half. At 0.25 a is full and b half, at 0.5 both are full, at 0.75 a is half and b full. - The Mix has a setting Curve with Crossfade (default) and Both at center. A plan and a chain only say `curve` where it is `both`, so old projects and their compiled plans stay as they were. - A share is not a straight line of `mix` with that curve. Two ramps of their own would dip to half each when `mix` glides across the middle. So a ConstantSourceNode carries `mix` on the audio thread, and two WaveShaperNodes make the shares from it. The knob of such a Mix is that one source. - The source is started with the voice and stopped when it is cut or ends by itself, so it does not run on after the voice. - A sound FX node in an instrument keeps the curve of a Mix inside it. - At 0.5 both sounds are added in full, up to +6 dB where both are loud. That is what several edges into the Output did before. The wiki says so. Found on the way: the suite of23bdc3f(task 529) failed the Step check in e2e 34. It timed the jump from the start of the voice, but a timed change runs from when it arrives. In CI that was 80 ms later, and the pitch rightly held to 2.08 s. - stats() says `tunedAt`, the second of the audio clock the last change moved a voice. A change that moves nothing, as On update sends every frame, leaves it. - The Step check times its readings from there. Tests: - sound-library.test.ts: both shares shaped from one source, a glide moves only the source, the source stops with a cut and with an end by itself (50 tests, 2 new) - soundfx.test.ts: curve only where set, one sound at 0 (41 tests) - instrument.test.ts: the curve through a sound FX node (34 tests) - Counter-checks: dropping the curve in throughFx and not stopping the source in done() each turn their new test red - e2e 34 on melektaus-atx: ALL PASSED, 48 checks (+1). Rendered offline in Chrome, a and b come to 1/0, 1/0.5, 1/1, 0.5/1 and 0/1 at mix 0 to 1, and a glide from 0 to 1 reads the same at 0.25, 0.5 and 0.75 s. Step jumped 2.04 s after the change. - Gate on melektaus-atx: CHECK EXIT 0, 244 test files, 3793 tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
076c564415
commit
fb4d65a2ab
8 files changed
+261
-25
No files matched your search
@@ -4,7 +4,7 @@ import type { SchedulerOptions } from '../core/music/Scheduler';
|
||||
import type { Sequence } from '../core/music/sequence';
|
||||
import type { FxStage } from '../core/soundfx/nodes';
|
||||
import { Music } from '../viewport/music';
|
||||
import { soundLibrary, stageNodes } from '../viewport/SoundLibrary';
|
||||
import { bothAtCenter, soundLibrary, stageNodes } from '../viewport/SoundLibrary';
|
||||
import { curveHooks } from './debug/curveHooks';
|
||||
import { documentHooks } from './debug/documentHooks';
|
||||
import { graphHooks } from './debug/graphHooks';
|
||||
@@ -58,6 +58,9 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
stop: (file: string, letRing: boolean) => soundLibrary.stop(file, letRing),
|
||||
/** The nodes a stage of a voice becomes, in any context – an offline one renders what it does. */
|
||||
stageNodes: (context: BaseAudioContext, stage: FxStage) => stageNodes(context, stage),
|
||||
/** What drives the two shares of a Mix "Both at center", in any context (unstarted). */
|
||||
bothAtCenter: (context: BaseAudioContext, mix: number, a: GainNode, b: GainNode) =>
|
||||
bothAtCenter(context, mix, a, b),
|
||||
},
|
||||
/**
|
||||
* The scheduler (#332), which nothing in the editor plays yet: a check hands it a sequence of
|
||||
|
||||
Reference in new issue
Block a user