Как получить целочисленное значение из байтового массива, возвращенного MetaMessage.getData ()?

1

Мне нужно получить значение темпа из midi файла. Я узнал, что команда set_tempo имеет значение 0x51, поэтому у меня есть эта часть кода:

    for (int i = 0; i < tracks[0].size(); i++) {
        MidiEvent event = tracks[0].get(i);
        MidiMessage message = event.getMessage();
        if (message instanceof MetaMessage) {
            MetaMessage mm = (MetaMessage) message;
            if(mm.getType()==SET_TEMPO){
                // now what?
                mm.getData();
            }
        }
    }

Но метод getData() возвращает массив байтов! Как я могу преобразовать его в обычную человеческую форму, ака целое? Я прочитал, что он хранится в таком формате: "tt tt tt", но все большие/маленькие endian, signed/unsigned и переменная длина делают его слишком запутанным.

Теги:
int
midi
javax.sound.midi
bytearray

2 ответа

5
Лучший ответ

Темп - это 3-байтовое целочисленное целое число, а бит в минуту вычисляется как
BPM = 60,000,000/(tt tt tt)

byte[] data = mm.getData();
int tempo = (data[0] & 0xff) << 16 | (data[1] & 0xff) << 8 | (data[2] & 0xff);
int bpm = 60000000 / tempo;
1

Я использую:

mpq = ((data[0] & 0x7f) << 14) | ((data[1] & 0x7f) << 7) | (data[2] & 0x7f);

Где mpq представляет микросекунды на четверть ноты или микросекунды за такт.

Причиной этого является то, что сообщения Midi используют только 7 бит в каждом байте для представления данных. Следует также отметить, что в Java тип данных байта (из которых - массив) является целым числом со знаком и имеет только место для 7 бит данных.

С момента создания этого сообщения у меня был следующий ответ от Ассоциации MIDI:

Номер параметра (tttttt) - это 24-битное целое число без знака, в формате большого конца.

"Установить темп" - это мета-событие, относящееся к спецификации SMF. Он применяется только к стандартным MIDI файлам, и, как и другие мета-события, не должны передаваться по проводам в реальном времени. С другой стороны, описание байта данных, которое вас сбивает с толку, относится к протоколу over-the-wire.

Поэтому исходный ответ на эту тему является правильным.

  • 0
    Разве оба решения не дают одинаковые результаты? Если это так, я не понимаю, в чем преимущество вашего решения.
  • 0
    Результаты будут отличаться примерно в 4 раза. Даже если первый результат делится на 4, он будет отличаться от второго результата до 3% в зависимости от последовательности битов и наличия знакового бита в каждом элементе данных. Способ проверить это - проверить продолжительность музыкального произведения, воспроизводимого или записанного в различных темпах.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню