/** * Audio graph utilities for Web Audio API. * * This module provides helper functions for creating and managing * the audio processing graph used in the stem mixer. */ /** * Create a gain node with initial value. */ export function createGain(context, value = 1) { const gain = context.createGain() gain.gain.setValueAtTime(value, context.currentTime) return gain } /** * Create an analyser node for visualization. */ export function createAnalyser(context, fftSize = 128) { const analyser = context.createAnalyser() analyser.fftSize = fftSize analyser.smoothingTimeConstant = 0.8 return analyser } /** * Create a simple audio graph for a single stem. * * source -> gainNode -> masterGain */ export function createStemGraph(context, buffer, gainNode, masterGain) { const source = context.createBufferSource() source.buffer = buffer source.connect(gainNode) gainNode.connect(masterGain) return source } /** * Smoothly transition a gain value. */ export function fadeGain(gainNode, targetValue, duration = 0.05) { const now = gainNode.context.currentTime gainNode.gain.linearRampToValueAtTime(targetValue, now + duration) } /** * Get frequency data from analyser as normalized values (0-1). */ export function getFrequencyData(analyser) { const data = new Uint8Array(analyser.frequencyBinCount) analyser.getByteFrequencyData(data) return Array.from(data).map(v => v / 255) } /** * Calculate RMS level from audio data. */ export function calculateRMS(audioData) { let sum = 0 for (let i = 0; i < audioData.length; i++) { sum += audioData[i] * audioData[i] } return Math.sqrt(sum / audioData.length) } /** * Convert decibels to linear gain. */ export function dbToGain(db) { return Math.pow(10, db / 20) } /** * Convert linear gain to decibels. */ export function gainToDb(gain) { return 20 * Math.log10(gain) }