1

我正在尝试生成 MIDI 文件并在 Android 上播放。我找到了 android-midi-lib,但几乎没有关于这个库的任何文档。我试图从这个库中运行示例。有用。但是在我的音符开始播放之前大约有 6 秒的延迟。我对笔记和midi格式一无所知。一切对我来说都是新的。

这是我的代码:

public class MyActivity extends Activity {

private MediaPlayer player = new MediaPlayer();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    MidiTrack tempoTrack = new MidiTrack();
    MidiTrack noteTrack = new MidiTrack();

    // 2. Add events to the tracks
    // 2a. Track 0 is typically the tempo map

    Tempo t = new Tempo();
    t.setBpm(228);

    tempoTrack.insertEvent(t);

    // 2b. Track 1 will have some notes in it
    for(int i = 0; i < 128; i++) {

        int channel = 0, pitch = i, velocity = 100;
        NoteOn on = new NoteOn(i*480, channel, pitch, velocity);
        NoteOff off = new NoteOff(i*480 + 120, channel, pitch, 0);

        noteTrack.insertEvent(on);
        noteTrack.insertEvent(off);
    }

    // It's best not to manually insert EndOfTrack events; MidiTrack will
    // call closeTrack() on itself before writing itself to a file

    // 3. Create a MidiFile with the tracks we created
    ArrayList<MidiTrack> tracks = new ArrayList<MidiTrack>();
    tracks.add(tempoTrack);
    tracks.add(noteTrack);

    MidiFile midi = new MidiFile(MidiFile.DEFAULT_RESOLUTION, tracks);

    // 4. Write the MIDI data to a file

    File output = new File("/sdcard/example.mid");
    try {
        midi.writeToFile(output);
    } catch(IOException e) {
        Log.e(getClass().toString(), e.getMessage(), e);
    }
    try {
        player.setDataSource(output.getAbsolutePath());
        player.prepare();
    } catch (Exception e) {
        Log.e(getClass().toString(), e.getMessage(), e);
    }
    player.start();
}

@Override
protected void onDestroy() {
    player.stop();
    player.release();
    super.onDestroy();
}

}

我发现这种延迟取决于 NoteOn 构造函数中的第一个参数(也可能是 NoteOff)。我不明白什么是480号码。我试图改变这个数字,这个数字比轨道前的延迟更短,但整个轨道更短。

似乎 480 值的音符之间的时间对我来说很好,但我不需要在它们之前延迟。

请帮帮我!

4

1 回答 1

1

好的,我发现了问题所在。

根据这个网址http://www.phys.unsw.edu.au/jw/notes.html钢琴的 MIDI 值例如从 21 开始。所以如果我从 0 开始循环,那么前 20 个值将不会播放任何东西.

现在关于延迟。

循环应该是这样的:

delay = 0;
duration = 480; // ms
for (int i = 21; i < 108; ++i) {
       noteTrack.insertNote(chanel, i, velocity, delay, duration);
       delay += duration;
}

延迟意味着应该在什么时间播放音符。因此,如果我们想一个一个地播放所有音符,我们需要将延迟设置为所有先前音符持续时间的总和。

于 2012-10-03T03:16:41.237 回答