From 986ccad5c90e2406ae62b9de3611c36e22a99d05 Mon Sep 17 00:00:00 2001 From: mrwnslz Date: Sun, 4 Oct 2026 00:28:44 +0200 Subject: [PATCH] =?UTF-8?q?Ambient:=20Zugfahrt=20=E2=80=93=20zweiter=20Kla?= =?UTF-8?q?ck=20jedes=20Paares=202=20Halbt=C3=B6ne=20h=C3=B6her;=20sw=20v8?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- static/ambient/index.html | 10 +++++----- static/js/sw.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/static/ambient/index.html b/static/ambient/index.html index a08a088..f8c2767 100644 --- a/static/ambient/index.html +++ b/static/ambient/index.html @@ -928,18 +928,18 @@ function buildWomb(K) { // Zugfahrt: Rollgeräusch + Schienenstöße. Jeder Stoß wird von zwei Achsen kurz nacheinander angeschlagen // (Achsabstand 3,1 m, Schienenlänge 33 m) -> "klack-klack ......... klack-klack", Pause ≈ 11× Paarabstand, Takt folgt der Geschwindigkeit. -function railClack(K, t, amp) { +function railClack(K, t, amp, pitch = 1) { const ctx = S.ctx, nb = noiseBuf("white"); - const s1 = ctx.createBufferSource(), bp = bq("bandpass", R(300, 650) * (.7 + .8 * K.b), .8), g1 = ctx.createGain(); // dumpfer Anschlag + const s1 = ctx.createBufferSource(), bp = bq("bandpass", R(300, 650) * (.7 + .8 * K.b) * pitch, .8), g1 = ctx.createGain(); // dumpfer Anschlag s1.buffer = nb; s1.connect(bp).connect(g1).connect(K.out); g1.gain.setValueAtTime(0, t); g1.gain.linearRampToValueAtTime(amp * .55, t + .004); g1.gain.exponentialRampToValueAtTime(.001, t + .08); s1.start(t, R(0, 8), .1); const o = ctx.createOscillator(), og = ctx.createGain(); // Schlag im Wagenboden - o.frequency.setValueAtTime(95, t); o.frequency.exponentialRampToValueAtTime(48, t + .12); + o.frequency.setValueAtTime(95 * pitch, t); o.frequency.exponentialRampToValueAtTime(48 * pitch, t + .12); og.gain.setValueAtTime(0, t); og.gain.linearRampToValueAtTime(amp * .8, t + .005); og.gain.exponentialRampToValueAtTime(.001, t + .24); o.connect(og).connect(K.out); o.start(t); o.stop(t + .3); // Karosserie klingt nach: zwei Resonanzmoden, lang abklingend - const f1 = R(170, 220); + const f1 = R(170, 220) * pitch; [[f1, 1.5, .65], [f1 * 1.9, .7, .45]].forEach(([f, a, dec]) => { const s2 = ctx.createBufferSource(), rb = bq("bandpass", f, 10), g2 = ctx.createGain(); s2.buffer = nb; s2.connect(rb).connect(g2).connect(K.out); @@ -964,7 +964,7 @@ function buildTrain(K) { const now = T(); while (K.nextJoint < now + 2.5) { // alle Achsen der Schienenstöße der nächsten Sekunden vorplanen (ein stockender Hauptthread reißt so keine Lücke) const v = K.v, t0 = K.nextJoint, amp = .8 * (.85 + Math.random() * .3); - [0, 3.1 / v].forEach((o, i) => railClack(K, t0 + o, amp * (i ? .9 : 1))); // zwei Achsen des Drehgestells, dann Pause bis zum nächsten Stoß + [0, 3.1 / v].forEach((o, i) => railClack(K, t0 + o, amp * (i ? .9 : 1), i ? 1.12 : 1)); // zwei Achsen des Drehgestells, dann Pause bis zum nächsten Stoß K.nextJoint += 33 / v; } if (now > K.nextPoints) { // Weiche: kurzes schnelles Klapperbündel diff --git a/static/js/sw.js b/static/js/sw.js index 45bdb3d..c7d9909 100644 --- a/static/js/sw.js +++ b/static/js/sw.js @@ -2,7 +2,7 @@ * diora service worker — caches the app shell for offline use. */ -const CACHE = 'diora-v81'; +const CACHE = 'diora-v82'; const SHELL = [ '/static/css/app.css', '/static/js/app.js',