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.