therickglenn/VoiceAnalyzer
0
1import React, { useEffect, useRef, useState } from "react";2 3const AudioVisualizer = () => {4 const audioContextRef = useRef(null);5 const analyserRef = useRef(null);6 const dataArrayRef = useRef(null);7 const sourceRef = useRef(null);8 const canvasRef = useRef(null);9 const [permissionGranted, setPermissionGranted] = useState(false);10 const [errorMessage, setErrorMessage] = useState(null);11 12 const initializeAudio = async () => {13 try {14 if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {15 throw new Error("getUserMedia is not supported in this browser.");16 }17 18 const stream = await navigator.mediaDevices.getUserMedia({ audio: true });19 setPermissionGranted(true);20 setErrorMessage(null);21 22 audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();23 analyserRef.current = audioContextRef.current.createAnalyser();24 25 sourceRef.current = audioContextRef.current.createMediaStreamSource(stream);26 sourceRef.current.connect(analyserRef.current);27 28 analyserRef.current.fftSize = 512;29 const bufferLength = analyserRef.current.frequencyBinCount;30 dataArrayRef.current = new Uint8Array(bufferLength);31 32 drawWaveform();33 } catch (err) {34 console.error('Error accessing microphone:', err);35 setErrorMessage(err.message);36 }37 };38 39 useEffect(() => {40 return () => {41 if (audioContextRef.current) {42 audioContextRef.current.close();43 }44 };45 }, []);46 47 const drawWaveform = () => {48 if (!canvasRef.current) return;49 50 const canvas = canvasRef.current;51 const ctx = canvas.getContext('2d');52 53 const renderFrame = () => {54 requestAnimationFrame(renderFrame);55 analyserRef.current.getByteTimeDomainData(dataArrayRef.current);56 57 ctx.fillStyle = '#000';58 ctx.fillRect(0, 0, canvas.width, canvas.height);59 60 ctx.lineWidth = 2;61 ctx.strokeStyle = '#00ffcc';62 ctx.beginPath();63 64 let sliceWidth = canvas.width / dataArrayRef.current.length;65 let x = 0;66 67 for (let i = 0; i < dataArrayRef.current.length; i++) {68 let v = dataArrayRef.current[i] / 128.0;69 let y = v * canvas.height / 2;70 71 if (i === 0) {72 ctx.moveTo(x, y);73 } else {74 ctx.lineTo(x, y);75 }76 77 x += sliceWidth;78 }79 80 ctx.lineTo(canvas.width, canvas.height / 2);81 ctx.stroke();82 };83 renderFrame();84 };85 86 return (87 <div className="container">88 <h1>Real-Time Audio Visualizer</h1>89 {!permissionGranted ? (90 <button className="start-button" onClick={initializeAudio}>Start Audio Analysis</button>91 ) : (92 <p>Analyzing audio...</p>93 )}94 {errorMessage && <p className="error-message">{errorMessage}</p>}95 <canvas ref={canvasRef} width={600} height={300} className="visualizer"></canvas>96 </div>97 );98};99 100export default AudioVisualizer;