Show a Chip node as a device with its wave and its pitch (#386)
The Chip had eleven numbers in rows and nothing that showed what they do to a note. Its node is now a device of one size like the Compressor's, and two screens draw the wave and the pitch from the settings, worked right in the instrument graph. - ChipPanel is 840x280 in the warm grey of a handheld console. A button per wave, the "follow note" lever and a chrome knob per number, grouped Oscillator, Slide, Vibrato, Arpeggio and Repeat. - The wave screen draws two periods as loud as the Chip plays them, a square at its duty. toneValue and periodicSteps come out of chip.ts, so the screen and the worklet share one formula. - The pitch screen draws what slide, delta slide, vibrato, arpeggio and repeat make of the pitch over a note. It ends where the note falls below "min frequency" and starts from A4 while the Chip follows the note. - Idle settings are faded, wired ones greyed and locked, as the rows were. Every change is one undo step. - Knobs take a bipolar range: 0 straight up, the taper bends each half. Slide, delta slide, duty sweep and arpeggio use it. - The Compressor's auto-gain lever is now a Lever with a name of its own, which the Chip uses for "follow note". - Presets give a Chip five columns, as a Filter has four since #385. Found on the way: - With the Chip this wide the Laser preset is about 3060 units. In a 1280 px window Fit stops at the least zoom of 0.25 and cuts the Notes node off. The zoom limit is left as it is. Tests: - Unit: chip-view (9 new), knob (1 new), chip, chip-presets and hardware-view, 53 green - e2e 34 on melektaus-atx: ALL PASSED, 131 checks (1 new). The first run was red on the check itself: a Laser's "min frequency" can lie above A4, and the screen then rightly says the note ends at once. - Gate on melektaus-atx: CHECK EXIT 0, 285 files, 4377 tests - Counter-check: a square drawn with its duty mirrored turns the wave test red Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c087993000
commit
eb78f3cbf3
14 files changed
+1190
-26
No files matched your search
@@ -2290,6 +2290,61 @@ export async function sound(t) {
|
||||
);
|
||||
await shot('34-instrument-preset');
|
||||
|
||||
// #386: the Laser's Chip is drawn as a device between its ports: a button per wave, the "follow
|
||||
// note" lever and a knob per number, each change one undo step, and its screens drawn from
|
||||
// it. A Laser falls: its pitch ends lower than it starts. Three undos bring the Laser back.
|
||||
await clickText('Fit');
|
||||
await sleep(300);
|
||||
const chipId = (
|
||||
await json(
|
||||
`__gm.state.project.assets.find((a) => a.id === ${JSON.stringify(insId)}).graph.nodes.find((n) => n.type === 'InstrumentChip')`,
|
||||
)
|
||||
).id;
|
||||
const chipPanel = () => json(`__gm.chip.panel('${chipId}')`);
|
||||
const chipShown = await chipPanel();
|
||||
const chipRect = chipShown.rect;
|
||||
const chipBeside = (p) => p.y > chipRect.y && p.y < chipRect.y + chipRect.h;
|
||||
await click(chipShown.waves.triangle.x, chipShown.waves.triangle.y);
|
||||
const chipPicked = { params: (await insGraph()).chip, panel: await chipPanel() };
|
||||
await click(chipShown.follow.at.x, chipShown.follow.at.y);
|
||||
const chipFollowed = { params: (await insGraph()).chip, panel: await chipPanel() };
|
||||
const slideDial = chipShown.knobs.slide.dial;
|
||||
await drag(slideDial.x, slideDial.y, slideDial.x, slideDial.y - 20);
|
||||
const chipSlid = (await insGraph()).chip;
|
||||
for (let i = 0; i < 3; i++) await press('z', { ctrl: true });
|
||||
const chipUndone = (await insGraph()).chip;
|
||||
check(
|
||||
'a Chip node shows its device between its ports; a wave button, the lever and a knob each change it as one undo step, and its screens follow',
|
||||
chipShown.shown &&
|
||||
chipShown.size.w === 840 &&
|
||||
chipShown.size.h === 280 &&
|
||||
Object.values(chipShown.inputs).length === 12 &&
|
||||
Object.values(chipShown.inputs).every((p) => p.x < chipRect.x && chipBeside(p)) &&
|
||||
Object.values(chipShown.outputs).every((p) => p.x > chipRect.x + chipRect.w && chipBeside(p)) &&
|
||||
chipShown.wave === laser.chip.wave &&
|
||||
chipShown.follow.on === false &&
|
||||
chipShown.knobs.slide.value === laser.chip.slide &&
|
||||
chipShown.pitch.from.startsWith(chipShown.knobs.frequency.number) &&
|
||||
chipShown.pitch.last < 0 &&
|
||||
chipPicked.params.wave === 'triangle' &&
|
||||
chipPicked.panel.waveScreen === 'TRIANGLE' &&
|
||||
chipPicked.panel.idle.includes('duty') &&
|
||||
chipFollowed.params.followNote === true &&
|
||||
chipFollowed.panel.follow.on &&
|
||||
chipFollowed.panel.idle.includes('frequency') &&
|
||||
// A Laser's "min frequency" may lie above A4: then it says the note ends at once.
|
||||
chipFollowed.panel.pitch.from.startsWith('A4 440 Hz') &&
|
||||
chipSlid.slide > laser.chip.slide &&
|
||||
JSON.stringify(chipUndone) === JSON.stringify(laser.chip),
|
||||
JSON.stringify({
|
||||
chipShown,
|
||||
chipPicked,
|
||||
chipFollowed,
|
||||
slide: [laser.chip.slide, chipSlid.slide],
|
||||
chipUndone,
|
||||
}),
|
||||
);
|
||||
|
||||
const beforeRandom = await stats();
|
||||
await clickHook('randomizeAt');
|
||||
const randomized = await waitFor(stats, (s) => s.started > beforeRandom.started);
|
||||
|
||||
Reference in new issue
Block a user