Skip to content

matiaszanolli/midi2nes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

98 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

MIDI to NES Compiler

๐ŸŽต 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.

Performance CPU Patterns

โšก Quick Start

One-command MIDI to NES ROM conversion:

python main.py input.mid output.nes

That's it! The compiler handles the entire pipeline automatically:

  1. Fast MIDI Parsing - Optimized parser with 120x performance improvement
  2. Intelligent Channel Mapping - Automatic track-to-NES-channel assignment
  3. Frame Generation - High-accuracy NES audio frame data
  4. Parallel Pattern Detection - Multi-core pattern compression (up to 95x compression)
  5. NES ROM Compilation - Ready-to-run NES ROM file

๐Ÿš€ Performance

Real-World Performance Results

  • 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

Test Results (input.mid - 51KB, 15 tracks)

Implementation Time Status
Original โˆž (timeout) โŒ Failed
Optimized 15 seconds โœ… Success

๐Ÿ“‹ Features

Core Features

  • ๐Ÿƒโ€โ™‚๏ธ 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)

Advanced Features

  • โšก 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

๐ŸŽฎ Usage Examples

Simple ROM Generation

# 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

Advanced Pipeline Control

# 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/

Development and Testing

# 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

๐Ÿ”ง Installation

Prerequisites

  • Python 3.8 or higher
  • CC65 toolchain (for NES ROM compilation)
  • Required Python packages (install via requirements.txt)

Quick Install

# 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/

๐Ÿ–ฅ๏ธ Multiprocessing

How It Works

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

Performance Scaling

  • 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

System Requirements

  • 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

๐ŸŽฏ Pattern Detection

Advanced Compression

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

Example Output

๐Ÿ“ˆ Found 19,285 candidate patterns
๐Ÿ” Selected 23 optimal patterns
๐Ÿ“ฆ Compression ratio: 95.86x

๐ŸŽผ Supported Formats

Input Formats

  • MIDI Files (.mid, .midi) - Standard MIDI format
  • All MIDI Types - Format 0, 1, and 2 supported
  • Complex Files - Multi-track, tempo changes, large files

Output Formats

  • 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

๐Ÿ“Š Performance Benchmarks

File Size Performance

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

Real-World Examples

  • Simple melodies: <1 second total processing
  • Complex orchestral: 15-30 seconds with high compression
  • Game soundtracks: Optimal pattern detection and ROM generation

๐Ÿ› Debug Tools

MIDI2NES includes a comprehensive suite of debugging and analysis tools to help troubleshoot conversion issues and analyze output quality.

Quick Debug Commands

# 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_analyzer

Available Debug Tools

  • audio_checker: APU pattern validation in NES ROMs
  • pattern_analysis: Pattern detection result analysis
  • ca65_inspector: Assembly output inspection
  • frame_analyzer: Frame generation debugging
  • music_structure_analyzer: Comprehensive ROM music analysis
  • pattern_reference_debugger: Pattern reference table analysis
  • performance_analyzer: MIDI parser performance testing
  • rom_tester: Complete pipeline validation

Programmatic Usage

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.

๐Ÿ› ๏ธ Development

Architecture

๐Ÿ“ 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

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Run the test suite: python -m pytest
  4. Submit a pull request

Testing

# Run all tests
python -m pytest

# Run performance tests
python test_input_performance.py

# Test ROM generation
python test_rom_generation.py

๐Ÿ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿค Acknowledgments

  • NES development community for technical documentation
  • CC65 development team for the excellent toolchain
  • Contributors and testers who helped optimize performance

๐Ÿ”— Links

About

Convert MIDI files to NES assembly code.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •