// Find this section of code in your analyzeAudio function for (let i = 0; i < timeSlices; i++) { const timePosition = i / timeSlices * duration; const sampleIndex = Math.floor(timePosition * buffer.sampleRate); // Get frequency data at this time position const dataArray = getFrequencyData(buffer, sampleIndex, analyzer.fftSize); // Draw frequency data for (let j = 0; j < dataArray.length; j++) { const value = dataArray[j]; const y = height - (j / dataArray.length * height); // Make sure x is properly defined for each iteration const x = i * sliceWidth; // Use a color gradient based on intensity const intensity = value / 255; const r = Math.floor(255 * intensity); const g = Math.floor(100 + 155 * intensity); const b = Math.floor(255 - 200 * intensity); tempCtx.fillStyle = `rgb(${r}, ${g}, ${b})`; tempCtx.fillRect(x, y, sliceWidth, height / dataArray.length); } // Detect artifacts const highFreqLoss = detectHighFrequencyLoss(dataArray); const preEcho = i > 0 ? detectPreEcho(buffer, sampleIndex, analyzer.fftSize) : false; const warbling = detectWarbling(buffer, sampleIndex, analyzer.fftSize); // Make sure x is defined here too const x = i * sliceWidth; // Mark artifacts on the spectrogram if (highFreqLoss) { artifacts.push({ type: 'High Frequency Loss', confidence: highFreqLoss.confidence, timeStart: timePosition, timeEnd: timePosition + (1 / timeSlices * duration), description: 'Loss of high frequencies above 16kHz' }); tempCtx.fillStyle = 'rgba(255, 0, 0, 0.2)'; tempCtx.fillRect(x, 0, sliceWidth, height * 0.2); // Top 20% where high frequencies are } if (preEcho) { artifacts.push({ type: 'Pre-Echo', confidence: preEcho.confidence, timeStart: timePosition - 0.01, timeEnd: timePosition, description: 'Unnatural noise before transient' }); tempCtx.fillStyle = 'rgba(0, 255, 0, 0.2)'; tempCtx.fillRect(Math.max(0, x - sliceWidth), 0, sliceWidth, height); } if (warbling) { artifacts.push({ type: 'Warbling', confidence: warbling.confidence, timeStart: timePosition, timeEnd: timePosition + (1 / timeSlices * duration), description: 'Modulation effects in low frequencies' }); tempCtx.fillStyle = 'rgba(0, 0, 255, 0.2)'; tempCtx.fillRect(x, height * 0.7, sliceWidth, height * 0.3); // Bottom 30% for low frequencies } }