从Track中删除MidiEvent失败 - MIDI / Java

时间:2011-03-24 12:02:46

标签: java arraylist midi

用户可以生成一组MIDI事件,这些事件又被添加到ArrayList,然后迭代并添加到Track对象,等待播放。我正在尝试删除轨道中的所有事件,我通过迭代集合中的所有MIDI事件并使用.remove()方法中的“CreateNoteOnEvent”/“CreateNoteOffEvent”来完成此操作。

由于某种原因,该方法始终返回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;
    }

1 个答案:

答案 0 :(得分:2)

在挖掘文档后,我发现如果你指定了索引,你可以在轨道中返回一个MidiEvent,我的第一个解决方案实现如下:

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

这段代码的问题是循环是在Track的长度上检查它的条件,这将随着事件被移除而改变,因此它最终会使条件失败并且循环中断而在轨道中留下几个事件仍然。

这是可行的解决方案:

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

简单但非常有效,而不是通过一个循环来迭代,这可以继续公平,而我通读文档并决定使用这种方法。虽然我没有描述它的性能,但我觉得这是一个比循环更好的解决方案,特别是当迭代次数可能相当高时。

我希望它对某人有所帮助,我花了好几个小时对此嗤之以鼻。

感谢您提供更多反馈!