Package org.jfugue

Source Code of org.jfugue.MidiEventManager

/*
* JFugue - API for Music Programming
* Copyright (C) 2003-2008  David Koelle
*
* http://www.jfugue.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

package org.jfugue;

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;

/**
* Places musical data into the MIDI sequence.
*
* <p>
* This was named EventManager in previous versions of JFugue. 
* </p>
*
*@author David Koelle
*@version 2.0
*@version 3.0 - renamed to MidiEventManager
*/
public final class MidiEventManager
{
    private final int CHANNELS = 16;
    private final int LAYERS = 16;
    private byte currentTrack = 0;
    private byte[] currentLayer = new byte[CHANNELS];
    private long time[][] = new long[CHANNELS][LAYERS];
    private Sequence sequence;
    private Track track[] = new Track[CHANNELS];

    public MidiEventManager(float sequenceTiming, int resolution)
    {
        try {
            this.sequence = new Sequence(sequenceTiming, resolution);
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        for (int i=0; i < CHANNELS; i++) {
            for (int u=0; u < LAYERS; u++) {
                time[i][u] = 0;
            }
            currentLayer[i] = 0;
            track[i] = sequence.createTrack();
        }
        currentTrack = 0;
    }
   
    /**
     * Sets the current track, or channel, to which new events will be added.
     * @param track the track to select
     */
    public void setCurrentTrack(byte track)
    {
        currentTrack = track;
    }

    /**
     * Sets the current layer within the track to which new events will be added.
     * @param track the track to select
     */
    public void setCurrentLayer(byte layer)
    {
        currentLayer[currentTrack] = layer;
    }

    /**
     * Advances the timer for the current track by the specified duration,
     * which is specified in Pulses Per Quarter (PPQ)
     * @param duration the duration to increase the track timer
     */
    public void advanceTrackTimer(long duration)
    {
        time[currentTrack][currentLayer[currentTrack]] += duration;
    }

    /**
     * Sets the timer for the current track by the given time,
     * which is specified in Pulses Per Quarter (PPQ)
     * @param newTime the time at which to set the track timer
     */
    public void setTrackTimer(long newTime)
    {
        time[currentTrack][currentLayer[currentTrack]] = newTime;
    }

    /**
     * Returns the timer for the current track.
     * @return the timer value for the current track, specified in Pulses Per Quarter (PPQ)
     */
    public long getTrackTimer()
    {
        return time[currentTrack][currentLayer[currentTrack]];
    }

    /**
     * Adds a MetaMessage to the current track. 
     *
     * @param command the MIDI command represented by this message
     * @param data1 the first data byte
     * @param data2 the second data byte
     */
    public void addMetaMessage(int type, byte[] bytes)
    {
        try {
            MetaMessage message = new MetaMessage();
            message.setMessage(type, bytes, bytes.length);
            MidiEvent event = new MidiEvent(message, getTrackTimer());
            track[currentTrack].add(event);
        } catch (InvalidMidiDataException e)
        {
            // We've kept a good eye on the data.  This exception won't happen.
            e.printStackTrace();
        }
    }


    /**
     * Adds a MIDI event to the current track. 
     *
     * @param command the MIDI command represented by this message
     * @param data1 the first data byte
     */
    public void addEvent(int command, int data1)
    {
        try {
            ShortMessage message = new ShortMessage();
            message.setMessage(command, currentTrack, data1);
            MidiEvent event = new MidiEvent(message, getTrackTimer());
            track[currentTrack].add(event);
        } catch (InvalidMidiDataException e)
        {
            // We've kept a good eye on the data.  This exception won't happen.
            e.printStackTrace();
        }
    }
   
    /**
     * Adds a MIDI event to the current track. 
     *
     * @param command the MIDI command represented by this message
     * @param data1 the first data byte
     * @param data2 the second data byte
     */
    public void addEvent(int command, int data1, int data2)
    {
        try {
            ShortMessage message = new ShortMessage();
            message.setMessage(command, currentTrack, data1, data2);
            MidiEvent event = new MidiEvent(message, getTrackTimer());
            track[currentTrack].add(event);
        } catch (InvalidMidiDataException e)
        {
            // We've kept a good eye on the data.  This exception won't happen.
            e.printStackTrace();
        }
    }
   
   
    /**
     * Adds a ShortMessage.NOTE_ON event to the current track, using attack and
     * decay velocity values.  Also adds a ShortMessage.NOTE_OFF command for
     * the note, using the duration parameter to space the NOTE_OFF command properly.
     *
     * Both the NOTE_ON and NOTE_OFF events can be suppressed.  This is useful
     * when notes are tied to other notes.
     *
     * @param data1 the first data byte, which contains the note value
     * @param data2 the second data byte for the NOTE_ON event, which contains the attack velocity
     * @param data3 the second data byte for the NOTE_OFF event, which contains the decay velocity
     * @param duration the duration of the note
     * @param addNoteOn whether a ShortMessage.NOTE_ON event should be created for for this event.  For the end of a tied note, this should be false; otherwise it should be true.
     * @param addNoteOff whether a ShortMessage.NOTE_OFF event should be created for for this event.  For the start of a tied note, this should be false; otherwise it should be true.
     */
    public void addNoteEvent(int data1, int data2, int data3, long duration, boolean addNoteOn, boolean addNoteOff)
    {
        try {
            if (addNoteOn) {
                ShortMessage message = new ShortMessage();
                message.setMessage(ShortMessage.NOTE_ON, currentTrack, data1, data2);
                MidiEvent event = new MidiEvent(message, getTrackTimer());
                track[currentTrack].add(event);
            }

            advanceTrackTimer(duration);

            if (addNoteOff) {
                ShortMessage message2 = new ShortMessage();
                message2.setMessage(ShortMessage.NOTE_OFF, currentTrack, data1, data3);
                MidiEvent event2 = new MidiEvent(message2, getTrackTimer());
                track[currentTrack].add(event2);
            }
        } catch (InvalidMidiDataException e)
        {
            // We've kept a good eye on the data.  This exception won't happen.
            e.printStackTrace();
        }
    }

    /**
     * Returns the current sequence, which is a collection of tracks.
     * If your goal is to add events to the sequence, you don't want to use this method to
     * get the sequence; instead, use the addEvent methods to add your events.
     * @return the current sequence
     */
    public Sequence getSequence()
    {
        return sequence;
    }
}
TOP

Related Classes of org.jfugue.MidiEventManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.