๐ต High-performance MIDI to NES ROM compiler with advanced pattern detection and multiprocessing optimization
Convert MIDI files into playable NES ROMs or use the generated audio data in homebrew NES games and music applications.
One-command MIDI to NES ROM conversion:
python main.py input.mid output.nesThat's it! The compiler handles the entire pipeline automatically:
- Fast MIDI Parsing - Optimized parser with 120x performance improvement
- Intelligent Channel Mapping - Automatic track-to-NES-channel assignment
- Frame Generation - High-accuracy NES audio frame data
- Parallel Pattern Detection - Multi-core pattern compression (up to 95x compression)
- NES ROM Compilation - Ready-to-run NES ROM file
- 120+ times faster than previous versions
- Multi-core processing using all available CPU cores
- Complex MIDI files (51KB, 15 tracks, 13,362 events) processed in ~15 seconds
- Pattern compression achieving up to 95.86x compression ratios
- Smart sampling for very large files with quality preservation
| Implementation | Time | Status |
|---|---|---|
| Original | โ (timeout) | โ Failed |
| Optimized | 15 seconds | โ Success |
- ๐โโ๏ธ High-performance MIDI parsing with optimized algorithms
- ๐ง Intelligent channel mapping with priority system
- ๐ฏ Accurate NES pitch tables with per-channel processing
- ๐ ADSR envelope processing for pulse channels
- ๐ Multiple duty cycle patterns for rich sound
- ๐๏ธ Advanced pattern detection with multiprocessing
- ๐ค Multiple export formats (CA65, NSF, FamiTracker)
- โก Parallel processing utilizing all CPU cores
- ๐ผ Multi-song support with bank switching
- ๐ Segment management for complex compositions
- โฑ๏ธ Enhanced tempo handling with accurate timing
- ๐ Pattern and loop point support
- ๐ฅ Drum mapping and DPCM support
- ๐ Visual progress bars with real-time speed and completion tracking
- ๐ก๏ธ Graceful fallback for compatibility
# Convert MIDI directly to NES ROM
python main.py song.mid
# Creates: song.nes (ready to play on emulators)
# Specify output filename
python main.py song.mid my_game.nes# Step-by-step processing for debugging/customization
python main.py parse input.mid parsed.json
python main.py map parsed.json mapped.json
python main.py frames mapped.json frames.json
python main.py detect-patterns frames.json patterns.json
python main.py export frames.json output.s --format ca65 --patterns patterns.json
python main.py prepare output.s nes_project/# Fast parsing only (for development)
python tracker/parser_fast.py input.mid output.json
# Run performance benchmarks
python main.py benchmark run input.mid
# Configuration management
python main.py config init my_config.yaml
python main.py config validate my_config.yaml
# Song bank management
python main.py song add input.mid --bank my_songs.json --name "My Song"
python main.py song list my_songs.json- Python 3.8 or higher
- CC65 toolchain (for NES ROM compilation)
- Required Python packages (install via requirements.txt)
# Clone the repository
git clone https://github.com/matiaszanolli/midi2nes.git
cd midi2nes
# Install dependencies
pip install -r requirements.txt
# Install CC65 toolchain
# macOS:
brew install cc65
# Ubuntu/Debian:
sudo apt-get install cc65
# Windows: Download from https://cc65.github.io/The MIDI2NES compiler automatically detects your system's CPU cores and distributes pattern detection work across multiple processes:
๐ Starting parallel pattern detection with 7 workers
๐ง Created 236 work chunks for parallel processing
Processing pattern chunks: 100%|โโโโโโโโโโโโ| 236/236 [00:12<00:00, 19.2chunk/s, patterns=5505]
๐ Found 5505 candidate patterns
โ
Parallel pattern detection completed in 12.49s
- Single-core: Traditional processing (legacy compatibility)
- Multi-core: Automatic work distribution across all CPU cores
- Large files: Smart sampling maintains quality while ensuring reasonable processing times
- Fallback safety: Graceful degradation if multiprocessing fails
- Minimum: Single-core system (fallback mode)
- Recommended: Multi-core CPU for optimal performance
- Memory: 1GB+ RAM for large MIDI files
- Storage: Minimal disk space for temporary files
The parallel pattern detection system identifies and compresses repeating musical patterns:
- Pattern Recognition: Finds exact and transposed musical phrases
- Variation Detection: Handles pitch shifts and volume changes
- Compression Scoring: Optimizes for NES memory constraints
- Non-overlapping Selection: Ensures optimal pattern selection
๐ Found 19,285 candidate patterns
๐ Selected 23 optimal patterns
๐ฆ Compression ratio: 95.86x
- MIDI Files (.mid, .midi) - Standard MIDI format
- All MIDI Types - Format 0, 1, and 2 supported
- Complex Files - Multi-track, tempo changes, large files
- NES ROM (.nes) - Ready-to-run NES ROM files
- CA65 Assembly (.s) - For integration with NES projects
- NSF Audio (.nsf) - NES Sound Format for music playback
- FamiTracker (.txt) - Import into FamiTracker editor
| File Size | Events | Processing Time | Pattern Detection |
|---|---|---|---|
| Small (<1KB) | <100 | <1s | Instant |
| Medium (1-10KB) | 100-1K | 1-5s | <5s |
| Large (10-50KB) | 1K-10K | 5-15s | 5-15s |
| Very Large (50KB+) | 10K+ | 15-30s | Smart sampling |
- Simple melodies: <1 second total processing
- Complex orchestral: 15-30 seconds with high compression
- Game soundtracks: Optimal pattern detection and ROM generation
MIDI2NES includes a comprehensive suite of debugging and analysis tools to help troubleshoot conversion issues and analyze output quality.
# Check audio patterns in generated ROM
python -m debug.audio_checker output.nes
# Analyze pattern compression effectiveness
python -m debug.pattern_analysis output/patterns
# Examine music structure in ROM
python -m debug.music_structure_analyzer output.nes
# Test ROM generation pipeline
python -m debug.rom_tester
# Performance analysis of MIDI parsing
python -m debug.performance_analyzeraudio_checker: APU pattern validation in NES ROMspattern_analysis: Pattern detection result analysisca65_inspector: Assembly output inspectionframe_analyzer: Frame generation debuggingmusic_structure_analyzer: Comprehensive ROM music analysispattern_reference_debugger: Pattern reference table analysisperformance_analyzer: MIDI parser performance testingrom_tester: Complete pipeline validation
from debug import (
check_audio_simple,
analyze_patterns,
test_rom_generation
)
# Validate ROM audio patterns
check_audio_simple("output.nes")
# Run full test suite
success = test_rom_generation()For detailed debug tool documentation, see debug/README.md.
๐ midi2nes/
โโโ ๐ต tracker/ # Core MIDI processing
โ โโโ parser_fast.py # Optimized MIDI parser
โ โโโ pattern_detector_parallel.py # Multi-core pattern detection
โ โโโ tempo_map.py # Advanced tempo handling
โโโ ๐ฎ nes/ # NES-specific components
โโโ ๐ค exporter/ # Output format generators
โโโ ๐ง config/ # Configuration management
โโโ ๐ debug/ # Debugging and analysis tools
โ โโโ audio_checker.py # ROM audio validation
โ โโโ pattern_analysis.py # Pattern compression analysis
โ โโโ performance_analyzer.py # MIDI parser benchmarking
โ โโโ rom_tester.py # Complete pipeline testing
โโโ ๐ benchmarks/ # Performance testing
- Fork the repository
- Create a feature branch
- Run the test suite:
python -m pytest - Submit a pull request
# Run all tests
python -m pytest
# Run performance tests
python test_input_performance.py
# Test ROM generation
python test_rom_generation.pyThis project is licensed under the MIT License - see the LICENSE file for details.
- NES development community for technical documentation
- CC65 development team for the excellent toolchain
- Contributors and testers who helped optimize performance