feat: add advanced audio effects and improve UI

Phase 6.5 Advanced Effects:
- Add Pitch Shifter with semitones and cents adjustment
- Add Time Stretch with pitch preservation using overlap-add
- Add Distortion with soft/hard/tube types and tone control
- Add Bitcrusher with bit depth and sample rate reduction
- Add AdvancedParameterDialog with real-time waveform visualization
- Add 4 professional presets per effect type

Improvements:
- Fix undefined parameter errors by adding nullish coalescing operators
- Add global custom scrollbar styling with color-mix transparency
- Add custom-scrollbar utility class for side panel
- Improve theme-aware scrollbar appearance in light/dark modes
- Fix parameter initialization when switching effect types

Integration:
- All advanced effects support undo/redo via EffectCommand
- Effects accessible via command palette and side panel
- Selection-based processing support
- Toast notifications for all effects

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-17 20:03:40 +01:00
parent f414573655
commit ee48f9475f
26 changed files with 6027 additions and 273 deletions

View File

@@ -4,9 +4,10 @@ import * as React from 'react';
import { cn } from '@/lib/utils/cn';
export interface SliderProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'> {
value?: number;
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'onValueChange'> {
value?: number | number[];
onChange?: (value: number) => void;
onValueChange?: (value: number[]) => void;
min?: number;
max?: number;
step?: number;
@@ -20,6 +21,7 @@ const Slider = React.forwardRef<HTMLInputElement, SliderProps>(
className,
value = 0,
onChange,
onValueChange,
min = 0,
max = 100,
step = 1,
@@ -30,8 +32,13 @@ const Slider = React.forwardRef<HTMLInputElement, SliderProps>(
},
ref
) => {
// Support both value formats (number or number[])
const currentValue = Array.isArray(value) ? value[0] : value;
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
onChange?.(parseFloat(e.target.value));
const numValue = parseFloat(e.target.value);
onChange?.(numValue);
onValueChange?.([numValue]);
};
return (
@@ -44,7 +51,7 @@ const Slider = React.forwardRef<HTMLInputElement, SliderProps>(
</label>
)}
{showValue && (
<span className="text-sm text-muted-foreground">{value}</span>
<span className="text-sm text-muted-foreground">{currentValue}</span>
)}
</div>
)}
@@ -54,7 +61,7 @@ const Slider = React.forwardRef<HTMLInputElement, SliderProps>(
min={min}
max={max}
step={step}
value={value}
value={currentValue}
onChange={handleChange}
disabled={disabled}
className={cn(