diff --git a/src/stores/visualizer.ts b/src/stores/visualizer.ts index fb5b6bd..50c7b68 100644 --- a/src/stores/visualizer.ts +++ b/src/stores/visualizer.ts @@ -344,7 +344,6 @@ function createVisualizerStore(): VisualizerStore { // ── Render loop (called at ~30fps) ───────────────────────────────── - let lastBarWriteAt = 0; const renderFrame = () => { if (!cava?.isReady || !sampleBuffer || !pcm) return; @@ -377,15 +376,8 @@ function createVisualizerStore(): VisualizerStore { if (count < sampleBuffer.length) return; const output = cava.execute(sampleBuffer); - // Write the UI signal at ~10fps, not 30: cava already smooths - // (noise reduction + peak release), and each Solid write costs a - // renderer diff pass. 3 of every 4 frames update only the pipeline. - const nowMs = performance.now(); - if (nowMs - lastBarWriteAt >= 95) { - lastBarWriteAt = nowMs; - // Normalize against the running peak and copy to a new array - setBarData(scaler(output)); - } + // Normalize against the running peak and copy to a new array + setBarData(scaler(output)); // Fresh frames only count once the position clock has MOVED from // the resume point: while the player is still re-buffering after a // long pause, the cache serves the same window and the spinner must diff --git a/tests/visualizer-throttle.test.ts b/tests/visualizer-throttle.test.ts deleted file mode 100644 index 8f371ab..0000000 --- a/tests/visualizer-throttle.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** bars signal writes are throttled to ~10fps; the render loop still runs 30fps. */ -import { test, expect } from "bun:test" -import { join } from "path" -import { tmpdir } from "os" - -process.env.XDG_CONFIG_HOME = join(tmpdir(), `podtui-th-${process.pid}`) -process.env.XDG_DATA_HOME = join(tmpdir(), `podtui-th-data-${process.pid}`) -process.env.PODTUI_AUDIO_BACKEND = "none" - -const { useVisualizer } = await import("../src/stores/visualizer") -const { setCurrentEpisode, setIsPlaying, setPosition } = await import("../src/utils/audio-signals") -import type { Episode } from "../src/types/episode" - -const wavPath = "/tmp/podtui-pause-cycle.wav" -const skip = !(Bun.which("ffmpeg") && Bun.file(wavPath).exists()) - -test.skipIf(skip)("barData updates at ~10fps while the loop runs at 30fps", async () => { - const viz = useVisualizer() - viz.setBarCount(64) - viz.setFocused(true) - setCurrentEpisode({ audioUrl: wavPath } as unknown as Episode) - setIsPlaying(true) - setPosition(5) - for (let i = 0; i < 200 && !(viz.barData().length > 0); i++) await Bun.sleep(25) - - let writes = 0 - let prev = viz.barData() - // count distinct array references the signal produced over 1s - const check = setInterval(() => { - const cur = viz.barData() - if (cur !== prev) { - writes++ - prev = cur - } - }, 16) - await Bun.sleep(1000) - clearInterval(check) - console.log(`barData writes in 1s: ${writes} (30fps loop would be ~15-20 distinct seen at 16ms sampling)`) - expect(writes).toBeGreaterThan(3) - expect(writes).toBeLessThanOrEqual(14) -}, 30_000)