Phase 22-23: Synthesis Engine, Extended Steps, Demo Sessions#15
Merged
Phase 22-23: Synthesis Engine, Extended Steps, Demo Sessions#15
Conversation
Consolidates all remaining music synthesis requirements from roadmap Phase 25 into a detailed spec including: - Dual oscillator architecture - Filter modulation with envelope - LFO system (vibrato, tremolo, filter sweeps) - Effects chain (reverb, delay, chorus, distortion) - Sampled instruments (piano, strings, brass) - XY pad / macro controls - FM synthesis Includes full Tone.js analysis: - Available synths (MonoSynth, DuoSynth, FMSynth, etc.) - Effects suite (25+ built-in effects) - Transport & scheduling capabilities - Bundle size impact (~100-120KB gzipped) - Browser compatibility Recommends hybrid approach: keep custom scheduler (polymetric support), integrate Tone.js for effects, sampler, and advanced synths.
Implements the hybrid approach from specs/SYNTHESIS-ENGINE.md:
- Keep existing scheduler (polymetric support)
- Add Tone.js for effects and advanced synths
New files:
- toneEffects.ts: Effects chain (Reverb, Delay, Chorus)
- toneSynths.ts: Advanced synths (FM, AM, Membrane, Metal, Pluck, Duo)
- Comprehensive test suites (60 new tests)
ToneEffectsChain features:
- Freeverb (instant ready, no async IR)
- FeedbackDelay with tempo-synced time ("8n", "4n")
- Chorus with LFO
- State serialization for multiplayer sync
- Proper disposal pattern
ToneSynthManager features:
- 11 presets: fm-epiano, fm-bass, fm-bell, am-bell, am-tremolo,
membrane-kick, membrane-tom, metal-cymbal, metal-hihat,
pluck-string, duo-lead
- Lazy synth instantiation
- Semitone to note/frequency conversion
AudioEngine integration:
- Async initialization (non-blocking)
- Full effects API (getEffectsState, applyEffectsState, etc.)
- playToneSynth() for advanced synth playback
- isToneSynthSample() for sample ID detection
Best practices applied (from spec Section 7):
- Singleton pattern for effects
- Deep copy for state (prevents mutation)
- Proper dispose() calls
- Value clamping for all parameters
All 597 tests pass.
This commit completes the Phase 25 synthesis features: - Distortion effect with waveshaping in effects chain - WebSocket integration for effects multiplayer sync - Tone.Sampler for sampled instruments (piano, strings, brass, electric-piano) - Advanced synth engine with dual oscillators, filter envelope, and LFO - XY Pad / Macro controls for real-time parameter control New presets: supersaw, sub-bass, wobble-bass, warm-pad, vibrato-lead, tremolo-strings, acid-bass, thick-lead All 716 tests passing.
Audit findings and fixes: - Fix voice active flag never resetting (advancedSynth.ts) - Add release timeout tracking and noteStartTime for voice stealing - Add delay.time validation allowlist (live-session.ts) - Clear loadPromise on error to allow retry (toneSampler.ts) - Remove dead code: unused clamp function and voiceNotes Map - Centralize C4_FREQUENCY and NOTE_NAMES in new constants.ts - Fix getAllParameterValues return type (xyPad.ts) - Reset state to defaults in toneEffects.ts dispose() - Fix concurrent resume() race condition with promise locking (engine.ts) - Add toneInitPromise for Tone.js initialization locking - Fix fire-and-forget initAudio() with error handling (StepSequencer.tsx) - Add audio context state check in Recorder.tsx handlePlaySlice New tests for all fixes (752 tests passing): - Voice release tracking and inactive state - Voice stealing based on noteStartTime - loadPromise error recovery - toneEffects state reset on dispose - constants.ts unit tests for delay time validation
Move the duplicate VALID_DELAY_TIMES constant from inline in live-session.ts to worker/invariants.ts for better organization. The constant is duplicated from audio/constants.ts because workers bundle separately from browser code.
Implement dynamic import for the audio engine to improve initial page load for users who are just viewing/sharing sessions without playing. Feature flag: VITE_LAZY_AUDIO=true enables lazy loading (default: false) Trigger classification (documented in lazyAudioLoader.ts): - Tier 1 (MUST trigger): Play button, sample preview, recording, chromatic notes - Tier 2 (SHOULD trigger): Step toggle, sample picker open, transpose change - Tier 3 (SHOULD NOT): Page load, session name, QR/share, mute/solo Components updated: - StepSequencer.tsx: Play uses getAudioEngine(), step toggle uses ensureAudioLoaded() - TrackRow.tsx: Preview handlers check isAudioLoaded() before playing - SamplePicker.tsx: Preview on hover triggers ensureAudioLoaded() - Recorder.tsx: Recording and playback use getAudioEngine() - ChromaticGrid.tsx: Note clicks check isAudioLoaded() for preview Roadmap updated with Phase 26: Performance optimization - Named Tone.js imports (tree-shaking) - planned - Code splitting for audio modules - planned - Lazy audio engine loading - implemented 761 tests passing.
Per Web Audio API specs, mouseenter/mouseover are NOT valid user gestures for unlocking AudioContext. Only click, touch, key events qualify. Changes: - SamplePicker: Don't call initialize() on hover - just skip preview - SamplePicker: Add ensureAudioLoaded() to handleSelect (click IS valid) This fixes silent hover previews being confusing - now they're intentionally silent until a valid gesture unlocks the AudioContext.
- Create audioTriggers.ts as single source of truth for audio decisions - Define trigger tiers: Tier 1 (require), Tier 2 (preload), Preview - Add 40 tests for gesture validation and trigger classification - Update all components to use centralized trigger handlers - Add window.__audioTriggers debug API in development mode
Comprehensive technical reference covering: - Signal flow and component relationships - All synth engines (Web Audio, Tone.js, Advanced) - Effects chain and parameter ranges - Lazy loading and trigger system - Sample system and parameter locks - Memory management and performance optimizations
The spec was missing concrete UI designs, violating the "Three Surfaces" lesson: API, State, and UI must all align for a feature to be complete. New section 9 adds: - Effects panel wireframes and interaction model - Sample picker updates for new synths - Three surfaces alignment checklist - Implementation priority (P0-P4) - Mobile responsive design requirements - Published session behavior
EffectsPanel (new): - LED bar meters for wet/dry (10 segments, click to set) - Effect-specific colors: Reverb=cyan, Delay=blue, Chorus=purple, Distortion=orange - Hardware synth rack aesthetic with glow effects - Responsive: 4-column desktop, 2-column tablet, 1-column mobile - JetBrains Mono for values, LED-style display SamplePicker updates: - Add 11 Tone.js synths (FM, Membrane, Metal, AM, Pluck, Duo) - Add 8 Advanced synths (Supersaw, Wobble, Acid 303, etc.) - Distinct colors: Synth=pink, Tone=cyan, Advanced=purple - Grouped by synthesis type (FM, Drum, Mod, Leads, Bass, Pads)
Section 9 refinements (based on UI philosophy analysis): - Add mobile-first ASCII mockup (stacked vertical layout) - Add visual design specification (slider styling, color coding) - Add typography guidelines matching existing patterns - Update desktop mockup for better readability New Section 10: Musical Surface Area Expansion - Before/after comparison (35→62 sounds, +77%) - Genre coverage matrix (10 genres now possible) - Sound design capabilities table New Section 11: Example Sessions - "Ambient Dreamscape" (reverb + pads) - "Acid Warehouse" (distortion + 303) - "Sunset Chillwave" (FM + chorus + delay) - "Dubstep Drop" (wobble bass + effects) - "Minimal Techno" (p-locks + effects) Each session includes verification checklist.
Fixes: - Remove unused type imports in advancedSynth.test.ts - Export default constants with _ prefix in advancedSynth.ts - Add getter for _noteFrequency to satisfy unused property check - Fix return type in audioTriggers.ts tryGetEngineForPreview to properly allow null - Widen Set type in constants.test.ts to allow checking arbitrary strings - Remove unused vi import from lazyAudioLoader.test.ts - Fix parameter property syntax in toneSynths.test.ts (TS1294) - Add type assertions for config properties in toneSynths.test.ts - Prefix unused loop variables with _ in test files - Remove unused imports from Recorder.tsx All 801 unit tests and 28 integration tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…ting - Fix track deletion memory leak: call audioEngine.removeTrackGain() when deleting tracks to clean up orphaned GainNodes - Fix SamplePicker preview parameter bugs for tone/advanced/sampled instruments with correct parameter ordering and readiness checks - Add sampled: prefix routing in scheduler for piano and future sampled instruments - Reorganize instruments by musical function (Drums, Bass, Keys, Leads, Pads, FX) instead of by engine type for intuitive browsing - Add collapsible categories on mobile, always expanded on desktop - Add minimum touch target sizes (44px mobile, 32px desktop) for instrument buttons - Fix eslint errors: unused vars, function declaration order, dynamic imports 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Memory leak fixes: - Engine.ts: Store unlock handler reference for proper cleanup - useMultiplayer.ts: Restore original clock sync handler on cleanup - App.tsx: Use useEffect for copied state timer instead of setTimeout in callback - Recorder.tsx: Disconnect BufferSource on playback end - StepSequencer.tsx: Use ref for copySource in keyboard listener to avoid recreating Code deduplication: - Extract clamp() to utils/math.ts (used by toneEffects, xyPad, grid reducers) - Extract DELAY_TIME_OPTIONS to audio/delay-constants.ts (used by Transport, EffectsPanel) - Create track-utils.ts with findTrackById, createStepsArray, createParameterLocksArray All 1598 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The chromatic/keyboard view was only being shown for tracks with 'synth:' prefix, ignoring sampled instruments like 'sampled:piano'. Added isMelodicInstrument() helper that correctly identifies all melodic instruments that should show the keyboard view: - synth: prefixed instruments (all melodic) - advanced: prefixed instruments (all melodic) - sampled: prefixed instruments (piano, etc.) - tone: prefixed instruments (except drum synths like membrane-kick) Regular samples (kick, snare, etc.) remain as percussive and don't show the keyboard view. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests cover all instrument categories: - synth: prefix instruments (melodic) - advanced: prefix instruments (melodic) - sampled: prefix instruments (melodic, including piano) - tone: prefix instruments (mixed - melodic vs drums) - Regular samples (percussive) - Edge cases (empty string, unknown prefix, case sensitivity) Also includes keyboard view requirement tests to prevent regression of the piano keyboard display bug. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents all work from this branch: - Memory leak fixes (16 confirmed leaks) - Code deduplication (math.ts, delay-constants.ts, track-utils.ts) - Keyboard view bug fix for sampled instruments - 62 new tests for isMelodicInstrument - Architecture audit findings (B+ grade) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This branch pulled forward and implemented most of Phase 25: - Sampled piano with multi-sampling (C2-C5) - Tone.js integration (FM, AM, Membrane, Metal, Pluck, Duo) - Advanced dual-oscillator synth (863 lines) - Effects chain (reverb, delay, chorus, distortion) - XY Pad / macro controls (370 lines) - Lazy audio loading - 5,963 lines of audio tests - 1,808-line synthesis spec Also includes memory leak fixes, code deduplication, and architecture audit from original scope. Renumbered phases 23-33 to account for new Phase 22. Marked Phase 25 as substantially complete. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Critical fixes: - MIDI-EXPORT.md: Remove dead link to non-existent research file - SESSION-LIFECYCLE.md: Fix "Project Phase 11" → "Phase 24" (Auth) - SYNTHESIS-ENGINE.md: Update status to "Substantially Complete" - SYNTHESIS-ENGINE.md: Fix success criteria checkboxes - MUSICAL-FOUNDATIONS-SUMMARY.md: Note that effects implemented in Phase 22 Phase reference updates: - Clarify Phase 22 (Synthesis Engine) vs Phase 25 (remaining work) - Update related references across specs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added: - Effects session persistence (Medium priority) - Bundle size verification (Low priority) - Critical note about effects sync requirement 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates to align code comments with ROADMAP.md: Phase Reference Fixes: - Phase 16 → Phase 26 for "Shared Sample Recording" (was incorrectly labeled) - Phase 21A → Phase 22 for synthesis engine work (16 files) - Phase 24 → Phase 21 for publishing features (was renumbered) - Phase 25 → Phase 22 for Tone.js integration (was pulled forward) Files Updated: 28 files across: - app/src/audio/ (synthesis, scheduling, effects) - app/src/components/ (UI components) - app/src/hooks/ (React hooks) - app/src/worker/ (Cloudflare worker) - app/src/sync/ (multiplayer) - app/src/*.css (styling comments) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 22: Implement per-player playback tracking to show which players
are currently playing in the multiplayer session.
Changes:
- Server: Replace session-wide isPlaying boolean with per-player Set
- Server: Include playingPlayerIds in snapshots for new/reconnecting clients
- Server: Broadcast playback_stopped when players disconnect while playing
- Client: Track playingPlayerIds in multiplayer state
- UI: Show pulsing play indicator on avatars of playing players
- Tests: Add 10 new tests for playback presence tracking
Key architectural decision: Each player independently controls their own
audio ("my ears, my control"), but we now show presence indicators so
others can see who's listening. Works in both regular and published sessions.
Also includes:
- Documentation cleanup (removed deferred items per user request)
- Spec consistency fixes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document the Phase 22 playback presence indicator feature: - STATUS.md: Add to Phase 11 "Also Completed (Later)" section - STATUS.md: Update file table descriptions - ROADMAP.md: Add section 14 under Phase 22 with full implementation details 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused createMockToneNode helper in audio-context-safety.test.ts - Add proper type casts for Tone.setContext mock calls - Prefix unused loop variable with underscore (_name) - Remove unused instrumentScheduleLoop import in playback-state-debug.test.ts - Prefix unused error variables with underscore in analyze-bug-patterns.ts All 1696 tests pass, build succeeds with no errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removed unused modules identified in codebase audit: - toneSampler.ts: R2-hosted sample approach, never integrated - Referenced non-existent /api/samples/ route - Superseded by sampled-instrument.ts with manifest-based loading - tone-note-players.ts: Strategy pattern with fallback behavior - Contradicts explicit no-fallback policy - Current note-player.ts uses simpler NotePlayerRegistry - Updated audio-context-safety.test.ts singleton audit: - Removed getSamplerManager() entry - Updated expected count from 4 to 3 Build passes, all 1676 tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Debugging Infrastructure: - Add debug-coordinator.ts: Central hub that coordinates debug subsystems based on URL flags (?debug=1, ?trace=1, ?audio-debug=1, ?log=1) - Add debug-tracer.ts: Structured observability with spans, correlation IDs, duration measurement, and performance statistics - Add log-store.ts: IndexedDB-based persistent log storage with auto-cleanup, TTL-based retention, and export capabilities - Add bug-patterns.ts: Registry of known bugs with symptoms, detection functions, and fix guidance - Add playback-state-debug.ts: Scheduler state verification and invariant checking for audio playback debugging CLI Tools: - Add analyze-logs.ts: Log file analysis with error grouping, timeline view, and session breakdown - Add post-fix-analysis.ts: Find similar bug patterns after fixing a bug - Add bug-capture.ts: Interactive wizard for documenting bugs - Add /post-fix Claude Code command for guided post-fix workflow Documentation: - Add DEBUGGING-LESSONS-LEARNED.md: Root cause analysis for fixed bugs - Add DEBUGGING-WORKFLOW.md: Step-by-step debugging procedures - Add AUDIO-CONTENT-TOOLS.md: Tools for audio content management - Add HIDDEN-UI-FEATURES.md: Spec for hidden advanced UI features (XY Pad) - Update development-tools.md: Comprehensive tool reference - Update ROADMAP.md and MIDI-EXPORT.md with new phases Audio Module Updates: - Integrate debug instrumentation into engine.ts, scheduler.ts, synth.ts - Add debug hooks to toneEffects.ts - Initialize debug coordinator in main.tsx - Enhance logger.ts with persistent storage and category support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The integration tests expected a session-wide `isPlaying` boolean, but Phase 22 changed to per-player playback tracking. Updated tests to check for `playingPlayerIds` and `playingPlayers` instead. Changes: - Check for `playingPlayerIds` array in debug endpoint - Check for `playingCount` in debug endpoint - Check for `playingPlayers` Set in runInDurableObject 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code cleanup based on branch audit: - Unify semitoneToFrequency into single canonical implementation in constants.ts - synth.ts now re-exports from constants.ts - AdvancedSynthEngine uses imported function - Removed duplicate class methods from ToneSynthManager and AdvancedSynthEngine - Remove orphaned VALID_DELAY_TIMES from constants.ts - Was only used in tests, duplicated worker/invariants.ts - UI uses delay-constants.ts, validation uses invariants.ts - Fix HMR zombie scheduler issue - Add import.meta.hot.accept() to scheduler.ts - Without accept(), dispose() wasn't called on HMR updates - Remove duplicate debug initialization from engine.ts - debug-coordinator.ts handles initialization - Removes redundant initDebugTracer/initPlaybackDebug/initBugPatterns calls - Clean up singleton patterns in Tone.js modules - Remove cached singletons that caused AudioContext mismatch on HMR - toneEffects.ts, toneSynths.ts, advancedSynth.ts now use fresh instances 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 23 UI Polish features: Effects Master Bypass: - Combined FX button with split click zones (bypass/panel toggle) - CSS Grid centering for perfect vertical alignment - Stable width via grid stacking (both states in DOM) - Visual feedback: green (active), red (bypassed) Playback Mode Toggle: - SET_TRACK_PLAYBACK_MODE reducer action - Desktop: button in TrackRow grid - Mobile: toggle in InlineDrawer - One-shot (plays to completion) vs Gate (cuts at step boundary) XY Pad Component: - Reusable 2D parameter control - Touch and mouse support - Integrated with reverb (wet/decay) - External labels for clean sizing LRU Sample Cache: - O(1) get/set with doubly-linked list - Reference counting prevents evicting in-use samples - Size-based eviction (64MB default) - 25 unit tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Completes Phase 23 with cache integration and lazy loading:
LRU Cache Integration:
- SampledInstrument now uses LRU cache for sample buffers
- Cache key format: `{instrumentId}:{note}` (e.g., piano:60)
- Cache checked before network fetch, populated after decode
- Reference counting API: acquireCacheReferences() / releaseCacheReferences()
- Engine exposes acquireInstrumentSamples() / releaseInstrumentSamples()
Lazy Loading:
- Removed eager preload at startup
- Instruments load on-demand via ensureLoaded() or load()
- Progressive loading preserved (C4 first, then remaining)
- Loading state API: getSampledInstrumentState(), onSampledInstrumentStateChange()
Test fix:
- Clear LRU cache in beforeEach to ensure predictable fetch behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… abstraction Critical bug fix: - preloadInstrumentsForTracks now handles both synth:piano and sampled:piano formats - Piano samples now correctly load before playback starts New abstraction (instrument-types.ts): - Centralized parseInstrumentId() for consistent prefix handling - collectSampledInstruments() replaces duplicated logic across 15+ files - Comprehensive tests (32 new tests) ESLint fixes (8 warnings resolved): - DebugOverlay: Made formatTimeAgo pure with state-based currentTime - Recorder: Documented intentional setState in effects - useMultiplayer: Added missing getStateForHash dependency - useQRMode: Documented intentional isActive dependency - useSession: Fixed mount-only effect and Date.now() purity Tests: 1728 passing (38 new) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… audit docs ## Extended Step Sequencer (64 → 128 steps) - MAX_STEPS now 128 (8 bars at 16th note resolution) - STEP_COUNT_OPTIONS: [4, 8, 12, 16, 24, 32, 64, 96, 128] - Added 128-step test coverage for polyrhythms and edge cases ## Bug Fix #8: Mid-playback sampled instrument preloading - SamplePicker now preloads sampled instruments on selection - Fixes piano not playing when added during playback - Added 5 tests for preloading behavior - Documented in DEBUGGING-LESSONS-LEARNED.md ## Demo Sessions (showcasing extended patterns) - progressive-house-build.json (128-step evolving build) - polyrhythmic-evolution.json (odd-length: 5, 7, 11, 13, 17, 19, 23 steps) - edm-drop-section.json (8-bar pre-drop + drop) - extended-afrobeat.json (96-step triplet groove) ## Documentation Audit (internal consistency) - Updated all references from 64 to 128 steps - Fixed CHANGELOG, ROADMAP, SPEC, STATUS, TUNING-CONSTANTS - Updated validation in session-api.ts and worker/validation.ts - Aligned types.ts comments with actual MAX_STEPS value 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## New Demo Sessions 1. **ambient-soundscape.json** — Atmospheric pads, shimmer, evolving, glass - High swing (45) for organic feel - Gate playback mode for sustained textures - Advanced synth: tremolo-strings 2. **synth-bass-showcase.json** — All bass varieties - Reese, Hoover, Acid 303, Wobble, FM Bass, Funk, Sub - Gate mode for wobble bass - Various patterns highlighting each bass character 3. **keys-and-piano.json** — Keyboard instruments - Sampled piano, Rhodes, Wurlitzer, Organ, FM Piano - E-Piano, Clavinet, Vibes - Jazz-influenced chord progression (swing: 35) 4. **electronic-leads.json** — EDM lead synths - Supersaw, Hypersaw, Advanced Supersaw - Thick Lead, Vibrato Lead, Duo Lead - Trance-style patterns at 138 BPM 5. **gate-mode-demo.json** — Playback mode comparison - Side-by-side GATE vs ONESHOT examples - Gated pads, strings, organ, bass, lead - Rhythmic chopping effects 6. **fx-and-percussion.json** — FX and synth drums - Tone.js drums: membrane kick/tom, metal cymbal/hihat - FM Bell, AM Bell, Synth Bell - Stab, Brass, Wobble, Growl ## Coverage Improvement Before: 11 sessions using ~15% of instruments After: 17 sessions using ~80% of instruments 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
TypeScript strict mode requires explicit type annotation for prevNode since it references self in initializer context. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The class name was changed during the SamplePicker refactor but the E2E tests were not updated. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR includes Phase 22 (Synthesis Engine) and Phase 23 (Polish) work:
Phase 22: Synthesis Engine
New Instruments (60+ total)
Effects Chain
Phase 23: Extended Steps & Polish
Extended Step Sequencer
[4, 8, 12, 16, 24, 32, 64, 96, 128]Bug Fix #8: Mid-Playback Preloading
Problem: Piano tracks added during playback never loaded
Fix: SamplePicker now preloads sampled instruments immediately on selection
Demo Sessions (17 total)
Documentation Audit
Updated all references for consistency across:
Test plan
npm run test -- --run)🤖 Generated with Claude Code