android midi库在notes之前延迟

android midi库在notes之前延迟,android,midi,Android,Midi,我正在尝试生成midi文件并在Android上播放。我找到了android midi库,但几乎没有关于该库的任何文档。我试图从这个库中运行示例。它起作用了。但在我的笔记开始播放之前,有大约6秒的延迟。我对音符和midi格式一无所知。对我来说,一切都是新的 这是我的密码: public class MyActivity extends Activity { private MediaPlayer player = new MediaPlayer(); @Override public void

我正在尝试生成midi文件并在Android上播放。我找到了android midi库,但几乎没有关于该库的任何文档。我试图从这个库中运行示例。它起作用了。但在我的笔记开始播放之前,有大约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();
}
公共类MyActivity扩展活动{
私有媒体播放器=新媒体播放器();
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MidiTrack tempoTrack=新MidiTrack();
MidiTrack noteTrack=新MidiTrack();
//2.将事件添加到曲目中
//2a.音轨0通常是节奏图
节奏t=新节奏();
t、 秘书长(228);
tempoTrack.insertEvent(t);
//2b.第1轨道将包含一些注释
对于(int i=0;i<128;i++){
int通道=0,节距=i,速度=100;
NoteOn on=新的NoteOn(i*480,通道,音高,速度);
NoteOff off=新NoteOff(i*480+120,通道,音高,0);
noteTrack.insertEvent(打开);
noteTrack.insertEvent(关闭);
}
//最好不要手动插入EndOfTrack事件;MidiTrack将
//在将自身写入文件之前对自身调用closeTrack()
//3.使用我们创建的曲目创建MIDI文件
ArrayList轨迹=新建ArrayList();
tracks.add(tempoTrack);
tracks.add(noteTrack);
MidiFile midi=新的MidiFile(MidiFile.DEFAULT_分辨率,曲目);
//4.将MIDI数据写入文件
文件输出=新文件(“/sdcard/example.mid”);
试一试{
midi.writeToFile(输出);
}捕获(IOE异常){
Log.e(getClass().toString(),e.getMessage(),e);
}
试一试{
setDataSource(output.getAbsolutePath());
player.prepare();
}捕获(例外e){
Log.e(getClass().toString(),e.getMessage(),e);
}
player.start();
}
@凌驾
受保护的空onDestroy(){
player.stop();
player.release();
super.ondestory();
}
}

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

对于我来说,480值的两个音符之间的时间间隔是可以的,但在它们出现之前我不需要任何延迟


请帮帮我

好的,我知道问题出在哪里了

根据这个url,例如,钢琴的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;
}
delay=0;
持续时间=480;//太太
对于(int i=21;i<108;++i){
insertNote(香奈儿,i,速度,延迟,持续时间);
延迟+=持续时间;
}

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

好的,我找到了问题所在

根据这个url,例如,钢琴的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;
}
delay=0;
持续时间=480;//太太
对于(int i=21;i<108;++i){
insertNote(香奈儿,i,速度,延迟,持续时间);
延迟+=持续时间;
}

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

我觉得延迟是试图创建、保存、加载和播放文件时固有的,所有这些都是通过onCreate方法完成的。这些不是即时操作。尝试将MediaPlayer.start()调用移动到由按钮触发的函数。当播放器初始化播放时,您应该期望有一个小的延迟,但提供的代码将第一个音符置于刻度0处,因此所经历的任何延迟都不是因为MIDI文件或库。此外,如果您不理解480值的用途,您应该了解更多关于MIDI的信息。在我看来,延迟似乎是尝试创建、保存、加载和播放文件时固有的,所有这些都是通过onCreate方法完成的。这些不是即时操作。尝试将MediaPlayer.start()调用移动到由按钮触发的函数。当播放器初始化播放时,您应该期望有一个小的延迟,但提供的代码将第一个音符置于刻度0处,因此所经历的任何延迟都不是因为MIDI文件或库。此外,如果您不了解480值的用途,您应该进一步了解MIDI。