A web-based pedagogical music game designed for practicing instrument intonation and rhythm. Players can upload MIDI files to generate game tiles, control playback speed, and use real instruments (via microphone) to play the game.
- ✅ MIDI File Upload - Supports standard MIDI file formats (.mid, .midi)
- ✅ MusicXML File Upload - Supports MusicXML format (.musicxml, .xml) with explicit tie handling
- ✅ Real-time Pitch Detection - Play your real instrument to hit the notes
- ✅ Microphone Integration - Detects pitch directly from your instrument
- ✅ Speed Control - Adjustable playback speed from 0.5x to 2.0x
- ✅ Falling Notes - Classic rhythm game visual experience
- ✅ Judgment System - Perfect/Good/Miss judgment based on timing and pitch accuracy
- ✅ Score Statistics - Real-time display of score, combo, and accuracy
- ✅ Pitch Preview - Listen to the pitch of the first note before starting
- Node.js (v18.0.0 or higher)
-
Clone the repository:
git clone https://github.com/maxchanhi/instrument-tiles.git cd instrument-tiles -
Install dependencies:
npm install
-
Start the server:
npm start
-
Visit
http://localhost:3000(or the port specified in your console) to play!
- Upload MIDI File - Click the "Upload MIDI File" button to select your MIDI file.
- Connect Microphone - Click "Connect Mic" to enable pitch detection.
- Preview Pitch - (Optional) Click "Preview Pitch" to hear the starting note.
- Adjust Speed - Use the slider to set a comfortable practice speed.
- Tile Duration - Adjust how long the notes appear visually.
- Start Game - Click the "Start Game" button.
- Sustain Your Pitch - When a note hits the red judgment line, play and hold the corresponding pitch on your instrument for the entire tile duration to get a PERFECT HOLD!
- Feedback - Watch for visual feedback and your score.
- Node.js & Express - Backend server
- HTML5 Canvas - Game rendering with "Neon Symphony" theme
- Web Audio API - Pitch detection and audio synthesis
- Native JavaScript - Core game logic
- CSS3 - Modern UI with glassmorphism and neon effects
music_game/
├── index.html # Main entry page
├── style.css # Stylesheet
├── game.js # Core game logic
├── pitch-detector.js # Microphone pitch detection logic
├── midi-parser.js # MIDI file parsing logic
├── musicxml-parser.js # MusicXML file parsing logic
└── README.md # Documentation
The fingering display feature interface is reserved. Once fingering data is ready, it can be added via:
// Set fingering data
game.setFingeringData({
"C4": "Fingering diagram or description",
"D4": "Fingering diagram or description",
// ...
});Fingering data can include:
- Fingering charts/images
- Text descriptions
- Fingering animations
You can adjust game parameters directly in the UI or in game.js:
- Speed - Playback speed slider (0.2x to 2.0x, default 1.0x)
- Note Speed - Tile falling speed (pixels/sec, default 150)
- Tile Duration - Display duration of tiles (beats)
- Count-In Beats - Number of metronome beats before playback starts (default 2, auto-adjusts for compound time)
- Tuning Offset - Pitch detection tuning offset in cents
In compound time signatures (6/8, 9/8, 12/8), the BPM control automatically adapts to represent dotted quarter note beats per minute (♩.), not quarter notes (♩). The label next to the BPM input shows which beat unit is active.
| Rating | Sustain % | Points |
|---|---|---|
| PERFECT | ≥ 80% | 150 |
| GOOD | ≥ 50% | 75 |
| OK | ≥ 5% | 25 |
| MISS | < 5% | 0 |
Short notes (< 0.3s duration) are judged on pitch only — any hold is PERFECT, no hold is MISS.
- Canvas height auto-adjusts: 45vh on tablets, 40vh on phones, 35vh on very small screens
- Tile minimum width: 2px (ensures visibility on narrow screens)
| Note | Color |
|---|---|
| C | Red |
| D | Orange |
| E | Yellow |
| F | Green |
| G | Light Blue |
| A | Dark Blue |
| B | Purple |
Sharp/flat variants use darker shades of the natural note color.
Happy Practicing! 🎶