Skip to content

Latest commit

 

History

124 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Metacreation Lab

MIDI-GPT for REAPER

License: MIT REAPER Python Powered by MIDI-GPT arXiv HuggingFace

AI-powered multi-track MIDI generation plugin for REAPER, built on the MIDI-GPT transformer model.

  • Fill in missing bars — select a region and the model generates notes that fit your existing arrangement
  • Generate new tracks — create empty bars, name the track by instrument, and let the model compose from scratch
  • Steer the output — control density, polyphony, and note duration per track from the dashboard
  • Iterative refinement — regenerate any bar, track, or region until you get what you want
  • Context-aware — the model reads surrounding MIDI and produces results that fit the key, groove, and texture

Related docs: INSTRUMENTS.md — MIDI instrument reference and track naming keywords · VST.md — free VST recommendations for synthesizing all GM instruments


Table of Contents


How It Works

MIDI-GPT for REAPER has two parts:

  1. Inference Server (midigpt-http) — Starts a stateless FastAPI server listening for generation requests on port 3456 (binds 0.0.0.0 by default, so it can run on a different machine than REAPER, e.g. a GPU workstation on the same network).
  2. Dashboard (REAPER_midigpt_dashboard.py) — The one window you interact with in REAPER: server address, track/SoundFont setup, global options, per-track controls (density, polyphony, key signature, pitch mask, remix, etc.), and a Run Infill button that reads your session, sends a generation payload to the server, and writes the result back into your project.

The dashboard's buttons are thin wrappers around a handful of underlying scripts (REAPER_midigpt_infill.py does the actual generation call, REAPER_midigpt_setup_tracks.py does track setup, etc.) — you never need to run those directly, but you can load them as their own ReaScript actions too if you want keyboard-shortcut access to one of them without opening the dashboard. See REAPER Setup.

The model sees your existing MIDI as context and generates new notes for the bars you select, producing results that fit musically with the surrounding material.


Requirements

  • REAPER 64-bit (v6 or later) — Download REAPER (make sure to select the 64-bit version for your OS)
  • ReaImGui — the REAPER extension the dashboard UI is built with. Install it via Extensions > ReaPack > Browse packages, search ReaImGui, install, then restart REAPER. (Don't have ReaPack? Get it first: reapack.com.) The installer checks for this and warns you if it's missing.
  • Python 3.10 – 3.12 (3.12 recommended) — Download Python
  • Git (required for installer package check)
  • OS: macOS, Linux, or Windows

Installation

One-Line Install (macOS / Linux)

Paste this into a terminal — it installs everything and offers to start the server immediately:

curl -fsSL https://raw.githubusercontent.com/Metacreation-Lab/midigpt-REAPER/main/bootstrap.sh | bash

Requirements: Python 3.10, 3.11, or 3.12 and git. If Python is missing, the installer will tell you exactly how to get it for your OS (Homebrew on macOS, apt on Ubuntu/Debian, or python.org for anything else). After installing, re-run the same command.

To update later: cd ~/midigpt-REAPER && ./update.sh

To uninstall: cd ~/midigpt-REAPER && ./uninstall.sh


Quick Install (Release Package)

Download the release zip, extract it, and double-click the installer for your OS:

OS Installer What to double-click
macOS Included Install - Mac.command
Linux Included Install - Linux.sh
Windows Included Install - Windows.bat

The installer handles everything automatically:

  1. System dependencies — Detects python and git.
  2. Python virtual environment — Creates .venv/ with PyTorch.
  3. MIDI-GPT backend — Installs the sibling MIDI-GPT library in editable mode.
  4. REAPER symlinks — Links the plugin's Scripts into your REAPER config folder, and checks whether the ReaImGui extension (required by the dashboard UI) is already installed, printing instructions if not.
  5. REAPER configuration — Edits reaper.ini to enable ReaScript and set the Python library path (quit REAPER first).
  6. Desktop shortcut — Places a "Start MIDI-GPT Server" launcher on your Desktop.

Note: REAPER should be closed during installation. REAPER overwrites reaper.ini when it quits, so any changes made while it's running will be lost.

Install from Source

If you cloned this repo and want to link a local MIDI-GPT backend repository:

# macOS / Linux
./install.sh --midigpt-src=/path/to/MIDI-GPT

# Windows (Git Bash / MSYS)
./install-windows.sh --midigpt-src=/c/path/to/MIDI-GPT

Installer flags:

Option Description
--midigpt-src=PATH Path to the MIDI-GPT backend source folder
--skip-deps Skip system dependency checks
--skip-reaper-config Don't modify reaper.ini

REAPER Setup

  1. Install ReaImGui (required, one-time): Extensions > ReaPack > Browse packages, search ReaImGui, install, then restart REAPER. The dashboard won't open without it. (Don't have ReaPack? Get it first: reapack.com.)

  2. Load the dashboard as a ReaScript action:

    • Open the Action List: Actions > Show Action List (or press ?).
    • Click New action, then select Load ReaScript....
    • Browse to: ~/Library/Application Support/REAPER/Scripts/MIDI-GPT/ (or %APPDATA%\REAPER\Scripts\MIDI-GPT\ on Windows).
    • Select REAPER_midigpt_dashboard.py and click Open. This is the only action you need — everything below is a button inside the window it opens.
    • (Optional) The dashboard's buttons are wrappers around REAPER_midigpt_infill.py, REAPER_midigpt_set_server.py, REAPER_midigpt_setup_tracks.py, REAPER_midigpt_set_soundfont_template.py, and REAPER_midigpt_apply_soundfont_template.py. Load any of those the same way if you want a keyboard shortcut for that one action specifically, without opening the dashboard — REAPER lists each as Script: <filename>.py in the Action List. Nothing about the dashboard requires this; it's purely a convenience for people who'd rather bind a hotkey than click a button.
  3. Open the dashboard: run the action you just loaded. The window has, top to bottom:

    • Actions row — the current server address and a Change... button next to it, a model picker (once the server responds), Setup Tracks, Use Selected Track as SoundFont Template, Apply Template to Selected Tracks, Run Infill, and Reset Global Options && Track Controls.
    • Global Options — generation-wide settings (temperature, context size, sampling, etc.) — see Controls Reference.
    • Track Controls — one collapsible section per track (density, polyphony, duration, key signature, pitch mask, remix, etc.).
    • Console — live log output for whatever you just ran (generation progress, errors, the outgoing request for debugging).

    All of it is saved per-project, so you only need to set it once per session.

  4. Point it at your server, if it's not local: click Change... next to "Server:" in the dashboard and enter the address (e.g. http://192.168.1.20:3456). Defaults to http://127.0.0.1:3456.

  5. Set up tracks (optional, saves manual work):

    • Click Setup Tracks in the dashboard. It auto-detects each track's GM instrument from its MIDI content and adds a Sforzando instance to any track that doesn't have one yet.
    • This is specifically for assigning a name in the first place, so it reads each track's actual MIDI content (channel 10 / Program Change events) rather than the current track name, since imported files usually give every track the same name to start with. Tracks it can't resolve that way are prompted for individually — a native dropdown list of all 128 GM instruments on macOS, or a keyword-entry dialog (piano/bass/drums/etc.) elsewhere. Resolved tracks are renamed to the matching name from INSTRUMENTS.md (e.g. acoustic_grand_piano, drums) so they're readable at a glance — from then on, generation uses that name as ground truth (see Set Up Your Session), not the track's MIDI content.
    • SoundFont setup (one-time): the first run adds an empty Sforzando to every track. Manually import your .sf2 (e.g. Arachno, see VST.md) into one track's Sforzando, select that track, then click Use Selected Track as SoundFont Template in the dashboard. From then on, Setup Tracks clones that already-loaded instance onto any track that doesn't have an instrument yet — no re-importing the SoundFont per track. To replace tracks that already got an empty Sforzando before the template existed, select them and click Apply Template to Selected Tracks.
    • Auto-selecting the instrument program (one-time per instrument): by default you still pick the program inside Sforzando manually (the dashboard's Console tells you which one, e.g. electric_bass_finger, per track). To make Setup Tracks select it for you, save it as a REAPER FX preset once: with that program showing in Sforzando, open the FX window's Presets dropdown → Save preset..., and name it MIDI-GPT: + the canonical name (e.g. MIDI-GPT: electric_bass_finger) — the MIDI-GPT: prefix keeps these separate from any of your own presets so nothing clashes. Once a preset exists for an instrument, every future track resolved to it gets that program selected automatically — this only needs doing once per instrument you actually use, ever.
    • Safe to re-run Setup Tracks: a track's instrument/preset is only ever touched if it added the instrument itself, and only until its preset selection is confirmed once — after that (or on any instrument you added/changed by hand), re-running leaves it alone. A preset that didn't take effect on one run (still loading) is retried automatically on the next.

Usage Tutorial

1. Start the Server

Double-click the Start MIDI-GPT Server shortcut on your Desktop, or run from the repo:

./start_midigpt_server.sh                                          # yellow_medium (default)
./start_midigpt_server.sh --pretrained prism_medium                # Prism model
./start_midigpt_server.sh --pretrained expressive_medium           # Expressive model
./start_midigpt_server.sh --ckpt /path/to/model.safetensors        # Local checkpoint

The model is fixed for the lifetime of the server process. To switch models, stop the server and restart it with a different flag. The dashboard auto-detects the running model via the server's /info endpoint and adjusts which per-track controls it shows accordingly.

2. Set Up Your Session

Name your tracks so the plugin can identify instruments — this is the ground truth generation uses, not any MIDI content on the track. Names are matched case-insensitively by keyword — a track named "my piano" or "PIANO chords" both resolve to piano. A name that matches no keyword falls back to detecting from the track's MIDI content (channel 10 for drums), and finally defaults to piano if that fails too. See INSTRUMENTS.md for the full keyword list, or just click Setup Tracks in the dashboard to have it resolved and renamed for you.

Add MIDI context to your tracks. The model uses surrounding notes as musical context when generating. Tracks with more coherent existing content produce more coherent output.

Open the dashboard and set per-track controls for any track where you want explicit control over density, polyphony, and duration. This is optional for tracks with existing content, but important for empty tracks — see Generating into Empty Tracks.

3. Select Context and Target Bars

Set the loop region (context window):

  • Enable the REAPER loop and position it over the bars you want the model to use as musical context.
  • The loop region should match the model's context size (model_dim, shown in the dashboard's Global Options panel — 4 bars for Yellow by default).
  • Without a loop region, the model uses the entire project as context, which is slower but still works.

Set the time selection (generation target):

  • Draw a time selection over the bars you want to generate or infill. This is what gets replaced.
  • If a MIDI item spans multiple bars and you only want to generate part of it, split the item first so only the target bars fall within your time selection.
  • You can target a single bar, a horizontal range across one track, or a vertical range across multiple tracks simultaneously.

4. Run Generation

Click Run Infill in the dashboard.

It reads your MIDI items and the dashboard's saved control values, sends a generation request to the server, and writes the result back — progress and the outgoing request appear in the dashboard's Console. Generated MIDI replaces whatever was in the target bars. Run it again to regenerate with different settings or a different random seed.

Generating into Empty Tracks

When generating into bars that contain no existing MIDI, the model has no content to infer controls from. Without explicit per-track settings, it tends toward silence or sparse output.

To get useful results on empty tracks:

  1. Create the track, name it with an instrument keyword, and create an empty MIDI item covering the target bars.
  2. In the dashboard's Track Controls for that track, set controls appropriate to the instrument. Density only affects drum tracks; Polyphony and Note Duration only affect melodic tracks — the dashboard shows only the controls relevant to the track it detects, so which columns apply depends on what kind of track you're setting up:
Instrument type Polyphony (min/max) Duration
Monophonic (flute, bass, lead) 1 / 1 Short–medium
Chordal (piano, pads, guitar) 3 / 6 Medium–long
Arpeggio 1 / 2 Short
Drum density Setting
Sparse (kick/snare only) Low
Standard groove Medium
Busy/fills High
  1. Run generation. Adjust the controls and regenerate until you get the character you want.

Tips and Common Gotchas

  • Loop size and model_dim: The loop region should be exactly model_dim bars (check the dashboard's Global Options panel). A mismatched loop forces the model to process more context than necessary, which slows generation.
  • Bars per step can exceed model_dim: You can generate more bars than model_dim in one run. The model steps through the target bars sequentially at model_dim-sized increments.
  • No per-track controls on empty bars: Without dashboard settings for a track, controls are inferred from existing content. On empty bars this biases strongly toward silence. Always set per-track controls when generating into empty tracks — polyphony/duration for melodic tracks, density for drum tracks.
  • Density vs. Polyphony/Duration: Density only ever affects drum tracks; Polyphony, Note Duration, Key Signature, Pitch Range, and Pitch Class Set only ever affect melodic tracks. Setting one on the wrong track type is a silent no-op — the dashboard hides whichever half doesn't apply once it detects the track's instrument.
  • Instrument fallback: Tracks with names the plugin doesn't recognize fall back to MIDI-content detection, then finally default to piano (instrument 0) if that fails too. If a track is generating piano-like output unexpectedly, check the track name against INSTRUMENTS.md — a matching name is more reliable than the content fallback.

Controls Reference

All controls below live in the dashboard window (REAPER_midigpt_dashboard.py), saved per-project — you only need to set them once per session, not per generation run.

Global Options

Parameter Slider Range Description
Temperature 0.1 to 3.0 Controls generation randomness. Lower = more conservative.
Context Size 2 to 16 The model's context window size in bars (default: 4).
Bars Per Step 1 to Context Size Number of bars generated per inference step.
Tracks Per Step 1 to 16 Number of tracks processed per step.
Polyphony Hard Limit 0 to 32 Global limit on simultaneous note onsets (0 = disabled).
Density Hard Limit 0 to 64 Global limit on note onsets per bar (0 = disabled).
Max Attempts 1 to 10 Max tries per step if checks fail.
Temp Escalation 1.0 to 3.0 Rand multiplier per failed attempt.
Top-p 0.0 to 1.0 Nucleus sampling probability threshold (1.0 = off).
Top-k 0 to 500 Keeps top-k highest-prob tokens (0 = off).
Anti-nucleus mask_p 0.0 to 0.95 Chops most-likely tokens to force novelty (0.0 = off).
Anti-nucleus mask_k 0 to 100 Chops top-k tokens after top_* filtering (0 = off).
Random Seed -1 to 999999 Fixed seed for reproducibility (-1 = random).
Batch Candidates 1 to 16 Generate multiple candidates per run and pick the best one in the dashboard. Disables token streaming above 1.
Checks None, Novelty, Silence, Both Enables validation filters.
Shuffle Steps No, Yes Shuffles order of generation steps.

Track Controls (Per-Track)

Density only ever affects drum tracks. Polyphony, Note Duration, Key Signature, Pitch Range, and Pitch Class Set only ever affect melodic tracks — setting one on the wrong track type is a silent no-op server-side. The dashboard detects each track's instrument and shows only the half that applies; if it can't tell, it shows both and says so.

Yellow Model Parameters

  • Density (0-10, drums only): Note density level.
  • Min / Max Polyphony (0-10, melodic only): Simultaneous note bounds.
  • Min / Max Note Duration (0-6, melodic only): Note duration bounds, quantized.
  • Autoregressive: Freely generate full track bar-by-bar.
  • Ignore: Ignores this track for generation (treats as context).

Prism Model Parameters

  • Key Signature (0-25, melodic only): Constrain output to a key (0 = any).
  • Pitch Range (0-128, melodic only): Max pitch span in semitones (0 = any).
  • Silence Proportion (0-10, both track types): Target proportion of silence (0 = any).
  • Min / Max Note Duration (0-6, melodic only): Quantized note duration bounds.
  • Density (0-10, drums only): Per-bar note density (applied to each generated bar).
  • Min / Max Polyphony (0-10, melodic only): Per-bar simultaneous note bounds.
  • Pitch Class Set (0-13, melodic only): Number of distinct pitch classes per bar (0 = any).
  • Autoregressive: Freely generate full track bar-by-bar.
  • Ignore: Ignores this track for generation (treats as context).

Expressive Model Parameters

  • All Prism parameters, plus NOMML (0-13, both track types): Quantization grid depth controlling microtiming expressivity (0 = any, 13 = fully expressive).

Pitch Mask & Remix (all models, if the loaded checkpoint supports them)

  • Pitch Mask: Off, constrain to a musical scale (root + preset), or an explicit set of allowed pitch classes — optionally reweighted toward a register (uniform range or a normal distribution around a mean pitch).
  • Remix: Regenerates a track's existing bars as a variation of what's already there (amount 0-1, pitch-only or pitch+duration) instead of generating fresh content.

Running Tests

To run the full suite of unit and integration tests:

./tests/integration/test_install.sh

Building a Release Package

To package the plugin, scripts, installers, and documentation for release:

./build_release.sh

This generates a ZIP file named MIDI-GPT-for-REAPER-[DATE].zip in the repository root.

About

AI-powered MIDI generation plugin for REAPER — fill in bars and generate tracks using MIDI-GPT

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages