Added support for attempting to use an alternate device to play midi,

even thought the java sequencer ignores the new Receiver.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1962 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2002-11-19 02:24:35 +00:00
parent 7f71748537
commit b0aabf1478
@@ -1,5 +1,5 @@
//
// $Id: SoundManager.java,v 1.17 2002/11/16 03:17:41 ray Exp $
// $Id: SoundManager.java,v 1.18 2002/11/19 02:24:35 ray Exp $
package com.threerings.media;
@@ -20,8 +20,10 @@ import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
@@ -45,6 +47,7 @@ import javax.swing.Timer;
import org.apache.commons.io.StreamUtils;
import com.samskivert.util.CollectionUtil;
import com.samskivert.util.LockableLRUHashMap;
import com.samskivert.util.LRUHashMap;
import com.samskivert.util.Queue;
@@ -98,6 +101,8 @@ public class SoundManager
// save things off
_rmgr = rmgr;
initMidi();
// create a thread to plays sounds and load sound
// data from the resource manager
_player = new Thread() {
@@ -332,6 +337,78 @@ public class SoundManager
}
}
/**
* Get a list of alternate midi devices.
*/
public MidiDevice.Info[] getAlternateMidiDevices ()
{
ArrayList infos = new ArrayList();
CollectionUtil.addAll(infos, MidiSystem.getMidiDeviceInfo());
// remove the synth/seqs, leaving only hardware midi thingies
for (Iterator iter=infos.iterator(); iter.hasNext(); ) {
try {
MidiDevice dev = MidiSystem.getMidiDevice(
(MidiDevice.Info) iter.next());
if ((dev instanceof Sequencer) ||
(dev instanceof Synthesizer)) {
iter.remove();
}
} catch (MidiUnavailableException mue) {
iter.remove();
}
}
return (MidiDevice.Info[]) infos.toArray(
new MidiDevice.Info[infos.size()]);
}
/**
* Attempt to use the alternate midi device for output.
* Return true if we're using it.
*/
public boolean useAlternateDevice (MidiDevice.Info devinfo)
{
Log.info("Trying alternate device: " + devinfo);
try {
MidiDevice dev = MidiSystem.getMidiDevice(devinfo);
Receiver rec = dev.getReceiver();
if (rec == null) {
Log.info("Got no device!");
return false;
}
_stoppingSong = true;
_sequencer.stop();
_sequencer.close();
Receiver old = _sequencer.getTransmitter().getReceiver();
Log.info("Old receiver: " + old);
if (old != null) {
old.close();
}
_sequencer.open();
// THIS DOESN'T WORK.
// See bug #4347135, specifically notes on the bottom.
_sequencer.getTransmitter().setReceiver(rec);
playTopSong();
// possibly shut down an old receiver
if (_receiver != null) {
_receiver.close();
}
// set the new receiver
_receiver = rec;
return true;
} catch (MidiUnavailableException mue) {
Log.warning("Use of alternate device failed [e=" + mue +
", device=" + devinfo + "].");
return false;
}
}
/**
* On the SoundManager thread,
* plays the sound file with the given pathname.
@@ -396,23 +473,6 @@ public class SoundManager
*/
protected void playSequence (MidiInfo info)
{
if (_sequencer == null) {
try {
Sequencer seq = MidiSystem.getSequencer();
seq.open();
if (seq instanceof Synthesizer) {
_midiChannels = ((Synthesizer) seq).getChannels();
//updateMusicVolume();
}
_sequencer = seq;
_sequencer.addMetaEventListener(this);
} catch (MidiUnavailableException mue) {
Log.warning("Midi unavailable. Can't play music.");
return;
}
}
stopCurrentSong(false);
_midiStack.addFirst(info);
playTopSong();
@@ -525,6 +585,27 @@ public class SoundManager
"[path=" + path + "].");
}
/**
* Initialize the midi system.
*/
protected void initMidi ()
{
try {
Sequencer seq = MidiSystem.getSequencer();
seq.open();
if (seq instanceof Synthesizer) {
_midiChannels = ((Synthesizer) seq).getChannels();
//updateMusicVolume();
}
_sequencer = seq;
_sequencer.addMetaEventListener(this);
} catch (MidiUnavailableException mue) {
Log.warning("Midi unavailable. Can't play music.");
return;
}
}
/**
* Stop playing and shutdown the midi system.
*/
@@ -533,6 +614,9 @@ public class SoundManager
_sequencer.removeMetaEventListener(this);
stopCurrentSong(false);
_sequencer.close();
if (_receiver != null) {
_receiver.close();
}
_sequencer = null;
_midiChannels = null;
_midiStack.clear();
@@ -932,6 +1016,10 @@ public class SoundManager
/** The sequencer that plays midi music. */
protected Sequencer _sequencer;
/** The receiver used to send midi from the sequencer to an alternate
* midi device. */
protected Receiver _receiver;
/** The channels in the sequencer, which we'll use to fuxor volumes. */
protected MidiChannel[] _midiChannels;