- Trashed any reference to line.drain(), we're not going back.

- Removed the RuntimeAdjust for tweaking the Line's buffer size.
- Feed data to the Line in chunks the same size as its buffer.
- Rather than sleeping 3 seconds, calculate how long it would take to play
  the line's entire buffer and sleep that long. It turns out that with
  the buffer size I'm using and the sample rates our sounds are encoded at,
  this is less than 400 ms.
- Went ahead and increased the maximum number of simultaneous line spoolers
  to 12.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2966 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2004-02-24 08:08:25 +00:00
parent 796c953c89
commit 7ac816f12c
@@ -1,5 +1,5 @@
// //
// $Id: SoundManager.java,v 1.69 2004/02/12 04:14:21 ray Exp $ // $Id: SoundManager.java,v 1.70 2004/02/24 08:08:25 ray Exp $
package com.threerings.media.sound; package com.threerings.media.sound;
@@ -989,8 +989,25 @@ public class SoundManager
_line = (SourceDataLine) AudioSystem.getLine(new DataLine.Info( _line = (SourceDataLine) AudioSystem.getLine(new DataLine.Info(
SourceDataLine.class, _format)); SourceDataLine.class, _format));
_line.open(_format, _outBufSize.getValue()); _line.open(_format, LINEBUF_SIZE);
_line.start(); _line.start();
// calculate how long we should sleep when 'draining' the line
float sampleRate = format.getSampleRate();
if (sampleRate == AudioSystem.NOT_SPECIFIED) {
sampleRate = 11025; // most of our sounds are
}
int sampleSize = format.getSampleSizeInBits();
if (sampleSize == AudioSystem.NOT_SPECIFIED) {
sampleSize = 16;
}
_drainTime = (int) Math.ceil(
(LINEBUF_SIZE * 8 * 1000) / (sampleRate * sampleSize));
if (_verbose.getValue()) {
Log.info("Calculated drainTime as " + _drainTime +
" (sampleSize=" + sampleSize +
", sampleRate=" + sampleRate + ")");
}
} }
/** /**
@@ -1066,7 +1083,7 @@ public class SoundManager
protected void playStream () protected void playStream ()
{ {
int count = 0; int count = 0;
byte[] data = new byte[BUFFER_SIZE]; byte[] data = new byte[LINEBUF_SIZE];
// if (_verbose.getValue()) { // if (_verbose.getValue()) {
Log.info("Sound playing [key=" + _key.key + "]."); Log.info("Sound playing [key=" + _key.key + "].");
@@ -1087,21 +1104,12 @@ public class SoundManager
} }
} }
// There is a major bug with using drain() under linux. It often // For now, we never trust _line.drain() because it seems that
// causes the thread to just loop forever inside the native // it is simply buggy. On multithreading systems
// implementation of drain(), and we're screwed. // (linux, windows XP with HT processors) it consistently booches.
// UPDATE- it seems that it happens under windows as well sometimes try {
// so I am now just disabling drain. Thread.sleep(_drainTime);
if (true || RunAnywhere.isLinux()) { } catch (InterruptedException ie) {
// we instead attempt to sleep long enough such that
// everything should be drained.
try {
Thread.sleep(NO_DRAIN_SLEEP_TIME);
} catch (InterruptedException ie) {
}
} else {
_line.drain();
} }
// clear it out so that we can wait for more. // clear it out so that we can wait for more.
@@ -1117,6 +1125,11 @@ public class SoundManager
/** The line that we spool to. */ /** The line that we spool to. */
protected SourceDataLine _line; protected SourceDataLine _line;
/** The amount of time we need to sleep after the last write
* of data to the line to be sure that all of it will have been
* played. */
protected int _drainTime;
/** Are we still active and usable for spooling sounds, or should /** Are we still active and usable for spooling sounds, or should
* we be removed. */ * we be removed. */
protected boolean _valid = true; protected boolean _valid = true;
@@ -1127,15 +1140,15 @@ public class SoundManager
/** 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();
/** The size of the line's buffer. */
protected static final int LINEBUF_SIZE = 8 * 1024;
/** 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 = 10; protected static final int MAX_SPOOLERS = 12;
/** The time we sleep if it's not safe to drain. */
protected static final long NO_DRAIN_SLEEP_TIME = 3000L;
} }
/** /**
@@ -1279,11 +1292,6 @@ public class SoundManager
"Test sound directory", "narya.media.sound.test_dir", "Test sound directory", "narya.media.sound.test_dir",
MediaPrefs.config, true, ""); MediaPrefs.config, true, "");
protected static RuntimeAdjust.IntAdjust _outBufSize =
new RuntimeAdjust.IntAdjust(
"Sound output buffer size", "narya.media.sound.outbufsize",
MediaPrefs.config, 8192);
protected static RuntimeAdjust.BooleanAdjust _verbose = protected static RuntimeAdjust.BooleanAdjust _verbose =
new RuntimeAdjust.BooleanAdjust( new RuntimeAdjust.BooleanAdjust(
"Verbose sound event logging", "narya.media.sound.verbose", "Verbose sound event logging", "narya.media.sound.verbose",