2

I currently have a midi file parsed into a JSON object. Below is an image of the midi object in my browser console.

midi JSON object in browser console

My goal is to take this data (marked in red) and convert each item in the list to timestamps in milliseconds.

From my research, I know the meaning of the "deltaTime" property and I believe the "timeDivision" value of 192 (underlined in the image above) should be related to the tempo of the midi file.

However, because of my sparse knowledge of the maths behind midi file values, I don't know how to convert all that information to milliseconds. I'm certain it must be a relatively simple math equation. But I'm really lost. I'm trying to build an object that should look like this and match the current millisecond time of the JSON object

[image of expected end results

How do I convert the "timeDivision" value combined with the list of individual "deltaTime" values to milliseconds?

Even a basic answer would suffice. I just need to understand the math behind those values.

Dai
  • 141,631
  • 28
  • 261
  • 374
Adebowale
  • 23
  • 3
  • how did you get from the picture of the object to the picture of the expected result? manually? – Jaromanda X Jul 02 '23 at 05:09
  • 1
    [Images](https://idownvotedbecau.se/imageofcode) are OK but aren't mandatory. Code as a [mcve] is required 99% of the time. – zer00ne Jul 02 '23 at 05:21
  • Please tell us **exactly** which MIDI libraries you're using - because [the official WebMIDI API doesn't expose structured MIDI messages](https://developer.mozilla.org/en-US/docs/Web/API/MIDIMessageEvent) (only raw bytes in a `Uint8Array`), and none of the other JS+MIDI libraries I found [have data-members like `deltaTime` and `metaType``, like WebmidiJS](https://webmidijs.org/api/classes/WebMidi#eventMap). – Dai Jul 02 '23 at 06:46
  • 1
    `timeDivision` does not refer to tempo. It means that the `deltaTime` numbers are all in units of 1/192nd of a beat. Have you read the MIDI specs? – Tim Roberts Jul 02 '23 at 06:49
  • The default tempo is 120 beats per minute. – Tim Roberts Jul 02 '23 at 06:55
  • @JaromandaX, Not quite. However, I'm well aware that should be the results because that track represents positions for syllables in a song (for a karaoke) app. I have an xml file for this same track and that is what the values are. The challenge is just getting the midi-only approach to work. – Adebowale Jul 02 '23 at 20:25
  • @Dai, I'm using the midi-parser-js library on [npm](https://www.npmjs.com/package/midi-parser-js) (in a browser context). – Adebowale Jul 02 '23 at 20:28
  • Thanks for pointing that out @Tim Roberts. I understand that now. Yes, I checked the specs but not so comprehensively. I found it really hard to find documentation for those exact terms `termDivision` because I think the midi to JSON parser I'm using has unique terminology names. Will take a closer look at the specs. – Adebowale Jul 02 '23 at 20:32

1 Answers1

2

Delta value units

Midi files may contain one or more meta events to specify tempo in terms of the number of microseconds per quarter note. The default tempo is 120 BPM.

In MIDI a "quarter note" corresponds to a single beat. This may be because crotchet beats in 4/4 time are quarter the length of a semibreve, also known as a "whole note".

Each quarter note is divided into a number of "pulses per quarter note" (PPQN) where each pulse generates a playback timing tick. (As an aside, high values of the PPQN clock period lead to quantization of playback note lengths, whereas low periods can reproduce more subtle timing variations a musician might have used when recording a piece.)

The value of PPQN is set in the "master track header" (MThd) chunk, in the last two bytes of the chunk, which has a length of 6 bytes. The field name of the PPQN value shown in documentation is Division, while in the proxy object listing it has been labelled "timeDivision", with a value of 192.

Delta values are the number of PPQN ticks since the previous Midi event or meta-event in the source MIDI file.

Delta time conversion to microseconds

So to convert delta times to microseconds, you could use the formula

 microSeconds = deltaTime / Division  // delta time in quarter notes
              * microSeconds_per_quarter_note;   // taken from the binary value supplied in a tempo meta event.

The microSeconds_per_quarter_note for the default tempo of 120 BPM would be

 (60 / BPM)    // length of 1 beat in seconds
 * 1000000     // in microseconds

Warning

Detecting tempo changes within a midi file requires full and accurate parsing of raw MIDI data: the byte sequences for tempo change may occur within System exclusive messages (perhaps others?) as a valid part of their content. I am not in a position to comment on the accuracy or completeness of JSON file data shown in the post.

Variations: Some midi files may contain SMPTE timing information not covered above.

See Also

traktor
  • 17,588
  • 4
  • 32
  • 53