Skip to content
Advertisement

Hexadecimal byte array from a Midi event to int

I’m trying to retrieve the tempo of a midi file through the javax.midi library.

MidiMessage message = event.getMessage();
if(message instanceof MetaMessage)
 MetaMessage mm = (MetaMessage) message;
 System.out.println(Arrays.toString(mm.getData()));
}

What I am expected to receive is an array of three ex, because the Set Tempo meta message (which is this case, has just 3 bytes specifying a miliseconds amount. This is how the midi event returns

0x07 0xA1 0x20

So if you join them you have 0x07A120 which is 500,000 ms, but Java returns in the print

[7, -95, 32]

First of all it is parsing it to decimal, and then I need to get this 500,000 number. I don’t know how to do it because first I need to join all the hex, and then I will have the number, but I don’t know how to do it.

Anyone can help me, please?

Advertisement

Answer

MetaMessage.getData() returns a byte array, which you turn into a list of bytes using Arrays.asList(), that’s why you print a list of bytes.

Below is a method that compute the tempo in beats per minute from a TEMPO MetaMessage. The mspq variable (milliseconds per quarter) is the value you seek.

/**
 * Get the tempo in BPM coded in a Tempo Midi message.
 *
 * @param tempoMsg Must be a tempo MetaMessage (type=81)
 * @return
 */
static public int getTempoInBPM(MetaMessage tempoMsg)
{
    byte[] data = tempoMsg.getData();
    if (tempoMsg.getType() != 81 || data.length != 3)
    {
        throw new IllegalArgumentException("tempoMsg=" + tempoMsg);   
    }
    int mspq = ((data[0] & 0xff) << 16) | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
    int tempo = Math.round(60000001f / mspq);
    return tempo;
}

Here you’ll find some more Midi utilities in java.

Advertisement