< prev index next >
src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencer.java
Print this page
*** 25,42 ****
package com.sun.media.sound;
import java.io.IOException;
import java.io.InputStream;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
! import javax.sound.midi.*;
!
/**
* A Real Time Sequencer
*
* @author Florian Bomers
--- 25,55 ----
package com.sun.media.sound;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
! import javax.sound.midi.ControllerEventListener;
! import javax.sound.midi.InvalidMidiDataException;
! import javax.sound.midi.MetaEventListener;
! import javax.sound.midi.MetaMessage;
! import javax.sound.midi.MidiDevice;
! import javax.sound.midi.MidiEvent;
! import javax.sound.midi.MidiMessage;
! import javax.sound.midi.MidiSystem;
! import javax.sound.midi.MidiUnavailableException;
! import javax.sound.midi.Receiver;
! import javax.sound.midi.Sequence;
! import javax.sound.midi.Sequencer;
! import javax.sound.midi.ShortMessage;
! import javax.sound.midi.Synthesizer;
! import javax.sound.midi.Track;
! import javax.sound.midi.Transmitter;
/**
* A Real Time Sequencer
*
* @author Florian Bomers
*** 46,57 ****
* - rename PlayThread to PlayEngine (because isn't a thread)
*/
final class RealTimeSequencer extends AbstractMidiDevice
implements Sequencer, AutoConnectSequencer {
- // STATIC VARIABLES
-
/** debugging flags */
private static final boolean DEBUG_PUMP = false;
private static final boolean DEBUG_PUMP_ALL = false;
/**
--- 59,68 ----
*** 71,81 ****
private static final Sequencer.SyncMode[] slaveSyncModes = { Sequencer.SyncMode.NO_SYNC };
private static final Sequencer.SyncMode masterSyncMode = Sequencer.SyncMode.INTERNAL_CLOCK;
private static final Sequencer.SyncMode slaveSyncMode = Sequencer.SyncMode.NO_SYNC;
-
/**
* Sequence on which this sequencer is operating.
*/
private Sequence sequence = null;
--- 82,91 ----
*** 85,102 ****
* Same for setTempoInMPQ...
* -1 means not set.
*/
private double cacheTempoMPQ = -1;
-
/**
* cache value for tempo factor until sequence is set
* -1 means not set.
*/
private float cacheTempoFactor = -1;
-
/** if a particular track is muted */
private boolean[] trackMuted = null;
/** if a particular track is solo */
private boolean[] trackSolo = null;
--- 95,110 ----
*** 106,156 ****
/**
* True if the sequence is running.
*/
private volatile boolean running;
!
! /** the thread for pushing out the MIDI messages */
private PlayThread playThread;
-
/**
! * True if we are recording
*/
private volatile boolean recording;
-
/**
! * List of tracks to which we're recording
*/
private final List<RecordingTrack> recordingTracks = new ArrayList<>();
-
private long loopStart = 0;
private long loopEnd = -1;
private int loopCount = 0;
-
/**
! * Meta event listeners
*/
private final ArrayList<Object> metaEventListeners = new ArrayList<>();
-
/**
! * Control change listeners
*/
private final ArrayList<ControllerListElement> controllerEventListeners = new ArrayList<>();
!
! /** automatic connection support */
private boolean autoConnect = false;
! /** if we need to autoconnect at next open */
private boolean doAutoConnectAtNextOpen = false;
! /** the receiver that this device is auto-connected to */
Receiver autoConnectedReceiver = null;
/* ****************************** CONSTRUCTOR ****************************** */
--- 114,165 ----
/**
* True if the sequence is running.
*/
private volatile boolean running;
! /**
! * the thread for pushing out the MIDI messages.
! */
private PlayThread playThread;
/**
! * True if we are recording.
*/
private volatile boolean recording;
/**
! * List of tracks to which we're recording.
*/
private final List<RecordingTrack> recordingTracks = new ArrayList<>();
private long loopStart = 0;
private long loopEnd = -1;
private int loopCount = 0;
/**
! * Meta event listeners.
*/
private final ArrayList<Object> metaEventListeners = new ArrayList<>();
/**
! * Control change listeners.
*/
private final ArrayList<ControllerListElement> controllerEventListeners = new ArrayList<>();
! /**
! * automatic connection support.
! */
private boolean autoConnect = false;
! /**
! * if we need to autoconnect at next open.
! */
private boolean doAutoConnectAtNextOpen = false;
! /**
! * the receiver that this device is auto-connected to.
! */
Receiver autoConnectedReceiver = null;
/* ****************************** CONSTRUCTOR ****************************** */
*** 159,171 ****
if (Printer.trace) Printer.trace(">> RealTimeSequencer CONSTRUCTOR");
if (Printer.trace) Printer.trace("<< RealTimeSequencer CONSTRUCTOR completed");
}
-
/* ****************************** SEQUENCER METHODS ******************** */
public synchronized void setSequence(Sequence sequence)
throws InvalidMidiDataException {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: setSequence(" + sequence +")");
--- 168,180 ----
if (Printer.trace) Printer.trace(">> RealTimeSequencer CONSTRUCTOR");
if (Printer.trace) Printer.trace("<< RealTimeSequencer CONSTRUCTOR completed");
}
/* ****************************** SEQUENCER METHODS ******************** */
+ @Override
public synchronized void setSequence(Sequence sequence)
throws InvalidMidiDataException {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: setSequence(" + sequence +")");
*** 209,219 ****
}
if (Printer.trace) Printer.trace("<< RealTimeSequencer: setSequence(" + sequence +") completed");
}
!
public synchronized void setSequence(InputStream stream) throws IOException, InvalidMidiDataException {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: setSequence(" + stream +")");
if (stream == null) {
--- 218,228 ----
}
if (Printer.trace) Printer.trace("<< RealTimeSequencer: setSequence(" + sequence +") completed");
}
! @Override
public synchronized void setSequence(InputStream stream) throws IOException, InvalidMidiDataException {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: setSequence(" + stream +")");
if (stream == null) {
*** 227,242 ****
if (Printer.trace) Printer.trace("<< RealTimeSequencer: setSequence(" + stream +") completed");
}
!
public Sequence getSequence() {
return sequence;
}
!
public synchronized void start() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: start()");
// sequencer not open: throw an exception
if (!isOpen()) {
--- 236,251 ----
if (Printer.trace) Printer.trace("<< RealTimeSequencer: setSequence(" + stream +") completed");
}
! @Override
public Sequence getSequence() {
return sequence;
}
! @Override
public synchronized void start() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: start()");
// sequencer not open: throw an exception
if (!isOpen()) {
*** 257,267 ****
implStart();
if (Printer.trace) Printer.trace("<< RealTimeSequencer: start() completed");
}
!
public synchronized void stop() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: stop()");
if (!isOpen()) {
throw new IllegalStateException("sequencer not open");
--- 266,276 ----
implStart();
if (Printer.trace) Printer.trace("<< RealTimeSequencer: start() completed");
}
! @Override
public synchronized void stop() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: stop()");
if (!isOpen()) {
throw new IllegalStateException("sequencer not open");
*** 278,316 ****
implStop();
if (Printer.trace) Printer.trace("<< RealTimeSequencer: stop() completed");
}
!
public boolean isRunning() {
return running;
}
!
public void startRecording() {
if (!isOpen()) {
throw new IllegalStateException("Sequencer not open");
}
start();
recording = true;
}
!
public void stopRecording() {
if (!isOpen()) {
throw new IllegalStateException("Sequencer not open");
}
recording = false;
}
!
public boolean isRecording() {
return recording;
}
!
public void recordEnable(Track track, int channel) {
if (!findTrack(track)) {
throw new IllegalArgumentException("Track does not exist in the current sequence");
}
--- 287,325 ----
implStop();
if (Printer.trace) Printer.trace("<< RealTimeSequencer: stop() completed");
}
! @Override
public boolean isRunning() {
return running;
}
! @Override
public void startRecording() {
if (!isOpen()) {
throw new IllegalStateException("Sequencer not open");
}
start();
recording = true;
}
! @Override
public void stopRecording() {
if (!isOpen()) {
throw new IllegalStateException("Sequencer not open");
}
recording = false;
}
! @Override
public boolean isRecording() {
return recording;
}
! @Override
public void recordEnable(Track track, int channel) {
if (!findTrack(track)) {
throw new IllegalArgumentException("Track does not exist in the current sequence");
}
*** 323,344 ****
}
}
}
!
public void recordDisable(Track track) {
synchronized(recordingTracks) {
RecordingTrack rc = RecordingTrack.get(recordingTracks, track);
if (rc != null) {
recordingTracks.remove(rc);
}
}
}
-
private boolean findTrack(Track track) {
boolean found = false;
if (sequence != null) {
Track[] tracks = sequence.getTracks();
for (int i = 0; i < tracks.length; i++) {
--- 332,352 ----
}
}
}
! @Override
public void recordDisable(Track track) {
synchronized(recordingTracks) {
RecordingTrack rc = RecordingTrack.get(recordingTracks, track);
if (rc != null) {
recordingTracks.remove(rc);
}
}
}
private boolean findTrack(Track track) {
boolean found = false;
if (sequence != null) {
Track[] tracks = sequence.getTracks();
for (int i = 0; i < tracks.length; i++) {
*** 349,377 ****
}
}
return found;
}
!
public float getTempoInBPM() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInBPM() ");
return (float) MidiUtils.convertTempo(getTempoInMPQ());
}
!
public void setTempoInBPM(float bpm) {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: setTempoInBPM() ");
if (bpm <= 0) {
// should throw IllegalArgumentException
bpm = 1.0f;
}
setTempoInMPQ((float) MidiUtils.convertTempo((double) bpm));
}
!
public float getTempoInMPQ() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInMPQ() ");
if (needCaching()) {
// if the sequencer is closed, return cached value
--- 357,385 ----
}
}
return found;
}
! @Override
public float getTempoInBPM() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInBPM() ");
return (float) MidiUtils.convertTempo(getTempoInMPQ());
}
! @Override
public void setTempoInBPM(float bpm) {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: setTempoInBPM() ");
if (bpm <= 0) {
// should throw IllegalArgumentException
bpm = 1.0f;
}
setTempoInMPQ((float) MidiUtils.convertTempo((double) bpm));
}
! @Override
public float getTempoInMPQ() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInMPQ() ");
if (needCaching()) {
// if the sequencer is closed, return cached value
*** 387,397 ****
return (float) MidiUtils.DEFAULT_TEMPO_MPQ;
}
return getDataPump().getTempoMPQ();
}
!
public void setTempoInMPQ(float mpq) {
if (mpq <= 0) {
// should throw IllegalArgumentException
mpq = 1.0f;
}
--- 395,405 ----
return (float) MidiUtils.DEFAULT_TEMPO_MPQ;
}
return getDataPump().getTempoMPQ();
}
! @Override
public void setTempoInMPQ(float mpq) {
if (mpq <= 0) {
// should throw IllegalArgumentException
mpq = 1.0f;
}
*** 408,418 ****
// reset the tempoInBPM and tempoInMPQ values so we won't use them again
cacheTempoMPQ = -1;
}
}
!
public void setTempoFactor(float factor) {
if (factor <= 0) {
// should throw IllegalArgumentException
return;
}
--- 416,426 ----
// reset the tempoInBPM and tempoInMPQ values so we won't use them again
cacheTempoMPQ = -1;
}
}
! @Override
public void setTempoFactor(float factor) {
if (factor <= 0) {
// should throw IllegalArgumentException
return;
}
*** 426,436 ****
// don't need cache anymore
cacheTempoFactor = -1;
}
}
!
public float getTempoFactor() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoFactor() ");
if (needCaching()) {
if (cacheTempoFactor != -1) {
--- 434,444 ----
// don't need cache anymore
cacheTempoFactor = -1;
}
}
! @Override
public float getTempoFactor() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoFactor() ");
if (needCaching()) {
if (cacheTempoFactor != -1) {
*** 439,471 ****
return 1.0f;
}
return getDataPump().getTempoFactor();
}
!
public long getTickLength() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickLength() ");
if (sequence == null) {
return 0;
}
return sequence.getTickLength();
}
!
public synchronized long getTickPosition() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickPosition() ");
if (getDataPump() == null || sequence == null) {
return 0;
}
return getDataPump().getTickPos();
}
!
public synchronized void setTickPosition(long tick) {
if (tick < 0) {
// should throw IllegalArgumentException
return;
}
--- 447,479 ----
return 1.0f;
}
return getDataPump().getTempoFactor();
}
! @Override
public long getTickLength() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickLength() ");
if (sequence == null) {
return 0;
}
return sequence.getTickLength();
}
! @Override
public synchronized long getTickPosition() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickPosition() ");
if (getDataPump() == null || sequence == null) {
return 0;
}
return getDataPump().getTickPos();
}
! @Override
public synchronized void setTickPosition(long tick) {
if (tick < 0) {
// should throw IllegalArgumentException
return;
}
*** 484,505 ****
} else {
getDataPump().setTickPos(tick);
}
}
!
public long getMicrosecondLength() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondLength() ");
if (sequence == null) {
return 0;
}
return sequence.getMicrosecondLength();
}
!
public long getMicrosecondPosition() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondPosition() ");
if (getDataPump() == null || sequence == null) {
return 0;
--- 492,513 ----
} else {
getDataPump().setTickPos(tick);
}
}
! @Override
public long getMicrosecondLength() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondLength() ");
if (sequence == null) {
return 0;
}
return sequence.getMicrosecondLength();
}
! @Override
public long getMicrosecondPosition() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondPosition() ");
if (getDataPump() == null || sequence == null) {
return 0;
*** 507,517 ****
synchronized (tempoCache) {
return MidiUtils.tick2microsecond(sequence, getDataPump().getTickPos(), tempoCache);
}
}
!
public void setMicrosecondPosition(long microseconds) {
if (microseconds < 0) {
// should throw IllegalArgumentException
return;
}
--- 515,525 ----
synchronized (tempoCache) {
return MidiUtils.tick2microsecond(sequence, getDataPump().getTickPos(), tempoCache);
}
}
! @Override
public void setMicrosecondPosition(long microseconds) {
if (microseconds < 0) {
// should throw IllegalArgumentException
return;
}
*** 532,569 ****
setTickPosition(MidiUtils.microsecond2tick(sequence, microseconds, tempoCache));
}
}
}
!
public void setMasterSyncMode(Sequencer.SyncMode sync) {
// not supported
}
!
public Sequencer.SyncMode getMasterSyncMode() {
return masterSyncMode;
}
!
public Sequencer.SyncMode[] getMasterSyncModes() {
Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[masterSyncModes.length];
System.arraycopy(masterSyncModes, 0, returnedModes, 0, masterSyncModes.length);
return returnedModes;
}
!
public void setSlaveSyncMode(Sequencer.SyncMode sync) {
// not supported
}
!
public Sequencer.SyncMode getSlaveSyncMode() {
return slaveSyncMode;
}
!
public Sequencer.SyncMode[] getSlaveSyncModes() {
Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[slaveSyncModes.length];
System.arraycopy(slaveSyncModes, 0, returnedModes, 0, slaveSyncModes.length);
return returnedModes;
}
--- 540,577 ----
setTickPosition(MidiUtils.microsecond2tick(sequence, microseconds, tempoCache));
}
}
}
! @Override
public void setMasterSyncMode(Sequencer.SyncMode sync) {
// not supported
}
! @Override
public Sequencer.SyncMode getMasterSyncMode() {
return masterSyncMode;
}
! @Override
public Sequencer.SyncMode[] getMasterSyncModes() {
Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[masterSyncModes.length];
System.arraycopy(masterSyncModes, 0, returnedModes, 0, masterSyncModes.length);
return returnedModes;
}
! @Override
public void setSlaveSyncMode(Sequencer.SyncMode sync) {
// not supported
}
! @Override
public Sequencer.SyncMode getSlaveSyncMode() {
return slaveSyncMode;
}
! @Override
public Sequencer.SyncMode[] getSlaveSyncModes() {
Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[slaveSyncModes.length];
System.arraycopy(slaveSyncModes, 0, returnedModes, 0, slaveSyncModes.length);
return returnedModes;
}
*** 575,643 ****
return sequence.getTracks().length;
}
return 0;
}
!
!
public synchronized void setTrackMute(int track, boolean mute) {
int trackCount = getTrackCount();
if (track < 0 || track >= getTrackCount()) return;
trackMuted = ensureBoolArraySize(trackMuted, trackCount);
trackMuted[track] = mute;
if (getDataPump() != null) {
getDataPump().muteSoloChanged();
}
}
!
public synchronized boolean getTrackMute(int track) {
if (track < 0 || track >= getTrackCount()) return false;
if (trackMuted == null || trackMuted.length <= track) return false;
return trackMuted[track];
}
!
public synchronized void setTrackSolo(int track, boolean solo) {
int trackCount = getTrackCount();
if (track < 0 || track >= getTrackCount()) return;
trackSolo = ensureBoolArraySize(trackSolo, trackCount);
trackSolo[track] = solo;
if (getDataPump() != null) {
getDataPump().muteSoloChanged();
}
}
!
public synchronized boolean getTrackSolo(int track) {
if (track < 0 || track >= getTrackCount()) return false;
if (trackSolo == null || trackSolo.length <= track) return false;
return trackSolo[track];
}
!
public boolean addMetaEventListener(MetaEventListener listener) {
synchronized(metaEventListeners) {
if (! metaEventListeners.contains(listener)) {
metaEventListeners.add(listener);
}
return true;
}
}
!
public void removeMetaEventListener(MetaEventListener listener) {
synchronized(metaEventListeners) {
int index = metaEventListeners.indexOf(listener);
if (index >= 0) {
metaEventListeners.remove(index);
}
}
}
!
public int[] addControllerEventListener(ControllerEventListener listener, int[] controllers) {
synchronized(controllerEventListeners) {
// first find the listener. if we have one, add the controllers
// if not, create a new element for it.
--- 583,650 ----
return sequence.getTracks().length;
}
return 0;
}
! @Override
public synchronized void setTrackMute(int track, boolean mute) {
int trackCount = getTrackCount();
if (track < 0 || track >= getTrackCount()) return;
trackMuted = ensureBoolArraySize(trackMuted, trackCount);
trackMuted[track] = mute;
if (getDataPump() != null) {
getDataPump().muteSoloChanged();
}
}
! @Override
public synchronized boolean getTrackMute(int track) {
if (track < 0 || track >= getTrackCount()) return false;
if (trackMuted == null || trackMuted.length <= track) return false;
return trackMuted[track];
}
! @Override
public synchronized void setTrackSolo(int track, boolean solo) {
int trackCount = getTrackCount();
if (track < 0 || track >= getTrackCount()) return;
trackSolo = ensureBoolArraySize(trackSolo, trackCount);
trackSolo[track] = solo;
if (getDataPump() != null) {
getDataPump().muteSoloChanged();
}
}
! @Override
public synchronized boolean getTrackSolo(int track) {
if (track < 0 || track >= getTrackCount()) return false;
if (trackSolo == null || trackSolo.length <= track) return false;
return trackSolo[track];
}
! @Override
public boolean addMetaEventListener(MetaEventListener listener) {
synchronized(metaEventListeners) {
if (! metaEventListeners.contains(listener)) {
metaEventListeners.add(listener);
}
return true;
}
}
! @Override
public void removeMetaEventListener(MetaEventListener listener) {
synchronized(metaEventListeners) {
int index = metaEventListeners.indexOf(listener);
if (index >= 0) {
metaEventListeners.remove(index);
}
}
}
! @Override
public int[] addControllerEventListener(ControllerEventListener listener, int[] controllers) {
synchronized(controllerEventListeners) {
// first find the listener. if we have one, add the controllers
// if not, create a new element for it.
*** 661,671 ****
// and return all the controllers this listener is interested in
return cve.getControllers();
}
}
!
public int[] removeControllerEventListener(ControllerEventListener listener, int[] controllers) {
synchronized(controllerEventListeners) {
ControllerListElement cve = null;
boolean flag = false;
for (int i=0; i < controllerEventListeners.size(); i++) {
--- 668,678 ----
// and return all the controllers this listener is interested in
return cve.getControllers();
}
}
! @Override
public int[] removeControllerEventListener(ControllerEventListener listener, int[] controllers) {
synchronized(controllerEventListeners) {
ControllerListElement cve = null;
boolean flag = false;
for (int i=0; i < controllerEventListeners.size(); i++) {
*** 688,726 ****
}
return cve.getControllers();
}
}
-
////////////////// LOOPING (added in 1.5) ///////////////////////
public void setLoopStartPoint(long tick) {
if ((tick > getTickLength())
|| ((loopEnd != -1) && (tick > loopEnd))
|| (tick < 0)) {
throw new IllegalArgumentException("invalid loop start point: "+tick);
}
loopStart = tick;
}
public long getLoopStartPoint() {
return loopStart;
}
public void setLoopEndPoint(long tick) {
if ((tick > getTickLength())
|| ((loopStart > tick) && (tick != -1))
|| (tick < -1)) {
throw new IllegalArgumentException("invalid loop end point: "+tick);
}
loopEnd = tick;
}
public long getLoopEndPoint() {
return loopEnd;
}
public void setLoopCount(int count) {
if (count != LOOP_CONTINUOUSLY
&& count < 0) {
throw new IllegalArgumentException("illegal value for loop count: "+count);
}
--- 695,737 ----
}
return cve.getControllers();
}
}
////////////////// LOOPING (added in 1.5) ///////////////////////
+ @Override
public void setLoopStartPoint(long tick) {
if ((tick > getTickLength())
|| ((loopEnd != -1) && (tick > loopEnd))
|| (tick < 0)) {
throw new IllegalArgumentException("invalid loop start point: "+tick);
}
loopStart = tick;
}
+ @Override
public long getLoopStartPoint() {
return loopStart;
}
+ @Override
public void setLoopEndPoint(long tick) {
if ((tick > getTickLength())
|| ((loopStart > tick) && (tick != -1))
|| (tick < -1)) {
throw new IllegalArgumentException("invalid loop end point: "+tick);
}
loopEnd = tick;
}
+ @Override
public long getLoopEndPoint() {
return loopEnd;
}
+ @Override
public void setLoopCount(int count) {
if (count != LOOP_CONTINUOUSLY
&& count < 0) {
throw new IllegalArgumentException("illegal value for loop count: "+count);
}
*** 728,746 ****
if (getDataPump() != null) {
getDataPump().resetLoopCount();
}
}
public int getLoopCount() {
return loopCount;
}
-
/* *********************************** play control ************************* */
! /*
! */
protected void implOpen() throws MidiUnavailableException {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: implOpen()");
//openInternalSynth();
--- 739,756 ----
if (getDataPump() != null) {
getDataPump().resetLoopCount();
}
}
+ @Override
public int getLoopCount() {
return loopCount;
}
/* *********************************** play control ************************* */
! @Override
protected void implOpen() throws MidiUnavailableException {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: implOpen()");
//openInternalSynth();
*** 818,835 ****
setTempoInMPQ((float) cacheTempoMPQ);
}
}
}
! /** populate the caches with the current values */
private synchronized void setCaches() {
cacheTempoFactor = getTempoFactor();
cacheTempoMPQ = getTempoInMPQ();
}
!
!
protected synchronized void implClose() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: implClose() ");
if (playThread == null) {
if (Printer.err) Printer.err("RealTimeSequencer.implClose() called, but playThread not instanciated!");
--- 828,846 ----
setTempoInMPQ((float) cacheTempoMPQ);
}
}
}
! /**
! * populate the caches with the current values.
! */
private synchronized void setCaches() {
cacheTempoFactor = getTempoFactor();
cacheTempoMPQ = getTempoInMPQ();
}
! @Override
protected synchronized void implClose() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: implClose() ");
if (playThread == null) {
if (Printer.err) Printer.err("RealTimeSequencer.implClose() called, but playThread not instanciated!");
*** 880,890 ****
playThread.start();
}
if (Printer.trace) Printer.trace("<< RealTimeSequencer: implStart() completed");
}
-
void implStop() {
if (Printer.trace) Printer.trace(">> RealTimeSequencer: implStop()");
if (playThread == null) {
if (Printer.err) Printer.err("RealTimeSequencer.implStop() called, but playThread not instanciated!");
--- 891,900 ----
*** 951,962 ****
}
}
getEventDispatcher().sendAudioEvents(message, sendToListeners);
}
-
-
private boolean needCaching() {
return !isOpen() || (sequence == null) || (playThread == null);
}
/**
--- 961,970 ----
*** 986,1041 ****
return newArray;
}
return array;
}
-
// OVERRIDES OF ABSTRACT MIDI DEVICE METHODS
protected boolean hasReceivers() {
return true;
}
// for recording
protected Receiver createReceiver() throws MidiUnavailableException {
return new SequencerReceiver();
}
!
protected boolean hasTransmitters() {
return true;
}
!
protected Transmitter createTransmitter() throws MidiUnavailableException {
return new SequencerTransmitter();
}
-
// interface AutoConnectSequencer
public void setAutoConnect(Receiver autoConnectedReceiver) {
this.autoConnect = (autoConnectedReceiver != null);
this.autoConnectedReceiver = autoConnectedReceiver;
}
-
-
- // INNER CLASSES
-
/**
* An own class to distinguish the class name from
! * the transmitter of other devices
*/
private class SequencerTransmitter extends BasicTransmitter {
private SequencerTransmitter() {
super();
}
}
-
final class SequencerReceiver extends AbstractReceiver {
void implSend(MidiMessage message, long timeStamp) {
if (recording) {
long tickPos = 0;
// convert timeStamp to ticks
--- 994,1046 ----
return newArray;
}
return array;
}
// OVERRIDES OF ABSTRACT MIDI DEVICE METHODS
+ @Override
protected boolean hasReceivers() {
return true;
}
// for recording
+ @Override
protected Receiver createReceiver() throws MidiUnavailableException {
return new SequencerReceiver();
}
! @Override
protected boolean hasTransmitters() {
return true;
}
! @Override
protected Transmitter createTransmitter() throws MidiUnavailableException {
return new SequencerTransmitter();
}
// interface AutoConnectSequencer
+ @Override
public void setAutoConnect(Receiver autoConnectedReceiver) {
this.autoConnect = (autoConnectedReceiver != null);
this.autoConnectedReceiver = autoConnectedReceiver;
}
/**
* An own class to distinguish the class name from
! * the transmitter of other devices.
*/
private class SequencerTransmitter extends BasicTransmitter {
private SequencerTransmitter() {
super();
}
}
final class SequencerReceiver extends AbstractReceiver {
+ @Override
void implSend(MidiMessage message, long timeStamp) {
if (recording) {
long tickPos = 0;
// convert timeStamp to ticks
*** 1078,1088 ****
}
}
}
}
-
private static class RealTimeSequencerInfo extends MidiDevice.Info {
private static final String name = "Real Time Sequencer";
private static final String vendor = "Oracle Corporation";
private static final String description = "Software sequencer";
--- 1083,1092 ----
*** 1091,1101 ****
RealTimeSequencerInfo() {
super(name, vendor, description, version);
}
} // class Info
-
private class ControllerListElement {
// $$jb: using an array for controllers b/c its
// easier to deal with than turning all the
// ints into objects to use a Vector
--- 1095,1104 ----
*** 1200,1210 ****
return c;
}
} // class ControllerListElement
-
static class RecordingTrack {
private final Track track;
private int channel;
--- 1203,1212 ----
*** 1242,1252 ****
return null;
}
}
-
final class PlayThread implements Runnable {
private Thread thread;
private final Object lock = new Object();
/** true if playback is interrupted (in close) */
--- 1244,1253 ----
*** 1349,1365 ****
oldThread.join(2000);
} catch (InterruptedException ie) {}
}
}
-
/**
* Main process loop driving the media flow.
*
* Make sure to NOT synchronize on RealTimeSequencer
* anywhere here (even implicit). That is a sure deadlock!
*/
public void run() {
while (!interrupted) {
boolean EOM = false;
boolean wasRunning = running;
--- 1350,1366 ----
oldThread.join(2000);
} catch (InterruptedException ie) {}
}
}
/**
* Main process loop driving the media flow.
*
* Make sure to NOT synchronize on RealTimeSequencer
* anywhere here (even implicit). That is a sure deadlock!
*/
+ @Override
public void run() {
while (!interrupted) {
boolean EOM = false;
boolean wasRunning = running;
*** 1407,1420 ****
} // end of while(!EOM && !interrupted && running)
if (Printer.debug) Printer.debug("end of play thread");
}
}
-
/**
* class that does the actual dispatching of events,
! * used to be in native in MMAPI
*/
private class DataPump {
private float currTempo; // MPQ tempo
private float tempoFactor; // 1.0 is default
private float inverseTempoFactor;// = 1.0 / tempoFactor
--- 1408,1420 ----
} // end of while(!EOM && !interrupted && running)
if (Printer.debug) Printer.debug("end of play thread");
}
}
/**
* class that does the actual dispatching of events,
! * used to be in native in MMAPI.
*/
private class DataPump {
private float currTempo; // MPQ tempo
private float tempoFactor; // 1.0 is default
private float inverseTempoFactor;// = 1.0 / tempoFactor
*** 1432,1442 ****
private int currLoopCounter = 0;
//private sun.misc.Perf perf = sun.misc.Perf.getPerf();
//private long perfFreq = perf.highResFrequency();
-
DataPump() {
init();
}
synchronized void init() {
--- 1432,1441 ----
*** 1514,1525 ****
applyDisabledTracks(trackDisabled, newDisabled);
}
trackDisabled = newDisabled;
}
-
-
synchronized void setSequence(Sequence seq) {
if (seq == null) {
init();
return;
}
--- 1513,1522 ----
*** 1566,1576 ****
}
}
if (DEBUG_PUMP) Printer.println(" noteOff: sent "+done+" messages.");
}
-
private boolean[] makeDisabledArray() {
if (tracks == null) {
return null;
}
boolean[] newTrackDisabled = new boolean[tracks.length];
--- 1563,1572 ----
*** 1654,1668 ****
// from the track while this method executes
}
if (DEBUG_PUMP) Printer.println(" sendNoteOffIfOn: sent "+done+" messages.");
}
-
/**
* Runtime application of mute/solo:
* if a track is muted that was previously playing, send
! * note off events for all currently playing notes
*/
private void applyDisabledTracks(boolean[] oldDisabled, boolean[] newDisabled) {
byte[][] tempArray = null;
synchronized(RealTimeSequencer.this) {
for (int i = 0; i < newDisabled.length; i++) {
--- 1650,1663 ----
// from the track while this method executes
}
if (DEBUG_PUMP) Printer.println(" sendNoteOffIfOn: sent "+done+" messages.");
}
/**
* Runtime application of mute/solo:
* if a track is muted that was previously playing, send
! * note off events for all currently playing notes.
*/
private void applyDisabledTracks(boolean[] oldDisabled, boolean[] newDisabled) {
byte[][] tempArray = null;
synchronized(RealTimeSequencer.this) {
for (int i = 0; i < newDisabled.length; i++) {
*** 1779,1790 ****
}
}
if (DEBUG_PUMP) Printer.println(" chaseTrackEvents track "+trackNum+": sent "+numControllersSent+" controllers.");
}
!
! /** chase controllers and program for all tracks */
synchronized void chaseEvents(long startTick, long endTick) {
if (DEBUG_PUMP) Printer.println(">> chaseEvents from tick "+startTick+".."+(endTick-1));
byte[][] tempArray = new byte[128][16];
for (int t = 0; t < tracks.length; t++) {
if ((trackDisabled == null)
--- 1774,1786 ----
}
}
if (DEBUG_PUMP) Printer.println(" chaseTrackEvents track "+trackNum+": sent "+numControllersSent+" controllers.");
}
! /**
! * chase controllers and program for all tracks.
! */
synchronized void chaseEvents(long startTick, long endTick) {
if (DEBUG_PUMP) Printer.println(">> chaseEvents from tick "+startTick+".."+(endTick-1));
byte[][] tempArray = new byte[128][16];
for (int t = 0; t < tracks.length; t++) {
if ((trackDisabled == null)
*** 1795,1805 ****
}
}
if (DEBUG_PUMP) Printer.println("<< chaseEvents");
}
-
// playback related methods (pumping)
private long getCurrentTimeMillis() {
return System.nanoTime() / 1000000l;
//return perf.highResCounter() * 1000 / perfFreq;
--- 1791,1800 ----
*** 1898,1908 ****
}
}
return changesPending;
}
-
/** the main pump method
* @return true if end of sequence is reached
*/
synchronized boolean pump() {
long currMillis;
--- 1893,1902 ----
*** 2076,2084 ****
}
} while (changesPending);
return EOM;
}
-
} // class DataPump
-
}
--- 2070,2076 ----
< prev index next >