Удалить MidiEvent из треков не удается - MIDI / Java - PullRequest
1 голос
/ 24 марта 2011

Пользователь имеет возможность генерировать набор событий MIDI, которые, в свою очередь, добавляются в ArrayList, а затем перебираются и добавляются в объект Track, ожидая воспроизведения.Я пытаюсь удалить все события, которые находятся в дорожке, я делаю это путем перебора всех MIDI-событий в коллекции и использую «CreateNoteOnEvent» / «CreateNoteOffEvent» в методе .remove ().

По какой-то причине метод всегда возвращает значение 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 Ответ

2 голосов
/ 24 марта 2011

Изучив документацию, я обнаружил, что вы можете на самом деле вернуть 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();

Простой, но очень эффективный, вместо того, чтобы повторять цикл, который мог бы продолжаться честно, пока я читал документацию и вместо этого определился с этим методом. Хотя я не описывал его производительность, у меня есть ощущение, что это лучшее решение, чем зацикливание, особенно когда число итераций может быть довольно большим.

Надеюсь, это кому-нибудь поможет, я часами чесал голову над этим.

Спасибо за дополнительный отзыв!

...