// Reduce an audio channel down to `buckets` peak amplitude samples in [0, 1]. // Used by decodePeaks; pure. export function bucketize(channel: Float32Array, buckets: number): Float32Array { const out = new Float32Array(buckets); if (buckets <= 0 || channel.length === 0) return out; const samplesPerBucket = Math.max(1, Math.floor(channel.length / buckets)); let peakMax = 0; for (let b = 0; b < buckets; b++) { const start = b * samplesPerBucket; const end = Math.min(start + samplesPerBucket, channel.length); let max = 0; for (let i = start; i < end; i++) { const v = channel[i]; const abs = v < 0 ? -v : v; if (abs > max) max = abs; } out[b] = max; if (max > peakMax) peakMax = max; } // Normalize so the loudest bucket reaches 1.0 — keeps quiet tracks visible. if (peakMax > 0 && peakMax < 1) { const scale = 1 / peakMax; for (let i = 0; i < out.length; i++) out[i] *= scale; } return out; }