Андроид - PullRequest
       74

Андроид

6 голосов
/ 11 июня 2019

У меня есть один миди-файл, и я проиграл этот миди-файл, используя MediaPlayer в Android, используя следующий код:

val mMediaPlayer = MediaPlayer.create(context, R.raw.test_ring_1)

mMediaPlayer?.start()

По умолчанию играю на одном инструменте, таком как пианино, теперь я хочу добавить звуковой шрифт (sf2/ sf3) файл для воспроизведения миди-нот с другим инструментом и с эффектами реверберации.

Пожалуйста, укажите способ достижения ожидаемого результата.

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Существуют две библиотеки, которые будут использоваться для воспроизведения миди-файла с использованием SoundFont.

Midi Driver

Просто синтезатор для воспроизведения MIDI-ноты на Android. Вы можете использовать его вместе с библиотекой USB / Bluetooth-MIDI для создания приложения MIDI.

Файл SoundFont2 поддерживается.

Android MIDI Library

Эта библиотека предоставляет интерфейс для чтения, манипулирования и записи файлов MIDI. «Воспроизведение» поддерживается в качестве системы диспетчеризации событий в режиме реального времени. Эта библиотека НЕ ​​включает фактическое воспроизведение звука или сопряжение устройства.

Для инициализации SF2-SoundBank

SF2Soundbank sf = new SF2Soundbank(getAssets().open("test.sf2"));
        synth = new SoftSynthesizer();
        synth.open();
        synth.loadAllInstruments(sf);
        synth.getChannels()[0].programChange(0);
        synth.getChannels()[1].programChange(1);
        recv = synth.getReceiver();

Воспроизведение нот миди из файла миди

MidiFile midiFile = new MidiFile(getAssets().open("test.mid"));

// Create a new MidiProcessor:
MidiProcessor processor = new MidiProcessor(midiFile);

// listen for all midi events:
processor.registerEventListener(new MidiEventListener() {
    @Override
    public void onStart(boolean fromBeginning) {

    }

    @Override
    public void onEvent(MidiEvent event, long ms) {

        if (event.getClass() == NoteOn.class) {

                NoteOn noteOn = ((NoteOn) event);

                try {
                    ShortMessage msg = new ShortMessage();
                    msg.setMessage(ShortMessage.NOTE_ON, channel, noteOn.getNoteValue(), noteOn.getVelocity());
                    recv.send(msg, ms);
                } catch (InvalidMidiDataException e) {
                    e.printStackTrace();
                }

            } else if (event.getClass() == NoteOff.class) {

                NoteOff noteOff = ((NoteOff) event);

                try {
                    ShortMessage msg = new ShortMessage();
                    msg.setMessage(ShortMessage.NOTE_ON, channel, noteOff.getNoteValue(), noteOff.getVelocity());
                    recv.send(msg, ms);
                } catch (InvalidMidiDataException e) {
                    e.printStackTrace();
                }

            }
    }

    @Override
    public void onStop(boolean finished) {

    }
}, MidiEvent.class);

// Start the processor:
processor.start();

Переменная для определения канала SF

private int channel = 0;
0 голосов
/ 19 июня 2019

Я проверил, что это работает

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try {
        SF2Soundbank sf = new SF2Soundbank(getAssets().open("SmallTimGM6mb.sf2"));
        synth = new SoftSynthesizer();
        synth.open();
        synth.loadAllInstruments(sf);
        synth.getChannels()[0].programChange(0);
        synth.getChannels()[1].programChange(1);
        recv = synth.getReceiver();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (MidiUnavailableException e) {
        e.printStackTrace();
    }


    this.findViewById(R.id.piano).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = MotionEventCompat.getActionMasked(event);
            if (action == MotionEvent.ACTION_DOWN) {
                try {
                    ShortMessage msg = new ShortMessage();
                    msg.setMessage(ShortMessage.NOTE_ON, 0, 60, 127);
                    recv.send(msg, -1);
                } catch (InvalidMidiDataException e) {
                    e.printStackTrace();
                }
            } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                try {
                    ShortMessage msg = new ShortMessage();
                    msg.setMessage(ShortMessage.NOTE_OFF, 0, 60, 127);
                    recv.send(msg, -1);
                } catch (InvalidMidiDataException e) {
                    e.printStackTrace();
                }
            }
            return true;
        }
    });

    this.findViewById(R.id.woodblock).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = MotionEventCompat.getActionMasked(event);
            if (action == MotionEvent.ACTION_DOWN) {
                try {
                    ShortMessage msg = new ShortMessage();
                    msg.setMessage(ShortMessage.NOTE_ON, 1, 60, 127);
                    recv.send(msg, -1);
                } catch (InvalidMidiDataException e) {
                    e.printStackTrace();
                }
            } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                try {
                    ShortMessage msg = new ShortMessage();
                    msg.setMessage(ShortMessage.NOTE_OFF, 1, 60, 127);
                    recv.send(msg, -1);
                } catch (InvalidMidiDataException e) {
                    e.printStackTrace();
                }
            }
            return true;
        }
    });
}

Не забудьте включить библиотеку sherlockmidi из репозитория ниже, образец также доступен в репозитории ниже.

https://github.com/agangzz/SherlockMidi

...