- added debug logging so that we can see the time elapsed between the

moment that a sound is requested to just before the LineSpooler object
  that it was given to starts writing the data to a line.
- Turned drain() back on, but only if we're not running under linux.
  If we're in linux, we instead sleep for 3 seconds, and gosh darn it, the
  sound should be finished after that.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2019 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2002-12-04 02:14:12 +00:00
parent 1d9de38b61
commit c321f7eb33
@@ -1,5 +1,5 @@
//
// $Id: SoundManager.java,v 1.35 2002/11/29 21:22:46 ray Exp $
// $Id: SoundManager.java,v 1.36 2002/12/04 02:14:12 ray Exp $
package com.threerings.media;
@@ -289,6 +289,7 @@ public class SoundManager
if (_player != null && (_clipVol != 0f) && isEnabled(type)) {
synchronized (_queue) {
if (_queue.size() < MAX_QUEUE_SIZE) {
Log.debug("play requested [key=" + key + "].");
_queue.append(PLAY);
_queue.append(new SoundKey(pkgPath, key));
@@ -348,7 +349,7 @@ public class SoundManager
AudioInputStream stream = AudioSystem.getAudioInputStream(
new ByteArrayInputStream(data));
LineSpooler.play(stream, _clipVol);
LineSpooler.play(stream, _clipVol, key);
} catch (IOException ioe) {
Log.warning("Error loading sound file [key=" + key +
@@ -718,7 +719,8 @@ public class SoundManager
/**
* Attempt to play the specified sound.
*/
public static void play (AudioInputStream stream, float volume)
public static void play (
AudioInputStream stream, float volume, SoundKey key)
throws LineUnavailableException
{
AudioFormat format = stream.getFormat();
@@ -733,7 +735,7 @@ public class SoundManager
_openSpoolers.remove(ii--);
nn--;
} else if (spooler.checkPlay(format, stream, volume)) {
} else if (spooler.checkPlay(format, stream, volume, key)) {
return;
}
}
@@ -745,7 +747,7 @@ public class SoundManager
spooler = new LineSpooler(format);
_openSpoolers.add(spooler);
spooler.checkPlay(format, stream, volume);
spooler.checkPlay(format, stream, volume, key);
spooler.start();
}
@@ -801,10 +803,12 @@ public class SoundManager
* doing so if we can.
*/
protected synchronized boolean checkPlay (
AudioFormat format, AudioInputStream stream, float volume)
AudioFormat format, AudioInputStream stream, float volume,
SoundKey key)
{
if (_valid && (_stream == null) && _format.matches(format)) {
_stream = stream;
_key = key;
SoundManager.adjustVolume(_line, volume);
notify();
return true;
@@ -853,6 +857,7 @@ public class SoundManager
int count = 0;
byte[] data = new byte[BUFFER_SIZE];
Log.debug("play happening [key=" + _key.key + "].");
while (_valid && count != -1) {
try {
count = _stream.read(data, 0, data.length);
@@ -869,47 +874,25 @@ public class SoundManager
}
}
// SO, I used to just always drain, but I found what appears
// to be a bug in linux's native implementation of drain
// that sometimes resulted in the internals of drain
// going into an infinite loop. Checking to see if the line
// isActive (engaging in I/O) before calling drain seems
// to have stopped the problem from happening.
//
// TODO: look at this some more.
// For now I'm turning draining back on, because I've seen
// instances of longer sounds reporting that they're not active
// while they're still playing, and so the next sound
// is significantly delayed. That sucks.
//
// Nov 29: drain() definitely hoses things.
// Mike just had 14 threads stuck in drain(). Back off.
if (_line.isActive()) {
// Log.info("Waiting for drain (" + hashCode() + ", active=" +
// _line.isActive() + ", running=" + _line.isRunning()+
// ") : " + incDrainers());
// wait for it to play all the way
// There is a major bug with using drain() under linux. It often
// causes the thread to just loop forever inside the native
// implementation of drain(), and we're screwed.
if (_shouldDrain) {
_line.drain();
// Log.info("drained: (" + hashCode() + ") :" + decDrainers());
} else {
// we instead attempt to sleep long enough such that
// everything should be drained.
try {
Thread.sleep(NO_DRAIN_SLEEP_TIME);
} catch (InterruptedException ie) {
}
}
// clear it out so that we can wait for more.
_stream = null;
}
// protected static final synchronized int incDrainers ()
// {
// return ++drainers;
// }
//
// protected static final synchronized int decDrainers ()
// {
// return --drainers;
// }
// static int drainers = 0;
/** The format that our line was opened with. */
protected AudioFormat _format;
@@ -923,15 +906,33 @@ public class SoundManager
* we be removed. */
protected boolean _valid = true;
/** Used for debugging. */
protected SoundKey _key;
/** The list of all the currently instantiated spoolers. */
protected static ArrayList _openSpoolers = new ArrayList();
/** Should we attempt to use line.drain()? */
protected static boolean _shouldDrain = true;
/** The maximum time a spooler will wait for a stream before
* deciding to shut down. */
protected static final long MAX_WAIT_TIME = 30000L;
/** The maximum number of spoolers we'll allow. This is a lot. */
protected static final int MAX_SPOOLERS = 24;
/** The time we sleep if it's not safe to drain. */
protected static final long NO_DRAIN_SLEEP_TIME = 3000L;
// see if we should use drain.
static {
String os = System.getProperty("os.name");
if (os == null || (os.indexOf("Linux") != -1)) {
_shouldDrain = false;
Log.info("Detected Linux, will not use drain() on lines.");
}
}
}
/**