noise: made in slices so the page keeps breathing, 16 kHz, brown and crackle a little quieter
shots / shots (push) Canceled after 28s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K6897PWcUEwHiqZMcVnNF6
This commit is contained in:
teahubxyzandClaude Fable 5.1 committed 2026-10-21 08:17:29 +00:00
1 parent e281e104dd
commit 5b1f63bd15
1 file changed
+6 -5
+6 -5
View File
@@ -875,16 +875,17 @@ function noiseSpec() {
const n = state.history.filter((t) => t.noise).length, kind = (String(state.seed).match(/\b(brown|pink|rain|white|crackle)\b/i) || [])[1]?.toLowerCase() || NOISES[n % NOISES.length];
return { title: `${kind} noise`, tags: `${kind} noise, room tone, made on this device`, lyrics: "", bpm: 60, key: "—", energy: 0.1, seconds: 300, meter: "4/4", noise: kind, station: state.station || "the noise floor", line: "nothing to learn here, just the room", seed: state.seed, made: Date.now(), look: state.look || "rings", palette: state.palette || "duo" };
}
function makeNoise(kind, seconds) {
const sr = 22050, n = sr * seconds, out = new Int16Array(n), rnd = prng(hash32(kind + seconds) || 1);
async function makeNoise(kind, seconds) {
const sr = 16000, n = sr * seconds, out = new Int16Array(n), rnd = prng(hash32(kind + seconds) || 1);
let b = 0, b0 = 0, b1 = 0, b2 = 0, lp = 0, drop = 0, dropLen = 0, dropAmp = 0;
for (let i = 0; i < n; i++) {
if (i % (sr * 5) === 0 && i) await new Promise((r) => setTimeout(r, 0)); // a slice at a time: the page keeps breathing
const w = rnd() * 2 - 1; let v;
if (kind === "white") v = w * 0.25;
else if (kind === "brown") { b = (b + 0.02 * w) / 1.02; v = b * 3.5; }
else if (kind === "brown") { b = (b + 0.02 * w) / 1.02; v = b * 2.2; }
else if (kind === "pink") { b0 = 0.99765 * b0 + w * 0.0990460; b1 = 0.96300 * b1 + w * 0.2965164; b2 = 0.57000 * b2 + w * 1.0526913; v = (b0 + b1 + b2 + w * 0.1848) * 0.12; }
else if (kind === "rain") { lp += (w - lp) * 0.3; v = lp * 0.5; if (drop <= 0 && rnd() < 0.004) { drop = dropLen = 30 + Math.floor(rnd() * 120); dropAmp = 0.15 + rnd() * 0.35; } if (drop > 0) { v += dropAmp * (drop / dropLen) * w; drop--; } }
else { lp += (w - lp) * 0.08; v = lp * 1.2; if (rnd() < 0.0015) { drop = dropLen = 20 + Math.floor(rnd() * 80); dropAmp = 0.3 + rnd() * 0.5; } if (drop > 0) { v += dropAmp * (drop / dropLen) * w; drop--; } }
else { lp += (w - lp) * 0.08; v = lp * 1.0; if (rnd() < 0.0015) { drop = dropLen = 20 + Math.floor(rnd() * 80); dropAmp = 0.3 + rnd() * 0.5; } if (drop > 0) { v += dropAmp * (drop / dropLen) * w; drop--; } }
const fade = Math.min(1, i / (sr * 2), (n - i) / (sr * 2));
out[i] = Math.max(-1, Math.min(1, v * fade)) * 32767;
}
@@ -912,7 +913,7 @@ async function speak(spec) {
return res.blob();
}
async function renderTrack(spec, onStatus) {
if (spec.noise) { await new Promise((r) => setTimeout(r, 50)); return makeNoise(spec.noise, spec.seconds || 300); }
if (spec.noise) return makeNoise(spec.noise, spec.seconds || 300);
if (spec.spoken) return speak(spec);
if (!state.key) { // shared worker: one call, audio back (Runware when the factory has a key, else Venice)
const started = Date.now(), tick = setInterval(() => onStatus && onStatus(Math.round((Date.now() - started) / 1000), 0, false), 1000);