Practical tools and curated content for hardware synth users:
- Generate, analyze, and send complete 128‑program banks (Korg MS2000)
- Decode, edit, and transmit Roland JP-8080/JP-8000 patches and bulk dumps
- Prototype and iterate on custom sound-design banks
- Decode and export factory banks for inspection and tooling
New in v1.3.0
Offset‑64 parameters now round-trip exactly (pan, modulation depths, patch intensities) thanks to dedicated helpers in the encoder/decoder.
- Send banks to hardware quickly (single or full bank)
- Generate custom banks from code (factories, experiments, internal projects)
- Analyze banks (FX usage, arp, naming, summary stats) and export JSON
- Inspect and modify patches at the byte level if needed
Located in docs/general/:
-
LEARNING_SUMMARY.md - Complete educational guide
- MIDI fundamentals and protocol
- System Exclusive (SysEx) message structure
- 7-to-8 bit encoding schemes
- Practical decoding techniques
- Real-world analysis examples
-
QUICK_REFERENCE.md - Fast-lookup reference
- MIDI message tables
- Manufacturer IDs
- Control Change (CC) mappings
- Bit manipulation formulas
- Common code snippets
Complete SysEx workflow for Korg MS2000: generator, decoder, analyzer, sender.
Location: implementations/korg/ms2000/
Highlights for sound designers:
- Banks ready to send:
- Factory:
implementations/korg/ms2000/patches/factory/FactoryBanks.syx
- Factory:
- Robust 7→8 encoding (variant v2) and offset‑64 handling, hardware-verified in v1.3.0
- Tools for compare, analyze, JSON export, and single-program dumps ship with matching CLI wrappers
Quick Start:
cd implementations/korg/ms2000/tools
python3 decode_sysex.py ../patches/factory/FactoryBanks.syxSee MS2000 README for full documentation.
- Full SysEx decoder/encoder for JP-8080 with compatibility layer for JP-8000 multi-packet exports
- Handles dual-message JP-8080 patches and stitches JP-8000 segments into JP-8080-safe payloads
- Analyze, copy, extract-from-bulk, and send patches via the shared
tools/send_sysex.py
midi-sysex-learning/
├── README.md # This file
├── LICENSE # MIT License
├── .gitignore # Git ignore rules
│
├── docs/ # General documentation
│ └── general/
│ ├── LEARNING_SUMMARY.md # Complete MIDI/SysEx tutorial
│ └── QUICK_REFERENCE.md # Quick lookup tables
│
└── implementations/ # Device-specific implementations
├── korg/ # Korg manufacturer
│ └── ms2000/ # MS2000 synthesizer
│ ├── README.md # MS2000-specific documentation
│ ├── docs/ # Technical specifications
│ ├── tools/ # Python tools
│ ├── patches/ # SysEx patch files
│ └── examples/ # Example outputs
└── roland/
└── jp-8080/ # JP-8080/JP-8000 synthesizers
├── README.md # JP-specific documentation
├── docs/ # Technical specifications
├── tools/ # Python tools
├── patches/ # (factory presets TBD)
└── examples/ # Example outputs and dumps
- Python 3.7 or higher
- No external dependencies for decoding/analysis (uses standard library only)
- Sending SysEx requires:
pip install mido python-rtmidi
Clone the repository:
git clone https://github.com/yourusername/midi-sysex-learning.git
cd midi-sysex-learning1. Learn MIDI fundamentals:
# Read the learning guide
cat docs/general/LEARNING_SUMMARY.md2. Decode a SysEx file (Factory, MS2000 example):
python3 implementations/korg/ms2000/tools/ms2000_cli.py \
inspect implementations/korg/ms2000/patches/factory/FactoryBanks.syx --limit 83. Decode and analyze a JP-8080/JP-8000 patch:
python3 implementations/roland/jp-8080/tools/jp8080_cli.py \
inspect implementations/roland/jp-8080/examples/wc_olo_garb_jp8080.syx4. Compare two patch banks (MS2000 example):
python3 implementations/korg/ms2000/tools/ms2000_cli.py compare file1.syx file2.syx5. Encode JSON back to .syx (optional, MS2000 example):
python3 implementations/korg/ms2000/tools/ms2000_cli.py encode \
implementations/korg/ms2000/examples/factory_banks.json \
/tmp/factory_roundtrip.syx --template implementations/korg/ms2000/patches/factory/FactoryBanks.syx6. Send a SysEx file to hardware (all synths):
# List MIDI outputs
python3 tools/send_sysex.py --list-outputs
# Send a .syx file (requires 'mido' + 'python-rtmidi')
python3 tools/send_sysex.py \
--file implementations/roland/jp-8080/examples/wc_olo_garb_jp8080.syx \
--out "JP-8080" --delay-ms 50For newcomers to MIDI and SysEx, we recommend this progression:
-
Start with basics → LEARNING_SUMMARY.md
- Read sections 1-2 (MIDI Fundamentals, SysEx Messages)
- Understand the 7-bit limitation and why encoding is needed
-
Study a real implementation → MS2000 Implementation
- Examine the SysEx file structure
- Run the decoder on factory patches
- Study the decoded output
-
Deep dive → Read the decoder source code
decode_sysex.py- Understand 7-to-8 bit decoding algorithm
- See how patch parameters are extracted
-
Reference as needed → QUICK_REFERENCE.md
- Look up message formats
- Find bit manipulation formulas
- Check manufacturer IDs
- ✅ MIDI protocol fundamentals (status/data bytes, channels, messages)
- ✅ System Exclusive (SysEx) message structure and purpose
- ✅ Manufacturer-specific implementations
- ✅ Binary data encoding schemes (7-to-8 bit packing)
- ✅ Hexadecimal and binary number systems
- ✅ File format analysis and reverse engineering
- ✅ Building practical MIDI tools in Python
- Backup and organize synthesizer patches
- Analyze factory presets to learn sound design
- Share patch banks with collaborators
- Archive sounds from specific projects
- Build patch librarian applications
- Create automated testing tools
- Develop patch editors with GUIs
- Implement MIDI-to-audio renderers
- Teach synthesis and MIDI concepts
- Demonstrate data encoding techniques
- Show real-world protocol implementation
- Provide hands-on learning materials
- Study parameter distributions in sound banks
- Analyze relationships between parameters and timbre
- Extract features for machine learning
- Document vintage equipment specifications
One of the key concepts demonstrated in this project is Korg's 7-to-8 bit encoding:
def decode_korg_7bit(encoded_data):
"""
MIDI restricts data bytes to 0-127 (bit 7 = 0).
To transmit 8-bit data (0-255), Korg packs:
- 7 bytes of 8-bit data → 8 bytes of 7-bit MIDI data
- First byte contains MSBs (bit 7) of next 7 bytes
- Remaining 7 bytes contain lower 7 bits
"""
decoded = bytearray()
i = 0
while i + 8 <= len(encoded_data):
msb_byte = encoded_data[i]
for j in range(7):
lower_7 = encoded_data[i + 1 + j] & 0x7F
# Note: hardware here uses variant v2 (MSB of byte j in bit j)
msb = (msb_byte >> (6 - j)) & 0x01
full_byte = (msb << 7) | lower_7
decoded.append(full_byte)
i += 8
return bytes(decoded)This adds ~14.3% overhead while maintaining MIDI compatibility.
Contributions are welcome! Here are some ideas:
- Add support for other synthesizers (Roland, Yamaha, Sequential, etc.)
- Implement bidirectional MIDI communication
- Create real-time parameter editors
- Add more visual diagrams
- Create video tutorials
- Translate to other languages
- Document additional MIDI features (NRPN, MPE, etc.)
- Build GUI applications
- Add patch randomization/generation
- Implement parameter interpolation
- Create audio feature to parameter mapping
- Add unit tests for decoder
- Test with more SysEx files
- Validate against hardware
This project is licensed under the MIT License - see LICENSE file for details.
Important Notes:
- Educational documentation and tools: MIT License (open source)
- Device specifications: Property of respective manufacturers (educational use)
- Factory patches: Property of manufacturers (archival/educational purposes)
- Custom/commercial patches: Respect original licensing
- MIDI Specification - MIDI Manufacturers Association
- Korg - MS2000 MIDI Implementation documentation
- Roland - JP-8000/JP-8080 MIDI implementation documentation
- Sound on Sound - Educational articles on SysEx
- Open source community - Python, Git, and various tools
- MIDI Association - Official MIDI specs and resources
- MIDI 1.0 Specification
- MIDI Implementation Chart Guide
- This project's Learning Summary
- python-rtmidi - Python MIDI I/O
- mido - MIDI objects for Python
- SendMIDI/ReceiveMIDI - Command-line MIDI tools
- ✅ Complete MIDI/SysEx educational documentation
- ✅ Korg MS2000 implementation with tools
- ✅ Roland JP-8080/JP-8000 implementation with tools
- ✅ 7-to-8 bit encoding/decoding
- ✅ Patch parameter extraction (partial)
- ⬜ Complete MS2000 parameter decoder (all 254 bytes)
- ⬜ Add more synthesizer implementations
- ⬜ GUI patch editor
- ⬜ Bidirectional MIDI communication
- ⬜ MIDI 2.0 support
- ⬜ Interactive web-based tools
- Issues: Use GitHub Issues for bugs and feature requests
- Discussions: For questions and discussions
- Pull Requests: Welcome! Please follow existing code style
Made with ❤️ for the MIDI and synthesizer community
Learn by doing. Understand by building.