genericized music playing, made transitioning from any music type to any
other clean and good. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1983 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,168 @@
|
|||||||
|
//
|
||||||
|
// $Id: MidiPlayer.java,v 1.1 2002/11/22 04:23:31 ray Exp $
|
||||||
|
|
||||||
|
package com.threerings.media;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does something extraordinary.
|
||||||
|
*/
|
||||||
|
public class MidiPlayer extends MusicPlayer
|
||||||
|
implements MetaEventListener
|
||||||
|
{
|
||||||
|
// documentation inherited
|
||||||
|
public void init ()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Sequencer seq = MidiSystem.getSequencer();
|
||||||
|
seq.open();
|
||||||
|
if (seq instanceof Synthesizer) {
|
||||||
|
_channels = ((Synthesizer) seq).getChannels();
|
||||||
|
//updateMusicVolume();
|
||||||
|
}
|
||||||
|
_sequencer = seq;
|
||||||
|
|
||||||
|
} catch (MidiUnavailableException mue) {
|
||||||
|
Log.warning("Midi unavailable! [e=" + mue + "].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void shutdown ()
|
||||||
|
{
|
||||||
|
_sequencer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void start (String set, String path)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_sequencer.setSequence(
|
||||||
|
new BufferedInputStream(_rmgr.getResource(set, path)));
|
||||||
|
_sequencer.start();
|
||||||
|
_sequencer.addMetaEventListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void stop ()
|
||||||
|
{
|
||||||
|
_sequencer.removeMetaEventListener(this);
|
||||||
|
_sequencer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void setVolume (float volume)
|
||||||
|
{
|
||||||
|
if (_channels != null) {
|
||||||
|
int setting = (int) (volume * 127.0);
|
||||||
|
for (int ii=0; ii < _channels.length; ii++) {
|
||||||
|
_channels[ii].controlChange(VOLUME_CONTROL, setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface MetaEventListener
|
||||||
|
public void meta (MetaMessage msg)
|
||||||
|
{
|
||||||
|
if (msg.getType() == END_OF_TRACK) {
|
||||||
|
_musicListener.musicStopped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// STUFF FROM ANOTHER TIME
|
||||||
|
// /**
|
||||||
|
// * 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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/** This is apparently the midi code for end of track. Wack. */
|
||||||
|
protected static final int END_OF_TRACK = 47;
|
||||||
|
|
||||||
|
/** The midi control for volume is 7. Ooooooo. */
|
||||||
|
protected static final int VOLUME_CONTROL = 7;
|
||||||
|
|
||||||
|
/** The sequencer. */
|
||||||
|
protected Sequencer _sequencer;
|
||||||
|
|
||||||
|
/** The channels in the sequencer, which we'll use to fuxor volumes. */
|
||||||
|
protected MidiChannel[] _channels;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: ModPlayer.java,v 1.2 2002/11/20 23:06:33 ray Exp $
|
// $Id: ModPlayer.java,v 1.3 2002/11/22 04:23:31 ray Exp $
|
||||||
|
|
||||||
package com.threerings.media;
|
package com.threerings.media;
|
||||||
|
|
||||||
@@ -20,36 +20,32 @@ import com.threerings.resource.ResourceManager;
|
|||||||
/**
|
/**
|
||||||
* Does something extraordinary.
|
* Does something extraordinary.
|
||||||
*/
|
*/
|
||||||
public class ModPlayer
|
public class ModPlayer extends MusicPlayer
|
||||||
{
|
{
|
||||||
public ModPlayer (ResourceManager rmgr, SoundManager smgr)
|
// documentation inherited
|
||||||
|
public void init ()
|
||||||
{
|
{
|
||||||
_rmgr = rmgr;
|
|
||||||
_smgr = smgr;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_device = new NaryaSoundDevice();
|
_device = new NaryaSoundDevice();
|
||||||
|
_device.start();
|
||||||
} catch (OutputDeviceException ode) {
|
} catch (OutputDeviceException ode) {
|
||||||
Log.warning("Unable to allocate sound channel for mod playing " +
|
Log.warning("Unable to allocate sound channel for mod playing " +
|
||||||
"[e=" + ode + "].");
|
"[e=" + ode + "].");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop ()
|
// documentation inherited
|
||||||
|
public void shutdown ()
|
||||||
{
|
{
|
||||||
_player = null;
|
_device.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
public void start (String set, String path)
|
public void start (String set, String path)
|
||||||
|
throws Exception
|
||||||
{
|
{
|
||||||
Module module = null;
|
Module module = ModuleLoader.read(
|
||||||
try {
|
new DataInputStream(_rmgr.getResource(set, path)));
|
||||||
module = ModuleLoader.read(
|
|
||||||
new DataInputStream(_rmgr.getResource(set, path)));
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
Log.warning("error loading oh shit oh shit: [e=" + ioe + "].");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final MicroMod mod = new MicroMod(
|
final MicroMod mod = new MicroMod(
|
||||||
module, _device, new LinearResampler());
|
module, _device, new LinearResampler());
|
||||||
@@ -57,9 +53,7 @@ public class ModPlayer
|
|||||||
_player = new Thread("narya mod player") {
|
_player = new Thread("narya mod player") {
|
||||||
public void run () {
|
public void run () {
|
||||||
|
|
||||||
_device.start();
|
while (mod.getSequenceLoopCount() == 0) {
|
||||||
while ((_player == Thread.currentThread()) &&
|
|
||||||
(mod.getSequenceLoopCount() == 0)) {
|
|
||||||
|
|
||||||
mod.doRealTimePlayback();
|
mod.doRealTimePlayback();
|
||||||
try {
|
try {
|
||||||
@@ -67,9 +61,14 @@ public class ModPlayer
|
|||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
// WFCares
|
// WFCares
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_player != Thread.currentThread()) {
|
||||||
|
// we were stopped!
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_device.stop();
|
_device.drain();
|
||||||
_smgr.songStopEvent();
|
_musicListener.musicStopped();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,10 +76,13 @@ public class ModPlayer
|
|||||||
_player.start();
|
_player.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// documentation inherited
|
||||||
* Set the volume of the midiplayer.
|
public void stop ()
|
||||||
* @param vol 0f - 1f (inclusive).
|
{
|
||||||
*/
|
_player = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
public void setVolume (float vol)
|
public void setVolume (float vol)
|
||||||
{
|
{
|
||||||
_device.setVolume(vol);
|
_device.setVolume(vol);
|
||||||
@@ -105,11 +107,16 @@ public class ModPlayer
|
|||||||
{
|
{
|
||||||
SoundManager.adjustVolume(sourceDataLine, vol);
|
SoundManager.adjustVolume(sourceDataLine, vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access the drain method of the line.
|
||||||
|
*/
|
||||||
|
public void drain ()
|
||||||
|
{
|
||||||
|
sourceDataLine.drain();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Thread _player;
|
protected Thread _player;
|
||||||
protected NaryaSoundDevice _device;
|
protected NaryaSoundDevice _device;
|
||||||
|
|
||||||
protected ResourceManager _rmgr;
|
|
||||||
protected SoundManager _smgr;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-15
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: MP3Manager.java,v 1.2 2002/11/20 04:03:09 ray Exp $
|
// $Id: Mp3Player.java,v 1.1 2002/11/22 04:23:31 ray Exp $
|
||||||
|
|
||||||
package com.threerings.media;
|
package com.threerings.media;
|
||||||
|
|
||||||
@@ -24,21 +24,24 @@ import com.threerings.resource.ResourceManager;
|
|||||||
/**
|
/**
|
||||||
* Does something extraordinary.
|
* Does something extraordinary.
|
||||||
*/
|
*/
|
||||||
public class MP3Manager
|
public class Mp3Player extends MusicPlayer
|
||||||
{
|
{
|
||||||
public MP3Manager (ResourceManager rmgr, SoundManager smgr)
|
// documentation inherited
|
||||||
|
public void init ()
|
||||||
{
|
{
|
||||||
_rmgr = rmgr;
|
|
||||||
_smgr = smgr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop ()
|
// documentation inherited
|
||||||
|
public void shutdown ()
|
||||||
{
|
{
|
||||||
_player = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
public void start (final String set, final String path)
|
public void start (final String set, final String path)
|
||||||
|
throws Exception
|
||||||
{
|
{
|
||||||
|
// TODO: some stuff needs to come out of here and into init/shutdown
|
||||||
|
// but we'll deal with all that later, d00d.
|
||||||
_player = new Thread("narya mp3 relay") {
|
_player = new Thread("narya mp3 relay") {
|
||||||
public void run () {
|
public void run () {
|
||||||
AudioInputStream inStream = null;
|
AudioInputStream inStream = null;
|
||||||
@@ -79,7 +82,7 @@ public class MP3Manager
|
|||||||
|
|
||||||
byte[] data = new byte[BUFFER_SIZE];
|
byte[] data = new byte[BUFFER_SIZE];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (_player == Thread.currentThread()) {
|
while (count >= 0) {
|
||||||
try {
|
try {
|
||||||
count = inStream.read(data, 0, data.length);
|
count = inStream.read(data, 0, data.length);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
@@ -88,13 +91,15 @@ public class MP3Manager
|
|||||||
}
|
}
|
||||||
if (count >= 0) {
|
if (count >= 0) {
|
||||||
line.write(data, 0, count);
|
line.write(data, 0, count);
|
||||||
} else {
|
}
|
||||||
break;
|
if (_player != Thread.currentThread()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
line.drain();
|
||||||
line.close();
|
line.close();
|
||||||
_smgr.songStopEvent();
|
_musicListener.musicStopped();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,10 +108,19 @@ public class MP3Manager
|
|||||||
_player.start();
|
_player.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void stop ()
|
||||||
|
{
|
||||||
|
_player = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void setVolume (float volume)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
protected Thread _player;
|
protected Thread _player;
|
||||||
|
|
||||||
protected ResourceManager _rmgr;
|
protected static final int BUFFER_SIZE = 8192;
|
||||||
protected SoundManager _smgr;
|
|
||||||
|
|
||||||
protected static final int BUFFER_SIZE = 128000;
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// $Id: MusicPlayer.java,v 1.1 2002/11/22 04:23:31 ray Exp $
|
||||||
|
|
||||||
|
package com.threerings.media;
|
||||||
|
|
||||||
|
import com.threerings.resource.ResourceManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does something extraordinary.
|
||||||
|
*/
|
||||||
|
public abstract class MusicPlayer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public interface MusicEventListener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A callback that all players should use when the song they are
|
||||||
|
* playing has finished playing (completely).
|
||||||
|
*/
|
||||||
|
public void musicStopped();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public final void init (
|
||||||
|
ResourceManager rmgr, MusicEventListener musicListener)
|
||||||
|
{
|
||||||
|
_rmgr = rmgr;
|
||||||
|
_musicListener = musicListener;
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do your init here.
|
||||||
|
*/
|
||||||
|
public void init ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown and free all resources.
|
||||||
|
*/
|
||||||
|
public void shutdown ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start playing the specified song.
|
||||||
|
*/
|
||||||
|
public abstract void start (String set, String path)
|
||||||
|
throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop playing the specified song.
|
||||||
|
*/
|
||||||
|
public abstract void stop ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the volume.
|
||||||
|
*
|
||||||
|
* @param volume 0f - 1f, inclusive.
|
||||||
|
*/
|
||||||
|
public abstract void setVolume (float volume);
|
||||||
|
|
||||||
|
/** The place we load data from. */
|
||||||
|
protected ResourceManager _rmgr;
|
||||||
|
|
||||||
|
/** Tell this guy about it when a song stops. */
|
||||||
|
protected MusicEventListener _musicListener;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SoundManager.java,v 1.23 2002/11/20 23:06:33 ray Exp $
|
// $Id: SoundManager.java,v 1.24 2002/11/22 04:23:31 ray Exp $
|
||||||
|
|
||||||
package com.threerings.media;
|
package com.threerings.media;
|
||||||
|
|
||||||
@@ -16,17 +16,6 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
import javax.sound.sampled.AudioFormat;
|
import javax.sound.sampled.AudioFormat;
|
||||||
import javax.sound.sampled.AudioInputStream;
|
import javax.sound.sampled.AudioInputStream;
|
||||||
import javax.sound.sampled.AudioSystem;
|
import javax.sound.sampled.AudioSystem;
|
||||||
@@ -64,7 +53,7 @@ import com.threerings.media.Log;
|
|||||||
// -- CLEANUP is NEEDED (lots of references to Sequences, when we're now
|
// -- CLEANUP is NEEDED (lots of references to Sequences, when we're now
|
||||||
// playing mods and mp3s as well. )
|
// playing mods and mp3s as well. )
|
||||||
public class SoundManager
|
public class SoundManager
|
||||||
implements MetaEventListener
|
implements MusicPlayer.MusicEventListener
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Create instances of this for your application to differentiate
|
* Create instances of this for your application to differentiate
|
||||||
@@ -109,7 +98,7 @@ public class SoundManager
|
|||||||
public void run () {
|
public void run () {
|
||||||
Object command = null;
|
Object command = null;
|
||||||
SoundKey key = null;
|
SoundKey key = null;
|
||||||
MidiInfo midiInfo = null;
|
MusicInfo musicInfo = null;
|
||||||
|
|
||||||
while (amRunning()) {
|
while (amRunning()) {
|
||||||
try {
|
try {
|
||||||
@@ -126,7 +115,7 @@ public class SoundManager
|
|||||||
key = (SoundKey) _queue.get();
|
key = (SoundKey) _queue.get();
|
||||||
|
|
||||||
} else if (PLAYMUSIC == command) {
|
} else if (PLAYMUSIC == command) {
|
||||||
midiInfo = (MidiInfo) _queue.get();
|
musicInfo = (MusicInfo) _queue.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,10 +124,10 @@ public class SoundManager
|
|||||||
playSound(key);
|
playSound(key);
|
||||||
|
|
||||||
} else if (PLAYMUSIC == command) {
|
} else if (PLAYMUSIC == command) {
|
||||||
playSequence(midiInfo);
|
playMusic(musicInfo);
|
||||||
|
|
||||||
} else if (STOPMUSIC == command) {
|
} else if (STOPMUSIC == command) {
|
||||||
stopSequence(key);
|
stopMusic(key);
|
||||||
|
|
||||||
} else if (LOCK == command) {
|
} else if (LOCK == command) {
|
||||||
_clipCache.lock(key);
|
_clipCache.lock(key);
|
||||||
@@ -159,7 +148,7 @@ public class SoundManager
|
|||||||
} else if (DIE == command) {
|
} else if (DIE == command) {
|
||||||
_resourceFreer.stop();
|
_resourceFreer.stop();
|
||||||
flushResources(true);
|
flushResources(true);
|
||||||
shutdownMidi();
|
shutdownMusic();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.warning("Captured exception in SoundManager loop.");
|
Log.warning("Captured exception in SoundManager loop.");
|
||||||
@@ -320,7 +309,7 @@ public class SoundManager
|
|||||||
{
|
{
|
||||||
synchronized (_queue) {
|
synchronized (_queue) {
|
||||||
_queue.append(PLAYMUSIC);
|
_queue.append(PLAYMUSIC);
|
||||||
_queue.append(new MidiInfo(set, path, numloops));
|
_queue.append(new MusicInfo(set, path, numloops));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,78 +325,6 @@ 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,
|
* On the SoundManager thread,
|
||||||
* plays the sound file with the given pathname.
|
* plays the sound file with the given pathname.
|
||||||
@@ -468,88 +385,107 @@ public class SoundManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play a sequence from the specified path.
|
* Play a song from the specified path.
|
||||||
*/
|
*/
|
||||||
protected void playSequence (MidiInfo info)
|
protected void playMusic (MusicInfo info)
|
||||||
{
|
{
|
||||||
if (_sequencer == null) {
|
Log.info("Playing: " + info);
|
||||||
initMidi();
|
// stop whatever's currently playing
|
||||||
|
if (_musicPlayer != null) {
|
||||||
|
_musicPlayer.stop();
|
||||||
|
handleMusicStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
stopCurrentSong(false);
|
// add the new song
|
||||||
_midiStack.addFirst(info);
|
_musicStack.addFirst(info);
|
||||||
playTopSong();
|
|
||||||
|
// and play it
|
||||||
|
playTopMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the specified sequence.
|
* Start the specified sequence.
|
||||||
*/
|
*/
|
||||||
protected void playTopSong ()
|
protected void playTopMusic ()
|
||||||
{
|
{
|
||||||
if (_midiStack.isEmpty()) {
|
if (_musicStack.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiInfo info = (MidiInfo) _midiStack.getFirst();
|
MusicInfo info = (MusicInfo) _musicStack.getFirst();
|
||||||
|
Class playerClass = getMusicPlayerClass(info.path);
|
||||||
|
|
||||||
// start the new one
|
// shutdown the old player if we're switching music types
|
||||||
try {
|
if (! playerClass.isInstance(_musicPlayer)) {
|
||||||
if (info.path.endsWith(".mp3")) {
|
if (_musicPlayer != null) {
|
||||||
_mp3player.start(info.set, info.path);
|
_musicPlayer.shutdown();
|
||||||
|
|
||||||
} else if (info.path.endsWith(".mod")) {
|
|
||||||
_modplayer.start(info.set, info.path);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_sequencer.setSequence(getMidiData(info));
|
|
||||||
if (info.msPosition != -1) {
|
|
||||||
// TODO: this doesn't work correctly
|
|
||||||
_sequencer.setTickPosition(info.tickPosition);
|
|
||||||
_sequencer.setMicrosecondPosition(info.msPosition);
|
|
||||||
info.msPosition = -1;
|
|
||||||
}
|
|
||||||
_sequencer.start();
|
|
||||||
//updateMusicVolume();
|
|
||||||
//Log.info("Now playing : " + info.path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (InvalidMidiDataException imda) {
|
// set up the new player
|
||||||
Log.warning("Invalid midi data, not playing [path=" +
|
try {
|
||||||
info.path + "].");
|
_musicPlayer = (MusicPlayer) playerClass.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Unable to instantiate music player [class=" +
|
||||||
|
playerClass + "].");
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
// scrap it, try again with the next song
|
||||||
Log.warning("ioe=" + ioe);
|
_musicPlayer = null;
|
||||||
|
_musicStack.removeFirst();
|
||||||
|
playTopMusic();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_musicPlayer.init(_rmgr, this);
|
||||||
|
_musicPlayer.setVolume(_musicVol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// play!
|
||||||
|
try {
|
||||||
|
_musicPlayer.start(info.set, info.path);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Error playing music, skipping [e=" + e +
|
||||||
|
", set=" + info.set + ", path=" + info.path + "].");
|
||||||
|
_musicStack.removeFirst();
|
||||||
|
playTopMusic();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the appropriate music player for the specified music file.
|
||||||
|
*/
|
||||||
|
protected static Class getMusicPlayerClass (String path)
|
||||||
|
{
|
||||||
|
path = path.toLowerCase();
|
||||||
|
|
||||||
|
if (path.endsWith(".mid") || path.endsWith(".rmf")) {
|
||||||
|
return MidiPlayer.class;
|
||||||
|
|
||||||
|
} else if (path.endsWith(".mod")) {
|
||||||
|
return ModPlayer.class;
|
||||||
|
|
||||||
|
} else if (path.endsWith(".mp3")) {
|
||||||
|
return Mp3Player.class;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop whatever song is currently playing and deal with the
|
* Stop whatever song is currently playing and deal with the
|
||||||
* MidiInfo associated with it.
|
* MusicInfo associated with it.
|
||||||
*/
|
*/
|
||||||
protected void stopCurrentSong (boolean wasStopped)
|
protected void handleMusicStopped ()
|
||||||
{
|
{
|
||||||
if (_midiStack.isEmpty()) {
|
if (_musicStack.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see what was playing
|
// see what was playing
|
||||||
MidiInfo current = (MidiInfo) _midiStack.getFirst();
|
MusicInfo current = (MusicInfo) _musicStack.getFirst();
|
||||||
|
|
||||||
// stop the existing song
|
|
||||||
if (!wasStopped) {
|
|
||||||
// TODO: fade?
|
|
||||||
_stoppingSong = true;
|
|
||||||
if (current.path.endsWith(".mp3")) {
|
|
||||||
_mp3player.stop();
|
|
||||||
|
|
||||||
} else if (current.path.endsWith(".mod")) {
|
|
||||||
_modplayer.stop();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_sequencer.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// see how many times the song was to loop and act accordingly
|
||||||
switch (current.loops) {
|
switch (current.loops) {
|
||||||
default:
|
default:
|
||||||
current.loops--;
|
current.loops--;
|
||||||
@@ -557,15 +493,7 @@ public class SoundManager
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// sorry charlie
|
// sorry charlie
|
||||||
_midiStack.removeFirst();
|
_musicStack.removeFirst();
|
||||||
break;
|
|
||||||
|
|
||||||
case -1:
|
|
||||||
// save info...
|
|
||||||
// TODO: this doesn't seem to work, and is out-n-out broken
|
|
||||||
// if we use the tickPos
|
|
||||||
current.msPosition = _sequencer.getMicrosecondPosition();
|
|
||||||
current.tickPosition = _sequencer.getTickPosition();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,34 +501,27 @@ public class SoundManager
|
|||||||
/**
|
/**
|
||||||
* Stop the sequence at the specified path.
|
* Stop the sequence at the specified path.
|
||||||
*/
|
*/
|
||||||
protected void stopSequence (SoundKey key)
|
protected void stopMusic (SoundKey key)
|
||||||
{
|
{
|
||||||
if (! _midiStack.isEmpty()) {
|
Log.info("Stopping: " + key);
|
||||||
MidiInfo current = (MidiInfo) _midiStack.getFirst();
|
if (! _musicStack.isEmpty()) {
|
||||||
|
MusicInfo current = (MusicInfo) _musicStack.getFirst();
|
||||||
|
|
||||||
// if we're currently playing this song..
|
// if we're currently playing this song..
|
||||||
if (key.equals(current)) {
|
if (key.equals(current)) {
|
||||||
|
Log.info("is top song!");
|
||||||
|
|
||||||
// stop it
|
// stop it
|
||||||
_stoppingSong = true;
|
_musicPlayer.stop();
|
||||||
if (key.path.endsWith(".mp3")) {
|
|
||||||
_mp3player.stop();
|
|
||||||
|
|
||||||
} else if (key.path.endsWith(".mod")) {
|
|
||||||
_modplayer.stop();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_sequencer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove it from the stack
|
// remove it from the stack
|
||||||
_midiStack.removeFirst();
|
_musicStack.removeFirst();
|
||||||
// start playing the next..
|
// start playing the next..
|
||||||
playTopSong();
|
playTopMusic();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// we aren't currently playing this song. Simply remove.
|
// we aren't currently playing this song. Simply remove.
|
||||||
for (Iterator iter=_midiStack.iterator(); iter.hasNext(); ) {
|
for (Iterator iter=_musicStack.iterator(); iter.hasNext(); ) {
|
||||||
if (key.equals(iter.next())) {
|
if (key.equals(iter.next())) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
return;
|
return;
|
||||||
@@ -614,119 +535,28 @@ public class SoundManager
|
|||||||
"[key=" + key + "].");
|
"[key=" + key + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the midi system.
|
|
||||||
*/
|
|
||||||
protected void initMidi ()
|
|
||||||
{
|
|
||||||
_mp3player = new MP3Manager(_rmgr, this);
|
|
||||||
_modplayer = new ModPlayer(_rmgr, this);
|
|
||||||
_modplayer.setVolume(_musicVol);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Sequencer seq = MidiSystem.getSequencer();
|
|
||||||
// Sequencer seq = getTritonusSequencer();
|
|
||||||
seq.open();
|
|
||||||
if (seq instanceof Synthesizer) {
|
|
||||||
_midiChannels = ((Synthesizer) seq).getChannels();
|
|
||||||
//updateMusicVolume();
|
|
||||||
}
|
|
||||||
_sequencer = seq;
|
|
||||||
_sequencer.addMetaEventListener(this);
|
|
||||||
|
|
||||||
Log.info("Seq class: " + _sequencer.getClass());
|
|
||||||
|
|
||||||
// _sequencer.getTransmitter().setReceiver(new Receiver() {
|
|
||||||
// public void close ()
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void send (javax.sound.midi.MidiMessage msg, long stamp)
|
|
||||||
// {
|
|
||||||
// Log.info("msg : " + msg);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
} catch (MidiUnavailableException mue) {
|
|
||||||
Log.warning("Midi unavailable. Can't play music.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Sequencer getTritonusSequencer ()
|
|
||||||
throws MidiUnavailableException
|
|
||||||
{
|
|
||||||
MidiDevice.Info[] info = MidiSystem.getMidiDeviceInfo();
|
|
||||||
for (int ii=0; ii < info.length; ii++) {
|
|
||||||
if (info[ii].toString().indexOf("Tritonus") != -1) {
|
|
||||||
MidiDevice dev = MidiSystem.getMidiDevice(info[ii]);
|
|
||||||
if (dev instanceof Sequencer) {
|
|
||||||
return (Sequencer) dev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.info("ACK SPUTTER!");
|
|
||||||
return MidiSystem.getSequencer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop playing and shutdown the midi system.
|
|
||||||
*/
|
|
||||||
protected void shutdownMidi ()
|
|
||||||
{
|
|
||||||
_sequencer.removeMetaEventListener(this);
|
|
||||||
stopCurrentSong(false);
|
|
||||||
_sequencer.close();
|
|
||||||
if (_receiver != null) {
|
|
||||||
_receiver.close();
|
|
||||||
}
|
|
||||||
_sequencer = null;
|
|
||||||
_midiChannels = null;
|
|
||||||
_midiStack.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to modify the music volume for any playing tracks.
|
* Attempt to modify the music volume for any playing tracks.
|
||||||
*/
|
*/
|
||||||
protected void updateMusicVolume ()
|
protected void updateMusicVolume ()
|
||||||
{
|
{
|
||||||
if (_modplayer != null) {
|
if (_musicPlayer != null) {
|
||||||
_modplayer.setVolume(_musicVol);
|
_musicPlayer.setVolume(_musicVol);
|
||||||
}
|
|
||||||
|
|
||||||
if (_midiChannels == null) {
|
|
||||||
Log.warning("Cannot modify music volume!");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
int setting = (int) (_musicVol * 127.0);
|
|
||||||
for (int ii=0; ii < _midiChannels.length; ii++) {
|
|
||||||
_midiChannels[ii].controlChange(MIDI_VOLUME_CONTROL, setting);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface MetaEventListener
|
// documentation inherited from interface MusicPlayer.MusicEventListener
|
||||||
public void meta (MetaMessage msg)
|
public void musicStopped ()
|
||||||
{
|
{
|
||||||
// Log.info("meta message: " + msg.getType() + ", msg=" +
|
handleMusicStopped();
|
||||||
// new String(msg.getData()));
|
playTopMusic();
|
||||||
|
|
||||||
if (msg.getType() == MIDI_END_OF_TRACK) {
|
|
||||||
songStopEvent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected void shutdownMusic ()
|
||||||
* Submitted by external players like the MP3Manager.
|
|
||||||
*/
|
|
||||||
public void songStopEvent ()
|
|
||||||
{
|
{
|
||||||
if (_stoppingSong) {
|
if (_musicPlayer != null) {
|
||||||
_stoppingSong = false;
|
_musicPlayer.stop();
|
||||||
} else {
|
_musicPlayer.shutdown();
|
||||||
stopCurrentSong(true);
|
|
||||||
playTopSong();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,7 +594,8 @@ public class SoundManager
|
|||||||
} else {
|
} else {
|
||||||
// set it up and put it in the cache
|
// set it up and put it in the cache
|
||||||
AudioInputStream stream = AudioSystem.getAudioInputStream(
|
AudioInputStream stream = AudioSystem.getAudioInputStream(
|
||||||
getResource(key));
|
new ByteArrayInputStream(StreamUtils.streamAsBytes(
|
||||||
|
_rmgr.getResource(key.set, key.path), BUFFER_SIZE)));
|
||||||
DataLine.Info dinfo = new DataLine.Info(
|
DataLine.Info dinfo = new DataLine.Info(
|
||||||
Clip.class, stream.getFormat());
|
Clip.class, stream.getFormat());
|
||||||
info = new ClipInfo(dinfo, stream);
|
info = new ClipInfo(dinfo, stream);
|
||||||
@@ -774,37 +605,6 @@ public class SoundManager
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the midi data for the specified path.
|
|
||||||
*/
|
|
||||||
protected InputStream getMidiData (MidiInfo info)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
InputStream stream = (InputStream) _midiCache.get(info);
|
|
||||||
if (stream != null) {
|
|
||||||
// reset the stream for the new user
|
|
||||||
stream.reset();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
stream = getResource(info);
|
|
||||||
_midiCache.put(info, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data specified by the path from the resource bundle.
|
|
||||||
* No caching is done.
|
|
||||||
*/
|
|
||||||
protected InputStream getResource (SoundKey key)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return new ByteArrayInputStream(StreamUtils.streamAsBytes(
|
|
||||||
_rmgr.getResource(key.set, key.path), BUFFER_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Adjust the volume of this clip.
|
// * Adjust the volume of this clip.
|
||||||
// */
|
// */
|
||||||
@@ -1042,7 +842,8 @@ public class SoundManager
|
|||||||
{
|
{
|
||||||
if (o instanceof SoundKey) {
|
if (o instanceof SoundKey) {
|
||||||
SoundKey that = (SoundKey) o;
|
SoundKey that = (SoundKey) o;
|
||||||
return (this.path == that.path) && (this.set == that.set);
|
return this.path.equals(that.path) &&
|
||||||
|
this.set.equals(that.set);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1067,18 +868,14 @@ public class SoundManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that tracks the information about our playing midi files.
|
* A class that tracks the information about our playing music files.
|
||||||
*/
|
*/
|
||||||
protected static class MidiInfo extends SoundKey
|
protected static class MusicInfo extends SoundKey
|
||||||
{
|
{
|
||||||
/** How many times to loop, or -1 for forever. */
|
/** How many times to loop, or -1 for forever. */
|
||||||
public int loops;
|
public int loops;
|
||||||
|
|
||||||
/** The position of big loopers, or -1 if none. */
|
public MusicInfo (String set, String path, int loops)
|
||||||
public long tickPosition = -1;
|
|
||||||
public long msPosition = -1;
|
|
||||||
|
|
||||||
public MidiInfo (String set, String path, int loops)
|
|
||||||
{
|
{
|
||||||
super(set, path);
|
super(set, path);
|
||||||
this.loops = loops;
|
this.loops = loops;
|
||||||
@@ -1106,10 +903,6 @@ public class SoundManager
|
|||||||
|
|
||||||
/** The queue of sound clips to be played. */
|
/** The queue of sound clips to be played. */
|
||||||
protected Queue _queue = new Queue();
|
protected Queue _queue = new Queue();
|
||||||
|
|
||||||
/** So that we ignore the stopped meta event when we stop a song
|
|
||||||
* ourselves. */
|
|
||||||
protected boolean _stoppingSong = false;
|
|
||||||
|
|
||||||
/** Volume levels for both sound clips and music. */
|
/** Volume levels for both sound clips and music. */
|
||||||
protected float _clipVol = 1f, _musicVol = 1f;
|
protected float _clipVol = 1f, _musicVol = 1f;
|
||||||
@@ -1117,28 +910,14 @@ public class SoundManager
|
|||||||
/** The cache of recent audio clips . */
|
/** The cache of recent audio clips . */
|
||||||
protected LockableLRUHashMap _clipCache = new LockableLRUHashMap(10);
|
protected LockableLRUHashMap _clipCache = new LockableLRUHashMap(10);
|
||||||
|
|
||||||
/** The cache of recent midi sequences. */
|
|
||||||
protected LRUHashMap _midiCache = new LRUHashMap(4);
|
|
||||||
|
|
||||||
/** The clips that are currently active. */
|
/** The clips that are currently active. */
|
||||||
protected ArrayList _activeClips = new ArrayList();
|
protected ArrayList _activeClips = new ArrayList();
|
||||||
|
|
||||||
/** The sequencer that plays midi music. */
|
|
||||||
protected Sequencer _sequencer;
|
|
||||||
|
|
||||||
protected MP3Manager _mp3player;
|
|
||||||
|
|
||||||
protected ModPlayer _modplayer;
|
|
||||||
|
|
||||||
/** 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;
|
|
||||||
|
|
||||||
/** The stack of songs that we're playing. */
|
/** The stack of songs that we're playing. */
|
||||||
protected LinkedList _midiStack = new LinkedList();
|
protected LinkedList _musicStack = new LinkedList();
|
||||||
|
|
||||||
|
/** The current music player, if any. */
|
||||||
|
protected MusicPlayer _musicPlayer;
|
||||||
|
|
||||||
/** A set of soundTypes for which sound is enabled. */
|
/** A set of soundTypes for which sound is enabled. */
|
||||||
protected HashSet _disabledTypes = new HashSet();
|
protected HashSet _disabledTypes = new HashSet();
|
||||||
@@ -1153,12 +932,6 @@ public class SoundManager
|
|||||||
protected Object FLUSH = new Object();
|
protected Object FLUSH = new Object();
|
||||||
protected Object DIE = new Object();
|
protected Object DIE = new Object();
|
||||||
|
|
||||||
/** This is apparently the midi code for end of track. Wack. */
|
|
||||||
protected static final int MIDI_END_OF_TRACK = 47;
|
|
||||||
|
|
||||||
/** The midi control for volume is 7. Ooooooo. */
|
|
||||||
protected static final int MIDI_VOLUME_CONTROL = 7;
|
|
||||||
|
|
||||||
/** The queue size at which we start to ignore requests to play sounds. */
|
/** The queue size at which we start to ignore requests to play sounds. */
|
||||||
protected static final int MAX_QUEUE_SIZE = 100;
|
protected static final int MAX_QUEUE_SIZE = 100;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user