Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualL. Spiro

Posted 15 December 2012 - 06:03 AM

I have worked with MIDI a ton and long ago I made a tool that generated valid MIDI files (the tool’s goal was to algorithmically generate music—it worked but the music it generated sucked ass).

Álvaro is correct about everything but the time. The times/durations must be in a resolution no shorter than microseconds. They should be stored in ULINT.
Today’s software have resolutions of up to around 960 PPQN (possibly more) and 250 BPM, giving you a resolution as low as 4.166667 microseconds between events.

The variable-length time stamps inside the MIDI files store the number of ticks between each successive event. For efficient run-time performance you should convert all of these event time stamps into literal times, which is why you need to store raw microsecond values. Internally you will still need to maintain this tick-style format so that you can add/remove events reliably and change the tempo, etc., without losing precision, but before playing a song you should make a quick prepass to convert all those ticks into absolute times.


Volume only ranges from 0 to 127, by the way. Most MIDI events do.

For anything you think will be in the range from 0-255, use an unsigned char, not a char. No reason to bite yourself in the ass with a useless sign bit, especially when shifting things.

For the instrument patch you are storing severely too little information. My Yamaha MOTIF XF8 has 1,353 voices and this is fairly common these days.
You need to look into the MSB/LSB system for selecting banks and patches.


L. Spiro

#1L. Spiro

Posted 15 December 2012 - 12:55 AM

I have worked with MIDI a ton and long ago I made a tool that generated valid MIDI files (the tool’s goal was to algorithmically generate music).

Álvaro is correct about everything but the time. The times/durations must be in a resolution no shorter than microseconds. They should be stored in ULINT.
Today’s software have resolutions of up to around 960 PPQN (possibly more) and 250 BPM, giving you a resolution as low as 4.166667 microseconds between events.

The variable-length time stamps inside the MIDI files store the number of ticks between each successive event. For efficient run-time performance you should convert all of these event time stamps into literal times, which is why you need to store raw microsecond values. Internally you will still need to maintain this tick-style format so that you can add/remove events reliably and change the tempo, etc., without losing precision, but before playing a song you should make a quick prepass to convert all those ticks into absolute times.


Volume only ranges from 0 to 127, by the way. Most MIDI events do.

For anything you think will be in the range from 0-255, use an unsigned char, not a char. No reason to bite yourself in the ass with a useless sign bit, especially when shifting things.

For the instrument patch you are storing severely too little information. My Yamaha MOTIF XF8 has 1,353 voices and this is fairly common these days.
You need to look into the MSB/LSB system for selecting banks and patches.


L. Spiro

PARTNERS