feat: complete Phase 7.4 - real-time track effects system
Implemented comprehensive real-time effect processing for multi-track audio: Core Features: - Per-track effect chains with drag-and-drop reordering - Effect bypass/enable toggle per effect - Real-time parameter updates (filters, dynamics, time-based, distortion, bitcrusher, pitch, timestretch) - Add/remove effects during playback without interruption - Effect chain persistence via localStorage - Automatic playback stop when tracks are deleted Technical Implementation: - Effect processor with dry/wet routing for bypass functionality - Real-time effect parameter updates using AudioParam setValueAtTime - Structure change detection for add/remove/reorder operations - Stale closure fix using refs for latest track state - ScriptProcessorNode for bitcrusher, pitch shifter, and time stretch - Dual-tap delay line for pitch shifting - Overlap-add synthesis for time stretching UI Components: - EffectBrowser dialog with categorized effects - EffectDevice component with parameter controls - EffectParameters for all 19 real-time effect types - Device rack with horizontal scrolling (Ableton-style) Removed offline-only effects (normalize, fadeIn, fadeOut, reverse) as they don't fit the real-time processing model. Completed all items in Phase 7.4: - [x] Per-track effect chain - [x] Effect rack UI - [x] Effect bypass per track - [x] Real-time effect processing during playback - [x] Add/remove effects during playback - [x] Real-time parameter updates - [x] Effect chain persistence 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,15 @@ export function AudioEditor() {
|
||||
clearTracks,
|
||||
} = useMultiTrack();
|
||||
|
||||
// Log tracks to see if they update
|
||||
React.useEffect(() => {
|
||||
console.log('[AudioEditor] Tracks updated:', tracks.map(t => ({
|
||||
name: t.name,
|
||||
effectCount: t.effectChain.effects.length,
|
||||
effects: t.effectChain.effects.map(e => e.name)
|
||||
})));
|
||||
}, [tracks]);
|
||||
|
||||
const {
|
||||
isPlaying,
|
||||
currentTime,
|
||||
@@ -280,7 +289,7 @@ export function AudioEditor() {
|
||||
|
||||
{/* Track Actions */}
|
||||
<div className="flex items-center gap-2 border-l border-border pl-4">
|
||||
<Button variant="outline" size="sm" onClick={addTrack}>
|
||||
<Button variant="outline" size="sm" onClick={() => addTrack()}>
|
||||
<Plus className="h-4 w-4 mr-1.5" />
|
||||
Add Track
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user