diff --git a/Backend/index.html b/Backend/index.html index 7ab431f..0e4006e 100644 --- a/Backend/index.html +++ b/Backend/index.html @@ -308,17 +308,26 @@ // Create audio processor node const source = audioContext.createMediaStreamSource(stream); - // Set up analyser for visualization + // Set up analyser for visualization with better settings analyser = audioContext.createAnalyser(); analyser.fftSize = 256; + analyser.smoothingTimeConstant = 0.8; // Add smoothing for nicer visualization + analyser.minDecibels = -90; + analyser.maxDecibels = -10; + visualizerBufferLength = analyser.frequencyBinCount; visualizerDataArray = new Uint8Array(visualizerBufferLength); + + // Connect source to analyzer first source.connect(analyser); // Hide the label when visualization is active visualizerLabel.style.opacity = '0'; // Start drawing the visualization + if (visualizerAnimationFrame) { + cancelAnimationFrame(visualizerAnimationFrame); + } drawVisualizer(); // Set up processor for audio processing @@ -628,47 +637,81 @@ // Call initially and on window resize resizeCanvas(); window.addEventListener('resize', resizeCanvas); + + // Create placeholder data array (will be used before streaming starts) + visualizerBufferLength = 128; // Default size + visualizerDataArray = new Uint8Array(visualizerBufferLength); } // Add the visualization drawing function function drawVisualizer() { - if (!isStreaming) { - if (visualizerAnimationFrame) { - cancelAnimationFrame(visualizerAnimationFrame); - visualizerAnimationFrame = null; - } - - // Clear the canvas - canvasContext.clearRect(0, 0, visualizerCanvas.width, visualizerCanvas.height); - visualizerLabel.style.opacity = '0.7'; + // Ensure we have the canvas context + if (!canvasContext) { + console.error("Canvas context not available"); return; } visualizerAnimationFrame = requestAnimationFrame(drawVisualizer); - // Get the frequency data - analyser.getByteFrequencyData(visualizerDataArray); + // If we're streaming and have an analyzer, get the frequency data + if (isStreaming && analyser) { + try { + analyser.getByteFrequencyData(visualizerDataArray); + } catch (e) { + console.error("Error getting frequency data:", e); + } + } else { + // If not streaming, gradually reduce all values to create a fade-out effect + for (let i = 0; i < visualizerDataArray.length; i++) { + visualizerDataArray[i] = Math.max(0, visualizerDataArray[i] - 5); + } + } - // Clear the canvas - canvasContext.clearRect(0, 0, visualizerCanvas.width, visualizerCanvas.height); + // Clear the canvas with a very slight background + canvasContext.fillStyle = 'rgba(245, 245, 245, 0.2)'; + canvasContext.fillRect(0, 0, visualizerCanvas.width, visualizerCanvas.height); // Calculate bar width based on canvas size and buffer length - const barWidth = (visualizerCanvas.width / visualizerBufferLength) * 2.5; - let barHeight; - let x = 0; + const width = visualizerCanvas.width; + const height = visualizerCanvas.height; + const barCount = Math.min(visualizerBufferLength, 64); // Limit bars for performance + const barWidth = width / barCount - 1; // Leave 1px gap // Draw bars - for (let i = 0; i < visualizerBufferLength; i++) { - barHeight = visualizerDataArray[i] / 2; // Scale down to fit in canvas + for (let i = 0; i < barCount; i++) { + // Use a logarithmic scale for better visualization of lower frequencies + const index = Math.floor(i * visualizerBufferLength / barCount); + const value = visualizerDataArray[index]; - // Use a gradient color based on frequency intensity - const hue = i / visualizerBufferLength * 180 + 180; // Blue to green spectrum - canvasContext.fillStyle = `hsl(${hue}, 100%, ${50 + (barHeight / 2)}%)`; + // Scale height (values typically range from 0-255) + const barHeight = (value / 255) * height; - canvasContext.fillRect(x, visualizerCanvas.height - barHeight, barWidth, barHeight); + // Position x coordinate + const x = i * (barWidth + 1); - x += barWidth + 1; + // Calculate gradient color based on frequency + const hue = 200 + (i / barCount * 60); // Blue to light-blue/cyan spectrum + const saturation = 90 - (value / 255 * 30); // More saturated for louder sounds + const lightness = 40 + (value / 255 * 30); // Brighter for louder sounds + + // Draw the bar + canvasContext.fillStyle = `hsl(${hue}, ${saturation}%, ${lightness}%)`; + canvasContext.fillRect(x, height - barHeight, barWidth, barHeight); + + // Add a subtle reflection + const gradientHeight = Math.min(10, barHeight / 3); + const gradient = canvasContext.createLinearGradient( + 0, height - barHeight, + 0, height - barHeight + gradientHeight + ); + gradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)'); + gradient.addColorStop(1, 'rgba(255, 255, 255, 0)'); + canvasContext.fillStyle = gradient; + canvasContext.fillRect(x, height - barHeight, barWidth, gradientHeight); } + + // Only show the label when not streaming + visualizerLabel.style.opacity = isStreaming ? '0' : '0.7'; }