Сообщение Mididriver для смены инструмента и воспроизведения мелодии с указанием c ударов в минуту - PullRequest
0 голосов
/ 03 мая 2020

Я использую billthefarmer / mididriver на android для воспроизведения миди-нот. Я использовал этот вопрос здесь в качестве отправной точки. Теперь я могу отправить сообщение на внутренний синтезатор android, чтобы воспроизвести определенную ноту c на каком-либо канале с заданной скоростью, а также прекратить воспроизведение этой ноты.

private void playNote(int noteNumber) {

        // Construct a note ON message for the specified at maximum velocity on channel 1:
        event = new byte[3];
        event[0] = (byte) (0x90 | 0x00);  // This is the channel I guess but why two hex?
        event[1] = (byte) noteNumber;  // specified note
        event[2] = (byte) 127;  // 0x7F = the maximum velocity (127)

        // Internally this just calls write() and can be considered obsoleted:
        //midiDriver.queueEvent(event);

        // Send the MIDI event to the synthesizer.
        midiDriver.write(event);

    }

    private void stopNote(int noteNumber) {

        // Construct a note OFF message for the specified note at minimum velocity on channel 1:
        event = new byte[3];
        event[0] = (byte) (0x80 | 0x00);  // again why two hex?
        event[1] = (byte) noteNumber;  // specified note
        event[2] = (byte) 0x00;  // 0x00 = the minimum velocity (0)

        // Send the MIDI event to the synthesizer.
        midiDriver.write(event);

    }

Из того, что я могу сделать вывод эти сообщения отправляются в байтах, потому что MIDI-файлы и сигналы также являются двоичными (возможно?). Во всяком случае, есть некоторые вопросы, которые я не мог решить.

  1. Как создать сообщение для смены инструмента на канале?

Я нашел этот в Интернете. Это правильный способ реализации?

private void selectInstrument(int instrument) {

        // message to select the instrument on channel 1:
        event = new byte[2];
        event[0] = (byte)(0xC0 | 0x00); // Can't I use int 0 for channel 1?
        event[1] = (byte)instrument;

        // Send the MIDI event to the synthesizer.
        midiDriver.write(event);

    }

int instrument - это общий номер инструмента MIDI уровня 1.

Как синтезатор решает, какое сообщение говорит ему воспроизвести / остановить ноту, а какое - поменять инструмент на канале? Это длина байтового массива?

До сих пор мое приложение воспроизводит только примечание c, основанное на нажатой кнопке. Если я буду sh, чтобы воспроизвести последовательность нот с указанным c ударов в минуту. Скажите 180 ударов в минуту и ​​одну ноту за удар. Я должен сделать все это с кодом? Или есть способ передать некоторое двоичное сообщение в синтезатор, где он может воспроизвести массив или последовательность указанных нот с заданной скоростью c (уд. / Мин). Если да, то как?

1 Ответ

1 голос
/ 03 мая 2020

Старшие четыре бита байта состояния определяют тип сообщения. Прочитайте спецификацию MIDI .

В комплект android.media.midi не входит секвенсор MIDI. Если ваши MIDI-сообщения не генерируются в реальном времени, возможно, было бы лучше записать их в файл .mid и указать системе воспроизвести его.

...