MIDI 2.0 Patch Selection Application
Project description
R2MIDI - MIDI 2.0 Patch Selection Application
R2MIDI is a modern application for managing and selecting MIDI patches across various devices. It provides a user-friendly interface for musicians and producers to quickly select and send MIDI program changes to their hardware.
Features
- Device Management: Automatically detects and manages MIDI devices
- Patch Selection: Browse and select patches/presets from your devices
- MIDI Control: Send program changes and bank select messages to your MIDI devices
- Multi-Device Support: Control multiple MIDI devices simultaneously
- Sequencer Integration: Optional routing to a sequencer port
- User-Friendly Interface: Clean, intuitive GUI for easy navigation
Installation
https://pypi.org/project/r2midi or as described below.
Prerequisites
- Python 3.8 or higher
- SendMIDI command-line tool
- MIDI devices connected to your computer
Installation Steps
-
Clone the repository:
git clone https://github.com/tirans/r2midi.git cd r2midi
-
Install dependencies:
pip install -r requirements.txt
Or using the pyproject.toml:
pip install -e .
Configuration
Environment Variables
Create a .env file in the project root with the following variables:
PORT=7777 # The port for the API server (default: 7777)
Device Configuration
Device definitions are stored as JSON files in the devices folder. Each device file should follow this format:
{
"name": "Device Name",
"midi_ports": {
"main": "MIDI Port Name",
"alternate": "Alternative MIDI Port Name"
},
"midi_channels": {
"main": 1,
"alternate": 2
},
"presets": [
{
"preset_name": "Preset 1",
"category": "Category",
"characters": ["warm", "bright"],
"cc_0": 0,
"pgm": 1
},
{
"preset_name": "Preset 2",
"category": "Another Category",
"characters": ["dark", "deep"],
"cc_0": 0,
"pgm": 2
}
]
}
An example device file for the Expressivee Osmose is included in the devices folder.
Usage
Starting the Application
Run the main application:
python main.py
This will:
- Start the API server on the configured port (default: 7777)
- Scan for connected MIDI devices
- Launch the GUI client
Using the GUI
The GUI is divided into two main panels:
Device Panel (Top)
- MIDI Output Port: Select the MIDI port to send commands to
- MIDI Channel: Select the MIDI channel (1-16)
- Sequencer Port: Optionally select a secondary port to send the same commands to (useful for recording in a DAW)
Patch Panel (Bottom)
- Browse patches by category
- Search for patches by name
- Select a patch to send to the device
Sending MIDI Commands
- Select a MIDI output port and channel in the Device Panel
- Select a patch in the Patch Panel
- Click the "Send MIDI" button to send the program change to your device
API Endpoints
The application provides a REST API that can be used by other applications:
GET /devices- Get a list of all devicesGET /patches- Get a list of all patchesGET /midi_port- Get a list of available MIDI portsPOST /preset- Send a preset to a MIDI port/channel
Example API usage with curl:
# Get all devices
curl http://localhost:7777/devices
# Get all patches
curl http://localhost:7777/patches
# Get MIDI ports
curl http://localhost:7777/midi_port
# Send a preset
curl -X POST http://localhost:7777/preset \
-H "Content-Type: application/json" \
-d '{"preset_name": "Preset Name", "midi_port": "MIDI Port Name", "midi_channel": 1}'
Development
Project Structure
main.py- Main entry point and API serverdevice_manager.py- Handles device scanning and managementmidi_utils.py- MIDI utility functionsmodels.py- Data modelsui_launcher.py- Launches the GUI clientversion.py- Contains the current version of the applicationpre-commit- Git hook script to increment version on commitmidi_patch_client/- GUI client applicationmain.py- Client entry pointapi_client.py- Client for the APImodels.py- Client-side data modelsui/- UI componentsmain_window.py- Main windowdevice_panel.py- Device selection panelpatch_panel.py- Patch selection panel
Running Tests
To run the tests:
# Install test dependencies
pip install -e ".[test]"
# Run all tests
pytest tests/
# Run with coverage
pytest --cov=. tests/
Troubleshooting
Common Issues
1No MIDI devices detected
- Check that your MIDI devices are connected and powered on
- Some devices may require specific drivers
2UI client fails to start
- Check the logs in the
logsdirectory for error messages - Ensure PyQt6 is properly installed
Logs
Logs are stored in the logs directory:
main.log- Main application logsdevice_manager.log- Device manager logsmidi_utils.log- MIDI utility logsui_launcher.log- UI launcher logsuvicorn.log- Web server logsall.log- Combined logs from all components
License
Version Management
The application version is stored in version.py and is automatically incremented on each push to the master branch using GitHub Actions.
How Version Incrementing Works
The version incrementing is handled by the GitHub Actions workflow defined in .github/workflows/python-package.yml. When code is pushed to the master branch, the workflow:
- Builds and tests the application
- Increments the patch version (the third number in the version)
- Updates both
version.pyandpyproject.tomlwith the new version - Commits and pushes the version changes back to the repository
- Creates a GitHub release with the new version
- Publishes the package to PyPI
For example, if the current version is 0.1.0, after a push to master it will be 0.1.1.
Manual Version Updates
For major or minor version updates (first or second number), manually edit the version.py and pyproject.toml files before pushing to master. The GitHub Actions workflow will still handle creating the release and publishing to PyPI.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Note: You don't need to worry about incrementing the version number. This is handled automatically by GitHub Actions when your changes are merged to the master branch.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file r2midi-0.1.6.tar.gz.
File metadata
- Download URL: r2midi-0.1.6.tar.gz
- Upload date:
- Size: 23.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74671e00b1e85c2643337b69e966aa1b186d873d9b563185b91789de1cec6895
|
|
| MD5 |
b08964825a1dd95ea5c67d561f1e458f
|
|
| BLAKE2b-256 |
d5db4a1213f015d195cf70d57f4295d9ecfa11085b19474f314169121d3cfc07
|
Provenance
The following attestation bundles were made for r2midi-0.1.6.tar.gz:
Publisher:
python-package.yml on tirans/r2midi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
r2midi-0.1.6.tar.gz -
Subject digest:
74671e00b1e85c2643337b69e966aa1b186d873d9b563185b91789de1cec6895 - Sigstore transparency entry: 218723026
- Sigstore integration time:
-
Permalink:
tirans/r2midi@d3dcd47341d0fa6cbecf15f8baac0a389d24cf23 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/tirans
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@d3dcd47341d0fa6cbecf15f8baac0a389d24cf23 -
Trigger Event:
push
-
Statement type:
File details
Details for the file r2midi-0.1.6-py3-none-any.whl.
File metadata
- Download URL: r2midi-0.1.6-py3-none-any.whl
- Upload date:
- Size: 25.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60d2868ef86720ad6eb302c8f2c6543c019d1a820db4bd78c758211d84e18a31
|
|
| MD5 |
c9bc9249e37618b41cf0cd0e3f5aed42
|
|
| BLAKE2b-256 |
c92600827d2b3a485fb99c806d7d724df50f6a4daf3c56c04234a55e93e369db
|
Provenance
The following attestation bundles were made for r2midi-0.1.6-py3-none-any.whl:
Publisher:
python-package.yml on tirans/r2midi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
r2midi-0.1.6-py3-none-any.whl -
Subject digest:
60d2868ef86720ad6eb302c8f2c6543c019d1a820db4bd78c758211d84e18a31 - Sigstore transparency entry: 218723032
- Sigstore integration time:
-
Permalink:
tirans/r2midi@d3dcd47341d0fa6cbecf15f8baac0a389d24cf23 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/tirans
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@d3dcd47341d0fa6cbecf15f8baac0a389d24cf23 -
Trigger Event:
push
-
Statement type: