# New Song format

**URL:** <https://forum.makecode.com/t/new-song-format/17763>\
**Category:** Arcade\
**Created:** [February 3, 2023, 6:12pm UTC](https://forum.makecode.com/t/new-song-format/17763 "2023-02-03T18:12:41Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![richard](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/richard/32/5417_2.png) [@richard](https://forum.makecode.com/u/richard)\
**Post date:** [February 3, 2023, 6:12pm UTC](https://forum.makecode.com/t/new-song-format/17763/1 "2023-02-03T18:12:41Z")

</div>

I just remembered that I promised @UnsignedArduino that I would make a post linking to the new song format! Well, better late than never.

The format of the song buffer is documented here:

> <https://github.com/microsoft/pxt/blob/master/pxtlib/music.ts#L341>

That file also contains all of the code for encoding/decoding the songs from buffers (in this case, uint8Arrays). The default instruments are all defined in the getEmptySong function.

This code is mirrored in the arcade game engine here:

> <https://github.com/microsoft/pxt-common-packages/blob/master/libs/mixer/instrument.ts>

If I were, hypothetically, making a webapp that converted midi files into the new song format, then I would:

1. Copy all of [this file](https://github.com/microsoft/pxt/blob/master/pxtlib/music.ts)
2. Also copy [these two functions](https://github.com/microsoft/pxt/blob/master/pxtlib/util.ts#L961-L973)

there are also a bunch of utility functions for manipulating songs here:

> <https://github.com/microsoft/pxt/blob/master/webapp/src/components/musicEditor/utils.ts#L91>

---

<div class="post-metadata">

**Author:** ![richard](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/richard/32/5417_2.png) [@richard](https://forum.makecode.com/u/richard)\
**Post date:** [February 3, 2023, 6:15pm UTC](https://forum.makecode.com/t/new-song-format/17763/2 "2023-02-03T18:15:10Z")

</div>

Once I’m done doing hot fixes, I will write some proper docs explaining the format in more detail!

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [February 3, 2023, 7:58pm UTC](https://forum.makecode.com/t/new-song-format/17763/3 "2023-02-03T19:58:58Z")

</div>

Thank you so much! ~~I definitely did not waste an entire day converting that entire first file you linked to Python first. 🤡 🤡 🤡~~

---

<div class="post-metadata">

**Author:** ![richard](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/richard/32/5417_2.png) [@richard](https://forum.makecode.com/u/richard)\
**Post date:** [February 3, 2023, 8:00pm UTC](https://forum.makecode.com/t/new-song-format/17763/4 "2023-02-03T20:00:51Z")

</div>

One other thing I just thought of, note events for tracks need to be sorted by the start tick (e.g. they need to be encoded in chronological order).

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [February 3, 2023, 8:41pm UTC](https://forum.makecode.com/t/new-song-format/17763/5 "2023-02-03T20:41:03Z")

</div>

Also one question: I have code like this:

```auto
song.tracks[0].notes.append(
    NoteEvent(
        notes=[
            Note(
                note=49, # Lowest C in octave
                enharmonicSpelling=EnharmonicSpelling.NORMAL
            )
        ],
        startTick=0,
        endTick=8
    )
)

```

Why is 49 “middle C?” Is it a MIDI note index? Or something else?

---

<div class="post-metadata">

**Author:** ![richard](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/richard/32/5417_2.png) [@richard](https://forum.makecode.com/u/richard)\
**Post date:** [February 3, 2023, 10:19pm UTC](https://forum.makecode.com/t/new-song-format/17763/6 "2023-02-03T22:19:45Z")

</div>

yup! the numbers are midi note numbers

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [February 6, 2023, 6:29am UTC](https://forum.makecode.com/t/new-song-format/17763/7 "2023-02-06T06:29:29Z")

</div>

Hi @richard, sorry to bother you but right now, I’m having difficulty with the instrument octaves. I’m setting the octave to 2 here:

> <https://github.com/UnsignedArduino/Arcade-MIDI-to-Song/blob/main/src/main.py#L33>

I’m using a test MIDI file that has a glissando of notes from MIDI note 21 to 108, the lowest and highest notes on a piano. For some reason, the notes appear to be “shifted” by a couple of octaves. You can hear it here:

> **[test](https://arcade.makecode.com/50032-42165-39434-64579)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

Do you have any idea why? I’ve tried other octaves like 0, 1, and 3 but they all produce shifted ranges too. Do I have to split up the notes to separate tracks that handle instruments with different octaves?

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [August 16, 2023, 9:58pm UTC](https://forum.makecode.com/t/new-song-format/17763/8 "2023-08-16T21:58:11Z")

</div>

Progress update I guess:

> **[arcade midi to song test](https://arcade.makecode.com/52097-28378-28260-16361)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

Reload the page if you want to stop the song, because restarting the simulator doesn’t stop the song for some reason.

---

<div class="post-metadata">

**Author:** ![richard](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/richard/32/5417_2.png) [@richard](https://forum.makecode.com/u/richard)\
**Post date:** [August 16, 2023, 9:58pm UTC](https://forum.makecode.com/t/new-song-format/17763/9 "2023-08-16T21:58:38Z")

</div>

Yeah, known bug… Not sure when it started.

---

<div class="post-metadata">

**Author:** ![richard](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/richard/32/5417_2.png) [@richard](https://forum.makecode.com/u/richard)\
**Post date:** [August 16, 2023, 10:03pm UTC](https://forum.makecode.com/t/new-song-format/17763/10 "2023-08-16T22:03:41Z")

</div>

Also WOW the song editor cannot handle that. Might have to look into re-implementing it…

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [August 18, 2023, 9:17pm UTC](https://forum.makecode.com/t/new-song-format/17763/11 "2023-08-18T21:17:35Z")

</div>

(self-promotion hehe)

The Python tool is mostly done, I only need to iron out a couple of bugs:

> **[GitHub - UnsignedArduino/Arcade-MIDI-to-Song: A Python tool to convert a MIDI...](https://github.com/UnsignedArduino/Arcade-MIDI-to-Song)**
>
> A Python tool to convert a MIDI file to a MakeCode Arcade song! (Work in progress) - GitHub - UnsignedArduino/Arcade-MIDI-to-Song: A Python tool to convert a MIDI file to a MakeCode Arcade song! (W...

I will be working on a web-based version.

---

<div class="post-metadata">

**Author:** ![InvalidProject](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/invalidproject/32/32554_2.png) [@InvalidProject](https://forum.makecode.com/u/InvalidProject)\
**Post date:** [August 21, 2023, 4:41pm UTC](https://forum.makecode.com/t/new-song-format/17763/12 "2023-08-21T16:41:41Z")

</div>

Are you saying there’s another way I can make music? 🤨

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [August 21, 2023, 4:54pm UTC](https://forum.makecode.com/t/new-song-format/17763/13 "2023-08-21T16:54:31Z")

</div>

Yes! My script can convert a `.midi` file (which can be exported from any music score editor) to MakeCode Arcade’s new(ish) song format! It works much better than ArcadeMIDI and Musical-Images and does not use an extension.

---

<div class="post-metadata">

**Author:** ![AqeeAqee](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/aqeeaqee/32/5424_2.png) [@AqeeAqee](https://forum.makecode.com/u/AqeeAqee)\
**Post date:** [August 21, 2023, 5:15pm UTC](https://forum.makecode.com/t/new-song-format/17763/14 "2023-08-21T17:15:32Z")

</div>

> [@UnsignedArduino](#):
>
> I’m using a test MIDI file that has a glissando of notes from MIDI note 21 to 108, the lowest and highest notes on a piano. For some reason, the notes appear to be “shifted” by a couple of octaves.

The reason is here, I guess:

> <https://github.com/microsoft/pxt-common-packages/blob/a77d135a4a0a6123c53abe104dac999cabd8f49f/libs/mixer/instrument.ts#L286-L292>

The “& 0x3f” masked off notes range to 0~63+octave\*12, so whatever the octave set it can’t arrange 88 difference notes. So need 2 instruments at lease, 2 tracks as well(each track contain only 1 intrument).

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [August 25, 2023, 11:11pm UTC](https://forum.makecode.com/t/new-song-format/17763/15 "2023-08-25T23:11:02Z")

</div>

Thank you so much!!! I just fixed the converter so that all the high notes work.

---

<div class="post-metadata">

**Author:** ![UnsignedArduino](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/unsignedarduino/32/592_2.png) [@UnsignedArduino](https://forum.makecode.com/u/UnsignedArduino)\
**Post date:** [September 5, 2023, 3:00pm UTC](https://forum.makecode.com/t/new-song-format/17763/16 "2023-09-05T15:00:47Z")

</div>

Hi @richard sorry to bother you, but I can’t seem to find the declaration of `U`: (which I’m assuming is the same as `pxt.U`)

```ts
  export function encodeSongToHex(song: Song) {
    const encoded = encodeSong(song);
    return U.toHex(encoded);
  }

```

```ts
  export function decodeSongFromHex(hex: string) {
    const bytes = pxt.U.fromHex(hex);

    return decodeSong(bytes);
  }

```

Is it a namespace of utility functions?

* * *

> <https://github.com/microsoft/pxt/blob/master/pxtlib/music.ts#L20>

> <https://github.com/microsoft/pxt/blob/master/pxtlib/music.ts#L237>

---

<div class="post-metadata">

**Author:** ![richard](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/richard/32/5417_2.png) [@richard](https://forum.makecode.com/u/richard)\
**Post date:** [September 11, 2023, 4:39pm UTC](https://forum.makecode.com/t/new-song-format/17763/17 "2023-09-11T16:39:19Z")

</div>

It’s the same as the pxtc.Util namespace. Declared here: [https://github.com/microsoft/pxt/blob/master/pxtlib/main.ts#L31](https://github.com/microsoft/pxt/blob/master/pxtlib/main.ts#L31)

And here is that function:

> <https://github.com/microsoft/pxt/blob/master/pxtlib/util.ts#L968>

---

<div class="post-metadata">

**Author:** ![labfox29](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/labfox29/32/9252_2.png) [@labfox29](https://forum.makecode.com/u/labfox29)\
**Post date:** [September 13, 2023, 4:27pm UTC](https://forum.makecode.com/t/new-song-format/17763/18 "2023-09-13T16:27:31Z")

</div>

How can i use this?

---

<div class="post-metadata">

**Author:** ![ChimbroDaPro](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/chimbrodapro/32/15852_2.png) [@ChimbroDaPro](https://forum.makecode.com/u/ChimbroDaPro)\
**Post date:** [September 18, 2023, 5:52pm UTC](https://forum.makecode.com/t/new-song-format/17763/19 "2023-09-18T17:52:45Z")

</div>

Dude. WHAT AM I EVEN LOOKING AT. Seriously, some people are just too smart.

---

<div class="post-metadata">

**Author:** ![Sarge](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/sarge/32/19590_2.png) [@Sarge](https://forum.makecode.com/u/Sarge)\
**Post date:** [September 18, 2023, 5:54pm UTC](https://forum.makecode.com/t/new-song-format/17763/20 "2023-09-18T17:54:43Z")

</div>

Makecode source code! 😃

[Next page](https://forum.makecode.com/t/new-song-format/17763.md?page=2)
