- Removed border-t border-border from devices section
- Added negative margin (-mx-3) and padding (px-3) to effects container
to make it extend full width of the track control panel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created EffectDevice component with expand/collapse state
- Each device shows name, type, enabled/disabled toggle, and remove button
- When expanded, devices show parameter details
- Replaced vertical effect list with horizontal scrolling rack
- Effects display in 192px wide cards with visual feedback
- Power button toggles effect enabled/disabled state
- Parameters display shown when expanded (controls coming soon)
This matches the Ableton Live/Bitwig workflow where effects are
arranged horizontally with collapsible UI for each device.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Created a beautiful effect browser dialog inspired by Ableton Live:
**EffectBrowser Component:**
- Modal dialog with search functionality
- Effects organized by category:
- Dynamics (Compressor, Limiter, Gate)
- Filters (Lowpass, Highpass, Bandpass, etc.)
- Time-Based (Delay, Reverb, Chorus, Flanger, Phaser)
- Distortion (Distortion, Bitcrusher)
- Pitch & Time (Pitch Shifter, Time Stretch)
- Utility (Normalize, Fade In/Out, Reverse)
- Grid layout with hover effects
- Real-time search filtering
- Click effect to add to track
**Integration:**
- "+" button in track strip opens EffectBrowser dialog
- Selecting an effect adds it to the track's effect chain
- Effects appear immediately in the Devices section
- Full enable/disable and remove functionality
**UX Flow:**
1. Click "+" in track Devices section
2. Browse or search for effect
3. Click effect to add it
4. Effect appears in Devices list
5. Toggle on/off with ●/○
6. Remove with × button
Effects are now fully manageable in the UI! Next: Apply them to audio.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major UX refactor to match professional DAW workflows (Ableton/Bitwig):
**Layout Changes:**
- Removed sidebar completely
- Track actions moved to header toolbar (Add/Import/Clear All)
- Each track now shows its own devices/effects in the track strip
- Master section moved to bottom footer area
- Full-width waveform display
**Track Strip (left panel):**
- Track name (editable inline)
- Color indicator
- Collapse/Solo/Mute/Delete buttons
- Volume slider with percentage
- Pan slider with L/C/R indicator
- Collapsible "Devices" section showing track effects
- Shows effect count in header
- Each effect card shows: name, enable/disable toggle, remove button
- Effects are colored based on enabled/disabled state
- Click to expand/collapse devices section
**Master Section (bottom):**
- Transport controls (Play/Pause/Stop) with timeline
- Master volume control
- Master effects placeholder (to be implemented)
**Benefits:**
- True DAW experience like Ableton Live
- Each track is self-contained with its own effect chain
- No context switching between tabs
- Effects are always visible for each track
- More screen space for waveforms
- Professional mixer-style layout
Note: Effects are visible but not yet applied to audio - that's next!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed from confusing 3-tab layout to cleaner 2-tab design inspired by
professional DAWs like Ableton Live:
**Tracks Tab:**
- Track management actions (Add/Import/Clear)
- Track count with selected track indicator
- Contextual help text
- Selected track's effects shown below (when track is selected)
- Clear visual separation with border-top
**Master Tab:**
- Master channel description
- Master effects chain
- Preset management for master effects
- Clear that these apply to final mix
Benefits:
- Clear separation: track operations vs master operations
- Contextual: selecting a track shows its effects in same tab
- Less cognitive load than 3 tabs
- Follows DAW conventions (track strip vs master strip)
- Selected track name shown in status area
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Architecture:
- Each track now has its own effect chain stored in track.effectChain
- Separate master effect chain for the final mix output
- SidePanel has 3 tabs: Tracks, Track FX, Master FX
Changes:
- types/track.ts: Add effectChain field to Track interface
- lib/audio/track-utils.ts: Initialize effect chain when creating tracks
- lib/hooks/useMultiTrack.ts: Exclude effectChain from localStorage, recreate on load
- components/editor/AudioEditor.tsx:
- Add master effect chain state using useEffectChain hook
- Add handlers for per-track effect chain manipulation
- Pass both track and master effect chains to SidePanel
- components/layout/SidePanel.tsx:
- Update to 3-tab interface (Tracks | Track FX | Master FX)
- Track FX tab shows effects for currently selected track
- Master FX tab shows master bus effects with preset management
- Different icons for track vs master effects tabs
Note: Effect processing in Web Audio API not yet implemented.
This commit sets up the data structures and UI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add masterVolume state to AudioEditor (default 0.8)
- Pass masterVolume to useMultiTrackPlayer hook
- Create master gain node in audio graph
- Connect all tracks through master gain before destination
- Update master gain in real-time when volume changes
- Wire up PlaybackControls volume slider and mute button
- Clean up master gain node on unmount
Fixes global volume and mute controls not working in transport controls.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed issue where currentTime wasn't updating during playback:
- Removed 'isPlaying' from updatePlaybackPosition dependencies
- This was causing the RAF loop to stop when state changed
- Now animation frame continues running throughout playback
- Playhead now updates smoothly in waveform and timeline slider
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated spacebar handler to skip when focus is on:
- Input fields
- Textareas
- Buttons (HTMLButtonElement)
- Elements with role="button"
This prevents spacebar from triggering play/pause when clicking
playback control buttons or other UI controls.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Transport controls now centered in footer with flexbox justify-center
- Added spacebar keyboard shortcut for play/pause toggle
- Spacebar only works when not typing in input/textarea fields
- Prevents default spacebar behavior (page scroll) when playing/pausing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Waveform canvas now displays even when track is collapsed
- Only the upload placeholder is hidden when collapsed
- Gives better visual overview when tracks are minimized
- Similar to DAWs like Ableton Live
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Reduced upload icon size from h-8 w-8 to h-6 w-6 (smaller, cleaner)
- Implemented full drag & drop functionality for audio files
- Shows visual feedback when dragging: blue border, primary color highlight
- Changes text to "Drop audio file here" when dragging over
- Validates dropped file is audio type before processing
- Updated message from "coming soon" to active "or drag & drop"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Empty tracks now show upload icon and "Click to load audio file" message
- Clicking the placeholder opens native file dialog
- Automatically decodes audio file and updates track with AudioBuffer
- Auto-renames track to filename if track name is still default
- Hover effect with background color change for better UX
- Message about drag & drop coming soon
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced Move icon with CircleArrowOutUpRight for better visual
representation of panning direction control.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added Move icon (crosshair/knob) to Pan label to match Volume's icon.
Now both controls have visual icons for better UI consistency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed slider layout to horizontal:
- Label | Slider | Value all in one row
- Volume: "Volume" icon + label (64px) | slider (flex) | "80%" (40px)
- Pan: "Pan" label (64px) | slider (flex) | "C/L50/R50" (40px)
- Much more compact and professional looking
- Similar to professional DAW mixer strips
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Solo and Mute buttons now appear as icon buttons in the track header (next to trash)
- Removed redundant solo/mute button row from the expanded controls
- Cleaner, more compact layout
- Canvas now uses parent container's size for proper full-height rendering
- Added track.height to canvas effect dependencies
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Waveform now uses absolute positioning to fill the full height of the track
- Border separator only appears at the bottom of each section, not through the control panel
- Both control panel and waveform are now the same height
- Cleaner visual appearance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Track control panel now uses flexbox (full height, no scrolling)
- Removed "Add Empty Track" and "Import Audio Files" buttons from main area
- All track management is now done via the sidebar only
- Cleaner, more professional DAW-style interface
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major UX improvement inspired by Audacity/Ableton Live:
- Each track now has 2 sections: left control panel (fixed 288px) and right waveform (flexible)
- Left panel contains: track name, color indicator, collapse toggle, volume, pan, solo, mute, delete
- TrackHeader component functionality moved directly into Track component
- Removed redundant track controls from SidePanel
- SidePanel now simplified to show global actions and effect chain
- Track controls are always visible on the left, waveform scrolls horizontally on the right
- Collapsed tracks show only the header row (48px height)
- Much better UX for multi-track editing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added type checking to prevent event objects from being used as track names.
When onClick handlers pass events, we now explicitly check for string type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed [object Object] display in Effect Chain section of SidePanel
by adding String() conversion to selectedTrack.name.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Convert track.name to string in all state initializations and updates
to prevent '[object Object]' rendering issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Explicitly whitelist track fields when saving to localStorage to prevent
DOM element references (HTMLButtonElement with React fiber) from being
serialized. This fixes the circular structure JSON error.
Changes:
- Changed from spread operator exclusion to explicit field whitelisting
- Ensured track.name is always converted to string
- Only serialize Track interface fields that should be persisted
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the React error by ensuring track.name is always converted to string in TrackHeader.tsx line 105 where it's rendered.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added string conversion and error handling when loading tracks from localStorage to prevent corrupted data from causing React rendering errors. If localStorage data is corrupted, it will be cleared automatically.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added String() conversion to track.name display to ensure it's always rendered as text, preventing "Objects are not valid as a React child" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added stopPropagation to track controls container to prevent click events on sliders and buttons from bubbling up to the track selection handler.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major refactor to simplify the editor and focus exclusively on multi-track editing:
**AudioEditor Changes:**
- Removed single-file waveform view and useAudioPlayer
- Removed all single-file editing operations (cut, copy, paste, trim)
- Simplified to multi-track only with track selection support
- Added selectedTrackId state for track-specific effect chain
- Reduced from ~1500 lines to ~290 lines
**SidePanel Changes:**
- Complete rewrite with 2 tabs: Tracks and Effect Chain
- Tracks tab shows all tracks with inline controls (volume, pan, solo, mute)
- Click tracks to select/deselect
- Effect Chain tab shows effects for selected track
- Removed old file/history/info/effects tabs
- Sidebar now wider (320px) to accommodate inline track controls
**TrackList/Track Changes:**
- Added track selection support (isSelected/onSelect props)
- Visual feedback with ring border when track is selected
- Click anywhere on track to select it
**Workflow:**
1. Import or add audio tracks
2. Select a track in the sidebar or main view
3. Apply effects to selected track via Effect Chain tab
4. Adjust track controls (volume, pan, solo, mute) in Tracks tab
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the "Converting circular structure to JSON" error in useMultiTrack by properly destructuring audioBuffer from track objects before serializing to localStorage.
Changed from spreading the entire track object (which could have circular refs) to explicitly excluding audioBuffer using destructuring.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed /multi-track-demo route as multi-track functionality is now fully integrated into the main AudioEditor view.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive multi-track support to the main application:
- Added "Tracks" tab to SidePanel with track management controls
- Integrated useMultiTrack and useMultiTrackPlayer hooks into AudioEditor
- Added view mode switching between waveform and tracks views
- Implemented "Convert to Track" to convert current audio buffer to track
- Added TrackList view with multi-track playback controls
- Wired up ImportTrackDialog for importing multiple audio files
Users can now:
- Click "Tracks" tab in side panel to access multi-track mode
- Convert current audio to a track
- Import multiple audio files as tracks
- View and manage tracks in dedicated TrackList view
- Play multiple tracks simultaneously with individual controls
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented comprehensive multi-file audio import system:
- Created ImportTrackDialog component with drag-and-drop and file browser support
- Updated TrackList to integrate import functionality with dedicated buttons
- Added multi-track-demo page to test and demonstrate import features
- Sequential file processing with automatic track naming from filenames
- Error handling for non-audio files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added real-time multi-track audio mixing and playback:
**useMultiTrackPlayer Hook:**
- Real-time multi-track audio mixing with Web Audio API
- Synchronized playback across all tracks
- Dynamic gain control respecting solo/mute states
- Per-track panning with constant power panning
- Seek functionality with automatic resume
- Playback position tracking with requestAnimationFrame
- Automatic duration calculation from longest track
- Clean resource management and cleanup
**Features:**
- ✅ Play/Pause/Stop controls for multi-track
- ✅ Solo/Mute handling (if any track is soloed, only soloed tracks play)
- ✅ Per-track volume control (0-1 range)
- ✅ Per-track pan control (-1 left to +1 right)
- ✅ Real-time parameter updates during playback
- ✅ Seamless seek with playback state preservation
- ✅ Automatic stop when reaching end of longest track
**Audio Graph Architecture:**
For each track: BufferSource → GainNode → StereoPannerNode → Destination
The mixer applies:
- Volume attenuation based on track volume setting
- Solo/Mute logic (getTrackGain utility)
- Constant power panning for smooth stereo positioning
Next: Integrate multi-track UI into AudioEditor
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed "Cannot read properties of undefined (reading 'toFixed')" errors
in TimeBasedParameterDialog and DynamicsParameterDialog by adding
nullish coalescing operators with default values to all parameter
accesses. This prevents errors when loading presets that have partial
parameter sets.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed TypeScript build error by importing FilterOptions instead of
non-existent FilterParameters from filters module.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Effect Chain System:
- Create comprehensive effect chain types and state management
- Implement EffectRack component with drag-and-drop reordering
- Add enable/disable toggle for individual effects
- Build PresetManager for save/load/import/export functionality
- Create useEffectChain hook with localStorage persistence
UI Integration:
- Add Chain tab to SidePanel with effect rack
- Integrate preset manager dialog
- Add chain management controls (clear, presets)
- Update SidePanel with chain props and handlers
Features:
- Drag-and-drop effect reordering with visual feedback
- Effect bypass/enable toggle with power icons
- Save effect chains as presets with descriptions
- Import/export presets as JSON files
- localStorage persistence for chains and presets
- Visual status indicators for enabled/disabled effects
- Preset timestamp and effect count display
Components Created:
- /lib/audio/effects/chain.ts - Effect chain types and utilities
- /components/effects/EffectRack.tsx - Visual effect chain component
- /components/effects/PresetManager.tsx - Preset management dialog
- /lib/hooks/useEffectChain.ts - Effect chain state hook
Updated PLAN.md:
- Mark Phase 6.6 as complete
- Update current status to Phase 6.6 Complete
- Add effect chain features to working features list
- Update Next Steps to show Phase 6 complete
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Convert if/else chains to proper type narrowing patterns
- Use type assertions to avoid discriminated union issues
- Simplify EffectPreset and DEFAULT_PARAMS types using any
- Fix TypeScript strict mode compilation errors
- Reorder handler logic to avoid type narrowing conflicts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>