Examples & Controllable Generation¶
This page showcases MIDI-GPT's core capabilities using recognizable, real-world musical examples: Track Sampling, Bar Infilling (Inpainting), and Autoregressive Continuation. All examples below are generated using the public yellow model checkpoint.
By setting Attribute Controls (such as polyphony, note density, and note duration), you can guide the model to generate musical parts that perfectly fit your composition.
Video Renders & MIDI Downloads¶
Generated examples below are rendered as MP4 videos with synthesized audio and a per-track piano-roll view. Context tracks are shown in blue/green, generated tracks in gold. Download links are provided for importing the .mid files into a DAW.
1. Controllable Track Sampling (Arrangement)¶
Track sampling generates a completely new track conditioned on one or more existing tracks. The model can also sample its own attribute controls from the prior — letting it choose style freely — or you can pin specific values to steer the output.
Example 1: Rock/Pop Drums — Californication¶
We take the guitar (acoustic_guitar_steel) and bass (electric_bass_finger) from RHCP's Californication as context and generate a drum track. By adjusting note_density (scale 0–9), we steer the drums from a near-silent beat to a dense, active pattern.
| Track | Instrument | Role |
|---|---|---|
| 0 | acoustic_guitar_steel |
Context |
| 1 | electric_bass_finger |
Context |
| 2 | drums |
Generated |
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False), # acoustic_guitar_steel (context)
TrackPrompt(id=1, bars=[], ignore=False), # electric_bass_finger (context)
TrackPrompt(
id=2,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"note_density": 1}
)
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
Example 2: Classical Cello — Bach's Harpsichord Concerto¶
We take the violin, violin, and viola tracks from J.S. Bach's Harpsichord Concerto in D Minor (BWV 1052) (solo section, bars 12–20) as context and generate a cello bassline restricted to monophonic (max_polyphony = 0). By sweeping max_note_duration from index 1 (16th notes) through index 4 (half notes) and adding a min_note_duration = 4 (sustained legato) variant, we get 5 generations spanning the full duration spectrum.
| Track | Instrument | Role |
|---|---|---|
| 0 | violin |
Context |
| 1 | viola |
Context |
| 2 | cello |
Context |
| 3 | cello |
Generated |
Rapid, bouncy staccato lines.
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False), # violin (context)
TrackPrompt(id=1, bars=[], ignore=False), # viola (context)
TrackPrompt(id=2, bars=[], ignore=False), # cello (context)
TrackPrompt(
id=3,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"max_polyphony": 0, "max_note_duration": 1}
)
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
Moderate 8th-note runs.
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False),
TrackPrompt(id=1, bars=[], ignore=False),
TrackPrompt(id=2, bars=[], ignore=False),
TrackPrompt(
id=3,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"max_polyphony": 0, "max_note_duration": 2}
)
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
Quarter-note walking-bass feel.
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False),
TrackPrompt(id=1, bars=[], ignore=False),
TrackPrompt(id=2, bars=[], ignore=False),
TrackPrompt(
id=3,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"max_polyphony": 0, "max_note_duration": 3}
)
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
Slow half-note pedal points.
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False),
TrackPrompt(id=1, bars=[], ignore=False),
TrackPrompt(id=2, bars=[], ignore=False),
TrackPrompt(
id=3,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"max_polyphony": 0, "max_note_duration": 4}
)
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
Long held bass notes — pure legato phrasing.
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False),
TrackPrompt(id=1, bars=[], ignore=False),
TrackPrompt(id=2, bars=[], ignore=False),
TrackPrompt(
id=3,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"max_polyphony": 0, "min_note_duration": 4}
)
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
Example 3: Guitar Solo — Black Magic Woman (model-sampled controls)¶
We take the electric_bass_finger and drums tracks from Santana's Black Magic Woman as context and resample the overdriven_guitar solo. No explicit attribute controls are set — the model samples its own controls from the prior, producing two stylistically distinct solos in the same harmonic context.
Tip: When you omit attribute controls, the model draws from its learned style distribution. This is useful for exploring diverse outputs without manually specifying constraints.
| Track | Instrument | Role |
|---|---|---|
| 0 | electric_bass_finger |
Context |
| 1 | overdriven_guitar |
Generated |
| 2 | drums |
Context |
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False), # electric_bass_finger (context)
TrackPrompt(
id=1,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False
# no attributes — model samples its own controls
),
TrackPrompt(id=2, bars=[], ignore=False), # drums (context)
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
2. Controllable Bar Infilling (Inpainting)¶
Bar infilling lets you select specific bars in any track and regenerate them while the model blends with the surrounding context.
Example 4: Orchestral Harp — SSBM All Star Intro¶
We take the full harp, bells, and strings tracks from the Super Smash Bros. Melee All Star Intro and delete bars 4–7 of the harp, asking the model to infill them with a note-duration constraint. The tubular_bells and string_ensemble_1 tracks play through all 8 bars as fixed context; the original harp bars 0–3 anchor the generation. The shaded region in the video marks the infilled bars.
| Track | Instrument | Role |
|---|---|---|
| 0 | tubular_bells |
Context |
| 1 | string_ensemble_1 |
Context |
| 2 | orchestral_harp |
Context (bars 0–3) + Generated (bars 4–7) |
Rapid 16th-note arpeggiated runs.
req = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False), # tubular_bells (context)
TrackPrompt(id=1, bars=[], ignore=False), # string_ensemble_1 (context)
TrackPrompt(
id=2,
bars=[4, 5, 6, 7],
autoregressive=False, # infill mode
attributes={"max_note_duration": 1}
),
],
config=InferenceConfig(model_dim=8, mask_mode="attention")
)
Slower 8th-note arpeggios — more lyrical.
3. Multi-Step Composition¶
By chaining multiple generation tasks you can build up a full arrangement incrementally.
Example 5: Multi-Step — Joe Hisaishi's Summer¶
Starting from a 3-track acoustic_grand_piano + electric_bass_finger + synth_strings_1 context, we perform three successive generations to build a 5-track arrangement:
- Continuation — extend all three tracks from bar 4 to bar 7 autoregressively
- Track sampling — add
acoustic_guitar_nylon(monophonic 16th notes) - Track sampling — add
drumsat high density
The final video shows all five tracks simultaneously. Gold tracks (acoustic_guitar_nylon, drums) are the last two generation steps; the shaded region (bars 4–7) marks the continuation portion of the first three tracks.
| Track | Instrument | Role |
|---|---|---|
| 0 | acoustic_grand_piano |
Context (bars 0–3) + Continued (bars 4–7) |
| 1 | electric_bass_finger |
Context (bars 0–3) + Continued (bars 4–7) |
| 2 | synth_strings_1 |
Context (bars 0–3) + Continued (bars 4–7) |
| 3 | acoustic_guitar_nylon |
Generated — max_polyphony=0, max_note_duration=1 |
| 4 | drums |
Generated — note_density=9 |
# Step 1: Continue all three tracks for bars 4-7
step1 = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[4, 5, 6, 7], autoregressive=True), # piano
TrackPrompt(id=1, bars=[4, 5, 6, 7], autoregressive=True), # bass
TrackPrompt(id=2, bars=[4, 5, 6, 7], autoregressive=True), # strings
],
config=InferenceConfig(model_dim=8, mask_mode="attention")
)
# Step 2: Add guitar (monophonic 16th notes)
step2 = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False), # piano (context)
TrackPrompt(id=1, bars=[], ignore=False), # bass (context)
TrackPrompt(id=2, bars=[], ignore=False), # strings (context)
TrackPrompt(
id=3,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"max_polyphony": 0, "max_note_duration": 1}
),
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)
# Step 3: Add drums
step3 = GenerationRequest(
tracks=[
TrackPrompt(id=0, bars=[], ignore=False),
TrackPrompt(id=1, bars=[], ignore=False),
TrackPrompt(id=2, bars=[], ignore=False),
TrackPrompt(id=3, bars=[], ignore=False), # guitar (context)
TrackPrompt(
id=4,
bars=[0, 1, 2, 3, 4, 5, 6, 7],
ignore=False,
attributes={"note_density": 9}
),
],
config=InferenceConfig(model_dim=8, mask_mode="attention", tracks_per_step=2)
)