Add v2 Game Boy sound engine (isolated from v1)
- Authentic DMG-CPU sound chip implementation: - 4 Pulse channels with duty cycle control (12.5%, 25%, 50%, 75%) - 2 Wave channels with 4-bit wavetables - 2 Noise channels with LFSR (7-bit and 15-bit modes) - GameBoy Colorizer effect chain: - Low-pass filter (natural GB rolloff) - Bit-crushing (4-bit DAC simulation) - Sample rate reduction - Saturation and high-pass filter - Presets: DMG, GBC, GBA, Clean - Intelligent MIDI processing: - Track analysis and role detection (bass, lead, drums, etc.) - Automatic channel mapping to GB channels - Chord arpeggiator for polyphony handling - GameBoy Arranger for fuller sound - BitMidi search integration - Completely isolated from v1 (no changes to src/)
This commit is contained in:
@@ -0,0 +1,603 @@
|
||||
# Wario Synth v2: Phase 2 Implementation Plan
|
||||
|
||||
**Project:** Wario Synthesis Engine v2
|
||||
**Owner:** Andy @ birdmania
|
||||
**Status:** Implementation Phase
|
||||
**Target:** Game Boy-authentic MIDI conversion with enhanced polyphony
|
||||
**Repository:** https://github.com/b1rdmania/motif
|
||||
|
||||
---
|
||||
|
||||
## Project Overview
|
||||
|
||||
Build a Game Boy-authentic synthesis engine (v2) that captures the true DMG-CPU sound chip character while preserving v1's "any MIDI works" philosophy. The v2 engine will be hosted separately and won't intrude on v1's functionality.
|
||||
|
||||
**Key Architecture Decision:** 8-channel "Super Game Boy" setup (4 pulse, 2 wave, 2 noise) instead of authentic 4-channel limitation. This preserves GB sound character while handling complex MIDI files gracefully.
|
||||
|
||||
---
|
||||
|
||||
## Critical Constraint: v1 Isolation
|
||||
|
||||
**v1 MUST remain completely untouched and functional throughout v2 development.**
|
||||
|
||||
### What stays UNTOUCHED (v1):
|
||||
|
||||
- `src/synthesis/SynthesisEngine.ts` - current engine, no changes
|
||||
- `src/core/MotifEngine.ts` - current orchestration, no changes
|
||||
- All existing files in `src/` - completely untouched
|
||||
- `index.html`, `play.html`, `embed.html` - no modifications
|
||||
- Live site at wario.style continues to work exactly as today
|
||||
|
||||
### What gets CREATED (v2):
|
||||
|
||||
- Brand new directory: `src-v2/` - entirely separate codebase
|
||||
- New entry point: `v2.html` - doesn't touch existing HTML files
|
||||
- Separate Vite build config if needed
|
||||
- Could become separate repo later if desired
|
||||
|
||||
### What v2 CAN import (read-only):
|
||||
|
||||
- `src/midi/MIDIParser.ts` - reuse existing MIDI parsing
|
||||
- Shared types from `src/types/index.ts` if compatible
|
||||
- Nothing else - all synthesis code is fresh
|
||||
|
||||
### Benefits of this approach:
|
||||
|
||||
1. Develop v2 while v1 stays live and stable
|
||||
2. If v2 has issues, v1 is completely unaffected
|
||||
3. A/B test with simple URL switch (`/` vs `/v2`)
|
||||
4. Rollback is trivial - just don't deploy v2 code
|
||||
5. Can eventually merge or keep separate forever
|
||||
|
||||
---
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
/Users/andy/MOTIF/
|
||||
├── src/ # v1 (current, unchanged)
|
||||
│ ├── core/MotifEngine.ts
|
||||
│ ├── synthesis/SynthesisEngine.ts
|
||||
│ └── ...
|
||||
├── src-v2/ # v2 (NEW - separate tree)
|
||||
│ ├── audio/
|
||||
│ │ ├── apu/
|
||||
│ │ │ ├── APU.ts # Main 8-channel coordinator
|
||||
│ │ │ ├── PulseChannel.ts # GB pulse with duty cycles
|
||||
│ │ │ ├── WaveChannel.ts # 4-bit wavetable
|
||||
│ │ │ ├── NoiseChannel.ts # LFSR noise
|
||||
│ │ │ └── Mixer.ts # Stereo mixing
|
||||
│ │ ├── synthesis/
|
||||
│ │ │ ├── DutyCycle.ts # 4 GB duty patterns
|
||||
│ │ │ ├── LFSR.ts # Noise generator
|
||||
│ │ │ ├── WaveTable.ts # 4-bit quantization
|
||||
│ │ │ └── FrequencyCalc.ts # GB frequency formulas
|
||||
│ │ └── midi/
|
||||
│ │ ├── TrackAnalyzer.ts # Analyze MIDI structure
|
||||
│ │ ├── ChannelMapper.ts # Assign tracks to 8 channels
|
||||
│ │ └── Arpeggiator.ts # Convert chords to arps
|
||||
│ ├── core/
|
||||
│ │ └── GameBoyPlayer.ts # Main v2 entry point
|
||||
│ └── types/
|
||||
│ └── index.ts # v2-specific types
|
||||
├── public/
|
||||
│ └── v2/ # v2 UI assets
|
||||
└── v2.html # v2 demo page
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Core Sound Engine (Week 1-2)
|
||||
|
||||
**Goal:** Implement authentic GB sound generation with Web Audio API
|
||||
|
||||
### 1.1 Duty Cycle Implementation
|
||||
|
||||
Create `src-v2/audio/synthesis/DutyCycle.ts`:
|
||||
|
||||
- Define 4 GB duty patterns (12.5%, 25%, 50%, 75%)
|
||||
- Convert patterns to `PeriodicWave` for Web Audio
|
||||
- Pattern format: 8-step arrays `[0,0,0,0,0,0,0,1]` etc
|
||||
|
||||
Create `src-v2/audio/apu/PulseChannel.ts`:
|
||||
|
||||
- Pre-create all 4 duty waveforms on init
|
||||
- `playNote(midiNote, duration, velocity)` method
|
||||
- Use GB frequency formula (not standard MIDI)
|
||||
- Simple envelope (fast attack, quick release)
|
||||
- Return `{ osc, gain }` for cleanup
|
||||
|
||||
**Success Criteria:** Each duty cycle sounds distinctly different when tested
|
||||
|
||||
### 1.2 GB Frequency Formulas
|
||||
|
||||
Create `src-v2/audio/synthesis/FrequencyCalc.ts`:
|
||||
|
||||
- `calculatePulseFrequency(midiNote)` → Hz
|
||||
- Formula: `131072 / (2048 - registerValue)`
|
||||
- Convert MIDI → standard freq → register → GB freq
|
||||
- `calculateWaveFrequency(midiNote)` → Hz
|
||||
- Formula: `65536 / (2048 - registerValue)`
|
||||
- `calculateNoiseFrequency(pitch, mode)` → Hz
|
||||
- Formula: `524288 / divisor / 2^(shift+1)`
|
||||
|
||||
**Success Criteria:** Frequencies are slightly "off" from standard tuning (GB characteristic)
|
||||
|
||||
### 1.3 LFSR Noise Generator
|
||||
|
||||
Create `src-v2/audio/synthesis/LFSR.ts`:
|
||||
|
||||
- Implement 15-bit LFSR (default mode)
|
||||
- Implement 7-bit LFSR (tonal mode)
|
||||
- `clock()` method returns 0 or 1
|
||||
- XOR bits 0 and 1, shift right, set bit 14
|
||||
|
||||
Create `src-v2/audio/apu/NoiseChannel.ts`:
|
||||
|
||||
- `playNoise(duration, frequency, velocity)` method
|
||||
- Generate buffer with LFSR output
|
||||
- Clock LFSR at calculated rate
|
||||
- Apply envelope to buffer playback
|
||||
|
||||
**Success Criteria:** Noise sounds crunchy/metallic, not smooth white noise
|
||||
|
||||
### 1.4 Wave Channel with 4-bit Quantization
|
||||
|
||||
Create `src-v2/audio/synthesis/WaveTable.ts`:
|
||||
|
||||
- Store 32 samples × 4-bit (0-15 values)
|
||||
- `quantize(value)` rounds to 4-bit
|
||||
- Presets: `generateBass()`, `generatePad()`, `generateLead()`
|
||||
- `createBuffer(audioContext)` converts to AudioBuffer
|
||||
|
||||
Create `src-v2/audio/apu/WaveChannel.ts`:
|
||||
|
||||
- Load wavetable on construction
|
||||
- `playNote(midiNote, duration, velocity)` method
|
||||
- Use `BufferSource` with looping
|
||||
- Set playback rate for pitch
|
||||
- Volume levels: 0, 100%, 50%, 25% (bit-shift style)
|
||||
|
||||
**Success Criteria:** Wave channel has audible digital "staircase" effect
|
||||
|
||||
### 1.5 Testing Phase 1
|
||||
|
||||
Create `src-v2/audio/test/soundTest.ts`:
|
||||
|
||||
- Test all 4 duty cycles sequentially
|
||||
- Test wave channel with bass preset
|
||||
- Test both noise modes (7-bit and 15-bit)
|
||||
- Play test sequence: duty sweeps, bass note, drum hits
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Channel Manager & 8-Channel APU (Week 2-3)
|
||||
|
||||
**Goal:** Coordinate 8 independent GB channels with mixing
|
||||
|
||||
### 2.1 APU Coordinator
|
||||
|
||||
Create `src-v2/audio/apu/APU.ts`:
|
||||
|
||||
- Initialize 4 pulse, 2 wave, 2 noise channels
|
||||
- Channel IDs: `p1-p4`, `w1-w2`, `n1-n2`
|
||||
- Master gain connected to destination
|
||||
- Per-channel gain nodes for mixing
|
||||
- `scheduleNote(note: ChannelNote)` routes to appropriate channel
|
||||
- Track which channels are busy (`channelBusy` map)
|
||||
- `isChannelFree(channelId, atTime)` for voice allocation
|
||||
|
||||
**Key Methods:**
|
||||
|
||||
- `scheduleNote({ channel, midiNote, startTime, duration, velocity })`
|
||||
- `schedulePulseNote()`, `scheduleWaveNote()`, `scheduleNoiseNote()`
|
||||
- `setChannelPan(channelId, pan)` for stereo
|
||||
|
||||
### 2.2 Channel Gain & Mixing
|
||||
|
||||
In `src-v2/audio/apu/APU.ts`:
|
||||
|
||||
- Each channel connects to individual `GainNode`
|
||||
- Individual gains connect to master gain
|
||||
- Master gain at ~0.7 to prevent clipping
|
||||
- Per-channel volumes match role importance
|
||||
|
||||
**Success Criteria:** Can play 8 simultaneous notes without clipping
|
||||
|
||||
### 2.3 Integration Test
|
||||
|
||||
Create `src-v2/audio/test/apuTest.ts`:
|
||||
|
||||
- Schedule notes on all 8 channels simultaneously
|
||||
- Verify no audio glitches or pops
|
||||
- Test channel busy/free logic
|
||||
- Test master volume control
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: MIDI Intelligence Layer (Week 3-4)
|
||||
|
||||
**Goal:** Smart track analysis and channel assignment for arbitrary MIDIs
|
||||
|
||||
### 3.1 Track Analyzer
|
||||
|
||||
Create `src-v2/audio/midi/TrackAnalyzer.ts`:
|
||||
|
||||
- `analyzeTrack(track)` returns `TrackAnalysis`
|
||||
- Detect drums (channel 9 or percussive patterns)
|
||||
- Calculate note range (min, max, avg pitch)
|
||||
- Calculate note density (notes per second)
|
||||
- Detect chords (simultaneous notes)
|
||||
- Assign role: `drums`, `bass`, `lead`, `harmony`, `pad`, `fx`
|
||||
|
||||
**Analysis Logic:**
|
||||
|
||||
- Drums: channel 9 OR very short notes with low pitch variation
|
||||
- Bass: average pitch < 48 (C3)
|
||||
- Lead: high pitch (>72) with high density (>5 notes/sec)
|
||||
- Pad: low density (<2 notes/sec), long notes
|
||||
- Harmony: medium density with detected chords
|
||||
- FX: very high density (>10 notes/sec)
|
||||
|
||||
### 3.2 Arpeggiator
|
||||
|
||||
Create `src-v2/audio/midi/Arpeggiator.ts`:
|
||||
|
||||
- `arpeggiate(notes, speed)` converts chords to fast note sequences
|
||||
- Group notes by time (10ms tolerance)
|
||||
- Single notes pass through unchanged
|
||||
- Chords (2+ simultaneous notes) → fast arpeggio
|
||||
- Default speed: 1/64 note
|
||||
- Sort chord notes low-to-high
|
||||
- Cycle through chord notes for full duration
|
||||
|
||||
**Success Criteria:** 3-note chord becomes smooth fast arpeggio
|
||||
|
||||
### 3.3 Channel Mapper
|
||||
|
||||
Create `src-v2/audio/midi/ChannelMapper.ts`:
|
||||
|
||||
- `mapTracks(midiTracks)` returns array of `ChannelAssignment`
|
||||
- Analyze all tracks first
|
||||
- Sort by priority (drums > bass > lead > harmony)
|
||||
- Assign intelligently:
|
||||
- Drums → `n1`, `n2` (noise channels)
|
||||
- Bass → `w1` (wave bass preset)
|
||||
- Pads → `w2` (wave pad preset)
|
||||
- Lead → `p1`, `p2` (pulse with sweep, 50% duty)
|
||||
- Harmony → `p3`, `p4` (pulse, 25% duty, arpeggiated)
|
||||
- Mark which tracks need arpeggiator
|
||||
- Specify duty cycle per assignment
|
||||
|
||||
**Priority Calculation:**
|
||||
|
||||
- Drums +30 points
|
||||
- Bass +25 points
|
||||
- Lead +20 points
|
||||
- Note density +up to 20 points
|
||||
- Velocity +up to 10 points
|
||||
|
||||
**Success Criteria:** Mario theme maps melody to pulse, no bass assigned (no bass in song)
|
||||
|
||||
### 3.4 Integration Test
|
||||
|
||||
Create `src-v2/audio/test/mapperTest.ts`:
|
||||
|
||||
- Load test MIDI (simple melody + bass + drums)
|
||||
- Run through analyzer and mapper
|
||||
- Verify drum tracks → noise channels
|
||||
- Verify bass → wave channel
|
||||
- Verify melody → pulse channel
|
||||
- Print channel assignments for inspection
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Main Player & Integration (Week 4)
|
||||
|
||||
**Goal:** Complete end-to-end MIDI → GB audio pipeline
|
||||
|
||||
### 4.1 Game Boy Player
|
||||
|
||||
Create `src-v2/core/GameBoyPlayer.ts`:
|
||||
|
||||
- Main entry point for v2 engine
|
||||
- `async playMIDI(midiBuffer: ArrayBuffer)`
|
||||
- Parse MIDI using existing `src/midi/MIDIParser.ts`
|
||||
- Analyze tracks → assign channels → convert to GB notes
|
||||
- Schedule all notes in APU
|
||||
- `stop()` method resets APU
|
||||
- Return playback info (duration, assignments for UI)
|
||||
|
||||
**Pipeline:**
|
||||
|
||||
1. Parse MIDI → `NoteEvent[]`
|
||||
2. Analyze tracks → `TrackAnalysis[]`
|
||||
3. Map to channels → `ChannelAssignment[]`
|
||||
4. Apply arpeggiator where needed
|
||||
5. Convert to `ChannelNote[]` format
|
||||
6. Schedule in APU
|
||||
|
||||
### 4.2 V2 Types
|
||||
|
||||
Create `src-v2/types/index.ts`:
|
||||
|
||||
- `ChannelNote` interface
|
||||
- `ChannelAssignment` interface
|
||||
- `TrackAnalysis` interface
|
||||
- `ArpNote` interface
|
||||
- GB-specific config types
|
||||
|
||||
### 4.3 Demo Page
|
||||
|
||||
Create `v2.html`:
|
||||
|
||||
- Simple test UI for v2 engine
|
||||
- File upload input for MIDI
|
||||
- Play/stop buttons
|
||||
- Volume slider
|
||||
- Display channel assignments
|
||||
- Show which channels are active (visual)
|
||||
|
||||
Create `src-v2/main.ts`:
|
||||
|
||||
- Wire up UI to `GameBoyPlayer`
|
||||
- Handle file uploads
|
||||
- Display playback state
|
||||
- Show assignment information
|
||||
|
||||
### 4.4 Integration Test
|
||||
|
||||
Test with reference MIDIs:
|
||||
|
||||
- **Mario theme:** Simple melody (should use p1)
|
||||
- **Tetris theme:** Bass + lead (should use w1 + p1)
|
||||
- **Pokémon theme:** Chords (should arpeggiate to p3/p4)
|
||||
- **Hotel California:** Complex (use all 8 channels)
|
||||
|
||||
**Success Criteria:**
|
||||
|
||||
- All test MIDIs sound recognizable
|
||||
- No audio glitches or pops
|
||||
- Drums sound punchy (noise)
|
||||
- Bass sounds solid (wave)
|
||||
- Melody is clear (pulse)
|
||||
- Chords arpeggiate smoothly
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Polish & Optimization (Week 5)
|
||||
|
||||
### 5.1 Performance Optimization
|
||||
|
||||
In `src-v2/audio/apu/APU.ts`:
|
||||
|
||||
- Limit simultaneous notes to 32 total
|
||||
- Implement voice stealing (oldest note first)
|
||||
- Add `onended` cleanup for oscillators
|
||||
- Pre-create reusable nodes where possible
|
||||
|
||||
### 5.2 Browser Compatibility
|
||||
|
||||
In `src-v2/core/GameBoyPlayer.ts`:
|
||||
|
||||
- Add AudioContext resume on user interaction
|
||||
- Handle Safari audio quirks
|
||||
- Add mobile audio unlock
|
||||
- Test on Chrome, Firefox, Safari
|
||||
|
||||
### 5.3 Advanced Features (Nice-to-Have)
|
||||
|
||||
- **Stereo Panning:** GB-style hard L/R/center per channel
|
||||
- **Duty Cycle Switching:** Change duty mid-playback for variation
|
||||
- **Custom Wavetables:** User-editable wave presets
|
||||
- **Export to WAV:** Offline rendering to downloadable file
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Deployment Strategy
|
||||
|
||||
### 6.1 Alpha Testing (Week 6)
|
||||
|
||||
- Deploy v2 to staging URL (e.g., `v2.wario.style` or `wario.style/beta`)
|
||||
- Keep v1 at main URL unchanged
|
||||
- Test with small group (5-10 people)
|
||||
- Gather feedback on authenticity
|
||||
- Fix critical bugs
|
||||
|
||||
### 6.2 Beta Release (Week 7)
|
||||
|
||||
- Deploy to production behind feature flag
|
||||
- Add "Try v2 Beta" button on main site
|
||||
- A/B test user preferences (v1 vs v2)
|
||||
- Monitor performance metrics
|
||||
- Gradual rollout: 10% → 50% → 100%
|
||||
|
||||
### 6.3 Full Release (Week 8)
|
||||
|
||||
- Make v2 the default engine
|
||||
- Keep v1 available as "Classic Mode"
|
||||
- Update README and docs
|
||||
- Social media announcement
|
||||
- Monitor error rates and feedback
|
||||
|
||||
**Rollback Plan:**
|
||||
|
||||
- Feature flag can instantly revert to v1
|
||||
- Maintain "problematic MIDI" database
|
||||
- User preference saved in localStorage
|
||||
|
||||
---
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Web Audio Implementation
|
||||
|
||||
**Key Web Audio APIs:**
|
||||
|
||||
- `PeriodicWave` for duty cycles
|
||||
- `OscillatorNode` for pulse channels
|
||||
- `AudioBufferSourceNode` for wave/noise
|
||||
- `GainNode` for volume/envelopes
|
||||
- `audioContext.currentTime` for precise scheduling
|
||||
|
||||
**Memory Management:**
|
||||
|
||||
```typescript
|
||||
source.onended = () => {
|
||||
source.disconnect()
|
||||
gain.disconnect()
|
||||
}
|
||||
```
|
||||
|
||||
**Latency Target:** <50ms from schedule to sound
|
||||
|
||||
### What Matters vs What Doesn't
|
||||
|
||||
**✅ CRITICAL (Implement):**
|
||||
|
||||
- Exact duty cycle patterns
|
||||
- LFSR noise generation
|
||||
- 4-bit wave quantization
|
||||
- GB frequency formulas
|
||||
- Fast arpeggios
|
||||
- Simple envelopes
|
||||
|
||||
**❌ SKIP (Emulator minutiae):**
|
||||
|
||||
- Length counter edge cases
|
||||
- DIV-APU timing sync
|
||||
- Wave RAM corruption bugs
|
||||
- Sweep overflow quirks
|
||||
- DAC pop suppression
|
||||
- High-pass filter modeling
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
Testing follows a layered approach - technical specs for implementation correctness, community feedback for authenticity.
|
||||
|
||||
### Layer 1: Technical Sanity Checks (Automated, Quick)
|
||||
|
||||
Quick checks that catch implementation bugs:
|
||||
|
||||
- **Waveform visualization** - view duty cycles in browser dev tools or canvas oscilloscope
|
||||
- **LFSR sequence verification** - first 20 values match known GB sequence
|
||||
- **Frequency spot-check** - play A4 (440Hz), verify it's slightly off (~438.5Hz due to GB register rounding)
|
||||
|
||||
Setup time: ~30 minutes. Run on every build.
|
||||
|
||||
### Layer 2: Reference MIDI Corpus (Manual, Essential)
|
||||
|
||||
Core QA loop with 5 test MIDIs:
|
||||
|
||||
| MIDI | What it tests |
|
||||
|------|---------------|
|
||||
| Mario Bros theme | Simple melody on pulse channels |
|
||||
| Tetris theme | Bass + lead separation |
|
||||
| Pokemon battle music | Chord arpeggiation |
|
||||
| Any pop song with drums | Noise channel percussion |
|
||||
| Hotel California | Complex multi-track mapping |
|
||||
|
||||
Process: Run each through v2, listen with headphones, note what sounds wrong.
|
||||
|
||||
### Layer 3: Community Vibe Check (Subjective, Final)
|
||||
|
||||
Post short clips to:
|
||||
|
||||
- r/chiptunes subreddit
|
||||
- Chiptune Café Discord
|
||||
|
||||
Ask: "Does this sound like a Game Boy?"
|
||||
|
||||
Real chiptune people will identify specific issues ("duty cycles wrong", "noise too clean", etc.)
|
||||
|
||||
### What to Skip
|
||||
|
||||
- Automated audio comparison (too complex, diminishing returns)
|
||||
- Cycle-accurate timing tests (emulator territory, not our goal)
|
||||
- Formal A/B studies (overkill for this project)
|
||||
|
||||
### Success Metrics
|
||||
|
||||
- All Layer 1 checks pass
|
||||
- All 5 reference MIDIs sound recognizable
|
||||
- Community feedback: "yes, sounds like GB"
|
||||
- Zero audio glitches or pops
|
||||
- Works on Chrome, Firefox, Safari
|
||||
- <100ms latency
|
||||
|
||||
---
|
||||
|
||||
## File Checklist
|
||||
|
||||
### Core Sound Engine (Phase 1)
|
||||
|
||||
- [ ] `src-v2/audio/synthesis/DutyCycle.ts`
|
||||
- [ ] `src-v2/audio/synthesis/FrequencyCalc.ts`
|
||||
- [ ] `src-v2/audio/synthesis/LFSR.ts`
|
||||
- [ ] `src-v2/audio/synthesis/WaveTable.ts`
|
||||
- [ ] `src-v2/audio/apu/PulseChannel.ts`
|
||||
- [ ] `src-v2/audio/apu/WaveChannel.ts`
|
||||
- [ ] `src-v2/audio/apu/NoiseChannel.ts`
|
||||
- [ ] `src-v2/audio/test/soundTest.ts`
|
||||
|
||||
### APU & Mixing (Phase 2)
|
||||
|
||||
- [ ] `src-v2/audio/apu/APU.ts`
|
||||
- [ ] `src-v2/audio/apu/Mixer.ts`
|
||||
- [ ] `src-v2/audio/test/apuTest.ts`
|
||||
|
||||
### MIDI Intelligence (Phase 3)
|
||||
|
||||
- [ ] `src-v2/audio/midi/TrackAnalyzer.ts`
|
||||
- [ ] `src-v2/audio/midi/Arpeggiator.ts`
|
||||
- [ ] `src-v2/audio/midi/ChannelMapper.ts`
|
||||
- [ ] `src-v2/audio/test/mapperTest.ts`
|
||||
|
||||
### Integration (Phase 4)
|
||||
|
||||
- [ ] `src-v2/core/GameBoyPlayer.ts`
|
||||
- [ ] `src-v2/types/index.ts`
|
||||
- [ ] `src-v2/main.ts`
|
||||
- [ ] `v2.html`
|
||||
|
||||
### Documentation
|
||||
|
||||
- [ ] `docs/GB_SOUND_SPECS.md` (technical reference)
|
||||
- [ ] `docs/V2_ARCHITECTURE.md` (system overview)
|
||||
- [ ] `CHANGELOG_V2.md` (version history)
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements (v3+)
|
||||
|
||||
**Short Term:**
|
||||
|
||||
- User-adjustable duty cycles via UI
|
||||
- Custom wavetable editor
|
||||
- Real-time parameter tweaking
|
||||
- Oscilloscope visualizer
|
||||
- MIDI file upload (not just search)
|
||||
|
||||
**Medium Term:**
|
||||
|
||||
- Frequency sweep on pulse channels
|
||||
- Vibrato effects
|
||||
- Echo/delay using note repeats
|
||||
- Better envelope shaping (ADSR editor)
|
||||
- Recording/export to WAV
|
||||
|
||||
**Long Term:**
|
||||
|
||||
- Full tracker-style sequencer
|
||||
- Multiple retro chips (NES APU, C64 SID)
|
||||
- VST plugin version
|
||||
- Mobile app with touch controls
|
||||
- Collaborative editing
|
||||
|
||||
---
|
||||
|
||||
**Document Version:** 2.0
|
||||
**Last Updated:** January 2026
|
||||
**Status:** Ready for implementation
|
||||
Reference in New Issue
Block a user