我正在尝试生成midi文件并在Android上播放。我找到了android-midi-lib,但几乎没有关于这个库的任何文档。我试图从这个lib运行示例。有用。但是在我的音符开始播放之前大约有6秒的延迟。我对notes和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的音符对我来说很好,但我不需要在它们之前延迟。
请帮帮我!
答案 0 :(得分:1)
好的,我发现了问题所在。
根据这个url 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;
}
延迟表示应该在什么时间播放音符。因此,如果我们想要逐个播放所有音符,我们需要将延迟设置为所有先前音符持续时间的总和。