/** * Noise Reduction UI Component * Professional noise reduction interface with multiple algorithms */ import { Activity, AlertCircle, Brain, Mic, MicOff, Volume2, Waves, Zap } from "lucide-react" import { useCallback, useState } from "react" import { useTranslation } from "react-i18next" import { Alert, AlertDescription } from "@/components/ui/alert" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Progress } from "@/components/ui/progress" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Slider } from "@/components/ui/slider" import { Switch } from "@/components/ui/switch" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import type { AnalysisResult, NoiseProfile, NoiseReductionConfig, } from "../../services/noise-reduction/noise-reduction-engine" export interface NoiseReductionSettings { enabled: boolean config: NoiseReductionConfig profileId?: string } interface NoiseReductionProps { settings: NoiseReductionSettings onChange: (settings: NoiseReductionSettings) => void onAnalyze?: () => void isProcessing?: boolean analysisResult?: AnalysisResult noiseProfiles?: NoiseProfile[] } export function NoiseReduction({ settings, onChange, onAnalyze, isProcessing = false, analysisResult, noiseProfiles = [], }: NoiseReductionProps) { const { t } = useTranslation() const [isLearning, setIsLearning] = useState(false) const [previewEnabled, setPreviewEnabled] = useState(false) const handleConfigChange = useCallback( (updates: Partial) => { onChange({ ...settings, config: { ...settings.config, ...updates, }, }) }, [settings, onChange], ) const handleAlgorithmChange = useCallback( (algorithm: NoiseReductionConfig["algorithm"]) => { // Set default values for different algorithms const defaults: Partial = { algorithm, strength: algorithm === "ai" ? 80 : 50, preserveVoice: algorithm === "ai" || algorithm === "adaptive", attackTime: 10, releaseTime: 100, frequencySmoothing: 0.5, noiseFloor: -60, gateThreshold: -40, } onChange({ ...settings, config: { ...settings.config, ...defaults, }, }) }, [settings, onChange], ) const getAlgorithmInfo = (algorithm: string) => { switch (algorithm) { case "spectral": return { icon: , name: t("fairlightAudio.effects.noiseReduction.algorithms.spectralGate.name"), description: t("fairlightAudio.effects.noiseReduction.algorithms.spectralGate.description"), } case "wiener": return { icon: , name: t("fairlightAudio.effects.noiseReduction.algorithms.wienerFilter.name"), description: t("fairlightAudio.effects.noiseReduction.algorithms.wienerFilter.description"), } case "ai": return { icon: , name: t("fairlightAudio.effects.noiseReduction.algorithms.aiDenoising.name"), description: t("fairlightAudio.effects.noiseReduction.algorithms.aiDenoising.description"), } case "adaptive": return { icon: , name: t("fairlightAudio.effects.noiseReduction.algorithms.adaptive.name"), description: t("fairlightAudio.effects.noiseReduction.algorithms.adaptive.description"), } default: return null } } const algorithmInfo = getAlgorithmInfo(settings.config.algorithm) return (
{settings.enabled ? : } Noise Reduction onChange({ ...settings, enabled })} aria-label="Enable noise reduction" />
{/* Algorithm Selection */}
{algorithmInfo &&

{algorithmInfo.description}

}
{/* Main Controls */} Basic Advanced Analysis {/* Strength Control */}
{settings.config.strength}%
handleConfigChange({ strength: value })} disabled={!settings.enabled} className="w-full" />
{/* Voice Preservation */} {(settings.config.algorithm === "ai" || settings.config.algorithm === "adaptive") && (
handleConfigChange({ preserveVoice })} disabled={!settings.enabled} />
)} {/* Noise Profile Selection */} {noiseProfiles.length > 0 && (
)} {/* Learn Noise Button */}
{/* Attack Time */}
{settings.config.attackTime}ms
handleConfigChange({ attackTime: value })} disabled={!settings.enabled} />
{/* Release Time */}
{settings.config.releaseTime}ms
handleConfigChange({ releaseTime: value })} disabled={!settings.enabled} />
{/* Frequency Smoothing */}
{Math.round(settings.config.frequencySmoothing * 100)}%
handleConfigChange({ frequencySmoothing: value })} disabled={!settings.enabled} />
{/* Noise Floor */} {(settings.config.algorithm === "spectral" || settings.config.algorithm === "wiener") && (
{settings.config.noiseFloor}dB
handleConfigChange({ noiseFloor: value })} disabled={!settings.enabled} />
)} {/* Gate Threshold */} {settings.config.algorithm === "spectral" && (
{settings.config.gateThreshold}dB
handleConfigChange({ gateThreshold: value })} disabled={!settings.enabled} />
)}
{/* Analysis Button */} {/* Analysis Results */} {analysisResult && (

SNR

{analysisResult.snr.toFixed(1)} dB

Noise Level

{analysisResult.noiseLevel.toFixed(1)} dB

Voice Detection

{analysisResult.voiceDetected ? "Detected" : "Not Detected"}

Confidence

{Math.round(analysisResult.confidence * 100)}%

{analysisResult.dominantFrequencies.length > 0 && (

Dominant Frequencies

{analysisResult.dominantFrequencies.map((freq, idx) => ( {freq} Hz ))}
)} {/* Recommendations */} {analysisResult.snr < 10 ? t("fairlightAudio.effects.noiseReduction.recommendations.highNoise") : analysisResult.voiceDetected ? t("fairlightAudio.effects.noiseReduction.recommendations.voiceDetected") : t("fairlightAudio.effects.noiseReduction.recommendations.noVoice")}
)}
{/* Preview Toggle */}
{previewEnabled && }
) }