Phase 1 — VisualizerStorageManager.swift
VisFrameBuffer is a flat ContiguousArray<Float> with frameCount and
pointsPerFrame. All frame data for a track lives in one contiguous
allocation rather than a [[Float]] array-of-arrays. loadCache now uses
Data(contentsOf:options:.alwaysMapped) — the OS maps the file into
virtual memory and faults pages in on demand rather than reading the
whole file into heap. copyFrame(at:into:) copies a frame slice
directly into _audioLevels using initialize(from:) — no intermediate
[Float] created.
Phase 2 — MitsuhaVisualizerView.swift + AudioPlayer.swift
VisualizerLevelBox now pre-allocates targetLevels, displayLevels,
idleLevels, and the full 16-slot history ring on first use via
resizeIfNeeded. This only triggers when numberOfPoints changes (rare —
settings slider). updateDisplayLevels writes directly into
box.targetLevels throughout — no var targetLevels = [Float](), no map,
no append. The history ring buffer now copies in-place into
pre-allocated slots, eliminating the COW trigger on every frame.
drawIdleState uses box.idleLevels — no Array(repeating:). The Canvas
body no longer falls back to Array(repeating:) since displayLevels is
always pre-allocated. The timer in AudioPlayer now calls
buf.copyFrame(at:into:&_audioLevels) directly — no intermediate
[Float] copy.
Phase 3 — View invalidation + drawBars fix
fillColors hoisted out of the drawBars per-bar loop — it was
allocating a new [Color] array count times per frame (8–24 allocations
per draw call at 60fps). Now computed once before the loop.
@ObservedObject var settings and @StateObject private var box are
correct — box has zero @Published properties so it never triggers
parent redraws. The Canvas closure only captures tickDate which
changes every tick, ensuring per-tick re-execution without touching
SwiftUI’s diffing engine.