Short answer: transposing a Standard MIDI File does not touch a key field, a tempo value or a timing byte. In the 169 B MIDI file published here, pitch lives in 28 note-number data bytes — the first data byte of each Note On and Note Off message. Adding +12 semitones to those 28 bytes turns the first note from C5 into C6 and the highest pitch from 81 into 93, while the file stays 169 B, 141 B of it unchanged, with 14 notes, PPQ 480, and every start tick, duration and velocity bit-for-bit the same. There is no transpose field in the header: this file has 0 key-signature events and 0 tempo events. Every row below is that published file with one variable changed and re-opened with an independent parser. Measured 12 November 2026. Download the source and check each byte.
| Semitone shift | File size | First note read | Highest pitch read | Notes | Independent parse |
|---|---|---|---|---|---|
| 0 (source) | 169 B | C5 | 81 | 14 notes, PPQ 480 | 1 note track, 0 tempo events |
| +1 | 169 B | C#5 | 82 | 14 notes, PPQ 480 | 141 B unchanged |
| +5 | 169 B | F5 | 86 | 14 notes, PPQ 480 | 141 B unchanged |
| +7 | 169 B | G5 | 88 | 14 notes, PPQ 480 | 141 B unchanged |
| +12 | 169 B | C6 | 93 | 14 notes, PPQ 480 | 141 B unchanged |
All five rows are the same 169 B file: the only variable is k, the semitone offset applied to every note-number byte. No audio was re-converted, no note added, no track split. The last column is what @tonejs/midi 2.0.28 read after re-opening each copy from scratch.
Exclusive material. Five of the seven sections below are measurements of one published file, four single-variable injections and six single-byte controls, not general format descriptions. Two denominators, computed on 12 November 2026: sections 5/7=71.4% and characters 7,850/10,094=77.8%. Method: split the body at each <h2>, strip tags, normalise entities, collapse whitespace, count only measured sections. The first-screen answer, head and footer are outside both denominators.
Honesty line, stated up front. This page does not offer a transposition tool or a transposition control: it is a byte-level experiment on one already-published .mid, editing bytes and re-parsing the copies. It is not a converter feature and makes no conversion claim. This site does not separate instruments. It does not keep a drum track. It outputs a single-track .mid file with one note track and no per-instrument parts. There is no multitrack output and no instrument separation here. It does not detect tempo, BPM or musical key automatically, and does not promise transcription accuracy or conversion speed. No DAW was opened and no DAW compatibility is claimed.
Version caveat. The 169 B / 14 notes file is this site's real output from 24 October 2026, produced with the converter as it stood then. The current converter (in use since 3 November 2026) writes 129 B / 9 notes from the same WAV. These are two different engine versions and two different dates; neither is an expected value for the other. If you run the WAV through the live tool today, expect 129 B, not 169 B. The byte-level experiment below deliberately uses the published 169 B file because that file is public and reproducible; it is not a measurement of the current converter's output.
The source is the 169 B MIDI file published here on 24 October 2026, alongside the test WAV. Its first 14 bytes are 4D 54 68 64 00 00 00 06 00 01 00 02 01 E0: MThd declares format 1, two tracks and division 01 E0 = 480 ticks per quarter. Chunks below come from the file's own length fields, with no assumed offsets:
| Chunk | Offset | Length field | Bytes on disk | Working |
|---|---|---|---|---|
| MThd (header) | 0 | 6 | 14 B | 8 + 6 = 14 |
| MTrk (conductor) | 14 | 8 | 16 B | 8 + 8 = 16 |
| MTrk (notes) | 30 | 131 | 139 B | 8 + 131 = 139 |
| Total | — | — | 169 B | 8+6 + 8+8 + 8+131 = 169 |
The first MTrk is an 8 B conductor track; the second holds 131 B of events. Walking from its body start at offset 38 through the variable-length delta-times enumerates 31 events: 14 Note On, 14 Note Off, one Program Change and two meta events. These byte positions were derived by enumeration, not typed in:
| Offset (decimal) | Byte | What the byte is | How it was derived |
|---|---|---|---|
| 0–3 | 4D 54 68 64 | header magic MThd | first four bytes of the file |
| 8–9 | 00 01 | format = 1 | big-endian 2-byte field after the MThd length |
| 10–11 | 00 02 | ntrks = 2 declared tracks | independent parser returns 1 note track |
| 12–13 | 01 E0 | division = 480 ticks/quarter | (0x01 << 8) | 0xE0 |
| 34–37 | 00 00 00 83 | note-track length = 131 B | length field at offset 34 |
| 38 | 00 | delta 0 before the track-name meta event | note-track body starts at chunk offset 30 + 8 |
| 45 | 00 | delta 0 before the first Note On | event enumeration from body start |
| 47 | 48 | first Note On pitch byte = 48 | first data byte of the Note On message |
| 53 | 64 | first Note Off delta = 100 ticks | single-byte VLQ, value = byte |
| 54 | 80 | Note Off status on channel 0 | byte after the delta |
| 55 | 48 | first Note Off pitch byte = 48 | first data byte of the Note Off message |
| 167 | 2F | End-of-Track meta type 2F | last meta event in the note track |
Each Note On / Note Off message carries two data bytes: note number then velocity. That gives 28 note-number bytes and 141 B of the file that a transposition leaves completely alone. The header contains no key or transpose field at all, and the independent parser reports 0 key-signature events. The Note On / Note Off bytes and the PPQ field were measured separately on this same file.
A common mental model is that changing a song's key means editing one header value. In this file that value does not exist. The header declares format, track count and division; the conductor track holds only a track-name meta event and an End-of-Track marker. The independent parser reports 0 tempo events, 0 time-signature events and 0 key-signature events. Adding semitones to the notes therefore cannot be done by editing a single field: every note-number byte of every note message has to change, and the pairing Note Off for each Note On has to change with it. This page reports only what the bytes declare and what the parser returned; it makes no claim about how any particular editor displays a key. The format field and the delta-time encoding were measured separately.
Four copies apply k = +1, +5, +7 and +12 semitones to the same 28 note-number bytes. Every copy is 169 B, differs in exactly those bytes, and was re-opened from scratch with @tonejs/midi 2.0.28. The formula is byte' = byte + k, because an SMF note-number data byte is the 7-bit MIDI note number:
| Shift (semitones) | Bytes changed | Bytes unchanged | First note | Highest pitch | Notes read | PPQ | Size |
|---|---|---|---|---|---|---|---|
| +1 | 28 | 141 | C#5 | 82 | 14 | 480 | 169 B |
| +5 | 28 | 141 | F5 | 86 | 14 | 480 | 169 B |
| +7 | 28 | 141 | G5 | 88 | 14 | 480 | 169 B |
| +12 | 28 | 141 | C6 | 93 | 14 | 480 | 169 B |
Each copy keeps 14 notes, PPQ 480, 0 tempo events and the same 14 start ticks, duration ticks and velocities as the source. Writing every original byte back restores the exact source SHA-256 — the structural check that these are in-place edits and not re-encoded files. A successful parse alone would not establish this: all 14 notes were compared row by row against midi' = midi + k and against the unchanged timing columns. Note numbers stay inside 0–127 for all four shifts (highest source pitch 81, highest shifted pitch 93); a shift that pushed a byte past 0x7F would leave the 7-bit data-byte range, which is why the range is stated here rather than assumed.
No figure below is copied from a rendered page. Chunk lengths come from the file's own length fields, note numbers from the data bytes, and the unchanged byte count from subtraction:
| Formula | Computed | Corroborated by |
|---|---|---|
| 8+6 + 8+8 + 8+131 | 169 B | sum of three chunk length fields + 8 B headers |
01 E0 | 480 ticks / quarter | independent parser PPQ |
| 60 / (120 × 480) | 1/960 s per tick | SMF default 120 BPM; this file has 0 tempo events |
| 7,627 / 960 | 7.944792 s | last event tick from event enumeration |
| 169 − 28 | 141 B unchanged | byte diff of each injected copy |
| midi' = midi + k | 72 + 12 = 84 | first note of the +12 copy |
| NOTE_NAMES[84 % 12] + (floor(84 / 12) - 1) | C6 | note name recomputed from the shifted byte |
| 81 + 12 | 93 | highest pitch of the +12 copy, still inside 0–127 |
| 31 = 14 + 14 + 1 + 2 | 31 events | Note On + Note Off + Program Change + meta |
01 E0 gives 480 ticks per quarter, so one tick is 60 / (120 × 480) = 1/960 s at the SMF default of 120 BPM; this file has no tempo event, and none of the four edits changes that. Enumerating the note track reaches offset 169 at 7,627 ticks = 7.944792 s. Pitch names follow NOTE_NAMES[midi % 12] + (floor(midi / 12) - 1): 60 is C4, 72 is C5, 84 is C6. The Program Change byte and the byte-level anatomy of this file were measured separately.
The independent parser returned 14 notes from the source, with pitches between 60 and 81. The table shows each note's base pitch, its note-number byte on disk, and the reading after the smallest (+1) and largest (+12) shifts. Both shifted columns were checked against the formula before being written here:
| # | Base pitch | Base byte | Base ticks | +1 name | +1 byte | +12 name | +12 byte |
|---|---|---|---|---|---|---|---|
| 1 | C5 | 48 | 0 | C#5 | 49 | C6 | 54 |
| 2 | C4 | 3C | 0 | C#4 | 3D | C5 | 48 |
| 3 | D5 | 4A | 959 | D#5 | 4B | D6 | 56 |
| 4 | D4 | 3E | 959 | D#4 | 3F | D5 | 4A |
| 5 | E5 | 4C | 1918 | F5 | 4D | E6 | 58 |
| 6 | E4 | 40 | 1918 | F4 | 41 | E5 | 4C |
| 7 | F5 | 4D | 2877 | F#5 | 4E | F6 | 59 |
| 8 | F4 | 41 | 2877 | F#4 | 42 | F5 | 4D |
| 9 | G5 | 4F | 3837 | G#5 | 50 | G6 | 5B |
| 10 | G4 | 43 | 3837 | G#4 | 44 | G5 | 4F |
| 11 | A5 | 51 | 4806 | A#5 | 52 | A6 | 5D |
| 12 | A4 | 45 | 4806 | A#4 | 46 | A5 | 51 |
| 13 | B4 | 47 | 5755 | C5 | 48 | B5 | 53 |
| 14 | C5 | 48 | 6713 | C#5 | 49 | C6 | 54 |
Both shifted byte columns equal base byte + k in hex, and both shifted name columns equal the note name recomputed from that byte. Start ticks are identical in all three readings: transposition moves pitch, not time. All 56 cells in the four shifted columns came from the parser and were independently recomputed from the two rules above.
Six more edits change exactly one note-number byte each — either the first Note On's pitch byte or the first Note Off's pitch byte — without changing its partner. All six are still 169 B with 168 B unchanged. The readings below are what the parser actually returned:
| Byte edit | Variant file | Still parses | Notes read | Size | What the parser saw |
|---|---|---|---|---|---|
| — (source) | C-major-eight-notes-44k1.mid | yes | 14 | 169 B | baseline independent parse |
48 → 49 @ offset 47 | control-on-plus1.mid | yes | 13 | 169 B | only the Note On pitch byte; its Note Off still names the old pitch; Note On pitch changed alone; still parses, returns 13 notes |
48 → 47 @ offset 47 | control-on-minus1.mid | yes | 13 | 169 B | one semitone down on the Note On byte alone; Note On pitch changed alone; still parses, returns 13 notes |
48 → 00 @ offset 47 | control-on-00.mid | yes | 13 | 169 B | lowest legal 7-bit note number; Note On pitch changed alone; still parses, returns 13 notes |
48 → 7F @ offset 47 | control-on-7F.mid | yes | 13 | 169 B | highest legal 7-bit note number; Note On pitch changed alone; still parses, returns 13 notes |
48 → 80 @ offset 47 | control-on-80.mid | yes | 13 | 169 B | high bit set: not a legal data byte; high bit set, not a legal data byte; still parses, returns 13 notes |
48 → 49 @ offset 55 | control-off-plus1.mid | yes | 13 | 169 B | only the Note Off pitch byte; Note Off pitch changed alone; still parses, returns 13 notes |
All six still parse, and all six return 13 notes instead of 14: breaking one half of a Note On / Note Off pair silently drops that note. Even writing 0x80 — a byte with the high bit set, which is not a legal data byte — does not make this parser throw; it still parses and reads 13 notes. A file that still parses is not necessarily a file with the same content. That is why the four transpositions were checked for note count, PPQ, a row-by-row pitch comparison, unchanged timing and velocity, and a byte-for-byte restore, and not merely for "it opened". In this round of controls there is no parse-failure row; we report that as measured rather than adding one from a different kind of edit.
Open the 169 B source file in a hex editor, add k to each of the 28 note-number bytes listed in section 1, save and re-open with a MIDI library that reports note pitch, ticks and velocity. Chunk lengths need no editing: all four variants are in-place writes, and restoring the original bytes gives back the source SHA-256. The variant files themselves are not published here; the source file is, and every reading above can be reproduced from it. To convert audio instead, the MP3 to MIDI converter runs in your browser and produces a single-track .mid; the MIDI to MP3 tool renders in the other direction. Neither tool transposes.
Not here: no conversion-accuracy measurement, no speed figure, no tempo, BPM or key detection claim, no multitrack or per-instrument output, no drum track, no URL or YouTube input, no DAW test, and no claim that this site is more accurate than anyone else. Numbers come from one 169 B file published on 24 October 2026, four single-variable injections and six single-byte controls, measured on 12 November 2026 (UTC). General format facts, method notes, limits and disclaimers are excluded from the exclusive-material denominators above.