⌨️ Keyboard shortcuts
Play in real gameCtrl+Enter
Validate JSON (Edit tab)Ctrl+Enter
Reset semitone offsetCtrl+0
Exit fullscreen gameEsc
Toggle light/dark themeCtrl+J

JSON MIDI

Converts between standard MIDI files, Piano Tiles 2-style song notation JSON, and USong binary files (v0.1.1), entirely in your browser. Format reference: pianotiles2-community.github.io/wiki/song.html
MIDI → JSON
JSON → MIDI
Edit JSON
USong → MIDI
🧬 MIDI Merger
🎮 Test JSON
🏆 Challenge Maker

Load MIDI

Drop a .mid file here, or click to browse
Parsing happens locally in your browser

Extract notes only ?

Uses the same settings above (min tile, chord timing, transpose, merge/DRUNK/Smart Sync, track selection) but outputs plain notation text instead of a JSON object — nothing gets wrapped into musics/scores.
?
?
5<> is the only tile type with confirmed syntax in the wiki ("double tile"). It merges multiple notes/chords across a paired lane at once — 2, 4, 8, even 16 at a time all work in-game. 3<> 6<> 7<> 8<> 9<> 10<> are named and described, but the wiki gives no worked example or note-count limit for any of them. Everything else here (pitch names, chord grouping, quantized durations, grid self-correction, measure barlines, time-signature detection) is implemented from confirmed spec.
🍺 DRUNK Mode's non-5<> tile types use your own chosen min/max note counts because the game doesn't document any — there's no "correct" number to check against. Start with small ranges (2–6) and test in-game before trusting a file with these enabled.

Load JSON

Drop a song JSON file here, or click to browse
Parsing happens locally in your browser
Reconstructs pitch and rhythm exactly from the notation letters, including unpacking 5<> double tiles. mute tokens produce a timed rest. Ignores baseBpm/baseBeats scroll-speed scaling (uses each part's bpm directly) since the in-game speed formula isn't published.

Create a blank JSON

Generates an empty, structurally-valid song — add notes yourself for a custom challenge.
Parts
Score tracks per part
baseBpm
bpm / baseBeats per part

Load JSON to edit

Drop a song JSON file here, or click to browse
Edit directly as text, or use the token editor below
Auto-fix strips trailing commas, balances unmatched brackets, trims garbage before/after the JSON body, and converts stray single quotes — a best-effort heuristic, not a guarantee, especially for malformed note-notation strings.

Load USong

Drop a .usong file here, or click to browse
Format v0.1.1 · parsed entirely in your browser, nothing is uploaded

Parse log

waiting for a file…

Piano roll

nothing to preview yet

Export

convert a file above to unlock the download
Only format version 1 (v0.1.1) is supported, since v0.1's header layout isn't documented. The song format doesn't fully define how tempo evolves under linear and classic PT2 acceleration, so this converter makes explicit choices — tap the ? below for details. Output MIDI always uses a fixed reference tempo of 120 BPM at 960 ticks/quarter; USong's own tempo curve is baked directly into note timing instead, so playback stays accurate regardless of what a MIDI player assumes about tempo.
Tempo timing assumptions ? — which mode is active is reported in the parse log for every file you load.

🧬 MIDI Merger ?

Load two or more MIDI files, pick which tracks from each to include, choose Chain or Layer mode, and download one merged .mid. Handy for stitching together the parts of a large song, or combining separately-composed instrument tracks into one file.
Drop MIDI files here, or click to browse
Add as many as you like — each one appears below with its own track list
No files loaded yet.

Load JSON to test

Loads a Piano Tiles 2 song JSON straight into the real Piano Tiles Zero game engine — no download, no copy-paste round trip needed. The JSON is parsed entirely by the game's own parser, not this site's.

1. Load source songs ?

Every file is checked for structural problems (bad JSON, missing parts, unrecognized notes/pitches) as soon as it's loaded — broken files are marked and can't be selected, so nothing unplayable can make it into the final challenge.
No songs loaded yet — add at least 3 JSON files to build a challenge.

2. Challenge structure

Number of parts in the challenge ?
?
Select songs above to continue — 0/3 selected.

4. Generate

Before combining anything, every resolved part is re-validated (pitch names, token shapes) and every part's scores array is padded/rebuilt to the same track count, with fresh sequential id/instruments/alternatives fields — the most common causes of an in-game crash when songs from different sources get mixed together.
⚠️

Are you sure?