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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user