diff --git a/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts b/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts index 49bdb1a..e235910 100644 --- a/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts +++ b/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts @@ -263,9 +263,8 @@ const BLOB_RESTITUTION_SOFT = 0.05; // residual restitution at strength = 0 (al * the soft end → elastic reflection of the inward velocity at the hard end. The waveform * is read-only authority: it pushes the fluid, the fluid never moves it. */ -// Phase 10 collision retune (Daniel: "less explosive, more bouncy", no jitter, no stuck wax). The -// smoothed waveform (item 1) gives a gently-moving boundary, so the response can be springier without -// buzzing. Restitution is now SUB-unity: a real bounce conserves-or-loses energy, never adds it — +// Phase 10 collision retune (Daniel: "less explosive, more bouncy", no jitter, no stuck wax). +// Restitution is now SUB-unity: a real bounce conserves-or-loses energy, never adds it — // over-unity (the old 1.1) injected energy each contact and read as "explosive". 0.85 at the hard end // is lively/springy; the soft end stays near-zero (mush). const WAVE_COLLIDE_SPRING = 10.0; // soft penalty stiffness pushing wax off the ribbon (slightly softer) @@ -550,43 +549,6 @@ function decodeSamples(base64: string): Uint8Array { return out; } -/** - * Envelope-follower smoothing time constant, seconds — mirrors C# - * RmsLoudnessAlgorithm.SmoothingTimeConstantSeconds. The ~50 ms target rounds the spikey - * per-sample loudness into a smooth ribbon contour (Phase 10 tuning). - */ -const SMOOTHING_TIME_CONSTANT_SECONDS = 0.05; - -/** - * Smooth the [0,255] loudness datum in place with a symmetric (zero-phase) one-pole envelope - * follower targeting SMOOTHING_TIME_CONSTANT_SECONDS. This runs at DECODE time so EXISTING stored - * mixes — whose vault profiles predate the C#-side preprocessing smoothing — read as a smooth - * curve with no data regeneration. New mixes are already smoothed at preprocessing; a second light - * pass over an already-smooth curve is near-idempotent, so applying it unconditionally here is safe. - * - * The coefficient a = exp(−secondsPerSample / τ): forward then backward pass cancels the single-pole - * lag (no time shift). Bytes stay [0,255]; we smooth in float and round back. A degenerate sample - * rate (≤0 or non-finite) leaves the data untouched. - */ -function smoothDatum(samples: Uint8Array, sampleCount: number, durationSeconds: number): void { - if (sampleCount < 2 || durationSeconds <= 0 || !Number.isFinite(durationSeconds)) return; - const secondsPerSample = durationSeconds / sampleCount; - const a = Math.exp(-secondsPerSample / SMOOTHING_TIME_CONSTANT_SECONDS); - - // Float working buffer over the real samples (tail padding, if any, is untouched). - const env = new Float32Array(sampleCount); - let acc = samples[0]; - for (let i = 0; i < sampleCount; i++) { - acc = a * acc + (1 - a) * samples[i]; - env[i] = acc; - } - acc = env[sampleCount - 1]; - for (let i = sampleCount - 1; i >= 0; i--) { - acc = a * acc + (1 - a) * env[i]; - samples[i] = Math.round(Math.min(255, Math.max(0, acc))); - } -} - // ── Shaders. ───────────────────────────────────────────────────────────────────── // // Vertex: trivial pass-through. We draw a single triangle that more than covers the @@ -2026,11 +1988,6 @@ export function create(canvas: HTMLCanvasElement): MixVisualizerHandle { return null; } - // Smooth the loudness contour at decode time so EXISTING mixes (stored before the C#-side - // preprocessing smoothing) read as a smooth curve with no regeneration. Mutates `samples` in - // place — both the GPU texture (below) and the CPU collision mirror (datum.samples) read it. - smoothDatum(samples, sampleCount, durationSeconds); - // Width = min(N, a safe power-of-two cap). The power-of-two cap (4096) is well // under every real GL_MAX_TEXTURE_SIZE and keeps row arithmetic clean; we // still clamp it to the actual max in case a driver reports something smaller.