Music and MIDI
Play, visualize, and edit musical phrases with a reusable piano roll and three local voices.
A musical sketch
Press Play and start sketching. Draw a note in the grid, drag it to move it, or pull its right edge to change its length. Choose a track tab and an instrument from the top bar. The piano roll is the same reusable Midi component that you can embed in an article, tutorial, or music lab.
⋯
Note details
Accessible note list
- Warm keys: C4, beat 0, for 3.25 beats
- Warm keys: E4, beat 0, for 3.25 beats
- Warm keys: G4, beat 0, for 3.25 beats
- Warm keys: B3, beat 4, for 3.25 beats
- Warm keys: D4, beat 4, for 3.25 beats
- Warm keys: G4, beat 4, for 3.25 beats
- Warm keys: A3, beat 8, for 3.25 beats
- Warm keys: C4, beat 8, for 3.25 beats
- Warm keys: E4, beat 8, for 3.25 beats
- Warm keys: G3, beat 12, for 3.25 beats
- Warm keys: B3, beat 12, for 3.25 beats
- Warm keys: D4, beat 12, for 3.25 beats
- Warm keys: C4, beat 16, for 3.25 beats
- Warm keys: E4, beat 16, for 3.25 beats
- Warm keys: G4, beat 16, for 3.25 beats
- Warm keys: A3, beat 20, for 3.25 beats
- Warm keys: C4, beat 20, for 3.25 beats
- Warm keys: E4, beat 20, for 3.25 beats
- Warm keys: G3, beat 24, for 3.25 beats
- Warm keys: B3, beat 24, for 3.25 beats
- Warm keys: D4, beat 24, for 3.25 beats
- Warm keys: F3, beat 28, for 3.25 beats
- Warm keys: A3, beat 28, for 3.25 beats
- Warm keys: C4, beat 28, for 3.25 beats
- High pulse: E5, beat 0, for 1.1 beats
- High pulse: G5, beat 1.5, for 0.75 beats
- High pulse: C5, beat 2.5, for 1.1 beats
- High pulse: D5, beat 4, for 1.1 beats
- High pulse: G5, beat 5.5, for 0.75 beats
- High pulse: B4, beat 6.5, for 1.1 beats
- High pulse: C5, beat 8, for 1.1 beats
- High pulse: E5, beat 9.5, for 0.75 beats
- High pulse: A4, beat 10.5, for 1.1 beats
- High pulse: B4, beat 12, for 1.1 beats
- High pulse: D5, beat 13.5, for 0.75 beats
- High pulse: G4, beat 14.5, for 1.1 beats
- High pulse: E5, beat 16, for 1.1 beats
- High pulse: G5, beat 17.5, for 0.75 beats
- High pulse: C5, beat 18.5, for 1.1 beats
- High pulse: C5, beat 20, for 1.1 beats
- High pulse: E5, beat 21.5, for 0.75 beats
- High pulse: A4, beat 22.5, for 1.1 beats
- High pulse: B4, beat 24, for 1.1 beats
- High pulse: D5, beat 25.5, for 0.75 beats
- High pulse: G4, beat 26.5, for 1.1 beats
- High pulse: A4, beat 28, for 1.1 beats
- High pulse: C5, beat 29.5, for 0.75 beats
- High pulse: F4, beat 30.5, for 1.1 beats
- Round bass: C2, beat 0, for 0.58 beats
- Round bass: C2, beat 1, for 0.58 beats
- Round bass: C2, beat 2.5, for 0.9 beats
- Round bass: C2, beat 3, for 0.58 beats
- Round bass: B1, beat 4, for 0.58 beats
- Round bass: B1, beat 5, for 0.58 beats
- Round bass: B1, beat 6.5, for 0.9 beats
- Round bass: B1, beat 7, for 0.58 beats
- Round bass: A1, beat 8, for 0.58 beats
- Round bass: A1, beat 9, for 0.58 beats
- Round bass: A1, beat 10.5, for 0.9 beats
- Round bass: A1, beat 11, for 0.58 beats
- Round bass: G1, beat 12, for 0.58 beats
- Round bass: G1, beat 13, for 0.58 beats
- Round bass: G1, beat 14.5, for 0.9 beats
- Round bass: G1, beat 15, for 0.58 beats
- Round bass: C2, beat 16, for 0.58 beats
- Round bass: C2, beat 17, for 0.58 beats
- Round bass: C2, beat 18.5, for 0.9 beats
- Round bass: C2, beat 19, for 0.58 beats
- Round bass: A1, beat 20, for 0.58 beats
- Round bass: A1, beat 21, for 0.58 beats
- Round bass: A1, beat 22.5, for 0.9 beats
- Round bass: A1, beat 23, for 0.58 beats
- Round bass: G1, beat 24, for 0.58 beats
- Round bass: G1, beat 25, for 0.58 beats
- Round bass: G1, beat 26.5, for 0.9 beats
- Round bass: G1, beat 27, for 0.58 beats
- Round bass: F1, beat 28, for 0.58 beats
- Round bass: F1, beat 29, for 0.58 beats
- Round bass: F1, beat 30.5, for 0.9 beats
- Round bass: F1, beat 31, for 0.58 beats
An original arrangement for synthesized piano, supersaw, and bass. Edits stay in this page until you export them.
For the component’s full property inspector and generated source, open the Midi playground.
Four built-in examples
These short, original studies ship with the components package. They are musical source material that you can change and export, rather than prerecorded audio.
| Preset | Study | MIDI file |
|---|---|---|
nocturne | A piano phrase with space between its notes. | Download piano study |
pulse | A repeating supersaw figure for comparing pitch, duration, and timbre. | Download supersaw study |
bassline | A low-register rhythm for experimenting with note lengths and velocity. | Download bass study |
ensemble | Three tracks sharing a pulse. Mute a part or change its voice to hear the arrangement differently. | Download ensemble |
Choose an example from the player, or supply its preset name:
---
import Midi from '@alkemdotdev/alkemist-components/midi';
---
<Midi preset="nocturne" title="Piano study" />
<Midi preset="pulse" editable={false} title="Listen and inspect" />The component includes scoped styles and browser behavior. It works in Astro and MDX without Alkemist’s Layout or Astro integration. Sound starts only after a user interaction.
Edit the notes
The top toolbar keeps playback and editing together. Draw adds notes: click for the last used length, or drag right to draw a longer note. Drag an existing note to change its time and pitch, or pull its right edge to resize it. Select moves existing notes without adding new ones. Erase removes notes on click; right-click also deletes a note. Each gesture is one Undo step. Snap controls the rhythmic grid.
Track tabs choose the part you are editing. The Instrument selector and Mute button apply to that track. Other tracks appear as faint reference notes. Click the bar ruler to move the playhead. More contains examples, volume, loop, MIDI import/export, and Reset. You can also drop a .mid file onto the editor.
Select a note and open Note details for exact pitch, start, length, and velocity, or to duplicate/delete it.
Space plays or pauses when the editor is focused. D/S/E choose Draw, Select, or Erase. Arrow keys move a selected note in pitch or time. Delete removes it, and Control/Command-Z undoes an edit. The numeric fields provide an alternative to dragging. The grid scrolls inside its container on narrow screens.
Play and Pause retain your position; Stop returns to the beginning. Loop repeats through the end of the final measure, including its trailing rest. Tempo changes its speed without changing pitch. Volume controls the output, while note velocity controls each note’s attack strength. Each track has its own voice and mute setting.
Edits live in memory. Export a .mid file before navigating away if you want to keep your changes. Exporting MIDI preserves musical notes, not a recording of the synthesized sound.
Three local voices
| Voice | Character |
|---|---|
piano | A warm synthesized piano voice with a percussive attack and decaying body. It is not an acoustic piano sample library. |
supersaw | Detuned saw voices with a softened attack and controlled high frequencies. |
bass | A rounded low-register voice for short rhythmic notes and sustained foundations. |
Keep voice="track" to use the arrangement’s individual voices, or set voice="piano", "supersaw", or "bass" to compare the same notes through a single sound. MIDI program numbers are exported for other players, but those players supply their own instruments and will sound different.
Author a sequence
Notes use MIDI pitch numbers (60 is middle C), quarter-note beats, and velocity from 0 to 1. A sequence contains named tracks, each with a voice and notes. Use stable, unique IDs for tracks and notes.
---
import Midi, { type MidiSequence } from '@alkemdotdev/alkemist-components/midi';
const phrase: MidiSequence = {
name: 'Three rising notes',
bpm: 96,
beatsPerBar: 4,
tracks: [
{
id: 'keys',
name: 'Piano',
voice: 'piano',
muted: false,
notes: [
{ id: 'a', pitch: 60, start: 0, duration: 1, velocity: 0.65 },
{ id: 'b', pitch: 64, start: 1, duration: 1, velocity: 0.72 },
{ id: 'c', pitch: 67, start: 2, duration: 2, velocity: 0.6 },
],
},
],
};
---
<Midi sequence={phrase} title="Three rising notes" />getMidiPreset() returns an independent copy you can modify. The same entry exports MidiProps, MidiSequence, MidiTrack, MidiNote, MusicVoice, importMidi(), and exportMidi() for programmatic use.
Import and export
Import a local .mid file in the player, or set src to an existing file. Local imports are parsed in the browser and are not uploaded. Cross-origin URLs must allow your site through CORS.
---
import Midi from '@alkemdotdev/alkemist-components/midi';
---
<Midi src="/music/my-study.mid" editable={false} title="Published score" />The editor works with note tracks at a single tempo. It reports unsupported tempo changes, controller automation, pitch bends, and percussion rather than claiming a lossless DAW project import. Review import warnings before exporting. This is a note editor and synthesizer; microphone recording, audio-to-MIDI conversion, hardware MIDI access, notation engraving, and audio-file export are not included.
Component parameters
| Prop | Default | Purpose |
|---|---|---|
title | Empty | Accessible player and toolbar name. |
caption | Empty | Supporting text beneath the editor. |
preset | nocturne | One of the four built-in studies. |
sequence | null | Structured notes; takes precedence over preset. |
src | Empty | A MIDI file URL; takes precedence over sequence. |
voice | track | Retain each track’s voice or override all tracks. |
editable | true | Enable note editing and local import. Playback remains available when false. |
loop | true | Repeat the musical phrase. |
volume | 0.65 | Output level from 0 to 1. |
tempo | 0 | Use the sequence’s tempo, or override with 30–240 BPM. |
height | 300 | Piano-roll viewport height in pixels. |
The player dispatches a bubbling alk:midi:change event with { sequence } after musical edits. The playground uses that event to update its source pane. Hosts can subscribe to save their own document; the component does not choose a storage service.
Playback foundation
Tone.js supplies synthesis and audio scheduling primitives; @tonejs/midi reads and writes MIDI files. Alkemist owns the sequence model, voice presets, editor, lifecycle, examples, and authoring API. Engines load only when needed, and removed players stop and release their audio resources.