首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android -使用MIDI文件播放SoundFont

Android -使用MIDI文件播放SoundFont
EN

Stack Overflow用户
提问于 2019-06-11 10:09:12
回答 2查看 5.2K关注 0票数 8

我有一个midi文件,我用下面的代码使用安卓中的MediaPlayer播放了这个midi文件:

代码语言:javascript
复制
val mMediaPlayer = MediaPlayer.create(context, R.raw.test_ring_1)

mMediaPlayer?.start()

它默认使用一种乐器,如钢琴,现在我想添加声音字体(sf2/sf3)文件,以发挥不同的乐器和混响效果的midi音符。

请指导达到预期效果的方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-21 09:45:13

有两个库将用于使用SoundFont播放midi文件。

Midi司机

只是一个在Android上播放MIDI音符的合成器。您可以使用它与USB/蓝牙- MIDI库一起创建您的MIDI应用程序。

支持SoundFont2文件。

Android MIDI图书馆

这个库提供了一个读取、操作和写入MIDI文件的接口。“回放”被支持作为一个实时事件调度系统。此库不包括实际的音频播放或设备接口。

初始化SF2-SoundBank

代码语言:javascript
复制
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();

播放Midi文件中的midi注释

代码语言:javascript
复制
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通道

代码语言:javascript
复制
private int channel = 0;
票数 2
EN

Stack Overflow用户

发布于 2019-06-19 07:10:55

我已经测试过了,它正在起作用。

代码语言:javascript
复制
    @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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56541361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档