Separate tracks which contain MIDI messages to multiple channels. - Java javax.sound.midi

Java examples for javax.sound.midi:MidiMessage

Description

Separate tracks which contain MIDI messages to multiple channels.

Demo Code


import java.util.ArrayList;
import java.util.List;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.Sequence;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;

public class Main{
    public static final int META_END_OF_TRACK = 0x2f;
    /**/*from  w  w w. j  a v  a 2 s .c om*/
     * Separate tracks which contain messages to multiple channels.
     * @param seq Sequence to be processed.
     * @return New sequence which does not contain mixed-channel tracks.
     * @throws InvalidMidiDataException throw if MIDI data is invalid.
     */
    public static Sequence SeparateMixedChannel(Sequence sourceSeq)
            throws InvalidMidiDataException {
        Sequence seq = new Sequence(sourceSeq.getDivisionType(),
                sourceSeq.getResolution());

        // process all input tracks
        for (int trackIndex = 0; trackIndex < sourceSeq.getTracks().length; trackIndex++) {
            Track sourceTrack = sourceSeq.getTracks()[trackIndex];

            List<Track> targetTracks = new ArrayList<Track>();
            List<Integer> targetChannels = new ArrayList<Integer>();

            targetTracks.add(seq.createTrack());
            targetChannels.add(null);

            // process all events
            for (int eventIndex = 0; eventIndex < sourceTrack.size(); eventIndex++) {
                MidiEvent event = sourceTrack.get(eventIndex);
                if (event.getMessage() instanceof ShortMessage) {
                    // channel message
                    ShortMessage message = (ShortMessage) event
                            .getMessage();
                    int targetIndex;

                    if (targetChannels.get(0) == null) {
                        // set the channel number
                        targetChannels.set(0, message.getChannel());
                        targetIndex = 0;
                    } else if ((targetIndex = targetChannels
                            .indexOf(message.getChannel())) == -1) {
                        targetIndex = targetChannels.size();
                        targetTracks.add(seq.createTrack());
                        targetChannels.add(message.getChannel());
                    }

                    Track targetTrack = targetTracks.get(targetIndex);
                    targetTrack.add(event);
                } else {
                    // non-channel message
                    boolean addToAll = false;
                    if (event.getMessage() instanceof MetaMessage) {
                        MetaMessage message = (MetaMessage) event
                                .getMessage();
                        if (message.getType() == MidiUtil.META_END_OF_TRACK) {
                            addToAll = true;
                        }
                    }

                    if (addToAll) {
                        for (Track targetTrack : targetTracks) {
                            targetTrack.add(event);
                        }
                    } else {
                        targetTracks.get(0).add(event);
                    }
                }
            }
        }
        return seq;
    }
}

Related Tutorials