diff --git a/client/src/App.tsx b/client/src/App.tsx
index c407245..3bd3413 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -17,6 +17,7 @@ import UploadPage from './Pages/UploadPage';
import PreviewPage from './Pages/PreviewPage';
import ProcessingPage from './Pages/ProcessingPage';
import ResultsPage from './Pages/ResultsPage';
+import AudioVisualizer from './components/AudioVisualizer';
// Custom Link component for AppBar
const App: React.FC = () => {
@@ -39,6 +40,7 @@ const App: React.FC = () => {
} />
} />
} />
+ }/>
diff --git a/client/src/Pages/UploadPage.tsx b/client/src/Pages/UploadPage.tsx
index 553d03f..ffccebe 100644
--- a/client/src/Pages/UploadPage.tsx
+++ b/client/src/Pages/UploadPage.tsx
@@ -108,6 +108,7 @@ function UploadPage() {
onChange={handleFileChange}
accept="audio/*,video/*"
/>
+
{file ? file.name : 'Drop your file here or click to browse'}
@@ -135,6 +136,7 @@ function UploadPage() {
+
);
}
diff --git a/client/src/assets/female-female-mixture.wav b/client/src/assets/female-female-mixture.wav
new file mode 100644
index 0000000..2137997
Binary files /dev/null and b/client/src/assets/female-female-mixture.wav differ
diff --git a/client/src/components/AudioVisualizer.tsx b/client/src/components/AudioVisualizer.tsx
new file mode 100644
index 0000000..bffcb67
--- /dev/null
+++ b/client/src/components/AudioVisualizer.tsx
@@ -0,0 +1,93 @@
+import audioFile from "../assets/female-female-mixture.wav";
+import { useEffect, useRef, useState } from "react";
+
+const AudioVisualizer: React.FC = () => {
+ const audioRef = useRef(null);
+ const canvasRef = useRef(null);
+ const audioContextRef = useRef(null);
+ const sourceRef = useRef(null);
+ const analyserRef = useRef(null);
+ const [isPlaying, setIsPlaying] = useState(false);
+ const [audioSrc, setAudioSrc] = useState("");
+
+ useEffect(() => {
+ setAudioSrc(audioFile);
+ }, []);
+
+ useEffect(() => {
+ if (!audioRef.current || !canvasRef.current) return;
+
+ if (!audioContextRef.current) {
+ audioContextRef.current = new (window.AudioContext || window.AudioContext)();
+ }
+ const audioContext = audioContextRef.current;
+
+ if (!analyserRef.current) {
+ analyserRef.current = audioContext.createAnalyser();
+ analyserRef.current.fftSize = 256;
+ }
+ const analyser = analyserRef.current;
+
+ if (!sourceRef.current) {
+ sourceRef.current = audioContext.createMediaElementSource(audioRef.current);
+ sourceRef.current.connect(analyser);
+ analyser.connect(audioContext.destination);
+ }
+
+ const bufferLength = analyser.frequencyBinCount;
+ const dataArray = new Uint8Array(bufferLength);
+ const canvas = canvasRef.current;
+ const ctx = canvas.getContext("2d");
+ if (!ctx) return;
+
+ const draw = () => {
+ if (!isPlaying) return;
+
+ analyser.getByteFrequencyData(dataArray);
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ const barWidth = canvas.width / bufferLength; // Fit bars within canvas width
+ const maxBarHeight = canvas.height * 0.9; // Scale bars relative to canvas height
+
+ let x = 0;
+ for (let i = 0; i < bufferLength; i++) {
+ const barHeight = (dataArray[i] / 255) * maxBarHeight; // Normalize height
+
+ ctx.fillStyle = `rgb(${barHeight + 100}, 50, 100)`;
+ ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
+ x += barWidth + 2; // Add spacing between bars
+ }
+
+ requestAnimationFrame(draw);
+ };
+
+ if (isPlaying) {
+ audioContext.resume();
+ draw();
+ }
+ }, [isPlaying]);
+
+ const togglePlay = () => {
+ const audio = audioRef.current;
+ if (!audio) return;
+
+ if (audio.paused) {
+ audio.play();
+ setIsPlaying(true);
+ } else {
+ audio.pause();
+ setIsPlaying(false);
+ }
+ };
+
+ return (
+
+ {audioSrc &&
}
+
+
+
+
+ );
+};
+
+export default AudioVisualizer;