public final class MidiDevices
extends java.lang.Object
This class encapsulates the Java MIDI functionality. It is not meant to instantiate any objects and contains only static methods.
After parsing a file and creating a MIDI sequence, the parsing class sets the sequence with setSequence().
After starting the player or reparsing and resetting the sequence, setupDevices() is called in order to create all devices, connect them with each other and pass the sequene to the sequencer.
The other methods of this class are mostly used by the player.
Modifier and Type | Field and Description |
---|---|
private static boolean[] |
channelMute |
private static boolean[] |
channelSolo |
private static byte[] |
channelVolumeLsb |
private static byte[] |
channelVolumeMsb |
static int |
DEFAULT_CHANNEL_VOL_LSB |
static int |
DEFAULT_CHANNEL_VOL_MSB |
static byte |
DEFAULT_MASTER_VOL_LSB |
static byte |
DEFAULT_MASTER_VOL_MSB |
static int |
DEFAULT_TEMPO_BPM |
static int |
DEFAULT_TEMPO_MPQ |
private static java.util.TreeMap<java.lang.Byte,java.util.TreeMap<java.lang.Integer,java.lang.String>> |
instruments
channel – program * 2^14 + bankMSB * 2^7 + bankLSB – instrument name
|
private static byte |
masterVolumeLsb |
private static byte |
masterVolumeMsb |
private static java.util.ArrayList<javax.swing.table.AbstractTableModel> |
noteHistoryObservers |
static int |
NUMBER_OF_CHANNELS |
private static PlayerController |
playerController |
private static javax.sound.midi.Receiver |
receiver |
private static javax.sound.midi.Soundbank |
selectedSoundbank |
private static javax.sound.midi.Sequence |
seq |
private static javax.sound.midi.Sequencer |
sequencer |
private static int |
skipFastQuarters |
private static int |
skipQuarters |
private static javax.sound.midi.Synthesizer |
synthesizer |
private static float |
tempoFactor |
static int |
WAITING_TIME_BEFORE_REMEMBER |
Modifier | Constructor and Description |
---|---|
private |
MidiDevices()
This class is only used statically so a public constructor is not needed.
|
Modifier and Type | Method and Description |
---|---|
static void |
addNoteHistoryObserver(javax.swing.table.AbstractTableModel observer,
byte channel)
Adds the given observer to the data structure for note history observers.
|
static void |
destroyDevices()
Closes and destroys all MIDI devices.
|
static void |
doSoundcheck(int channel,
int[] instr,
int note,
byte volume,
int velocity,
int duration,
boolean keep)
Plays one note in the given channel.
|
static void |
fastForward()
Increments the current position in the MIDI stream by 16 quarter notes.
|
static void |
fastRewind()
Decrements the current position in the MIDI stream by 16 quarter notes.
|
static void |
forward()
Increments the current position in the MIDI stream by 4 quarter notes.
|
static byte |
getChannelVolume(byte channel)
Returns the current volume MSB of the given channel.
|
static byte |
getMasterVolume()
Returns the current master volume MSB.
|
static boolean |
getMute(int channel)
Determines if the given channel is muted.
|
static javax.sound.midi.Sequence |
getSequence()
Returns the sequence.
|
static boolean |
getSolo(int channel)
Determines if the given channel is soloed.
|
static javax.sound.midi.Soundbank |
getSoundbank()
Returns the currently selected soundbank if available, or otherwise the default soundbank if available, or null if neither is available.
|
static float |
getTempo()
Returns the current tempo factor that is responsible for the playing speed.
|
static long |
getTickLength()
Returns the length of the current MIDI stream in ticks.
|
static long |
getTickPosition()
Returns the current tick position in the MIDI stream.
|
static java.lang.String |
getTimeLength()
Returns the length of the current MIDI stream in the time format hh:mm:ss.
|
static java.lang.String |
getTimePosition()
Returns the current time in the MIDI stream.
|
private static void |
initInstrumentsIfNotYetDone(boolean soundbankAvailable)
Initializes the instruments of the right soundbank, if not yet done.
|
private static void |
initSoftwareInstruments(byte channel,
java.util.ArrayList<java.util.HashMap<java.lang.String,java.lang.String>> soundbankInstruments)
Initializes the instruments of a software soundbank, that are supported for the given channel.
|
static boolean |
isPlaying()
Determines if the sequencer is currently playing.
|
static boolean |
isSequenceSet()
Indicates if a sequence has been set.
|
static java.lang.String |
microsecondsToTimeString(long microseconds)
Transforms the given microseconds into a time string in the format hh:mm:ss.
|
static void |
pause()
Pauses a MIDI sequence that is currently being played.
|
static void |
play()
Starts to play the current MIDI sequence - or continues to play a paused sequence.
|
static void |
refreshChannelActivity(byte channel)
Is called if the activity of a channel has changed from active to inactive or the other way round.
|
static void |
refreshInstrument(byte channel)
Queries the current bank and instrument information and channel comment from the
SequenceAnalyzer and displays it on the player UI. |
static void |
refreshLyrics()
Is queried if the displayed lyrics must change.
|
static void |
refreshNoteHistory(byte channel)
Is called if at least one NOTE-ON event an a channel has occurred.
|
private static void |
rememberVolume()
Restores the volume settings in the sequencer.
|
static void |
resetNoteHistoryObservers()
Removes all note history observers from the according data structure.
|
static void |
restoreChannelAfterSoundcheck(int channel)
Restores the given channel’s state after the channel has been changed for a soundcheck.
|
static void |
rewind()
Decrements the current position in the MIDI stream by 4 quarter notes.
|
private static void |
sendChangeChannelVolumeMsg(int channelNumber,
byte volMsb,
byte volLsb)
Changes the volume of a channel by sending according MIDI messages.
|
private static void |
sendMessage(javax.sound.midi.MidiMessage msg)
Sends the given MIDI message immediately to the receiver, if possible.
|
private static void |
setAllChannelVolumes()
Sets the channel volume of every channel to the currently configured value.
|
static void |
setChannelVolume(int channelNumber,
byte volMsb,
byte volLsb)
Sets the volume of a channel.
|
private static void |
setMasterVolume()
Sets the master volume to the currently configured value by sending an according SysEx message.
|
static void |
setMasterVolume(byte volMsb,
byte volLsb)
Sets the master volume configuration to the given values.
|
static void |
setMute(int channel,
boolean mute)
Sets the mute state of the given channel.
|
static void |
setSequence(javax.sound.midi.Sequence sequence)
Sets the sequence.
|
static void |
setSolo(int channel,
boolean solo)
Sets the solo state of the given channel.
|
static void |
setSoundbank(javax.sound.midi.Soundbank soundbank)
Sets the given soundbank so that it can be used by the synthesizer.
|
static void |
setTempo(float factor)
Sets the tempo factor of the sequencer.
|
static void |
setTickPosition(long pos)
Sets the position of the current MIDI stream to the given value in ticks.
|
static void |
setupDevices(PlayerController controller)
Initializes all needed MIDI devices and connects them with each other.
|
private static javax.sound.midi.Transmitter |
setupSequencer()
Creates and initializes the sequencer.
|
private static javax.sound.midi.Receiver |
setupSynthesizer()
Initializes a software or hardware synthesizer.
|
static void |
stop()
Stops a MIDI sequence that is currently being played and resets it’s current position.
|
public static final int WAITING_TIME_BEFORE_REMEMBER
public static final byte DEFAULT_MASTER_VOL_MSB
public static final byte DEFAULT_MASTER_VOL_LSB
public static final int DEFAULT_CHANNEL_VOL_MSB
public static final int DEFAULT_CHANNEL_VOL_LSB
public static final int DEFAULT_TEMPO_BPM
public static final int DEFAULT_TEMPO_MPQ
public static final int NUMBER_OF_CHANNELS
private static PlayerController playerController
private static float tempoFactor
private static byte masterVolumeMsb
private static byte masterVolumeLsb
private static javax.sound.midi.Sequence seq
private static javax.sound.midi.Sequencer sequencer
private static javax.sound.midi.Synthesizer synthesizer
private static javax.sound.midi.Receiver receiver
private static int skipQuarters
private static int skipFastQuarters
private static javax.sound.midi.Soundbank selectedSoundbank
private static boolean[] channelMute
private static boolean[] channelSolo
private static byte[] channelVolumeMsb
private static byte[] channelVolumeLsb
private static java.util.TreeMap<java.lang.Byte,java.util.TreeMap<java.lang.Integer,java.lang.String>> instruments
channel – program * 2^14 + bankMSB * 2^7 + bankLSB – instrument name
private static java.util.ArrayList<javax.swing.table.AbstractTableModel> noteHistoryObservers
private MidiDevices()
This class is only used statically so a public constructor is not needed.
public static void setSequence(javax.sound.midi.Sequence sequence)
Sets the sequence. This is called by the file parser objects after creating the sequence via the SequenceCreator
class.
sequence
- The sequence to be set.public static javax.sound.midi.Sequence getSequence()
Returns the sequence. This is called by the exporter classes.
public static boolean isSequenceSet()
Indicates if a sequence has been set.
public static void setupDevices(PlayerController controller) throws javax.sound.midi.InvalidMidiDataException, javax.sound.midi.MidiUnavailableException, SequenceNotSetException, java.io.IOException
Initializes all needed MIDI devices and connects them with each other.
controller
- The player controller object.javax.sound.midi.InvalidMidiDataException
- if the sequence contains invalid data.javax.sound.midi.MidiUnavailableException
- if a device is not reachable.SequenceNotSetException
- if no sequence has been set yet. That means, no music file has been parsed successfully.java.io.IOException
- on I/O problems.private static javax.sound.midi.Transmitter setupSequencer() throws SequenceNotSetException, javax.sound.midi.MidiUnavailableException, javax.sound.midi.InvalidMidiDataException
Creates and initializes the sequencer.
SequenceNotSetException
- if no sequence has been set yet. That means, no music file has been parsed successfully.javax.sound.midi.MidiUnavailableException
- if a device is not reachable.javax.sound.midi.InvalidMidiDataException
- if the sequence contains invalid data.private static javax.sound.midi.Receiver setupSynthesizer() throws javax.sound.midi.MidiUnavailableException
Initializes a software or hardware synthesizer. If a soundbank file has been selected, loads this file into the synthesizer.
javax.sound.midi.MidiUnavailableException
- if a device is not reachable.private static void initInstrumentsIfNotYetDone(boolean soundbankAvailable)
Initializes the instruments of the right soundbank, if not yet done.
soundbankAvailable
- true if a software soundbank is available; false if a hardware synthesizer is used.private static void initSoftwareInstruments(byte channel, java.util.ArrayList<java.util.HashMap<java.lang.String,java.lang.String>> soundbankInstruments)
Initializes the instruments of a software soundbank, that are supported for the given channel.
channel
- MIDI channelsoundbankInstruments
- pre-analyzed soundbank instrumentspublic static void refreshChannelActivity(byte channel)
Is called if the activity of a channel has changed from active to inactive or the other way round. Gets the new channel activity from the SequenceAnalyzer
.
channel
- Channel number from 0 to 15.public static void refreshLyrics()
Is queried if the displayed lyrics must change. Gets the new lyrics from the SequenceAnalyzer
and changes the UI accordingly.
public static void destroyDevices()
Closes and destroys all MIDI devices.
public static void play() throws java.lang.IllegalStateException
Starts to play the current MIDI sequence - or continues to play a paused sequence.
java.lang.IllegalStateException
public static void pause() throws javax.sound.midi.InvalidMidiDataException, javax.sound.midi.MidiUnavailableException, java.lang.IllegalStateException
Pauses a MIDI sequence that is currently being played.
javax.sound.midi.InvalidMidiDataException
javax.sound.midi.MidiUnavailableException
java.lang.IllegalStateException
- if the sequencer is closed.public static void stop() throws javax.sound.midi.MidiUnavailableException, java.lang.IllegalStateException
Stops a MIDI sequence that is currently being played and resets it’s current position.
javax.sound.midi.MidiUnavailableException
java.lang.IllegalStateException
- if the sequencer is closed.public static void forward()
Increments the current position in the MIDI stream by 4 quarter notes.
public static void fastForward()
Increments the current position in the MIDI stream by 16 quarter notes.
public static void rewind()
Decrements the current position in the MIDI stream by 4 quarter notes.
public static void fastRewind()
Decrements the current position in the MIDI stream by 16 quarter notes.
public static long getTickPosition()
Returns the current tick position in the MIDI stream.
public static java.lang.String getTimePosition()
Returns the current time in the MIDI stream.
public static long getTickLength()
Returns the length of the current MIDI stream in ticks.
public static java.lang.String getTimeLength()
Returns the length of the current MIDI stream in the time format hh:mm:ss.
public static java.lang.String microsecondsToTimeString(long microseconds)
Transforms the given microseconds into a time string in the format hh:mm:ss.
microseconds
- number of microseconds to be transformed.public static void setTickPosition(long pos)
Sets the position of the current MIDI stream to the given value in ticks.
Also refreshes the channel activity and note history.
pos
- Tickstamp to be set.private static void rememberVolume()
Restores the volume settings in the sequencer.
For some mysterious reasons all volume settings are destroyed:
So we have to restore them again in these cases.
In some cases we have to wait a little until the volume resetting is accepted by the MIDI system.
public static boolean isPlaying()
Determines if the sequencer is currently playing.
public static void setTempo(float factor)
Sets the tempo factor of the sequencer.
factor
- Tempo factor.public static float getTempo()
Returns the current tempo factor that is responsible for the playing speed.
public static byte getMasterVolume()
Returns the current master volume MSB.
private static void setAllChannelVolumes()
Sets the channel volume of every channel to the currently configured value.
public static void setMasterVolume(byte volMsb, byte volLsb)
Sets the master volume configuration to the given values. Changes the master volume accordingly.
volMsb
- Most significant byte of the master volume.volLsb
- Most significant byte of the master volume.private static void setMasterVolume()
Sets the master volume to the currently configured value by sending an according SysEx message.
private static void sendMessage(javax.sound.midi.MidiMessage msg)
Sends the given MIDI message immediately to the receiver, if possible.
msg
- MIDI message.public static void setChannelVolume(int channelNumber, byte volMsb, byte volLsb)
Sets the volume of a channel. Sets the configuration and sends according message for MSB and LSB.
channelNumber
- Channel number from 0 to 15.volMsb
- Most significant byte of the channel volume (0-127).volLsb
- Most significant byte of the channel volume (0-127).private static void sendChangeChannelVolumeMsg(int channelNumber, byte volMsb, byte volLsb)
Changes the volume of a channel by sending according MIDI messages.
channelNumber
- Channel number from 0 to 15.volMsb
- Most significant byte (number from 0 to 127).volLsb
- Least significant byte (number from 0 to 127).public static byte getChannelVolume(byte channel)
Returns the current volume MSB of the given channel.
channel
- Channel number from 0 to 15.public static void setMute(int channel, boolean mute)
Sets the mute state of the given channel. A muted channel doesn’t produce an audio signal while playing.
channel
- Channel number from 0 to 15.mute
- true: muted; false: not muted.public static boolean getMute(int channel)
Determines if the given channel is muted. A muted channel doesn’t produce an audio signal while playing.
channel
- Channel number from 0 to 15.public static boolean getSolo(int channel)
Determines if the given channel is soloed. If at least one channel is soloed at a time, than only soloed channels produce an audio signal while playing. All non-soloed channels stay quiet.
channel
- Channel number from 0 to 15.public static void setSolo(int channel, boolean solo)
Sets the solo state of the given channel. If at least one channel is soloed at a time, than only soloed channels produce an audio signal while playing. All non-soloed channels stay quiet.
channel
- Channel number from 0 to 15.solo
- true: solo; false: not solo.public static void refreshNoteHistory(byte channel)
Is called if at least one NOTE-ON event an a channel has occurred. Informs the according table model about the change.
channel
- Channel number from 0 to 15.public static void refreshInstrument(byte channel)
Queries the current bank and instrument information and channel comment from the SequenceAnalyzer
and displays it on the player UI.
channel
- Channel number from 0 to 15.public static void resetNoteHistoryObservers()
Removes all note history observers from the according data structure. Initializes the data structure, if not yet done.
public static void addNoteHistoryObserver(javax.swing.table.AbstractTableModel observer, byte channel)
Adds the given observer to the data structure for note history observers. The observer will be triggered whenever a note in the given channel is played. Then it is responsible for refreshing the note history table for that channel.
observer
- Note history observer.channel
- Channel number from 0 to 15.public static void setSoundbank(javax.sound.midi.Soundbank soundbank)
Sets the given soundbank so that it can be used by the synthesizer.
soundbank
- Custom soundbank.public static javax.sound.midi.Soundbank getSoundbank()
Returns the currently selected soundbank if available, or otherwise the default soundbank if available, or null if neither is available.
public static void doSoundcheck(int channel, int[] instr, int note, byte volume, int velocity, int duration, boolean keep)
Plays one note in the given channel. This method is called from the soundcheck module. After playing the note, the old instrument number (program number) and channel volume are restored.
channel
- Channel number from 0 to 15.instr
- Instrument specification (program number, bank MSB, bank LSB)note
- Note or percussion instrument number.volume
- Channel volume for the note to be played.velocity
- Velocity (note volume) for the note to be played.duration
- Note length in milliseconds.keep
- true to keep the settings after playing the note, false to restore the channel’s state.public static void restoreChannelAfterSoundcheck(int channel)
Restores the given channel’s state after the channel has been changed for a soundcheck.
This is called from the soundcheck method directly (if the keep checkbox is unchecked) or after a soundcheck when the keep checkbox is un-checked later.
channel
- Channel number.