Commit Graph

61 Commits

Author SHA1 Message Date
a626427142 feat: implement Phase 12.3 - Project Export/Import
Added full export/import functionality for projects:

Export Features:
- Export button for each project in Projects dialog
- Downloads project as JSON file with all data
- Includes tracks, audio buffers, effects, automation, settings
- Filename format: {project_name}_{timestamp}.json

Import Features:
- Import button in Projects dialog header
- File picker for .json files
- Automatically generates new project ID to avoid conflicts
- Appends "(Imported)" to project name
- Preserves all project data

This enables:
- Backup of projects outside the browser
- Sharing projects with collaborators
- Migration between computers/browsers
- Version snapshots at different stages

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 10:25:06 +01:00
1b41fca393 fix: serialize automation data to prevent DataCloneError
Deep clone automation data using JSON.parse(JSON.stringify()) to remove
any functions before saving to IndexedDB. This prevents DataCloneError
when trying to store non-serializable data.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 10:02:37 +01:00
67abbb20cb fix: serialize effects properly to avoid DataCloneError
Effects contain non-serializable data like functions and audio nodes that
cannot be stored in IndexedDB. Added proper serialization.

Changes:
- Added serializeEffects function to strip non-serializable data
- Uses JSON parse/stringify to deep clone parameters
- Preserves effect type, name, enabled state, and parameters
- Fixes DataCloneError when saving projects with effects

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 09:56:02 +01:00
0d86cff1b7 feat: disable localStorage persistence and add auto-load last project
**useMultiTrack.ts:**
- Removed localStorage persistence (tracks, effects, automation)
- Now relies entirely on IndexedDB via project management system
- Simpler state management without dual persistence

**AudioEditor.tsx:**
- Store last project ID in localStorage when saving
- Auto-load last project on page mount
- Only runs once per session with hasAutoLoaded flag
- Falls back to empty state if project can't be loaded

**Benefits:**
- No more conflicts between localStorage and IndexedDB
- Effects and automation properly persisted
- Seamless experience - reload page and your project is ready
- Single source of truth (IndexedDB)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 09:51:27 +01:00
b743f97276 fix: project loading and add editable project name
Fixed project loading to restore all track properties and added inline
project name editing in header.

**AudioEditor.tsx:**
- Added `loadTracks` from useMultiTrack hook
- Fixed `handleLoadProject` to use `loadTracks()` instead of recreating tracks
  - Now properly restores all track properties (effects, automation, volume, pan, etc.)
  - Shows track count in success toast message
- Added editable project name input in header
  - Positioned between logo and track actions
  - Auto-sizes based on text length
  - Saves on blur (triggers auto-save)
  - Smooth hover/focus transitions
  - Muted color that brightens on interaction

**useMultiTrack.ts:**
- Added `loadTracks()` method to replace all tracks at once
- Enables proper project loading with full state restoration
- Maintains all track properties during load

**Fixes:**
- Projects now load correctly with all tracks and their audio buffers
- Track properties (effects, automation, volume, pan, etc.) fully restored
- Project name can be edited inline in header
- Auto-save triggers when project name changes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 09:32:34 +01:00
d3a5961131 feat: implement Phase 12.2 - Project Management UI Integration
Integrated complete project management system with auto-save:

**AudioEditor.tsx - Full Integration:**
- Added "Projects" button in header toolbar (FolderOpen icon)
- Project state management (currentProjectId, currentProjectName, projects list)
- Comprehensive project handlers:
  - `handleOpenProjectsDialog` - Opens dialog and loads project list
  - `handleSaveProject` - Saves current project to IndexedDB
  - `handleNewProject` - Creates new project with confirmation
  - `handleLoadProject` - Loads project and restores all tracks/settings
  - `handleDeleteProject` - Deletes project with cleanup
  - `handleDuplicateProject` - Creates project copy
- Auto-save effect: Saves project every 30 seconds when tracks exist
- ProjectsDialog component integrated with all handlers
- Toast notifications for all operations

**lib/storage/projects.ts:**
- Re-exported ProjectMetadata type for easier importing
- Fixed type exports

**Key Features:**
- **Auto-save**: Automatically saves every 30 seconds
- **Project persistence**: Full track state, audio buffers, effects, automation
- **Smart loading**: Restores zoom, track order, and all track properties
- **Safety confirmations**: Warns before creating new project with unsaved changes
- **User feedback**: Toast messages for all operations (save, load, delete, duplicate)
- **Seamless workflow**: Projects → Import → Export in logical toolbar order

**User Flow:**
1. Click "Projects" to open project manager
2. Create new project or load existing
3. Work on tracks (auto-saves every 30s)
4. Switch between projects anytime
5. Duplicate projects for experimentation
6. Delete old projects to clean up

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 09:26:57 +01:00
e1c19ffcb3 feat: implement Phase 12.1 - Project Management with IndexedDB
Added complete project save/load system using IndexedDB:

**New Files:**
- `lib/storage/db.ts` - IndexedDB database schema and operations
  - ProjectMetadata interface for project metadata
  - SerializedAudioBuffer and SerializedTrack for storage
  - Database initialization with projects object store
  - Audio buffer serialization/deserialization functions
  - CRUD operations for projects

- `lib/storage/projects.ts` - High-level project management service
  - Save/load project state with tracks and settings
  - List all projects sorted by last updated
  - Delete and duplicate project operations
  - Track serialization with proper type conversions
  - Audio buffer and effect chain handling

- `components/dialogs/ProjectsDialog.tsx` - Project list UI
  - Grid view of all projects with metadata
  - Project actions: Open, Duplicate, Delete
  - Create new project button
  - Empty state with call-to-action
  - Confirmation dialog for deletions

**Key Features:**
- IndexedDB stores complete project state (tracks, audio buffers, settings)
- Efficient serialization of AudioBuffer channel data
- Preserves all track properties (effects, automation, volume, pan)
- Sample rate and duration tracking
- Created/updated timestamps
- Type-safe with full TypeScript support

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 09:19:52 +01:00
37f910acb7 feat: complete Phase 11.4 - comprehensive audio file import
Implemented advanced audio import capabilities:

**Import Features:**
- Support for WAV, MP3, OGG, FLAC, M4A, AIFF formats
- Sample rate conversion using OfflineAudioContext
- Stereo to mono conversion (equal channel mixing)
- Normalize on import option (99% peak with 1% headroom)
- Comprehensive codec detection from MIME types and extensions

**API Enhancements:**
- ImportOptions interface (convertToMono, targetSampleRate, normalizeOnImport)
- importAudioFile() function returning buffer + metadata
- AudioFileInfo with AudioMetadata (codec, duration, channels, sample rate, file size)
- Enhanced decodeAudioFile() with optional import transformations

**UI Components:**
- ImportDialog component with import settings controls
- Sample rate selector (44.1kHz - 192kHz)
- Checkbox options for mono conversion and normalization
- File info display (original sample rate and channels)
- Updated FileUpload to show AIFF support

**Technical Implementation:**
- Offline resampling for quality preservation
- Equal-power channel mixing for stereo-to-mono
- Peak detection across all channels
- Metadata extraction with codec identification

Phase 11 (Export & Import) now complete!

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 08:25:36 +01:00
c3e295f695 fix: use lamejs Mp3Encoder API for proper module initialization
Switched from low-level Lame API to Mp3Encoder class which:
- Properly initializes all required modules (Lame, BitStream, etc.)
- Handles module dependencies via setModules() calls
- Provides a simpler encodeBuffer/flush API
- Resolves "init_bit_stream_w is not defined" error

Updated TypeScript declarations to export Mp3Encoder and WavHeader
from lamejs/src/js/index.js

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 08:19:48 +01:00
51114330ea fix: use direct ES module imports from lamejs source files
Fixed MP3 export by importing lamejs modules directly from source:
- Import MPEGMode, Lame, and BitStream from individual source files
- Use Lame API directly instead of Mp3Encoder wrapper
- Updated TypeScript declarations for each module
- Resolves "MPEGMode is not defined" error

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 08:16:52 +01:00
d5c84d35e4 fix: install lamejs from GitHub repo for proper browser support
Switched from npm package to GitHub repo (github:zhuker/lamejs) which
includes the proper browser build. Reverted to simple dynamic import.

Fixes MP3 export MPEGMode reference error.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 08:11:46 +01:00
77916d4d07 fix: load lamejs from pre-built browser bundle
Changed MP3 export to dynamically load the pre-built lame.min.js
bundle from node_modules instead of trying to import the CommonJS
module. The browser bundle properly bundles all dependencies including
MPEGMode and exposes a global lamejs object.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 08:06:24 +01:00
8112ff1ec3 fix: add CommonJS compatibility for lamejs dynamic import
Fixed MP3 export error by handling both default and named exports
from lamejs module to support CommonJS/ESM interop.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 07:52:17 +01:00
6577d9f27b feat: add MP3 and FLAC export formats
Implemented Phase 11.1 export format support:
- Added MP3 export using lamejs library
- Added FLAC export using fflate DEFLATE compression
- Updated ExportDialog with format selector and format-specific options
  - MP3: bitrate selector (128/192/256/320 kbps)
  - FLAC: compression quality slider (0-9)
  - WAV: bit depth selector (16/24/32-bit)
- Updated AudioEditor to route export based on selected format
- Created TypeScript declarations for lamejs
- Fixed AudioStatistics to use audioBuffer instead of buffer property

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 02:14:32 +01:00
7dc0780bd2 feat: implement Phase 10.1 & 10.2 - frequency analyzer and spectrogram
Added real-time audio analysis visualizations to master column:

- FrequencyAnalyzer component with FFT bar display
  - Canvas-based rendering with requestAnimationFrame
  - Color gradient from cyan to green based on frequency
  - Frequency axis labels (20Hz, 1kHz, 20kHz)

- Spectrogram component with time-frequency waterfall display
  - Scrolling visualization with ImageData pixel manipulation
  - Color mapping: black → blue → cyan → green → yellow → red
  - Vertical frequency axis with labels

- Master column redesign
  - Fixed width layout (280px)
  - Toggle buttons to switch between FFT and Spectrum views
  - Integrated above master controls with 300px minimum height

- Exposed masterAnalyser from useMultiTrackPlayer hook
  - Analyser node now accessible to visualization components

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 01:40:04 +01:00
34452862ca fix: remove double dB conversion from track levels for consistent metering
Track levels were being converted to dB scale twice:
1. First in useMultiTrackPlayer via linearToDbScale()
2. Again in TrackFader via linearToDb()

This caused tracks to show incorrect meter levels compared to master.
Now both track and master levels store raw linear values (0-1) and
let the fader components handle the single dB conversion for display.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 00:55:46 +01:00
7a45a985c7 fix: convert master meter levels to dB scale for consistent metering
Previously, master meters received raw linear values (0-1) while track
meters received dB-normalized values, causing inconsistent metering display.
Now both master peak and RMS levels are converted using linearToDbScale()
for accurate comparison between track and master levels.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 00:50:27 +01:00
c33a77270b feat: complete Phase 10.3 - master metering with peak/RMS display
Added comprehensive master output level monitoring:
- Created MasterMeter component with dual vertical bars (peak + RMS)
- Implemented real-time level monitoring in useMultiTrackPlayer hook
- Added master analyser node connected to audio output
- Displays color-coded levels (green/yellow/red) based on dB thresholds
- Shows numerical dB readouts for both peak and RMS
- Includes clickable clip indicator with reset functionality
- Integrated into PlaybackControls next to master volume

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:56:53 +01:00
c54d5089c5 feat: complete Phase 9.3 - automation recording with write/touch/latch modes
Implemented comprehensive automation recording system for volume, pan, and effect parameters:

- Added automation recording modes:
  - Write: Records continuously during playback when values change
  - Touch: Records only while control is being touched/moved
  - Latch: Records from first touch until playback stops

- Implemented value change detection (0.001 threshold) to prevent infinite loops
- Fixed React setState-in-render errors by:
  - Using queueMicrotask() to defer state updates
  - Moving lane creation logic to useEffect
  - Properly memoizing touch handlers with useMemo

- Added proper value ranges for effect parameters:
  - Frequency: 20-20000 Hz
  - Q: 0.1-20
  - Gain: -40-40 dB

- Enhanced automation lane auto-creation with parameter-specific ranges
- Added touch callbacks to all parameter controls (volume, pan, effects)
- Implemented throttling (100ms) to avoid excessive automation points

Technical improvements:
- Used tracksRef and onRecordAutomationRef to ensure latest values in animation loops
- Added proper cleanup on playback stop
- Optimized recording to only trigger when values actually change

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:29:18 +01:00
4c6453d115 feat: add effect parameter automation and fix mode logic
Completed Phase 9.3 - Full Automation Playback:
-  Effect parameter automation implementation
-  Fixed automation mode logic (now applies in all modes)
-  Automatic parameter range conversion (normalized to actual values)

Effect parameter automation:
- Parses effect parameter IDs (format: effect.{effectId}.{paramName})
- Finds corresponding effect nodes in audio graph
- Converts normalized 0-1 automation values to actual parameter ranges
- Applies parameters using updateEffectParameters during playback
- Works with all effect types (filters, dynamics, time-based, etc.)

Automation mode fix:
- Removed incorrect mode !== 'read' checks
- Automation now plays back in all modes (read/write/touch/latch)
- Mode will control recording behavior, not playback

Technical notes:
- Used type assertion (as any) for dynamic parameter updates
- Maintains parameter range from automation lane valueRange
- Integrated with existing effect update mechanism

Phase 9 Status:
 9.1: Automation lanes UI complete
 9.2: Automation points complete
 9.3: Real-time playback (volume, pan, effects) complete
 9.3: Automation recording (next milestone)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 19:08:18 +01:00
dac8ac4723 feat: implement real-time automation playback for volume and pan
Phase 9.3 - Automation Playback:
- Added real-time automation evaluation during playback
- Automation values are applied continuously via requestAnimationFrame
- Volume automation: Interpolates between points and applies to gain nodes
- Pan automation: Converts 0-1 values to -1 to 1 for StereoPannerNode

Implementation details:
- New applyAutomation() function runs in RAF loop alongside level monitoring
- Evaluates automation at current playback time using evaluateAutomationLinear
- Applies values using setValueAtTime for smooth Web Audio API parameter changes
- Automation loop lifecycle matches playback (start/pause/stop/cleanup)
- Respects automation mode (only applies when mode !== 'read')

Technical improvements:
- Added automationFrameRef for RAF management
- Proper cleanup in pause(), unmount, and playback end scenarios
- Integrated with existing effect chain restart mechanism
- Volume automation multiplied with track gain (mute/solo state)

Next steps:
- Effect parameter automation (TODO in code)
- Automation recording (write mode implementation)
- Touch and latch modes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 19:06:02 +01:00
d2709b8fc2 refactor: move effects panel from global to per-track
- Added showEffects property to Track type
- Added "E" button with Sparkles icon to toggle per-track effects
- Effects panel now appears below each track when toggled
- Removed global EffectsPanel from AudioEditor
- Updated useMultiTrack to persist showEffects state
- Streamlined workflow: both automation and effects are now per-track

This aligns the UX with professional DAWs like Ableton Live, where
effects and automation are track-scoped rather than global.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 18:44:06 +01:00
03a7e2e485 feat: implement Phase 9.1 - Automation lanes UI
Added comprehensive automation lane UI with Ableton-style design:

**Automation Components:**
- AutomationLane: Canvas-based rendering with grid lines, curves, and points
- AutomationHeader: Parameter name, mode selector, value display
- AutomationPoint: Interactive draggable points with hover states

**Automation Utilities:**
- createAutomationLane/Point: Factory functions
- evaluateAutomationLinear: Interpolation between points
- formatAutomationValue: Display formatting with unit support
- addAutomationPoint/updateAutomationPoint/removeAutomationPoint

**Track Integration:**
- Added "A" toggle button in track control panel
- Automation lanes render below waveform
- Default lanes for Volume (orange) and Pan (green)
- Support for add/edit/delete automation points
- Click to add, drag to move, double-click to delete

**Visual Design:**
- Dark background with horizontal grid lines
- Colored curves with semi-transparent fill (20% opacity)
- 4-6px automation points, 8px on hover
- Mode indicators (Read/Write/Touch/Latch) with colors
- Value labels and current value display

Ready for playback integration in next step.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 18:34:35 +01:00
17381221d8 feat: refine UI with effects panel improvements and visual polish
Major improvements:
- Fixed multi-file import (FileList to Array conversion)
- Auto-select first track when adding to empty project
- Global effects panel folding state (independent of track selection)
- Effects panel collapsed/disabled when no track selected
- Effect device expansion state persisted per-device
- Effect browser with searchable descriptions

Visual refinements:
- Removed center dot from pan knob for cleaner look
- Simplified fader: removed volume fill overlay, dynamic level meter visible through semi-transparent handle
- Level meter capped at fader position (realistic mixer behavior)
- Solid background instead of gradient for fader track
- Subtle volume overlay up to fader handle
- Fixed track control width flickering (consistent 4px border)
- Effect devices: removed shadows/rounded corners for flatter DAW-style look, added consistent border-radius
- Added border between track control and waveform area

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 18:13:38 +01:00
9b1eedc379 feat: Ableton Live-style effects and complete automation system
Enhanced visual design:
- Improved device rack container with darker background and inner shadow
- Device cards now have rounded corners, shadows, and colored indicators
- Better visual separation between enabled/disabled effects
- Active devices highlighted with accent border

Complete automation infrastructure (Phase 9):
- Created comprehensive type system for automation lanes and points
- Implemented AutomationPoint component with drag-and-drop editing
- Implemented AutomationHeader with mode controls (Read/Write/Touch/Latch)
- Implemented AutomationLane with canvas-based curve rendering
- Integrated automation lanes into Track component below effects
- Created automation playback engine with real-time interpolation
- Added automation data persistence to localStorage

Automation features:
- Add/remove automation points by clicking/double-clicking
- Drag points to change time and value
- Multiple automation modes (Read, Write, Touch, Latch)
- Linear and step curve types (bezier planned)
- Adjustable lane height (60-180px)
- Show/hide automation per lane
- Real-time value display at playhead
- Color-coded lanes by parameter type
- Keyboard delete support (Delete/Backspace)

Track type updates:
- Added automation field to Track interface
- Updated track creation to initialize empty automation
- Updated localStorage save/load to include automation data

Files created:
- components/automation/AutomationPoint.tsx
- components/automation/AutomationHeader.tsx
- components/automation/AutomationLane.tsx
- lib/audio/automation/utils.ts (helper functions)
- lib/audio/automation/playback.ts (playback engine)
- types/automation.ts (complete type system)

Files modified:
- components/effects/EffectDevice.tsx (Ableton-style visual improvements)
- components/tracks/Track.tsx (automation lanes integration)
- types/track.ts (automation field added)
- lib/audio/track-utils.ts (automation initialization)
- lib/hooks/useMultiTrack.ts (automation persistence)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 16:30:01 +01:00
49dd0c2d38 feat: complete Phase 8.3 - recording settings (input gain, mono/stereo, sample rate)
Recording Settings (Phase 8.3):
- Added input gain control (0.0-2.0 with dB display)
- Real-time gain adjustment via GainNode during recording
- Mono/Stereo recording mode selection
- Sample rate matching (44.1kHz, 48kHz, 96kHz)
- Mono conversion averages all channels when enabled
- Recording settings panel shown when track is armed

Components Created:
- RecordingSettings.tsx: Settings panel with gain slider, mono/stereo toggle, sample rate buttons

Components Modified:
- useRecording hook: Added settings state and GainNode integration
- AudioEditor: Pass recording settings to TrackList
- TrackList: Forward settings to Track components
- Track: Show RecordingSettings when armed for recording

Technical Details:
- GainNode inserted between source and analyser in recording chain
- Real-time gain updates via gainNode.gain.value
- AudioContext created with target sample rate
- Mono conversion done post-recording by averaging channels
- Settings persist during recording session

Phase 8 Complete:
-  Phase 8.1: Audio Input
-  Phase 8.2: Recording Controls (punch/overdub)
-  Phase 8.3: Recording Settings
- 📋 Phase 9: Automation (NEXT)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:51:38 +01:00
db01209f77 feat: implement professional logarithmic dB scale for level meters
Converted level meters from linear to logarithmic (dB) scale to
match professional audio software behavior and human hearing.

The Problem:
- Linear scale (0-100%) doesn't match perceived loudness
- Doesn't match professional DAW meter behavior
- Half-volume audio appears at 50% but sounds much quieter
- No industry-standard dB reference

The Solution:
- Convert linear amplitude to dB: 20 * log10(linear)
- Normalize -60dB to 0dB range to 0-100% display
- Matches professional audio metering standards

dB Scale Mapping:
  0 dB (linear 1.0)    = 100% (full scale, clipping)
 -6 dB (linear ~0.5)   = 90%  (loud)
-12 dB (linear ~0.25)  = 80%  (normal)
-20 dB (linear ~0.1)   = 67%  (moderate)
-40 dB (linear ~0.01)  = 33%  (quiet)
-60 dB (linear ~0.001) = 0%   (silence threshold)

Implementation:
- Added linearToDbScale() function to both hooks
- useMultiTrackPlayer: playback level monitoring
- useRecording: input level monitoring
- Formula: (dB - minDb) / (maxDb - minDb)
- Range: -60dB (min) to 0dB (max)

Benefits:
 Professional audio metering standards
 Matches human perception of loudness
 Consistent with DAWs (Pro Tools, Logic, Ableton)
 Better visual feedback for mixing/mastering
 More responsive in useful range (-20dB to 0dB)

Now properly mastered tracks will show levels in the
90-100% range, matching what you'd see in professional software.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:23:33 +01:00
a0ce83a654 fix: use Float32Array for accurate full-range level measurement
Switched from Uint8Array to Float32Array for level monitoring
to get accurate, full-precision audio measurements.

The Problem:
- getByteTimeDomainData() uses Uint8Array (0-255)
- Byte conversion: (value - 128) / 128 has asymmetric range
- Positive peaks: (255-128)/128 = 0.992 (not full 1.0)
- Precision loss from byte quantization
- Mastered tracks with peaks at 0dBFS only showed ~50%

The Solution:
- Switched to getFloatTimeDomainData() with Float32Array
- Returns actual sample values directly in -1.0 to +1.0 range
- No conversion needed, no precision loss
- Accurate representation of audio peaks

Changes Applied:
- useMultiTrackPlayer: Float32Array with analyser.fftSize samples
- useRecording: Float32Array with analyser.fftSize samples
- Peak detection: Math.abs() on float values directly

Benefits:
 Full 0-100% range for properly mastered audio
 Higher precision (32-bit float vs 8-bit byte)
 Symmetric range (-1.0 to +1.0, not -1.0 to ~0.992)
 Accurate metering for professional audio files

Now mastered tracks with peaks at 0dBFS will correctly show
~100% on the meters instead of being capped at 50%.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:21:31 +01:00
3e6fbda755 fix: move analyser before gain node to show true audio levels
Repositioned analyser nodes in audio graph to measure raw audio
levels before volume/gain adjustments.

The Problem:
- Analyser was after gain node in signal chain
- Track volume defaults to 0.8 (80%)
- Audio was scaled down before measurement
- Meters only showed ~50% of actual audio peaks

The Solution:
- Moved analyser to immediately after source
- Now measures raw audio before any processing
- Shows true audio content independent of fader position

Audio Graph Changes:
Before: source -> gain -> pan -> effects -> analyser -> master
After:  source -> analyser -> gain -> pan -> effects -> master

Benefits:
 Meters show full 0-100% range based on audio content
 Meter reading independent of volume fader position
 Accurate representation of track audio levels
 Increased smoothingTimeConstant to 0.8 for smoother motion

This is how professional DAWs work - level meters show the
audio content, not the output level after the fader.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:17:42 +01:00
8367cbf6e7 fix: switch from RMS to peak detection for more accurate level meters
Changed level calculation from RMS to peak detection to show
more realistic and responsive meter values.

The Problem:
- RMS calculation produced values typically in 0-30% range
- Audio signals have low average RMS (0.1-0.3 for music)
- Meters appeared broken, never reaching higher levels

The Solution:
- Switched to peak detection (max absolute value)
- Peaks now properly show 0-100% range
- More responsive to transients and dynamics
- Matches typical DAW meter behavior

Algorithm Change:
Before (RMS):
  rms = sqrt(sum(normalized²) / length)

After (Peak):
  peak = max(abs(normalized))

Applied to Both:
- Recording input level monitoring (useRecording)
- Playback output level monitoring (useMultiTrackPlayer)

Benefits:
 Full 0-100% range utilization
 More responsive visual feedback
 Accurate representation of audio peaks
 Consistent with professional audio software

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:15:16 +01:00
a157172e3d fix: resolve playback level monitoring closure issue
Fixed playback level meters staying at 0% by resolving React closure
issue in the monitoring loop - same pattern as the recording fix.

The Problem:
- monitorPlaybackLevels callback checked stale `isPlaying` state
- Animation loop would run once and never continue
- Dependency on isPlaying caused callback recreation on every state change

The Solution:
- Added isMonitoringLevelsRef to track state independent of React
- Removed isPlaying dependency from callback (now has empty deps [])
- Set ref to true when starting playback
- Set ref to false when pausing, stopping, or ending playback
- Animation loop checks ref instead of stale closure state

Monitoring State Management:
- Start: play() sets isMonitoringLevelsRef.current = true
- Stop: pause(), stop(), onended, and cleanup set it to false
- Loop: continues while ref is true, stops when false

This ensures the requestAnimationFrame loop runs continuously
during playback and calculates real-time RMS levels for all tracks.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:12:42 +01:00
6fbb677bd2 feat: implement real-time playback level monitoring for all tracks
Added comprehensive playback level monitoring system that shows
real-time audio levels during playback for each track.

useMultiTrackPlayer Hook:
- Added AnalyserNode for each track in audio graph
- Implemented RMS-based level calculation with requestAnimationFrame
- Added trackLevels state (Record<string, number>) tracking levels by track ID
- Insert analysers after effects chain, before master gain
- Monitor levels continuously during playback
- Clean up level monitoring on pause/stop

Audio Graph Chain:
source -> gain -> pan -> effects -> analyser -> master gain -> destination

AudioEditor Integration:
- Extract trackLevels from useMultiTrackPlayer hook
- Pass trackLevels down to TrackList component

TrackList & Track Components:
- Accept and forward trackLevels prop
- Pass playbackLevel to individual Track components
- Track component displays appropriate level:
  * Recording level (with "Input" label) when armed/recording
  * Playback level (with "Level" label) during normal playback

Visual Feedback:
- Color-coded meters: green -> yellow (70%) -> red (90%)
- Real-time percentage display
- Seamless switching between input and output modes

This completes Phase 8 (Recording) with full bidirectional level monitoring!

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:01:55 +01:00
cf0c37caa6 fix: resolve recording level meter monitoring closure issue
Fixed the input level meter staying at 0% during recording by:

Closure Issue Resolution:
- Added isMonitoringRef to track monitoring state independent of React state
- Removed state dependencies from monitorInputLevel callback
- Animation loop now checks ref instead of stale closure state

Changes:
- Set isMonitoringRef.current = true when starting recording
- Set isMonitoringRef.current = false when stopping/pausing recording
- Animation frame continues while ref is true, stops when false
- Proper cleanup in stopRecording, pauseRecording, and unmount effect

This ensures the requestAnimationFrame loop continues properly and
updates the RMS level calculation in real-time during recording.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:56:30 +01:00
c0ca4d7913 fix: migrate existing tracks to new 180px height from localStorage
Added migration logic to useMultiTrack hook:
- When loading tracks from localStorage, check if height < DEFAULT_TRACK_HEIGHT
- Automatically upgrade old heights (120px, 150px) to new default (180px)
- Preserves custom heights that are already >= 180px

This fixes the inline style issue where existing tracks had
style="height: 120px" that was cutting off the level meter.

After this update, refreshing the page will automatically upgrade
all existing tracks to the new height without losing any data.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:53:31 +01:00
5e6c61d951 feat: implement Phase 8.1 - audio recording infrastructure
Added recording capabilities to the multi-track editor:
- useRecording hook with MediaRecorder API integration
- Audio input device enumeration and selection
- Microphone permission handling
- Input level monitoring with RMS calculation
- InputLevelMeter component with visual feedback
- Record-enable button per track with pulsing indicator
- Real-time input level display when recording

Recording infrastructure is complete. Next: integrate into AudioEditor
for global recording control and buffer storage.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:37:01 +01:00
74879a42cf feat: implement multi-track waveform selection and editing with undo/redo
Added comprehensive selection and editing capabilities to multi-track editor:
- Visual selection overlay with Shift+drag interaction on waveforms
- Multi-track edit commands (cut, copy, paste, delete, duplicate)
- Full keyboard shortcut support (Ctrl+X/C/V/D, Delete, Ctrl+Z/Y)
- Complete undo/redo integration via command pattern
- Per-track selection state with localStorage persistence
- Audio buffer manipulation utilities (extract, insert, delete, duplicate segments)
- Toast notifications for all edit operations
- Red playhead to distinguish from blue selection overlay

All edit operations are fully undoable and integrated with the existing
history manager system.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 13:05:05 +01:00
beb7085c89 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>
2025-11-18 12:08:33 +01:00
f640f2f9d4 feat: implement per-track and master effect chains (Option 3)
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>
2025-11-18 07:30:46 +01:00
2f8718626c feat: implement global volume and mute controls
- 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>
2025-11-18 07:20:29 +01:00
5817598c48 fix: playback position animation frame not updating
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>
2025-11-18 07:16:07 +01:00
64902fa707 chore: remove debug console.log statements
Cleaned up debugging code now that track name rendering issue is resolved.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 22:51:42 +01:00
cf1358e051 fix: ensure track name is always a string in createTrack
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>
2025-11-17 22:50:43 +01:00
7c19c069bf fix: convert selectedTrack.name to string in Effect Chain header
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>
2025-11-17 22:46:28 +01:00
6b540ef8fb fix: prevent localStorage circular reference in track serialization
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>
2025-11-17 22:36:07 +01:00
a2636bb3a9 fix: ensure track names are strings when loading from localStorage
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>
2025-11-17 22:30:45 +01:00
4735b5fb00 fix: resolve circular reference error in localStorage
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>
2025-11-17 22:04:13 +01:00
d566a86c58 feat: implement multi-track playback system (Phase 7.3)
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>
2025-11-17 21:03:39 +01:00
3c950eeba7 feat: implement Phase 7.1-7.2 multi-track infrastructure
Added core multi-track support with track management and controls:

**Track Types & Utilities:**
- Track interface with audio buffer, controls (volume/pan/solo/mute)
- Track utility functions for creation, mixing, and gain calculation
- Track color system with 9 preset colors
- Configurable track heights (60-300px)

**Components:**
- TrackHeader: Collapsible track controls with inline name editing
  - Solo/Mute buttons with visual feedback
  - Volume slider (0-100%) and Pan control (L-C-R)
  - Track color indicator and remove button
- Track: Waveform display component with canvas rendering
  - Click-to-seek on waveform
  - Playhead visualization
  - Support for collapsed state
- TrackList: Container managing multiple tracks
  - Scrollable track list with custom scrollbar
  - Add track button
  - Empty state UI

**State Management:**
- useMultiTrack hook with localStorage persistence
- Add/remove/update/reorder track operations
- Track buffer management

Features implemented:
-  Track creation and removal
-  Track naming (editable)
-  Track colors
-  Solo/Mute per track
-  Volume fader per track (0-100%)
-  Pan control per track (L-C-R)
-  Track collapse/expand
-  Track height configuration
-  Waveform visualization per track
-  Multi-track audio mixing utilities

Next: Integrate into AudioEditor and implement multi-track playback

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
8a0bd46593 fix: correct FilterOptions import in effect chain
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>
2025-11-17 20:34:38 +01:00
0986896756 feat: add Phase 6.6 Effect Chain Management system
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>
2025-11-17 20:27:08 +01:00