Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334#!/usr/bin/env node// One ascending sine arpeggio. Each note arrives at the next physical seat;// pitch rhythm and circular speed share the same accelerating transport.import { mkdir, writeFile } from 'node:fs/promises';const notes = [60, 64, 67, 72, 76, 79, 84, 88];const events = [], doors = [0];let time = 0;for (let i = 0; i < 120; i++) { // Three smooth breaths: 1.05 sec/note -> .23 -> 1.05. const speed = .5 - .5 * Math.cos(2 * Math.PI * i / 40); const step = 1.05 - .82 * speed; events.push({ t: time, dur: step * .92, hz: 440 * 2 ** ((notes[i % notes.length] - 69) / 12), g: .95, wave: 'sine', attack: .008, decay: Math.min(.06, step * .13) }); time += step; doors.push(time);}const dur = time + .4, fieldShift = [];let cursor = 0;// The one-lane score has zero default spin. An unwrapped fieldShift ribbon// describes the exact continuous angle, sampled at 100 Hz for interpolation.const points = Math.ceil(dur * 100);for (let i = 0; i <= points; i++) { const t = i / points * dur; while (cursor + 1 < doors.length && t >= doors[cursor + 1]) cursor++; const part = cursor + 1 < doors.length ? (t - doors[cursor]) / (doors[cursor + 1] - doors[cursor]) : 0; fieldShift.push(+((cursor + part) * 2 / 5).toFixed(7));}const score = { name: 'Sine Ring', dur, gain: .65, movements: [{ name: 'Breathe around the ring', t0: 0, t1: dur }], fieldShift, lanes: [{ name: 'sine', color: [255, 209, 80], events }] };const directory = new URL('../scores/', import.meta.url);await mkdir(directory, { recursive: true });await writeFile(new URL('sine-ring.nsscore', directory), JSON.stringify(score) + '\n');console.log(`Sine Ring: ${dur.toFixed(1)} sec, 120 notes, 24 circuits, three accelerations/decelerations`);