2011-03-24 54 views
1

用户有能力生成一组MIDI事件,然后将这些事件添加到ArrayList中,然后迭代并添加到Track对象中,等待播放。我试图删除轨道中的所有事件,我通过迭代集合中的所有MIDI事件并使用.remove()方法中的“CreateNoteOnEvent”/“CreateNoteOffEvent”来完成此操作。从跟踪中删除MidiEvent失败 - MIDI/Java

由于某些原因,该方法始终返回为false,因为它无法找到要删除的事件或未能删除它。

我是否正确地做了这件事?我只是假设我以与添加它们相同的方式删除这些事件。

谢谢!

删除:

Iterator itr = collection.iterator(); 

     try 
     { 
      if(sequencer.isRunning()) 
      { 
       Stop(); 
      } 
      while (itr.hasNext()) 
      { 
       MIDIMessageContainer msg = (MIDIMessageContainer) itr.next(); 

       if(!track.remove(CreateNoteOnEvent(msg.GetChannel(), msg.GetKey(), msg.GetTick(), msg.GetVelocity()))) 
       { 
        Logger.Add("MIDI Event not removed"); 
        return false; 
       } 
       if(!track.remove(CreateNoteOffEvent(msg.GetChannel(), msg.GetKey(), msg.GetTick(), msg.GetVelocity()))) 
       { 
        Logger.Add("MIDI Event not removed"); 
        return false; 
       } 
      } 

      collection.clear(); 
      return true; 
     } 

CreateNoteOnEvent:

private static MidiEvent CreateNoteOnEvent(int channel, int pitch, long tick, int velocity) 
    { 
     ShortMessage noteOnMessage = new ShortMessage(); 

     try 
     { 
      noteOnMessage.setMessage(ShortMessage.NOTE_ON, channel, pitch, velocity); 
     } 
     catch (Exception e) 
     { 
      Logger.Add(e.getMessage()); 
     } 

     MidiEvent event = new MidiEvent(noteOnMessage, tick); 
     return event; 
    } 

CreateNoteOffEvent:

private static MidiEvent CreateNoteOffEvent(int channel, int pitch, long tick, int velocity) 
    { 
     ShortMessage noteOffMessage = new ShortMessage(); 

     try 
     { 
      noteOffMessage.setMessage(ShortMessage.NOTE_OFF, channel, pitch, velocity); 
     } 
     catch (Exception e) 
     { 
      Logger.Add(e.getMessage()); 
     } 

     MidiEvent event = new MidiEvent(noteOffMessage, tick + 1); 
     return event; 
    } 

回答

2

挖后我发现,你可以INFACT在轨道返回的MidiEvent如果指定索引的文档周围晋,我的第一个实施方案的是这样的:

for(int i = 0; i < track.size(); i++) 
{ 
     if(!track.remove(track.get(i))) 
     { 
       Logger.Add("MIDI Event not removed"); 
     } 
} 

这段代码的问题是循环正在检查它的条件的轨道长度,这将随着事件被删除而改变,所以它最终将会失败并跳出循环,从而留下轨道中的若干事件。

这是工作的解决方案:

_sequence.deleteTrack(_track); 
_track = _sequence.createTrack(); 

简单但非常有效的,而不是通过一个循环,而我通过阅读文件并在这个方法决定,而不是可能会持续一个公平的迭代。虽然我没有描述它的性能,但我认为这是比循环更好的解决方案,尤其是当迭代次数相当高时。

我希望它可以帮助别人,我花了几个小时在这个问题上挠头。

感谢您的额外反馈!