- 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:
@@ -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;
|
package com.threerings.media;
|
||||||
|
|
||||||
@@ -289,6 +289,7 @@ public class SoundManager
|
|||||||
if (_player != null && (_clipVol != 0f) && isEnabled(type)) {
|
if (_player != null && (_clipVol != 0f) && isEnabled(type)) {
|
||||||
synchronized (_queue) {
|
synchronized (_queue) {
|
||||||
if (_queue.size() < MAX_QUEUE_SIZE) {
|
if (_queue.size() < MAX_QUEUE_SIZE) {
|
||||||
|
Log.debug("play requested [key=" + key + "].");
|
||||||
_queue.append(PLAY);
|
_queue.append(PLAY);
|
||||||
_queue.append(new SoundKey(pkgPath, key));
|
_queue.append(new SoundKey(pkgPath, key));
|
||||||
|
|
||||||
@@ -348,7 +349,7 @@ public class SoundManager
|
|||||||
AudioInputStream stream = AudioSystem.getAudioInputStream(
|
AudioInputStream stream = AudioSystem.getAudioInputStream(
|
||||||
new ByteArrayInputStream(data));
|
new ByteArrayInputStream(data));
|
||||||
|
|
||||||
LineSpooler.play(stream, _clipVol);
|
LineSpooler.play(stream, _clipVol, key);
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.warning("Error loading sound file [key=" + key +
|
Log.warning("Error loading sound file [key=" + key +
|
||||||
@@ -718,7 +719,8 @@ public class SoundManager
|
|||||||
/**
|
/**
|
||||||
* Attempt to play the specified sound.
|
* 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
|
throws LineUnavailableException
|
||||||
{
|
{
|
||||||
AudioFormat format = stream.getFormat();
|
AudioFormat format = stream.getFormat();
|
||||||
@@ -733,7 +735,7 @@ public class SoundManager
|
|||||||
_openSpoolers.remove(ii--);
|
_openSpoolers.remove(ii--);
|
||||||
nn--;
|
nn--;
|
||||||
|
|
||||||
} else if (spooler.checkPlay(format, stream, volume)) {
|
} else if (spooler.checkPlay(format, stream, volume, key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -745,7 +747,7 @@ public class SoundManager
|
|||||||
|
|
||||||
spooler = new LineSpooler(format);
|
spooler = new LineSpooler(format);
|
||||||
_openSpoolers.add(spooler);
|
_openSpoolers.add(spooler);
|
||||||
spooler.checkPlay(format, stream, volume);
|
spooler.checkPlay(format, stream, volume, key);
|
||||||
spooler.start();
|
spooler.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,10 +803,12 @@ public class SoundManager
|
|||||||
* doing so if we can.
|
* doing so if we can.
|
||||||
*/
|
*/
|
||||||
protected synchronized boolean checkPlay (
|
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)) {
|
if (_valid && (_stream == null) && _format.matches(format)) {
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
|
_key = key;
|
||||||
SoundManager.adjustVolume(_line, volume);
|
SoundManager.adjustVolume(_line, volume);
|
||||||
notify();
|
notify();
|
||||||
return true;
|
return true;
|
||||||
@@ -853,6 +857,7 @@ public class SoundManager
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
byte[] data = new byte[BUFFER_SIZE];
|
byte[] data = new byte[BUFFER_SIZE];
|
||||||
|
|
||||||
|
Log.debug("play happening [key=" + _key.key + "].");
|
||||||
while (_valid && count != -1) {
|
while (_valid && count != -1) {
|
||||||
try {
|
try {
|
||||||
count = _stream.read(data, 0, data.length);
|
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
|
// There is a major bug with using drain() under linux. It often
|
||||||
// to be a bug in linux's native implementation of drain
|
// causes the thread to just loop forever inside the native
|
||||||
// that sometimes resulted in the internals of drain
|
// implementation of drain(), and we're screwed.
|
||||||
// going into an infinite loop. Checking to see if the line
|
if (_shouldDrain) {
|
||||||
// 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
|
|
||||||
_line.drain();
|
_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.
|
// clear it out so that we can wait for more.
|
||||||
_stream = null;
|
_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. */
|
/** The format that our line was opened with. */
|
||||||
protected AudioFormat _format;
|
protected AudioFormat _format;
|
||||||
|
|
||||||
@@ -923,15 +906,33 @@ public class SoundManager
|
|||||||
* we be removed. */
|
* we be removed. */
|
||||||
protected boolean _valid = true;
|
protected boolean _valid = true;
|
||||||
|
|
||||||
|
/** Used for debugging. */
|
||||||
|
protected SoundKey _key;
|
||||||
|
|
||||||
/** The list of all the currently instantiated spoolers. */
|
/** The list of all the currently instantiated spoolers. */
|
||||||
protected static ArrayList _openSpoolers = new ArrayList();
|
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
|
/** The maximum time a spooler will wait for a stream before
|
||||||
* deciding to shut down. */
|
* deciding to shut down. */
|
||||||
protected static final long MAX_WAIT_TIME = 30000L;
|
protected static final long MAX_WAIT_TIME = 30000L;
|
||||||
|
|
||||||
/** The maximum number of spoolers we'll allow. This is a lot. */
|
/** The maximum number of spoolers we'll allow. This is a lot. */
|
||||||
protected static final int MAX_SPOOLERS = 24;
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user