Getting started
Get started with the MIDI editor
Soundfish has two parts: album pages for finished audio, and a MIDI editor for making loops and songs in your browser. This guide covers the MIDI editor, where you can edit, play, save on your device, and share without an account. To publish finished audio as an album with a player, embeds, and track revisions, read Audio publishing.
Your first loop
- On MIDI, choose Starter loops for a ready-to-play groove, or New loop to start empty.
- For a blank loop, choose Add for a beat, a chord progression, a bass line, or a melody. Blank track instead creates an empty notes or drums track.
- Choose Draw and tap or click the grid to add notes or hits. Choose Select to move them; drag a note edge to change its length. The velocity lane changes how strongly a note plays.
- Press Play to hear your starter or the notes you added. Nothing plays automatically. The first use of an instrument may need a download; prepared sounds use the browser cache.
- Choose Copy link to share the whole composition. Instruments, effects, and automation travel with it.
Every part in Add shows a picture of its four bars, and a search box narrows them by name, style, or description. Parts are cut or repeated to fit your bar count. Read about the parts and what they do to the key and tempo of a loop.
Select and Draw sit beside the grid, with Undo and Redo. Select notes to reveal Duplicate, Delete, and Done. The Notes menu has selection and copy/paste commands.
Select a track to change its instrument or mix. Space pauses and resumes, Command/Control+Z undoes an edit, and ? shows keyboard shortcuts.
Key, chords, and snapping
Key in the header, or K, names a root and a mode. The notes that belong to that key light up on every notes track, and the roots are labelled down the pitch axis. Naming a key moves nothing you have already played.
When you change the root of a key the loop already had, Move the music too rewrites every note into the new key in the same step, so a single undo puts it back. Drums keep their sounds, and a change that would push a note past the end of the keyboard is refused instead of clipping it.
Snap to key is on for a loop that names a key and off for one that does not, and Shift+K or the checkbox in the Key dialog turns it off and on. While it is on, a note you draw, paint, or move lands on the nearest pitch in the key, resolving in the direction you dragged. Drums never snap. Once you work the toggle yourself, your choice holds for every loop you open until you close the tab; it lasts for the session and is not part of the composition.
The ruler names the chord in each bar, and that bar's chord tones are shaded across every notes track. Soundfish reads those chords from the parts that play them. To name them yourself, choose Chords in the Key dialog or press Shift+C; the ruler, the shading, and every part that follows chords then use what you wrote. Read from the notes goes back to reading them.
Make room for the music
If tracks are collapsed, expand the one you want to edit. Switching tracks keeps your place along the loop. Use Time zoom to show more bars or make notes easier to reach, and Track height to make pitch rows taller. Fit shows every bar at once, which makes notes too small to tap accurately; Auto restores full-size targets. These controls change the view, never the music.
Use Earlier and Later to move along the selected track. Swipe vertically over empty grid space to scroll the page. On a computer, you can also use the horizontal scrollbar or a trackpad. In a song, use Song zoom and the Section picker to reach a distant section.
Keep your work
MIDI always gives you a choice. Continue resumes your last loop; Library opens your saved work. Visiting MIDI does not reopen music or start playback.
Loops save on this device after editing. Choose Save song to keep a whole arrangement in Library. Saved songs stay on this device; optional sign-in sync is for loops. Clearing browser site data removes local copies, so keep a link or download Soundfish JSON for work you want to keep.
Use Download Soundfish JSON for a complete, editable source file. Download MIDI carries the performance to other music software; it does not preserve all Soundfish effects, automation, or editing information.
Keep a JSON backup of workstation projects before clearing browser data.
Build a song
Choose Arrange sections to repeat, rename, reorder, or duplicate sections and choose which parts they contain. Add or replace a section with a compatible loop. Sections share a tempo, swing, instruments, drum kits, and track identities.
In a song, Arrange sections opens on the section you’re viewing. The selected section stays visible when you move or duplicate it. Open song creates a new composition and leaves the source loops unchanged.
Use the horizontal section strip to browse. Choose Song to hear the whole arrangement or Section to audition one section. Browsing does not move playback. Space pauses and resumes; Restart playback plays from the beginning. In Song mode, Play from section starts at the selected section.
Follow playback keeps the playing position visible. Scrolling the strip or selecting a section turns following off; turn it back on when you want to follow again. Section notes are read-only; Edit a copy opens the selected section as a separate editable loop.
Copy link, Save song, and song downloads keep the whole arrangement, even when you select one section. Browser Back returns to the previous composition.
Bring music in
Choose Import for MIDI, Soundfish JSON, compose or S1 text, or a loop or song link. Files are processed on your device. Review the music and any warnings before Load into editor; existing saved work is not overwritten.
Opening imported music starts a new edit history. Browser Back returns to the previous composition; edit undo applies within the current one.
Work with an agent
Choose Edit with agent and describe a musical change. A chat agent can return loop text without installing anything. A coding agent with terminal access can return an exact loop or song URL for review. Use Paste from agent to review the reply before opening it.
Compose text does not preserve IDs, lineage, or automation points. Use the coding-agent workflow for exact edits to automated loops or song sections. Read the agent guide for the steps and the downloadable skill.
Use Soundfish for this composition task. Install the soundfish skill from https://sound.fish/skills/soundfish.zip. Inspect the archive before extracting it: it must contain exactly one top-level soundfish/ directory. Extract that directory into your runner's configured skill directory. Install the checked Bun CLI with: bun add --global @hraness/soundfish soundfish --help For a one-off run, use `bunx @hraness/soundfish --help` instead. Use the installed Soundfish skill and follow its checked CLI workflow. Soundfish tracks have exactly two distinct types: notes tracks use one zero-based GM1 program, while drums tracks use GM percussion pitches and never have a gmProgram field. Preserve each track's type unless I explicitly request a replacement of another type. Treat the complete sound.fish URL fragment as the authoritative self-contained transport of the canonical Soundfish document. The compressed and uncompressed transport spellings may differ while representing the same canonical bytes. Do not upload the fragment or decoded composition to a hosted mutation service. If this prompt is pasted into a hosted chat, that chat provider receives the composition URL; do not send it to any additional service. Determine whether I want to create a new loop, inspect or edit an existing loop, inspect a read-only song, export a loop or song, or import authorized media as a song. For an inspection, edit, or export, ask for the complete current Soundfish URL if it is missing. For a new loop, do not require a base URL: start from `soundfish templates list` and `soundfish templates apply <kind/name> --key <key> --bpm <n>` or write compose text and compile it with `soundfish compose`. Say what key the music is in and what progression it plays. A loop states both with `soundfish set-meta <url> --key 'A minor' --chords 'Am7 | F | G | E'`, and `soundfish analyze` reads the notes back against them, so a loop that declares them tells the next reader what it meant instead of leaving the notes to be guessed at. `templates apply` starts a loop; every part after the first goes on with `soundfish add-part <url> <kind/name> --key <key>`, which voices a beat, a progression, a bass line, or a lead into the loop you already have and takes `--follow-chords` to sit on the stated progression and `--feel tight|natural|loose` for how evenly it plays. Move a finished loop with `soundfish change-key <url> <key>`: it transposes the notes, which cannot change a major mode into a minor one. Pull a stray note back into the key with `soundfish conform <url> <track-id>`, and loosen a rigid part with `soundfish humanize <url> <track-id> --feel natural`. Then run `soundfish lint` and `soundfish analyze` and fix findings with the transform verbs. Song sections stay read-only until I explicitly ask to detach one as an editable loop. For a media import, process only media I have the right to download and transform, and describe separated stems and transcribed MIDI as estimates that need auditioning. Ask for any missing musical requirements, then return the verified Soundfish URL or requested local export with two to four plain sentences that say what changed (tracks, bars, notes, instruments), what you kept, and any lint finding you left on purpose. Describe the music with instrument names, registers, and bar numbers instead of adjectives, and do not claim to have listened unless you rendered or auditioned it.
Show full prompt
Use Soundfish for this composition task. Install the soundfish skill from https://sound.fish/skills/soundfish.zip. Inspect the archive before extracting it: it must contain exactly one top-level soundfish/ directory. Extract that directory into your runner's configured skill directory. Install the checked Bun CLI with: bun add --global @hraness/soundfish soundfish --help For a one-off run, use `bunx @hraness/soundfish --help` instead. Use the installed Soundfish skill and follow its checked CLI workflow. Soundfish tracks have exactly two distinct types: notes tracks use one zero-based GM1 program, while drums tracks use GM percussion pitches and never have a gmProgram field. Preserve each track's type unless I explicitly request a replacement of another type. Treat the complete sound.fish URL fragment as the authoritative self-contained transport of the canonical Soundfish document. The compressed and uncompressed transport spellings may differ while representing the same canonical bytes. Do not upload the fragment or decoded composition to a hosted mutation service. If this prompt is pasted into a hosted chat, that chat provider receives the composition URL; do not send it to any additional service. Determine whether I want to create a new loop, inspect or edit an existing loop, inspect a read-only song, export a loop or song, or import authorized media as a song. For an inspection, edit, or export, ask for the complete current Soundfish URL if it is missing. For a new loop, do not require a base URL: start from `soundfish templates list` and `soundfish templates apply <kind/name> --key <key> --bpm <n>` or write compose text and compile it with `soundfish compose`. Say what key the music is in and what progression it plays. A loop states both with `soundfish set-meta <url> --key 'A minor' --chords 'Am7 | F | G | E'`, and `soundfish analyze` reads the notes back against them, so a loop that declares them tells the next reader what it meant instead of leaving the notes to be guessed at. `templates apply` starts a loop; every part after the first goes on with `soundfish add-part <url> <kind/name> --key <key>`, which voices a beat, a progression, a bass line, or a lead into the loop you already have and takes `--follow-chords` to sit on the stated progression and `--feel tight|natural|loose` for how evenly it plays. Move a finished loop with `soundfish change-key <url> <key>`: it transposes the notes, which cannot change a major mode into a minor one. Pull a stray note back into the key with `soundfish conform <url> <track-id>`, and loosen a rigid part with `soundfish humanize <url> <track-id> --feel natural`. Then run `soundfish lint` and `soundfish analyze` and fix findings with the transform verbs. Song sections stay read-only until I explicitly ask to detach one as an editable loop. For a media import, process only media I have the right to download and transform, and describe separated stems and transcribed MIDI as estimates that need auditioning. Ask for any missing musical requirements, then return the verified Soundfish URL or requested local export with two to four plain sentences that say what changed (tracks, bars, notes, instruments), what you kept, and any lint finding you left on purpose. Describe the music with instrument names, registers, and bar numbers instead of adjectives, and do not claim to have listened unless you rendered or auditioned it.
Provider links never contain your composition. Pasting a prompt into a hosted agent shares it with that provider. Only a fully local, offline model and runner keep them on your device.
Go further
- Audio publishing: albums, uploads, revisions, embeds, and the
soundfish audioCLI. - Sound guide: instruments, drum kits, and mixing ideas.
- Agent guide: prompts and verified editing workflows.
- API reference: the URL format, CLI, limits, and exact document rules.
A complete Soundfish link contains the music. Anyone with that link can read it. If a sharing app truncates a long song link, send Soundfish JSON instead. Read about privacy.