diff --git a/src-tauri/src/audio_toolkit/audio/recorder.rs b/src-tauri/src/audio_toolkit/audio/recorder.rs index c3f23adbb..d516d6f1d 100644 --- a/src-tauri/src/audio_toolkit/audio/recorder.rs +++ b/src-tauri/src/audio_toolkit/audio/recorder.rs @@ -256,14 +256,14 @@ fn run_consumer( let mut recording = false; // ---------- spectrum visualisation setup ---------------------------- // - const BUCKETS: usize = 16; + const BUCKETS: usize = 25; const WINDOW_SIZE: usize = 512; let mut visualizer = AudioVisualiser::new( in_sample_rate, WINDOW_SIZE, BUCKETS, - 400.0, // vocal_min_hz - 4000.0, // vocal_max_hz + 150.0, // vocal_min_hz + 2500.0, // vocal_max_hz ); fn handle_frame( diff --git a/src/overlay/RecordingOverlay.css b/src/overlay/RecordingOverlay.css index e11b509c3..c711e269c 100644 --- a/src/overlay/RecordingOverlay.css +++ b/src/overlay/RecordingOverlay.css @@ -1,12 +1,12 @@ .recording-overlay { - height: 36px; + height: 40px; width: 172px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; padding: 6px; background: #000000cc; - border-radius: 18px; + border-radius: 22px; opacity: 0; transition: opacity 300ms ease-out; box-sizing: border-box; @@ -31,20 +31,19 @@ .bars-container { display: flex; - align-items: end; + align-items: center; justify-content: center; - gap: 3px; - padding-bottom: 0px; + gap: 2px; height: 24px; - overflow: hidden; + background: transparent !important; } .bar { - width: 6px; + width: 2px; background: #ffe5ee; - max-height: 20px; - border-radius: 2px; - transition: height 80ms linear; + max-height: 24px; + border-radius: 10px; + transition: height 60ms ease-out, opacity 120ms ease-out; min-height: 4px; } diff --git a/src/overlay/RecordingOverlay.tsx b/src/overlay/RecordingOverlay.tsx index 0270491f4..8533422d8 100644 --- a/src/overlay/RecordingOverlay.tsx +++ b/src/overlay/RecordingOverlay.tsx @@ -16,8 +16,8 @@ const RecordingOverlay: React.FC = () => { const { t } = useTranslation(); const [isVisible, setIsVisible] = useState(false); const [state, setState] = useState("recording"); - const [levels, setLevels] = useState(Array(16).fill(0)); - const smoothedLevelsRef = useRef(Array(16).fill(0)); + const [levels, setLevels] = useState(Array(25).fill(0)); + const smoothedLevelsRef = useRef(Array(25).fill(0)); useEffect(() => { const setupEventListeners = async () => { @@ -46,7 +46,11 @@ const RecordingOverlay: React.FC = () => { }); smoothedLevelsRef.current = smoothed; - setLevels(smoothed.slice(0, 9)); + + // Symmetric mirror effect for Apple-like visualization + const half = smoothed.slice(0, 12); + const symmetricLevels = [...half.slice().reverse(), ...half]; + setLevels(symmetricLevels); }); // Cleanup function @@ -80,9 +84,8 @@ const RecordingOverlay: React.FC = () => { key={i} className="bar" style={{ - height: `${Math.min(20, 4 + Math.pow(v, 0.7) * 16)}px`, // Cap at 20px max height - transition: "height 60ms ease-out, opacity 120ms ease-out", - opacity: Math.max(0.2, v * 1.7), // Minimum opacity for visibility + height: `${Math.min(24, 4 + Math.pow(v * 0.8, 0.6) * 22)}px`, + opacity: Math.max(0.4, Math.min(1, v * 3)), }} /> ))}