Show a Reverb node as a device with a round screen of its tail (#389)
The Compressor, the Gain, the Chip and the Envelope are devices in the graph. The Reverb was still a list of rows, and how long and how dark its tail rings was left to the numbers. - The node is a plate of 640x280 in pale lavender. Its inputs are on the left, its output on the right. - A round screen draws the tail as rings out from the sound. A ring's radius is its time, as the root of its seconds, on one scale up to 10.5 s for every Reverb. So a Room is a small disc and a Cave fills two thirds. - A ring is as bright as the tail is loud there, evenly in dB. Its colour is how much of the highs is left, from ice to violet, with the cut-off of the impulse response (reverbCutoff, now shared). - The pre-delay is a dark gap round the dot, a dashed ring marks -60 dB. Seeded dots stand for the reflections. Wet fades the tail against the dot. - A type of Sound draws the peaks of its sound from the library, each against its loudest. It says LOADING until they are there. - A button for each type, a list of the sounds and four chrome knobs: Decay, Damping, Pre-delay and Wet. - A knob the type does not take is greyed but turns. It goes over to Custom with the type's numbers, as one undo step. Picking a sound makes the type Sound, also one step. - NodeParamDrag can write several settings as one drag for that. - Test hook __gm.reverb.panel(nodeId), for the sound FX and the instrument graph. Tests: - Unit reverb-view: 10 new tests for the plate, the knob turn, the numbers per type, the scale, the tail and the texts. A screen that ignores damping turns the highs test red. - e2e 34 (atx): 1 new check (device between its ports, decay knob of a Hall goes to Custom as one undo step, Cave button, a sound from the list makes it Sound and draws that sound). - Probe pictures on stein2: Room, Hall, Cave, Plate, Custom with damping 1 and pre-delay 0.3 s, Sound. - Gate (atx): CHECK EXIT 0, 287 files, 4393 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c75e72d4ee
commit
e8021b1fd3
11 files changed
+1249
-29
No files matched your search
@@ -1214,6 +1214,79 @@ export async function sound(t) {
|
||||
graph.nodes = graph.nodes.filter((n) => n.id !== 'fx-hw');
|
||||
graph.edges = graph.edges.filter((e) => !['fx-e15', 'fx-e16'].includes(e.id));
|
||||
graph.edges.push(${JSON.stringify(edge('fx-e3', 'fx-gain', 'out', 'fx-out', 'in'))});`);
|
||||
// #389: a Reverb node is drawn as a device with a round screen of its tail. A knob its type does
|
||||
// not take goes over to Custom with the type's numbers, as one undo step; a sound picked on
|
||||
// it makes the type Sound and the screen draws that sound's tail. It is wired to nothing.
|
||||
await mutate(`
|
||||
const graph = __gm.state.project.assets.find((a) => a.id === ${JSON.stringify(fxId)}).graph;
|
||||
graph.nodes.push(${JSON.stringify(node('fx-rv', 'SoundFxReverb', 0, 400, { room: 'hall' }))});`);
|
||||
await evaluate('__gm.soundfx.fit()');
|
||||
await sleep(100);
|
||||
const reverbPanel = () => json("__gm.reverb.panel('fx-rv')");
|
||||
const reverbParams = () =>
|
||||
json(
|
||||
`__gm.state.project.assets.find((a) => a.id === ${JSON.stringify(fxId)}).graph.nodes.find((n) => n.id === 'fx-rv').params`,
|
||||
);
|
||||
const rvShown = await reverbPanel();
|
||||
const rvRect = rvShown.rect;
|
||||
const rvBeside = (p) => p.y > rvRect.y && p.y < rvRect.y + rvRect.h;
|
||||
const rvDial = rvShown.knobs.decay.dial;
|
||||
await drag(rvDial.x, rvDial.y, rvDial.x, rvDial.y - 20);
|
||||
const rvTurned = { params: await reverbParams(), panel: await reverbPanel() };
|
||||
await press('z', { ctrl: true });
|
||||
const rvUndone = await reverbParams();
|
||||
await click(rvShown.rooms.cave.x, rvShown.rooms.cave.y);
|
||||
const rvCave = { params: await reverbParams(), panel: await reverbPanel() };
|
||||
await click(rvCave.panel.sound.at.x, rvCave.panel.sound.at.y);
|
||||
const rvOffered = (await json('__gm.menuRows()')) ?? [];
|
||||
const rvPick = rvOffered.find((row) => row);
|
||||
const rvPickAt = await t.locate(rvPick, true);
|
||||
await click(rvPickAt.x, rvPickAt.y);
|
||||
const rvSound = {
|
||||
params: await reverbParams(),
|
||||
panel: await waitFor(reverbPanel, (p) => p.scope.kind === 'sound'),
|
||||
};
|
||||
await press('z', { ctrl: true });
|
||||
const rvSoundUndone = await reverbParams();
|
||||
check(
|
||||
'a Reverb node shows its device between its ports; a knob of a room goes to Custom with its numbers as one undo step, a type button switches, a picked sound makes it Sound and draws that sound',
|
||||
rvShown.shown &&
|
||||
rvShown.size.w === 640 &&
|
||||
rvShown.size.h === 280 &&
|
||||
rvShown.room === 'hall' &&
|
||||
['decay', 'damping', 'predelay', 'impulse'].every((key) => rvShown.idle.includes(key)) &&
|
||||
Object.keys(rvShown.inputs).join() === 'in,mix' &&
|
||||
Object.values(rvShown.inputs).every((p) => p.x < rvRect.x && rvBeside(p)) &&
|
||||
Object.values(rvShown.outputs).every((p) => p.x > rvRect.x + rvRect.w && rvBeside(p)) &&
|
||||
rvShown.scope.kind === 'made' &&
|
||||
rvShown.scope.reach > 0.48 &&
|
||||
rvShown.scope.reach < 0.5 &&
|
||||
rvShown.scope.says.ends === 'ENDS 2.52 s' &&
|
||||
rvShown.highs === 'HIGHS 5.5 kHz' &&
|
||||
rvTurned.params.room === 'custom' &&
|
||||
rvTurned.params.decay > 2.5 &&
|
||||
rvTurned.params.damping === 0.35 &&
|
||||
rvTurned.params.predelay === 0.02 &&
|
||||
Object.keys(rvTurned.panel.inputs).length === 5 &&
|
||||
rvTurned.panel.idle.join() === 'impulse' &&
|
||||
rvTurned.panel.scope.reach > rvShown.scope.reach &&
|
||||
rvUndone.room === 'hall' &&
|
||||
rvUndone.decay === undefined &&
|
||||
rvCave.params.room === 'cave' &&
|
||||
rvCave.panel.scope.reach > 0.68 &&
|
||||
Boolean(rvPick) &&
|
||||
rvSound.params.room === 'sound' &&
|
||||
Boolean(rvSound.params.impulse) &&
|
||||
rvSound.panel.sound.text === rvPick &&
|
||||
rvSound.panel.scope.kind === 'sound' &&
|
||||
rvSound.panel.scope.rings > 0 &&
|
||||
rvSoundUndone.room === 'cave' &&
|
||||
rvSoundUndone.impulse === undefined,
|
||||
JSON.stringify({ rvShown, rvTurned, rvUndone, rvCave, rvOffered, rvSound, rvSoundUndone }),
|
||||
);
|
||||
await mutate(`
|
||||
const graph = __gm.state.project.assets.find((a) => a.id === ${JSON.stringify(fxId)}).graph;
|
||||
graph.nodes = graph.nodes.filter((n) => n.id !== 'fx-rv');`);
|
||||
await showTab('scene');
|
||||
await mutate(`
|
||||
const graph = __gm.state.project.assets.find((a) => a.id === 'sn-logic').graph;
|
||||
|
||||
Reference in new issue
Block a user