/** * Waveform peak generation utilities */ /** * Generate waveform peaks from an AudioBuffer */ export function generatePeaks( audioBuffer: AudioBuffer, width: number, channelIndex: number = 0 ): Float32Array { const channelData = audioBuffer.getChannelData(channelIndex); const peaks = new Float32Array(width); const samplesPerPeak = Math.floor(channelData.length / width); for (let i = 0; i < width; i++) { const start = i * samplesPerPeak; const end = Math.min(start + samplesPerPeak, channelData.length); let max = 0; for (let j = start; j < end; j++) { const abs = Math.abs(channelData[j]); if (abs > max) { max = abs; } } peaks[i] = max; } return peaks; } /** * Generate peaks for all channels */ export function generateMultiChannelPeaks( audioBuffer: AudioBuffer, width: number ): Float32Array[] { const peaks: Float32Array[] = []; for (let i = 0; i < audioBuffer.numberOfChannels; i++) { peaks.push(generatePeaks(audioBuffer, width, i)); } return peaks; } /** * Generate min/max peaks for more detailed waveform visualization */ export function generateMinMaxPeaks( audioBuffer: AudioBuffer, width: number, channelIndex: number = 0 ): { min: Float32Array; max: Float32Array } { const channelData = audioBuffer.getChannelData(channelIndex); const min = new Float32Array(width); const max = new Float32Array(width); const samplesPerPeak = Math.floor(channelData.length / width); for (let i = 0; i < width; i++) { const start = i * samplesPerPeak; const end = Math.min(start + samplesPerPeak, channelData.length); let minVal = 1; let maxVal = -1; for (let j = start; j < end; j++) { const val = channelData[j]; if (val < minVal) minVal = val; if (val > maxVal) maxVal = val; } min[i] = minVal; max[i] = maxVal; } return { min, max }; } /** * Normalize peaks to a given range */ export function normalizePeaks(peaks: Float32Array, targetMax: number = 1): Float32Array { const normalized = new Float32Array(peaks.length); let max = 0; // Find max value for (let i = 0; i < peaks.length; i++) { if (peaks[i] > max) { max = peaks[i]; } } // Normalize const scale = max > 0 ? targetMax / max : 1; for (let i = 0; i < peaks.length; i++) { normalized[i] = peaks[i] * scale; } return normalized; }