SunAudioOutputpublic class SunAudioOutput extends InputStream implements AudioOutput
Fields Summary |
---|
protected sun.audio.AudioStream | audioStream | protected int | bufLength | protected byte[] | buffer | protected static int | EOM | protected boolean | paused | protected boolean | started | protected boolean | flushing | private boolean | startAfterWrite | protected AudioFormat | format | private int | SUN_MAGIC | private int | HDR_SIZE | private int | FILE_LENGTH | private int | SAMPLE_RATE | private int | ENCODING | private int | CHANNELS | int | in | int | out | boolean | eom | int | samplesPlayed | private boolean | isMuted | private double | gain | private byte[] | silence | private static final int | END_OF_MEDIA_PADDING_LENGTHpadding length of silence at the end of the media (default constant) | private int | endOfMediaPaddingLengthpadding length of silence at the end of the media | private byte[] | conversionBuffer | static final int | SLEEP_TIME | protected boolean | internalDelayUpdate | private SunAudioPlayThread | timeUpdatingThread | protected int | sunAudioInitialCount | protected int | sunAudioFinalCount | protected int | silenceCount | private static JMFSecurity | jmfSecurity | private static boolean | securityPrivelege | private Method[] | m | private Class[] | cl | private Object[] | args |
Constructors Summary |
---|
public SunAudioOutput()
try {
jmfSecurity = JMFSecurityManager.getJMFSecurity();
securityPrivelege = true;
} catch (SecurityException e) {
}
|
Methods Summary |
---|
public int | bufferAvailable()
if (SunAudioRenderer.runningOnMac)
return 0;
return bufLength - dataAvailable() - 1;
| public int | dataAvailable()
if (in == out)
return 0;
else {
if (in > out)
return in - out;
else
return bufLength - (out - in);
}
| public synchronized void | dispose()
if (audioStream != null) {
timeUpdatingThread.kill();
sun.audio.AudioPlayer.player.stop(audioStream);
}
buffer = null;
| public void | drain()
int remain;
int len;
synchronized (this) {
remain = endOfMediaPaddingLength;
// pad the end of the media with silence
// (used to drain sun.audio.AudioPlayer.player)
while (remain > 0) {
len = write(silence,0,remain);
remain -= len;
}
// drain the JMF buffer.
while (in != out && !paused) {
try {
wait();
} catch (InterruptedException e) { }
}
// We'll need to drain longer on the Mac.
if (SunAudioRenderer.runningOnMac) {
try {
Thread.sleep(SunAudioRenderer.DEVICE_LATENCY/1000000L);
} catch (InterruptedException e) {}
}
}
| public void | finalize()
super.finalize();
dispose();
| public synchronized void | flush()
//System.out.println("SunAudioOutput flush ");
in = 0;
out = 0;
sunAudioInitialCount = sunAudioFinalCount = samplesPlayed;
flushing = true;
notifyAll();
| public double | getGain()
return 0f;
| public long | getMediaNanoseconds()
/*
double samples = (double)samplesPlayed;
//samples = samples/(double)format.getSampleRate();
// SunAudioOutput plays at 8 Khz
samples = samples/(double)8000;
// System.out.println("AudioPlay.getTick() " + samples);
return (audioStream == null ? 0 : (long)(samples * 1000000000L) );
*/
return (audioStream == null ? 0 : samplesPlayed * 125000L);
| public boolean | getMute()
return isMuted;
| public float | getRate()
return 1.0f;
| public boolean | initialize(javax.media.format.AudioFormat format, int length)
this.format = format;
//bufLength = length;
//bufLength = 8000; // hardcode the number to 8000.
bufLength = 12000; // hardcode the number to 12000.
buffer = new byte[bufLength];
silence = new byte[bufLength];
for (int i = 0; i < bufLength; i++)
silence[i] = 127;
if ( /*securityPrivelege &&*/ (jmfSecurity != null) ) {
String permission = null;
try {
if (jmfSecurity.getName().startsWith("jmf-security")) {
permission = "thread";
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD);
m[0].invoke(cl[0], args[0]);
permission = "thread group";
jmfSecurity.requestPermission(m, cl, args, JMFSecurity.THREAD_GROUP);
m[0].invoke(cl[0], args[0]);
} else if (jmfSecurity.getName().startsWith("internet")) {
PolicyEngine.checkPermission(PermissionID.THREAD);
PolicyEngine.assertPermission(PermissionID.THREAD);
}
} catch (Throwable e) {
if (JMFSecurityManager.DEBUG) {
System.err.println("Unable to get " + permission +
" privilege " + e);
}
securityPrivelege = false;
// TODO: Do the right thing if permissions cannot be obtained.
// User should be notified via an event
}
}
if ( (jmfSecurity != null) && (jmfSecurity.getName().startsWith("jdk12"))) {
try {
Constructor cons = jdk12CreateThreadAction.cons;
timeUpdatingThread = (SunAudioPlayThread) jdk12.doPrivM.invoke(
jdk12.ac,
new Object[] {
cons.newInstance(
new Object[] {
SunAudioPlayThread.class,
})});
} catch (Exception e) {
}
} else {
timeUpdatingThread = new SunAudioPlayThread();
}
timeUpdatingThread.setStream(this);
setPaddingLength(END_OF_MEDIA_PADDING_LENGTH); // defualt size
// BB
ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
DataOutputStream tempData = new DataOutputStream(tempOut);
try {
tempData.writeInt(SUN_MAGIC);
tempData.writeInt(HDR_SIZE);
tempData.writeInt(FILE_LENGTH);
tempData.writeInt(ENCODING);
tempData.writeInt(SAMPLE_RATE);
tempData.writeInt(CHANNELS);
} catch (Exception e) {}
byte[] buf = tempOut.toByteArray();
write(buf, 0, buf.length);
String encoding = format.getEncoding();
int sampleRate = (int)format.getSampleRate();
if (!( (format.getChannels() == 1) &&
(sampleRate == 8000) &&
(encoding.equals(AudioFormat.ULAW)) ) ) {
System.out.println("AudioPlay:Unsupported Audio Format");
return false;
}
try {
audioStream = new sun.audio.AudioStream(this);
} catch (Exception e) {
System.err.println("Exception: " + e);
audioStream = null;
return false;
}
return true;
| public void | pause()
//System.out.println("SunAudioOutput pause ");
if (audioStream != null) {
timeUpdatingThread.pause();
sun.audio.AudioPlayer.player.stop(audioStream);
}
paused = true;
| public synchronized int | read()
// Block if the buffer is empty.
while (in == out) {
if (eom) {
eom = false;
return EOM;
}
try {
wait();
} catch (InterruptedException e) {
}
}
int ret = buffer[out++] & 0xFF;
if (out >= buffer.length) {
out = 0;
}
return ret;
| public synchronized int | read(byte[] b, int off, int len)
//System.out.println("AP:needs: " + len + " available: " + dataAvailable());
//System.out.println("AP: read3: " + Thread.currentThread() + ": " +
// Thread.currentThread().getPriority() +
// ": paused, avail: " + paused + ": " + available());
int inputLength=len;
if (len <= 0) {
return -1;
}
if ( (len>4) && (!internalDelayUpdate) ) {
//System.out.println("sunAudioInternalDelay "+len);
internalDelayUpdate=true;
timeUpdatingThread.setInternalDelay(len);
}
if (dataAvailable() == 0) {
//System.out.println("underflow - no data: " + inputLength);
System.arraycopy(silence, 0, b, off, inputLength);
//timeUpdatingThread.resetSampleCountTime();
//sunAudioInitialCount=sunAudioFinalCount;
silenceCount += inputLength;
return inputLength;
}
// This read will not block
int c = read();
if (c < 0) {
return -1;
}
b[off] = (byte) c;
int rlen = 1;
if ( in != out ) {
int avail, need, size;
len--; // 1 byte read and copied.
if (out < in) {
avail = (in - out);
if (avail > len)
avail = len;
System.arraycopy(buffer, out, b, off+1, avail);
out += avail;
rlen += avail;
} else if ( out > in ) {
avail = bufLength - out;
if (avail >= len) {
avail = len;
System.arraycopy(buffer, out, b, off+1, avail);
out += avail;
if (out >= bufLength)
out = 0;
rlen += avail;
} else {
System.arraycopy(buffer, out, b, off+1, avail);
out += avail;
if (out >= bufLength)
out = 0;
int copied = avail;
rlen += avail;
need = (len - avail);
avail = (in - out);
if (need <= avail)
size = need;
else
size = avail;
System.arraycopy(buffer, 0, b, off+1+copied, size);
out += size;
rlen += size;
}
}
}
// Notify if there's any waiting writer.
if (isMuted) {
//System.err.println("muted -- fill with silence");
System.arraycopy(silence, 0, b, off, inputLength);
} else {
if (rlen<inputLength) {
// pad the rest of the buffer with silence
// but don't update the sample count
//System.out.println("underflow - pad with silence: " + (inputLength-rlen));
System.arraycopy(silence, 0, b, off+rlen, inputLength-rlen);
silenceCount += (inputLength-rlen);
} else if (silenceCount > 0) {
// There were some silence filled in before. We'll
// need to compensate for that.
if (silenceCount > rlen) {
silenceCount -= rlen;
rlen = 0;
} else {
rlen -= silenceCount;
silenceCount = 0;
}
}
}
timeUpdatingThread.resetSampleCountTime();
sunAudioInitialCount=sunAudioFinalCount;
sunAudioFinalCount+=rlen;
notifyAll();
return inputLength;
| public synchronized void | resume()
//System.out.println("SunAudioOutput resume ");
if ( (audioStream != null) && (!started || paused) ) {
started=true;
//System.out.println("start the player "+dataAvailable());
sun.audio.AudioPlayer.player.start(audioStream);
timeUpdatingThread.start();
}
paused = false;
| public void | setGain(double g)
| public void | setMute(boolean m)
// System.out.println("AudioPlay.setMute()");
isMuted = m;
| protected void | setPaddingLength(int paddingLength)
//System.out.println("SunAudioOutput setPaddingLength "+ paddingLength);
endOfMediaPaddingLength = paddingLength;
if (endOfMediaPaddingLength > silence.length)
endOfMediaPaddingLength = silence.length;
| public float | setRate(float r)
return 1.0f;
| public synchronized int | write(byte[] data, int off, int len)
//System.out.println("SunAudioOutput.write , try len"+len+" in "+in+" out "+out);
//System.out.println("abc: SunAudioOutput.write "+len);
flushing = false;
if (len <= 0)
return 0;
// Block if the buffer is full.
while ((in + 1) % buffer.length == out) {
try {
wait();
} catch (InterruptedException e) {
}
}
if (flushing) {
return 0;
}
int wlen = 0;
if (true) {
int canWrite, actualWrite, actualWrite1, length1;
if (in < out) {
canWrite = out - in -1;
actualWrite = (canWrite < len) ? canWrite : len;
System.arraycopy(data, off, buffer, in, actualWrite);
in += actualWrite;
wlen += actualWrite;
} else {
if (out == 0)
length1 = bufLength - in - 1;
else
length1 = bufLength - in;
if (length1 >= len) {
actualWrite = len;
System.arraycopy(data, off, buffer, in, actualWrite);
in += actualWrite;
if (in >= bufLength)
in = 0;
wlen += actualWrite;
} else {
actualWrite = length1;
System.arraycopy(data, off, buffer, in, actualWrite);
in += actualWrite;
if (in >= bufLength)
in = 0;
wlen += actualWrite;
len -= actualWrite;
actualWrite1 = actualWrite;
if (out > 0) {
canWrite = out -in -1;
actualWrite = (canWrite < len) ? canWrite : len;
System.arraycopy(data, off+actualWrite1,
buffer, 0, actualWrite);
wlen += actualWrite;
in = actualWrite;
}
}
}
}
// Notify the waiting reader.
notifyAll();
//System.out.println("before wlen "+wlen+" in "+in+" out "+out);
//saveInput(data,off,wlen);
return wlen;
|
|