mod playing capabilities.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1974 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2002-11-20 04:03:09 +00:00
parent 10523980c6
commit 2178d75392
3 changed files with 137 additions and 36 deletions
@@ -1,5 +1,5 @@
// //
// $Id: MP3Manager.java,v 1.1 2002/11/20 01:33:34 ray Exp $ // $Id: MP3Manager.java,v 1.2 2002/11/20 04:03:09 ray Exp $
package com.threerings.media; package com.threerings.media;
@@ -37,7 +37,7 @@ public class MP3Manager
_player = null; _player = null;
} }
public void start (final String path) public void start (final String set, final String path)
{ {
_player = new Thread("narya mp3 relay") { _player = new Thread("narya mp3 relay") {
public void run () { public void run () {
@@ -46,7 +46,9 @@ public class MP3Manager
inStream = AudioSystem.getAudioInputStream( inStream = AudioSystem.getAudioInputStream(
// new ByteArrayInputStream(StreamUtils.streamAsBytes( // new ByteArrayInputStream(StreamUtils.streamAsBytes(
// _rmgr.getResource(path), 8192))); // _rmgr.getResource(path), 8192)));
new BufferedInputStream(_rmgr.getResource(path), 4096)); // TODO: use the fucking resource sets
new BufferedInputStream(
_rmgr.getResource(set, path), 4096));
} catch (Exception e) { } catch (Exception e) {
Log.warning("MP3 fuckola [path=" + path + Log.warning("MP3 fuckola [path=" + path +
", e=" + e + "]."); ", e=" + e + "].");
@@ -0,0 +1,89 @@
//
// $Id: ModPlayer.java,v 1.1 2002/11/20 04:03:09 ray Exp $
package com.threerings.media;
import java.io.DataInputStream;
import java.io.IOException;
import micromod.MicroMod;
import micromod.Module;
import micromod.ModuleLoader;
import micromod.output.JavaSoundOutputDevice;
import micromod.output.OutputDeviceException;
import micromod.output.PCM16StreamOutputDevice;
import micromod.output.converters.SS16LEAudioFormatConverter;
import micromod.resamplers.LinearResampler;
import com.threerings.resource.ResourceManager;
/**
* Does something extraordinary.
*/
public class ModPlayer
{
public ModPlayer (ResourceManager rmgr, SoundManager smgr)
{
_rmgr = rmgr;
_smgr = smgr;
}
public void stop ()
{
_player = null;
}
public void start (String set, String path)
{
PCM16StreamOutputDevice devvy = null;
try {
devvy = new JavaSoundOutputDevice(
new SS16LEAudioFormatConverter(), 44100, 1000);
} catch (OutputDeviceException ode) {
Log.warning("Oh we're fucked with the mod [e=" + ode + "].");
return;
}
Module module = null;
try {
module = ModuleLoader.read(
new DataInputStream(_rmgr.getResource(set, path)));
} catch (IOException ioe) {
Log.warning("error loading oh shit oh shit: [e=" + ioe + "].");
return;
}
final PCM16StreamOutputDevice outdev = devvy;
final MicroMod mod = new MicroMod(
module, outdev, new LinearResampler());
_player = new Thread("narya mod player") {
public void run () {
outdev.start();
while ((_player == Thread.currentThread()) &&
(mod.getSequenceLoopCount() == 0)) {
mod.doRealTimePlayback();
try {
Thread.sleep(20);
} catch (InterruptedException ie) {
// WFCares
}
}
outdev.stop();
_smgr.songStopEvent();
}
};
_player.setDaemon(true);
_player.start();
}
protected Thread _player;
protected ResourceManager _rmgr;
protected SoundManager _smgr;
}
@@ -1,5 +1,5 @@
// //
// $Id: SoundManager.java,v 1.21 2002/11/20 02:41:38 ray Exp $ // $Id: SoundManager.java,v 1.22 2002/11/20 04:03:09 ray Exp $
package com.threerings.media; package com.threerings.media;
@@ -61,6 +61,8 @@ import com.threerings.media.Log;
*/ */
// TODO: // TODO:
// - fade music out when stopped? // - fade music out when stopped?
// -- CLEANUP is NEEDED (lots of references to Sequences, when we're now
// playing mods and mp3s as well. )
public class SoundManager public class SoundManager
implements MetaEventListener implements MetaEventListener
{ {
@@ -107,7 +109,6 @@ public class SoundManager
public void run () { public void run () {
Object command = null; Object command = null;
SoundKey key = null; SoundKey key = null;
String path = null;
MidiInfo midiInfo = null; MidiInfo midiInfo = null;
while (amRunning()) { while (amRunning()) {
@@ -119,13 +120,11 @@ public class SoundManager
// some commands have an additional argument. // some commands have an additional argument.
if ((PLAY == command) || if ((PLAY == command) ||
(STOPMUSIC == command) ||
(LOCK == command) || (LOCK == command) ||
(UNLOCK == command)) { (UNLOCK == command)) {
key = (SoundKey) _queue.get(); key = (SoundKey) _queue.get();
} else if (STOPMUSIC == command) {
path = (String) _queue.get();
} else if (PLAYMUSIC == command) { } else if (PLAYMUSIC == command) {
midiInfo = (MidiInfo) _queue.get(); midiInfo = (MidiInfo) _queue.get();
} }
@@ -139,7 +138,7 @@ public class SoundManager
playSequence(midiInfo); playSequence(midiInfo);
} else if (STOPMUSIC == command) { } else if (STOPMUSIC == command) {
stopSequence(path); stopSequence(key);
} else if (LOCK == command) { } else if (LOCK == command) {
_clipCache.lock(key); _clipCache.lock(key);
@@ -309,19 +308,19 @@ public class SoundManager
/** /**
* Start playing the specified music repeatedly. * Start playing the specified music repeatedly.
*/ */
public void pushMusic (String path) public void pushMusic (String set, String path)
{ {
pushMusic(path, -1); pushMusic(set, path, -1);
} }
/** /**
* Start playing music for the specified number of loops. * Start playing music for the specified number of loops.
*/ */
public void pushMusic (String path, int numloops) public void pushMusic (String set, String path, int numloops)
{ {
synchronized (_queue) { synchronized (_queue) {
_queue.append(PLAYMUSIC); _queue.append(PLAYMUSIC);
_queue.append(new MidiInfo(path, numloops)); _queue.append(new MidiInfo(set, path, numloops));
} }
} }
@@ -329,11 +328,11 @@ public class SoundManager
* Remove the specified music from the playlist. If it is currently * Remove the specified music from the playlist. If it is currently
* playing, it will be stopped and the previous song will be started. * playing, it will be stopped and the previous song will be started.
*/ */
public void removeMusic (String path) public void removeMusic (String set, String path)
{ {
synchronized (_queue) { synchronized (_queue) {
_queue.append(STOPMUSIC); _queue.append(STOPMUSIC);
_queue.append(path); _queue.append(new SoundKey(set, path));
} }
} }
@@ -496,9 +495,13 @@ public class SoundManager
// start the new one // start the new one
try { try {
if (info.path.endsWith(".mp3")) { if (info.path.endsWith(".mp3")) {
_mp3player.start(info.path); _mp3player.start(info.set, info.path);
} else if (info.path.endsWith(".mod")) {
_modplayer.start(info.set, info.path);
} else { } else {
_sequencer.setSequence(getMidiData(info.path)); _sequencer.setSequence(getMidiData(info));
if (info.msPosition != -1) { if (info.msPosition != -1) {
// TODO: this doesn't work correctly // TODO: this doesn't work correctly
_sequencer.setTickPosition(info.tickPosition); _sequencer.setTickPosition(info.tickPosition);
@@ -538,6 +541,10 @@ public class SoundManager
_stoppingSong = true; _stoppingSong = true;
if (current.path.endsWith(".mp3")) { if (current.path.endsWith(".mp3")) {
_mp3player.stop(); _mp3player.stop();
} else if (current.path.endsWith(".mod")) {
_modplayer.stop();
} else { } else {
_sequencer.stop(); _sequencer.stop();
} }
@@ -566,18 +573,22 @@ public class SoundManager
/** /**
* Stop the sequence at the specified path. * Stop the sequence at the specified path.
*/ */
protected void stopSequence (String path) protected void stopSequence (SoundKey key)
{ {
if (! _midiStack.isEmpty()) { if (! _midiStack.isEmpty()) {
MidiInfo current = (MidiInfo) _midiStack.getFirst(); MidiInfo current = (MidiInfo) _midiStack.getFirst();
// if we're currently playing this song.. // if we're currently playing this song..
if (path.equals(current.path)) { if (key.equals(current)) {
// stop it // stop it
_stoppingSong = true; _stoppingSong = true;
if (path.endsWith(".mp3")) { if (key.path.endsWith(".mp3")) {
_mp3player.stop(); _mp3player.stop();
} else if (key.path.endsWith(".mod")) {
_modplayer.stop();
} else { } else {
_sequencer.stop(); _sequencer.stop();
} }
@@ -590,7 +601,7 @@ public class SoundManager
} 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=_midiStack.iterator(); iter.hasNext(); ) {
if (path.equals(((MidiInfo) iter.next()).path)) { if (key.equals(iter.next())) {
iter.remove(); iter.remove();
return; return;
} }
@@ -600,7 +611,7 @@ public class SoundManager
} }
Log.debug("Sequence stopped that wasn't in the stack anymore " + Log.debug("Sequence stopped that wasn't in the stack anymore " +
"[path=" + path + "]."); "[key=" + key + "].");
} }
/** /**
@@ -609,6 +620,7 @@ public class SoundManager
protected void initMidi () protected void initMidi ()
{ {
_mp3player = new MP3Manager(_rmgr, this); _mp3player = new MP3Manager(_rmgr, this);
_modplayer = new ModPlayer(_rmgr, this);
try { try {
Sequencer seq = MidiSystem.getSequencer(); Sequencer seq = MidiSystem.getSequencer();
@@ -747,7 +759,7 @@ 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.set, key.path)); getResource(key));
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);
@@ -760,18 +772,17 @@ public class SoundManager
/** /**
* Get the midi data for the specified path. * Get the midi data for the specified path.
*/ */
protected InputStream getMidiData (String path) protected InputStream getMidiData (MidiInfo info)
throws IOException throws IOException
{ {
InputStream stream = (InputStream) _midiCache.get(path); InputStream stream = (InputStream) _midiCache.get(info);
if (stream != null) { if (stream != null) {
// reset the stream for the new user // reset the stream for the new user
stream.reset(); stream.reset();
} else { } else {
// TODO: unhack stream = getResource(info);
stream = getResource("boot", path); _midiCache.put(info, stream);
_midiCache.put(path, stream);
} }
return stream; return stream;
@@ -782,11 +793,11 @@ public class SoundManager
* Get the data specified by the path from the resource bundle. * Get the data specified by the path from the resource bundle.
* No caching is done. * No caching is done.
*/ */
protected InputStream getResource (String set, String path) protected InputStream getResource (SoundKey key)
throws IOException throws IOException
{ {
return new ByteArrayInputStream(StreamUtils.streamAsBytes( return new ByteArrayInputStream(StreamUtils.streamAsBytes(
_rmgr.getResource(set, path), BUFFER_SIZE)); _rmgr.getResource(key.set, key.path), BUFFER_SIZE));
} }
/** /**
@@ -1053,11 +1064,8 @@ public class SoundManager
/** /**
* A class that tracks the information about our playing midi files. * A class that tracks the information about our playing midi files.
*/ */
protected static class MidiInfo protected static class MidiInfo extends SoundKey
{ {
/** The path, duh. */
public String path;
/** How many times to loop, or -1 for forever. */ /** How many times to loop, or -1 for forever. */
public int loops; public int loops;
@@ -1065,9 +1073,9 @@ public class SoundManager
public long tickPosition = -1; public long tickPosition = -1;
public long msPosition = -1; public long msPosition = -1;
public MidiInfo (String path, int loops) public MidiInfo (String set, String path, int loops)
{ {
this.path = path; super(set, path);
this.loops = loops; this.loops = loops;
} }
} }
@@ -1115,6 +1123,8 @@ public class SoundManager
protected MP3Manager _mp3player; protected MP3Manager _mp3player;
protected ModPlayer _modplayer;
/** The receiver used to send midi from the sequencer to an alternate /** The receiver used to send midi from the sequencer to an alternate
* midi device. */ * midi device. */
protected Receiver _receiver; protected Receiver _receiver;