Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 649baf40ab | |||
| 9702af640b |
@@ -4,7 +4,7 @@ import { installNestedScrollBehavior } from "./utils/nested-scroll";
|
|||||||
import type { Feed } from "./types/feed"
|
import type { Feed } from "./types/feed"
|
||||||
import type { Episode } from "./types/episode"
|
import type { Episode } from "./types/episode"
|
||||||
|
|
||||||
const VERSION = "0.9.0";
|
const VERSION = "0.9.1";
|
||||||
|
|
||||||
interface CliArgs {
|
interface CliArgs {
|
||||||
version: boolean;
|
version: boolean;
|
||||||
|
|||||||
@@ -344,7 +344,6 @@ function createVisualizerStore(): VisualizerStore {
|
|||||||
|
|
||||||
// ── Render loop (called at ~30fps) ─────────────────────────────────
|
// ── Render loop (called at ~30fps) ─────────────────────────────────
|
||||||
|
|
||||||
let lastBarWriteAt = 0;
|
|
||||||
const renderFrame = () => {
|
const renderFrame = () => {
|
||||||
if (!cava?.isReady || !sampleBuffer || !pcm) return;
|
if (!cava?.isReady || !sampleBuffer || !pcm) return;
|
||||||
|
|
||||||
@@ -377,15 +376,8 @@ function createVisualizerStore(): VisualizerStore {
|
|||||||
if (count < sampleBuffer.length) return;
|
if (count < sampleBuffer.length) return;
|
||||||
const output = cava.execute(sampleBuffer);
|
const output = cava.execute(sampleBuffer);
|
||||||
|
|
||||||
// Write the UI signal at ~10fps, not 30: cava already smooths
|
// Normalize against the running peak and copy to a new array
|
||||||
// (noise reduction + peak release), and each Solid write costs a
|
setBarData(scaler(output));
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
// Fresh frames only count once the position clock has MOVED from
|
// Fresh frames only count once the position clock has MOVED from
|
||||||
// the resume point: while the player is still re-buffering after a
|
// the resume point: while the player is still re-buffering after a
|
||||||
// long pause, the cache serves the same window and the spinner must
|
// long pause, the cache serves the same window and the spinner must
|
||||||
|
|||||||
@@ -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)
|
|
||||||
Reference in New Issue
Block a user