Improve your drumming timing! A Python tool that analyzes MIDI drum recordings and measures timing precision against a perfect grid. Helps you identify which drums need timing work and suggests optimal quantization settings.
β¨ Timing Analysis: Measures how far each hit is from perfect timing (in milliseconds)
π Scoring System: 0-100 score per drum (Excellent/Good/Acceptable/Needs Work/Poor)
π΅ Two Analysis Modes: Grid-based (absolute timing) and Groove-aware (consistency)
πΈ Auto Grid Detection: Tests multiple grids (16th, triplets, 8th, etc.) to find best fit
π― Quantization Advisor: Suggests Logic Pro settings for best results
π Progress Tracking: Compare before/after quantization to see improvement
# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txtAnalyze multiple MIDI files with a visual interface:
./start.shThis will start:
- Backend API on http://localhost:8000
- Web UI on http://localhost:5173
The web interface lets you:
- View all MIDI files in the
mid-filesfolder - See timing analysis results in a table
- Top 5 drums displayed with timing error and score
- Refresh to scan for new files
- Configure the MIDI folder path
Analyze individual files:
python -m audio your_drums.midOutput:
MIDI Drum Analysis: your_drums.mid
Duration: 180.5s
Tempo: 120.0 BPM
Total Drum Hits: 842
TIMING QUALITY ANALYSIS
Drum Score Rating Error Hits
------------------------------------------------------------
Bass Drum 1 60.8 Acceptable 30.4ms 440 β
Acoustic Snare 59.2 Acceptable 31.4ms 270 β
Closed Hi-Hat 59.8 Acceptable 31.1ms 473 β
Not sure what quantization to use in your DAW?
python suggest_quantize.py your_drums.midOutput:
π΅ MUSICAL FIT (what the song is written in):
Primary: 16th notes (1/16) - 30.70ms error
Also try: 16th note triplets (1/16T)
β‘ TECHNICAL BEST (tightest possible fit):
Grid: 32nd notes (1/32) - 15.55ms error
π Logic Pro Settings:
1. Select all MIDI notes (Cmd+A)
2. Press 'Q' or go to: Edit β Quantize
3. Set Grid: 1/16
4. Set Q-Strength: 80-100%
5. Apply
# Edit compare_files.py to set your files
python compare_files.pyExample Results:
UNQUANTIZED:
Bass Drum: 30.40ms β Score 60.8 (Acceptable)
Snare: 31.41ms β Score 59.2 (Acceptable)
QUANTIZED:
Bass Drum: 0.43ms β Score 99.1 (Excellent) β
Snare: 0.10ms β Score 99.8 (Excellent) β
Measures absolute timing - how close each hit is to a perfect quantized grid.
Best for:
- Validating quantized MIDI files
- Comparing before/after quantization
- Studio work requiring strict tempo adherence
- Click track practice and timing drills
Example: If your kick drum hits 30ms after the grid, you get 30ms error.
Measures timing consistency - how consistently you maintain your groove, even if it's slightly ahead/behind the grid.
Best for:
- Evaluating real human performances
- Identifying true timing problems vs. intentional feel
- Analyzing laid-back or pushed grooves
- Understanding timing stability
Example: If all your kicks are 30ms late but consistent (Β±5ms variation), you get a high score because your groove is stable.
Key Difference: Grid-based penalizes any offset from the grid. Groove-aware first detects your natural groove offset, then measures consistency around that groove.
In Web UI: Click the π΅ Groove-Aware or π Grid-Based button at the top. This re-analyzes all files.
In CLI: Use the --mode flag:
python -m audio your_drums.mid --mode groove-aware
python -m audio your_drums.mid --mode grid-based| Score | Rating | Avg Error | What It Means |
|---|---|---|---|
| 90-100 | Excellent | <10ms | Pro studio level (accounts for e-drum latency) |
| 70-89 | Good | 10-20ms | Professional live playing, tight timing |
| 40-69 | Acceptable | 20-35ms | Solid playing with human feel |
| 20-39 | Needs Work | 35-50ms | Noticeable looseness, practice recommended |
| 0-19 | Poor | >50ms | Objectively problematic timing |
Real-world expectations:
- E-drum recordings: 25-35ms typical (Acceptable) β includes 5-10ms system latency
- Professional drummers: 10-20ms on acoustic kits (Good)
- Quantized MIDI: <10ms (Excellent)
- Perfect quantization: <1ms (Excellent, 99+ score)
Note: Thresholds calibrated based on research showing professional drummers typically deviate 10-20ms in real performances, and e-drum systems add 5-10ms inherent latency.
./start.shLaunches the web interface for analyzing multiple files at once. See all your MIDI files with their timing analysis in a visual table.
Manual startup:
# Terminal 1 - Backend
source venv/bin/activate
python api_server.py
# Terminal 2 - Frontend
cd web-ui
npm run devpython -m audio <midi_file.mid>Full timing analysis with scores per drum type.
Filter by specific drum:
python -m audio <midi_file.mid> --details "Acoustic Snare"
python -m audio <midi_file.mid> --details "Bass Drum 1"Shows detailed analysis for only one drum (useful for focused practice).
python suggest_quantize.py <midi_file.mid>Suggests best DAW quantization settings.
python compare_files.pyCompare two files side-by-side (edit script to set file paths).
python debug_timing.py # Quick overview of one file
python debug_detailed.py # Beat-by-beat analysis- Record your drums in your DAW β Export as MIDI
- Analyze:
python -m audio my_drums.mid - Get advice:
python suggest_quantize.py my_drums.mid - Quantize in DAW using suggested settings
- Export quantized version β
my_drums_quantized.mid - Compare: Edit
compare_files.pyand run to see improvement - Practice the parts that scored lowest!
- All GM Drum Notes: Bass drums, snares, toms, hi-hats, cymbals
- Timing Precision: Deviation from grid in milliseconds
- Grid Detection: Auto-detects 32nd, 16th triplets, 16th, 8th triplets, 8th, quarter notes
- Tempo Changes: Handles tempo changes within the file
- Musical Structure: Works with real songs (handles breaks, fills, interludes)
- Each hit compared to nearest grid position
- Modulo-based positioning handles files starting at any beat
- Tempo map tracking across all MIDI tracks
- Sub-millisecond precision for validation
- Detects your natural groove offset using 8-16 stable hits from the middle of the performance
- Uses median for outlier resistance (skips first/last 10% of song)
- Measures consistency with IQR (interquartile range) - robust statistic
- Identifies outliers using Tukey's fences (hits >1.5ΓIQR from groove)
- Priority drums: Bass Drum 1 > Acoustic Snare > Closed Hi-Hat (most stable)
Algorithm:
- Find most consistent drum type (lowest IQR, 16+ hits required)
- Extract middle stable region (skip intros/outros)
- Calculate median offset from grid (your groove)
- Subtract groove offset from all hits
- Measure consistency (IQR) and score based on tightness
Metrics:
- Groove Offset: How far your natural groove is from the grid (Β±ms)
- IQR: Interquartile range showing timing consistency (lower = tighter)
- Outlier %: Percentage of hits significantly outside your groove
- Consistency Rating: Tight (<10ms IQR), Good (<20ms), Fair (<30ms), Loose (β₯30ms)
"All my scores are poor even after quantization"
- Make sure you exported the MIDI after quantizing in your DAW
- Check that quantization was actually applied (not just preview)
"The suggested grid doesn't match my song"
- Use the "Musical Fit" recommendation, not "Technical Best"
- Try both straight and triplet versions to hear which sounds right
"Beat positions show huge numbers (>1000)"
- This is normal! MIDI files can have silence before drums start
- The analyzer handles this automatically with modulo math
# Install in development mode
pip install -e .
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black audio/
# Lint
ruff check audio/- README.md (this file) - User guide
- WEB_UI.md - Web interface documentation
- GROOVE_AWARE_ANALYSIS.md - Technical details on groove-aware analysis
- AGENTS.md - Architecture and design decisions
- DEVELOPMENT_SUMMARY.md - Complete development history
MIT License - Feel free to use and modify!
Built with: Python 3.8+, mido (MIDI parsing), numpy (statistics)
Works with: Logic Pro, Ableton, FL Studio, any DAW that exports MIDI