| META TOPICPARENT | name="JMFQuickstartGuide" |
<-- This creates the navigation links to : Home | Help | Index | etc. -->
The following JMF utility program from the JMF Quickstart Guide allows you to capture directly from JavaSound.
It is based on the LiveData sample code. Please refer to that sample for usage instructions.
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/LiveData.html
The sample consists of 2 classes:
JavaSoundDataSource
import javax.media.Time;
import javax.media.protocol.*;
import java.io.IOException;
public class JavaSoundDataSource extends PushBufferDataSource {
protected Object [] controls = new Object[0];
protected boolean started = false;
protected String contentType = "raw";
protected boolean connected = false;
protected Time duration = DURATION_UNKNOWN;
protected JavaSoundStream[] streams = null;
protected JavaSoundStream stream = null;
public JavaSoundDataSource() {
}
public String getContentType() {
if (!connected){
System.err.println("Error: DataSource not connected");
return null;
}
return contentType;
}
public void connect() throws IOException {
if (connected)
return;
connected = true;
}
public void disconnect() {
try {
if (started)
stop();
} catch (IOException e) {}
connected = false;
}
public void start() throws IOException {
// we need to throw error if connect() has not been called
if (!connected)
throw new java.lang.Error("DataSource must be connected before it can be started");
if (started)
return;
started = true;
stream.start(true);
}
public void stop() throws IOException {
if ((!connected) || (!started))
return;
started = false;
stream.start(false);
}
public Object [] getControls() {
return controls;
}
public Object getControl(String controlType) {
try {
Class cls = Class.forName(controlType);
Object cs[] = getControls();
for (int i = 0; i < cs.length; i++) {
if (cls.isInstance(cs[i]))
return cs[i];
}
return null;
} catch (Exception e) { // no such controlType or such control
return null;
}
}
public Time getDuration() {
return duration;
}
public PushBufferStream [] getStreams() {
if (streams == null) {
streams = new JavaSoundStream[1];
stream = streams[0] = new JavaSoundStream();
}
return streams;
}
JavaSoundStream
Note: JavaSoundFormats.getFormatList() is a static function whose job it is to return an array of acceptable formats. Because "acceptable formats" is project-specific, you will need to implement this function yourself.
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import java.io.IOException;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
public class JavaSoundStream implements PushBufferStream, Runnable {
/* JMF STUFF */
protected ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW);
protected int maxDataLength;
protected boolean started;
protected Thread thread;
protected BufferTransferHandler transferHandler;
protected Control [] controls = new Control[0];
protected AudioFormat audio_out_format;
protected javax.sound.sampled.AudioFormat audio_in_format;
/* JavaSound Stuff */
TargetDataLine tdl = null;
public JavaSoundStream() {
/* Start the thread */
thread = new Thread(this);
/* JavaSound Stuff */
javax.sound.sampled.AudioFormat formats[] = JavaSoundFormats.getFormatList(); /* Write your own code to get an array of acceptable formats */
for (javax.sound.sampled.AudioFormat format : formats) {
DataLine.Info dlinfo = new DataLine.Info(TargetDataLine.class,
format);
if (AudioSystem.isLineSupported(dlinfo)) {
try {
audio_in_format = format;
tdl = (TargetDataLine)AudioSystem.getLine(dlinfo);
break;
}
catch(LineUnavailableException e) {
// No need to do anything
}
}
}
/* If we don't have a targetdataoutput object, give up */
if (tdl == null) {
System.err.println("No TargetDataLines found!");
return;
}
/* JMF Stuff */
System.err.println(audio_in_format);
audio_out_format = new AudioFormat(AudioFormat.LINEAR,
(double)audio_in_format.getSampleRate(),
audio_in_format.getSampleSizeInBits(),
audio_in_format.getChannels(),
(audio_in_format.isBigEndian()) ? AudioFormat.BIG_ENDIAN : AudioFormat.LITTLE_ENDIAN,
(audio_in_format.getEncoding() == javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED) ? AudioFormat.SIGNED : AudioFormat.UNSIGNED
);
}
/***************************************************************************
* SourceStream
***************************************************************************/
public ContentDescriptor getContentDescriptor() {
return cd;
}
public long getContentLength() {
return LENGTH_UNKNOWN;
}
public boolean endOfStream() {
return false;
}
/***************************************************************************
* PushBufferStream
***************************************************************************/
private int seqNo = 0;
public Format getFormat() {
return audio_out_format;
}
public void read(Buffer buffer) throws IOException {
synchronized (this) {
Object outdata = buffer.getData();
if (outdata == null || !(outdata.getClass() == Format.byteArray) ||
((byte[])outdata).length < maxDataLength) {
}
outdata = new byte[tdl.available()];
buffer.setData(outdata);
int length = tdl.read((byte[])outdata, 0, ((byte[])outdata).length);
buffer.setFormat( audio_out_format );
buffer.setSequenceNumber(seqNo++);
buffer.setLength(length);
}
}
public void setTransferHandler(BufferTransferHandler transferHandler) {
synchronized (this) {
this.transferHandler = transferHandler;
notifyAll();
}
}
void start(boolean started) {
synchronized ( this ) {
this.started = started;
if (started && !thread.isAlive()) {
thread = new Thread(this);
thread.start();
}
/* Open up the TargetDataLine */
if (tdl != null) {
try {
tdl.open();
tdl.start();
}
catch(LineUnavailableException e){
this.started = false;
}
}
notifyAll();
}
}
/***************************************************************************
* Runnable
***************************************************************************/
public void run() {
while (started) {
synchronized (this) {
while (transferHandler == null && started) {
try {
wait(1000);
} catch (InterruptedException ie) {
}
}
}
if (started && transferHandler != null) {
transferHandler.transferData(this);
try {
Thread.currentThread().sleep( 10 );
}
catch (InterruptedException ise) {
}
}
}
}
// Controls
public Object [] getControls() {
return controls;
}
public Object getControl(String controlType) {
try {
Class cls = Class.forName(controlType);
Object cs[] = getControls();
for (int i = 0; i < cs.length; i++) {
if (cls.isInstance(cs[i]))
return cs[i];
}
return null;
} catch (Exception e) { // no such controlType or such control
return null;
}
}
}
|