Midi Tools 1.5


SP4CEBAR 2021-05-02 20:12 (Edited)

This program can read, play and convert midi files.

You can choose to use the internal or an external disk, or both, but that's not supported yet. You can also choose what rom entry to use. In this version, you can load midi files of 32KB and below, in a future version I want to increase this to 64KB (with two disks).

Loading A MIDI File

To load in a midi file, you can open a .mid file in a hex editor, if you're on IOS you could use an online hex editor*. In the hex editor you can copy the hex data and paste it in this program, or the disk.nx program, or another program which can use this program as a tool. I've loaded a midi file for the nyan cat song in local rom entry 5.

HEX Editor

* This online hex editor is one of the few which allows you to copy the hex data to clipboard: Make sure to uncheck the "Use 0x and comma as separator".


When converting a midi file to an NX music file you can set the precision of the quantization: a value of 1 means that it'll preserve the music as best as it can, but it'll probably not fit in the 64 tracks of NX music, and the playback speed could be very slow.

Loading 64 KB

Although the program doesn't support it yet, you can theoretically load 64KB using both the internal and an external disk. To do this you'll need to split the file two files of 32KB or less. I think the best way to do this is to use a text editor with numbered lines like this compiler website: Then paste the 64KB of midi data into the text editor, go to the end of line 2048 and hit enter. Copy the first part to the disk.nx program or another program which can use this program as a tool, make sure it doesn't have any other ROM file in it. Finally, copy the second part to the ROM of this program, and remove/replace the midi data stored in ROM 5.




1.3 - Never gonna give you up

1.2 - important fix

Known Bugs And Errors:

With each update the program changes quite a bit. So If something doesn't work, just try a previous version.

Big thanks to Timo for helping me with the midi file system

Midi Tools.nx | Open in app
2021-05-06 21:47
Midi Tools.nx | Open in app
2021-05-06 18:31
Midi Tools.nx | Open in app
2021-05-04 10:48
Midi Tools.nx | Open in app
2021-05-03 22:01
Midi Tools.nx | Open in app
2021-05-03 08:36
Midi Tools.nx | Open in app
2021-05-02 20:12

CubicleHead 2021-05-03 11:30

So awesome! This will be very useful!

SP4CEBAR 2021-05-03 18:10


G-9 2021-05-04 12:07 (Edited)

Still not working :(
EDIT : I tried ur file to hex converter and it worked :3

Disk.nx | Open in app
2021-05-04 12:31

SP4CEBAR 2021-05-04 14:17


G-9 2021-05-04 18:54

Nice markdown :3

SP4CEBAR 2021-05-04 21:26 (Edited)

When I realized that markdown is the same markup language discord uses, I could use it straightaway

SP4CEBAR 2022-01-21 16:24

Read, play, and convert used to share the same loop, Man was that annoying to work with
It was one enormous block of code

I've just broken it up into subprograms and separate loops for each operation, it looks so much cleaner now

SP4CEBAR 2022-01-21 17:32 (Edited)

Also I used the variable "I" to hold the memory address, and whats worse is that I made it a global variable, why did I think that was a good idea

SP4CEBAR 2022-01-21 17:43

I managed to change the order of the tasks
It now reads the next delta T after it has executed a midi command (instead of before)
With this I know the time to wait in advance, which is essential if I want to make a scheduler (multitask)

G-9 2022-01-22 14:41

Amazing you did a real great job

SP4CEBAR 2022-01-22 16:54

Thank you!

SP4CEBAR 2022-01-22 21:22 (Edited)

I think I figured out why some tracks won't play correctly
I think that storing the address and the timecodes for each track in the scheduler isn't enough, I think my decoder needs more variables (it's been a while since I last worked on it)

SP4CEBAR 2022-01-22 21:28 (Edited)

I caught my midi decoder jumping $800 addresses ahead, so clearly it's missing something...

SP4CEBAR 2022-01-22 22:50 (Edited)

The jumping is caused by it reading a metadata command with a really long length, which is wrong
So it must've gone off-track earlier...

G-9 2022-01-23 14:36

I'm so hyped for both bugfix and multitrack convert :D
The song output would be amazing 🤩
Also to you have a trick about how to guess precision number ? My #15 file is filled with A-0 😂

SP4CEBAR 2022-01-23 17:51

I'm trying to make it play multiple tracks at once, this requires a scheduler and things get more complicated, I'm currently filling my program with tracers to compare the multitrack player with the single track player
The converter doesn't need a scheduler, it converts the tracks one by one (NX tracks are monophonic)
The precision is used for time quantization (aligning notes to a grid), when the NX file size is too big, you may want it to be less precise, and if it doesn't sound as good, you may want more precision (you may not be able to fit the whole song inside the 64 NX tracks)

(unstable wifi connection made me have to rewrite this)

SP4CEBAR 2022-01-23 19:33

I just got an idea: I could make a new file format called "NX Tracks" which contains just the tracks part of the NX music file format, but I can store as much NX tracks as needed
I could make my music editor compatible with that format as well
It would allow the converter of this midi tool to make music files that are much bigger

SP4CEBAR 2022-01-23 21:02

I have this bug memorial in my code:
I think it just happened again...

SP4CEBAR 2022-01-23 21:04

The first 8 bytes of each midi track contains the size of the track, which shouldn't be read as midi data, because it's not
This is what a good offset looks like: FOR I=INDEX(J)+8 TO INDEX(J+1)-1

SP4CEBAR 2022-01-23 21:06

YAAAS, the multitrack reader can now read the nyan cat midi file (which it couldn't before)

SP4CEBAR 2022-01-23 21:09


SP4CEBAR 2022-01-23 21:28

And the track playback is in sync!

SP4CEBAR 2022-01-23 21:29

It's done!!
*Well at least the scheduler-based midi player*

SP4CEBAR 2022-01-23 21:30

Next I'll try to find a way to optimize the usage of the four voices

SP4CEBAR 2022-01-26 21:18 (Edited)

The tracks slowly drift out of sync
This is probably caused by lag (the program can run behind on schedule), and the rounding of delta times (I have to convert delta times to NX-frames)
That's the issue with delta times, they are relative, it can't know whether or not it's synced with the other tracks unless it has an absolute time count to compare it to.
So I guess I've got to sum the delta times together for each track so that I can convert that to NX-frames and subtract TIMER from it to generate synced delta time values.

SP4CEBAR 2022-01-26 21:26 (Edited)

Also I think the converter needs more options
Currently you can only convert the tracks from the start until the memory (NX tracks) runs out
I want to add an option to select a single track to convert
Also, I want to add an option to export quantized notes as a file
And, I want to add an option to export unquantized notes as a file
I want to make my piano roll music studio compatible with those files so that you can do more post processing to improve the quantization quality
But it's a ton of work I'll probably not do any of this soon

nathanielbabiak 2022-06-05 03:52 (Edited)

Hey, as you were developing this, did you learn anything about the audio registers? I posted a question here... Any chance you could take a look?

SP4CEBAR 2022-06-05 20:15 (Edited)

@nathanielbabiak yes, I've done some tests myself on some of the audio registers, I'll try to answer your questions
I remember that I once understood how sounds are started and stopped via the registers, but I may have forgotten it now, I'll see if I can find some code that starts or stops sounds via registers
Either way, this program displays the state of those registers, and that was quite helpful for my research

SP4CEBAR 2022-06-05 20:20

I found a program that writes registers to start playing an arpeggio when you touch the screen and the sounds stop once you stop touching the screen

Voice Simulator.nx | Open in app
2022-06-05 20:20

SP4CEBAR 2022-06-05 20:29

After analyzing my code, I think this starts a sound
POKE $FF42,PEEK($FF42)MOD 64+64+128
And this stops a sound
POKE $FF42,PEEK($FF42)MOD 64+64

And there's also this, with the comment "INTITALIZE VOICES" above it
'POKE $FF42,PEEK($FF42)MOD 64+128

SP4CEBAR 2022-06-05 20:36

These lines of code read the status byte of voice 1 (peek($FF42)), set the most significant two bits to zero (mod 64), and then add their own most significant bit 2-bit codes (+64) and or (+128)

SP4CEBAR 2022-06-05 21:16

I just posted an answer to your question
I guess I wrote you a textbook

nathanielbabiak 2022-06-06 03:38

Thanks - this is excellent stuff!

Log in to reply.