JavaSoundSourceStreampublic class JavaSoundSourceStream extends BasicSourceStream implements PushBufferStreamJavaSound capture stream. |
Fields Summary |
---|
DataSource | dsource | TargetDataLine | dataLine | AudioFormat | format | AudioFormat | devFormat | boolean | reconnect | int | bufSize | BufferTransferHandler | transferHandler | boolean | started | AudioFormatChooser | afc | BufferControl | bc | CircularBuffer | cb | PushThread | pushThread | static int | DefRate | static int | DefBits | static int | DefChannels | static int | DefSigned | static int | DefEndian | static int | OtherEndian | static Format[] | supported | protected static CaptureDeviceInfo[] | deviceList | private static JMFSecurity | jmfSecurity | private static boolean | securityPrivelege | private Method[] | mSecurity | private Class[] | clSecurity | private Object[] | argsSecurity | static int | DefaultMinBufferSize | static int | DefaultMaxBufferSize | long | bufLenReq |
Constructors Summary |
---|
public JavaSoundSourceStream(DataSource ds)
try {
jmfSecurity = JMFSecurityManager.getJMFSecurity();
securityPrivelege = true;
} catch (SecurityException e) {
}
supported = new javax.media.Format[] {
// The first one is the default.
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
44100,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
2,
DefEndian,
DefSigned),
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
44100,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
1,
DefEndian,
DefSigned),
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
22050,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
2,
DefEndian,
DefSigned),
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
22050,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
1,
DefEndian,
DefSigned),
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
11025,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
2,
DefEndian,
DefSigned),
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
11025,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
1,
DefEndian,
DefSigned),
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
8000,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
2,
DefEndian,
DefSigned),
new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
8000,
16, //javax.media.format.AudioFormat.NOT_SPECIFIED,
1,
DefEndian,
DefSigned),
};
deviceList = new CaptureDeviceInfo [] {
new CaptureDeviceInfo("JavaSound audio capture",
new MediaLocator("javasound://44100"),
supported)
};
super(new ContentDescriptor(ContentDescriptor.RAW), LENGTH_UNKNOWN);
dsource = ds;
bc = new BC(this);
controls = new javax.media.Control[2];
controls[0] = new FC(this);
controls[1] = bc;
|
Methods Summary |
---|
public void | connect()Connect to the device. It in turn calls openDev to do the
real work.
// Return if it's already connected.
if (isConnected())
return;
if (JavaSoundOutput.isOpen()) {
Log.warning("JavaSound is already opened for rendering. Will capture at the default format.");
format = null;
}
openDev();
if (pushThread == null) {
if ( /*securityPrivelege && */ (jmfSecurity != null) ) {
String permission = null;
try {
if (jmfSecurity.getName().startsWith("jmf-security")) {
permission = "thread";
jmfSecurity.requestPermission(mSecurity, clSecurity, argsSecurity,
JMFSecurity.THREAD);
mSecurity[0].invoke(clSecurity[0], argsSecurity[0]);
permission = "thread group";
jmfSecurity.requestPermission(mSecurity, clSecurity, argsSecurity,
JMFSecurity.THREAD_GROUP);
mSecurity[0].invoke(clSecurity[0], argsSecurity[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;
pushThread = (PushThread) jdk12.doPrivM.invoke(
jdk12.ac,
new Object[] {
cons.newInstance(
new Object[] {
PushThread.class,
})});
} catch (Exception e) {
// System.out.println("Exception: creating pushThread");
}
} else {
pushThread = new PushThread();
}
pushThread.setSourceStream(this);
}
if (reconnect)
Log.comment("Capture buffer size: " + bufSize);
devFormat = format;
reconnect = false;
| public void | disconnect()
if (dataLine == null)
return;
/*
dataLine.drain();
*/
dataLine.stop();
dataLine.close();
dataLine = null;
devFormat = null;
if (pushThread != null) {
pushThread.kill();
pushThread = null;
}
| public java.lang.Object[] | getControls()
return controls;
| public javax.media.Format | getFormat()
return format;
| public static javax.media.Format[] | getSupportedFormats()
return supported;
| public boolean | isConnected()
return devFormat != null;
| public static javax.media.CaptureDeviceInfo[] | listCaptureDeviceInfo()
return deviceList;
| void | openDev()Open the capture device.
DataLine.Info info;
javax.sound.sampled.AudioFormat afmt = null;
if (format != null) {
afmt = JavaSoundOutput.convertFormat(format);
int chnls = (format.getChannels() ==
javax.media.format.AudioFormat.NOT_SPECIFIED ?
1 : format.getChannels());
int size = (format.getSampleSizeInBits() ==
javax.media.format.AudioFormat.NOT_SPECIFIED ?
16 : format.getSampleSizeInBits());
int frameSize = (size * chnls)/8;
if (frameSize == 0)
frameSize = 1;
bufSize = (int)(format.getSampleRate() * frameSize *
bc.getBufferLength() / 1000);
info = new DataLine.Info(TargetDataLine.class, afmt, bufSize);
} else {
info = new DataLine.Info(TargetDataLine.class,
null, AudioSystem.NOT_SPECIFIED);
}
if (!AudioSystem.isLineSupported(info)) {
Log.error("Audio not supported: " + info + "\n");
throw new IOException("Cannot open audio device for input.");
}
try {
dataLine = (TargetDataLine)AudioSystem.getLine(info);
if (format != null) {
dataLine.open(afmt, bufSize);
} else {
dataLine.open();
format = JavaSoundOutput.convertFormat(dataLine.getFormat());
}
bufSize = dataLine.getBufferSize();
//dataLine.start();
} catch (Exception e) {
Log.error("Cannot open audio device for input: " + e);
throw new IOException(e.getMessage());
}
| public static javax.media.Format | parseLocator(javax.media.MediaLocator ml)Parse the javasound media locator which specifies the format.
A valid media locator is of the form:
javasound://[rate]/[sizeInBits]/[channels]/[big|little]/[signed|unsigned]
int rate, bits, channels, endian, signed;
String rateStr = null, bitsStr = null, channelsStr = null;
String endianStr = null, signedStr = null;
// Parser the media locator to extract the requested format.
String remainder = ml.getRemainder();
if (remainder != null && remainder.length() > 0) {
while (remainder.length() > 1 && remainder.charAt(0) == '/")
remainder = remainder.substring(1);
// Now see if there's a sample rate specified.
int off = remainder.indexOf('/");
if (off == -1) {
if (!remainder.equals(""))
rateStr = remainder;
} else {
rateStr = remainder.substring(0, off);
remainder = remainder.substring(off + 1);
// Now see if there's a sample size specified
off = remainder.indexOf('/");
if (off == -1) {
if (!remainder.equals(""))
bitsStr = remainder;
} else {
bitsStr = remainder.substring(0, off);
remainder = remainder.substring(off + 1);
// Now see if there's a channels specified
off = remainder.indexOf('/");
if (off == -1) {
if (!remainder.equals(""))
channelsStr = remainder;
} else {
channelsStr = remainder.substring(0, off);
remainder = remainder.substring(off + 1);
// Now see if there's endian specified.
off = remainder.indexOf('/");
if (off == -1) {
if (!remainder.equals(""))
endianStr = remainder;
} else {
endianStr = remainder.substring(0, off);
if (!remainder.equals(""))
signedStr = remainder.substring(off + 1);
}
}
}
}
}
// Sample Rate
rate = DefRate;
if (rateStr != null) {
try {
Integer integer = Integer.valueOf(rateStr);
if (integer != null)
rate = integer.intValue();
} catch (Throwable t) { }
// Range check.
if (rate <= 0 || rate > 96000) {
Log.warning("JavaSound capture: unsupported sample rate: " + rate);
rate = DefRate;
Log.warning(" defaults to: " + rate);
}
}
// Sample Size
bits = DefBits;
if (bitsStr != null) {
try {
Integer integer = Integer.valueOf(bitsStr);
if (integer != null)
bits = integer.intValue();
} catch (Throwable t) { }
// Range check.
if (bits != 8 && bits != 16) {
Log.warning("JavaSound capture: unsupported sample size: " + bits);
bits = DefBits;
Log.warning(" defaults to: " + bits);
}
}
// # of channels
channels = DefChannels;
if (channelsStr != null) {
try {
Integer integer = Integer.valueOf(channelsStr);
if (integer != null)
channels = integer.intValue();
} catch (Throwable t) { }
// Range check.
if (channels != 1 && channels != 2) {
Log.warning("JavaSound capture: unsupported # of channels: " + channels);
channels = DefChannels;
Log.warning(" defaults to: " + channels);
}
}
// Endian
endian = DefEndian;
if (endianStr != null) {
if (endianStr.equalsIgnoreCase("big"))
endian = javax.media.format.AudioFormat.BIG_ENDIAN;
else if (endianStr.equalsIgnoreCase("little"))
endian = javax.media.format.AudioFormat.LITTLE_ENDIAN;
else {
Log.warning("JavaSound capture: unsupported endianess: " + endianStr);
Log.warning(" defaults to: big endian");
}
}
// Signed
signed = DefSigned;
if (signedStr != null) {
if (signedStr.equalsIgnoreCase("signed"))
signed = javax.media.format.AudioFormat.SIGNED;
else if (signedStr.equalsIgnoreCase("unsigned"))
signed = javax.media.format.AudioFormat.UNSIGNED;
else {
Log.warning("JavaSound capture: unsupported signedness: " + signedStr);
Log.warning(" defaults to: signed");
}
}
javax.media.format.AudioFormat fmt;
fmt = new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR,
rate, bits, channels, endian, signed);
return fmt;
| public void | read(javax.media.Buffer in)
Buffer buffer;
Object data;
synchronized (cb) {
while (!cb.canRead()) {
try {
cb.wait();
} catch (Exception e) {}
}
buffer = cb.read();
}
// Swap data with the input buffer and my own buffer.
data = in.getData();
in.copy(buffer);
buffer.setData(data);
synchronized (cb) {
cb.readReport();
cb.notify();
}
| public javax.media.Format | setFormat(javax.media.Format fmt)Set the capture format.
if (started) {
Log.warning("Cannot change audio capture format after started.");
return format;
}
if (fmt == null)
return format;
javax.media.Format f = null;
for (int i = 0; i < supported.length; i++) {
if (fmt.matches(supported[i]) &&
(f = fmt.intersects(supported[i])) != null) {
break;
}
}
if (f == null)
return format;
try {
if (devFormat != null) {
if (!devFormat.matches(f) && !JavaSoundOutput.isOpen()) {
// Can't change format if JavaSound is already opened
// for rendering.
//System.err.println("The capture format has changed.");
format = (javax.media.format.AudioFormat)f;
disconnect();
connect();
}
} else {
format = (javax.media.format.AudioFormat)f;
connect();
}
} catch (IOException e) {
return null;
}
if (afc != null)
afc.setCurrentFormat(format);
return format;
| public void | setTransferHandler(javax.media.protocol.BufferTransferHandler th)
transferHandler = th;
| public void | start()Start capturing.
if (dataLine == null)
throw new IOException("A JavaSound input channel cannot be opened.");
if (started)
return;
// Check if the GUI control has specified a new format.
if (afc != null) {
Format f;
if ((f = afc.getFormat()) != null && !f.matches(format)) {
if (setFormat(f) == null) {
//System.err.println("The chosen format is not supported.");
}
}
afc.setEnabled(false);
}
// Disconnect the source if the reconnect flag is on.
if (reconnect)
disconnect();
// Connect the source if it's not already connected.
if (!isConnected())
connect();
// Flush the old data.
synchronized (cb) {
while (cb.canRead()) {
cb.read();
cb.readReport();
}
cb.notifyAll();
}
pushThread.start();
dataLine.flush();
dataLine.start();
started = true;
| public void | stop()Stop the capture.
if (!started)
return;
pushThread.pause();
if (dataLine != null)
dataLine.stop();
started = false;
if (afc != null && !JavaSoundOutput.isOpen())
afc.setEnabled(true);
| public boolean | willReadBlock()
return !started;
|
|