?? rawdatasourcehandler.java
字號:
/*
* RawDataSourceHandler.java
*
* Created on Mar 16, 2004
*
*/
package gov.nist.applet.phone.media.messaging;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import javax.media.Buffer;
import javax.media.DataSink;
import javax.media.IncompatibleSourceException;
import javax.media.MediaLocator;
import javax.media.datasink.DataSinkErrorEvent;
import javax.media.datasink.DataSinkEvent;
import javax.media.datasink.DataSinkListener;
import javax.media.datasink.EndOfStreamEvent;
import javax.media.protocol.BufferTransferHandler;
import javax.media.protocol.PullBufferDataSource;
import javax.media.protocol.PullBufferStream;
import javax.media.protocol.PushBufferDataSource;
import javax.media.protocol.PushBufferStream;
import javax.media.protocol.SourceStream;
import javax.media.protocol.DataSource;
/**
* This Data source Handler allow one to write directly from a DataSource
* to an array of byte.
* This Data Source Handler allow one to fill a buffer with MPEG_AUDIO
* or GSM audio data.
* Example : One can record his voice from a microphone to a buffer in either a
* MP3 or GSM format. To get the buffer with the recorded voice just call the
* getRecordBuffer method
*
* @author Jean Deruelle <jean.deruelle@nist.gov>
*
* <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
*/
public class RawDataSourceHandler implements DataSink, BufferTransferHandler{
public static final int NUMBER_OF_BYTES_FOR_ONE_SECOND=18928;
DataSource source;
PullBufferStream pullStrms[] = null;
PushBufferStream pushStrms[] = null;
//length of the buffer read
int bufferLengthRead=0;
//length of the buffer read
int bufferLength=0;
// Data sink listeners.
private Vector listeners = new Vector(1);
// Stored all the streams that are not yet finished (i.e. EOM
// has not been received.
SourceStream unfinishedStrms[] = null;
// Loop threads to pull data from a PullBufferDataSource.
// There is one thread per each PullSourceStream.
Loop loops[] = null;
Buffer readBuffer;
ByteArrayOutputStream baout=null;
/**
* Default Constructor
*/
public RawDataSourceHandler(){
baout=new ByteArrayOutputStream();
}
/**
*
* @param duration - duration to buffer in sec
*/
public RawDataSourceHandler(int duration){
bufferLength=duration*NUMBER_OF_BYTES_FOR_ONE_SECOND;
baout=new ByteArrayOutputStream(bufferLength);
}
/**
* Set the data source of this data source handler
* @exception IncompatibleSourceException - if the data source cannot be
* handled, this exception is thrown
*/
public void setSource(DataSource source) throws IncompatibleSourceException {
//System.out.println(source.getClass().getName());
// Different types of DataSources need to handled differently.
if (source instanceof PushBufferDataSource) {
pushStrms = ((PushBufferDataSource)source).getStreams();
unfinishedStrms = new SourceStream[pushStrms.length];
// Set the transfer handler to receive pushed data from
// the push DataSource.
for (int i = 0; i < pushStrms.length; i++) {
pushStrms[i].setTransferHandler(this);
unfinishedStrms[i] = pushStrms[i];
}
} else if (source instanceof PullBufferDataSource) {
pullStrms = ((PullBufferDataSource)source).getStreams();
unfinishedStrms = new SourceStream[pullStrms.length];
// For pull data sources, we'll start a thread per
// stream to pull data from the source.
loops = new Loop[pullStrms.length];
for (int i = 0; i < pullStrms.length; i++) {
loops[i] = new Loop(this, pullStrms[i]);
unfinishedStrms[i] = pullStrms[i];
}
} else {
// This handler only handles push or pull buffer datasource.
throw new IncompatibleSourceException();
}
this.source = source;
readBuffer = new Buffer();
}
/**
* For completeness, DataSink's require this method.
* But we don't need it.
*/
public void setOutputLocator(MediaLocator ml) {
}
/**
* For completeness, DataSink's require this method.
* But we don't need it.
*/
public MediaLocator getOutputLocator() {
return null;
}
/**
* Get the current content type for this data source handler
*
* @return The current <CODE>ContentDescriptor</CODE> for this data source handler.
*/
public String getContentType() {
return source.getContentType();
}
/**
* Our DataSink does not need to be opened.
*/
public void open() {
}
/**
* @see javax.media.DataSink#start()
*/
public void start() {
try {
source.start();
} catch (IOException e) {
System.err.println(e);
}
// Start the processing loop if we are dealing with a
// PullBufferDataSource.
if (loops != null) {
for (int i = 0; i < loops.length; i++)
loops[i].restart();
}
}
/**
* @see javax.media.DataSink#stop()
*/
public void stop() {
try {
source.stop();
} catch (IOException e) {
System.err.println(e);
}
// Start the processing loop if we are dealing with a
// PullBufferDataSource.
if (loops != null) {
for (int i = 0; i < loops.length; i++)
loops[i].pause();
}
}
/**
* @see javax.media.DataSink#close()
*/
public void close() {
stop();
if (loops != null) {
for (int i = 0; i < loops.length; i++)
loops[i].kill();
}
System.out.println(bufferLengthRead+" bytes have been read");
System.out.println("nb bytes actually in the buffer: "+baout.size());
//writeBufferToFile("d://temp//data.txt");
}
/**
* @see javax.media.DataSink#addDataSinkListener(javax.media.datasink.DataSinkListener)
*/
public void addDataSinkListener(DataSinkListener dsl) {
if (dsl != null)
if (!listeners.contains(dsl))
listeners.addElement(dsl);
}
/**
* @see javax.media.DataSink#removeDataSinkListener(javax.media.datasink.DataSinkListener)
*/
public void removeDataSinkListener(DataSinkListener dsl) {
if (dsl != null)
listeners.removeElement(dsl);
}
/**
* Send event to the listeners
* @param event - the vent to send
*/
protected void sendEvent(DataSinkEvent event) {
if (!listeners.isEmpty()) {
synchronized (listeners) {
Enumeration list = listeners.elements();
while (list.hasMoreElements()) {
DataSinkListener listener =
(DataSinkListener)list.nextElement();
listener.dataSinkUpdate(event);
}
}
}
}
/**
* This will get called when there's data pushed from the
* PushBufferDataSource.
* @param stream - stream from which the data are transferred
*/
public void transferData(PushBufferStream stream) {
//System.out.println("push");
try {
stream.read(readBuffer);
} catch (IOException e) {
System.err.println(e);
sendEvent(new DataSinkErrorEvent(this, e.getMessage()));
return;
}
bufferData(readBuffer);
// Check to see if we are done with all the streams.
if (readBuffer.isEOM() && checkDone(stream)) {
sendEvent(new EndOfStreamEvent(this));
}
}
/**
* This is called from the Loop thread to pull data from
* the PullBufferStream.
* @param stream - stream from which the data are pulled
*/
public boolean readPullData(PullBufferStream stream) {
//System.out.println("pull");
try {
stream.read(readBuffer);
} catch (IOException e) {
System.err.println(e);
return true;
}
bufferData(readBuffer);
if (readBuffer.isEOM()) {
// Check to see if we are done with all the streams.
if (checkDone(stream)) {
System.err.println("All done!");
close();
}
return true;
}
return false;
}
/**
* Check to see if all the streams are processed.
* @param strm - the stream to check
*/
public boolean checkDone(SourceStream strm) {
boolean done = true;
for (int i = 0; i < unfinishedStrms.length; i++) {
if (strm == unfinishedStrms[i])
unfinishedStrms[i] = null;
else if (unfinishedStrms[i] != null) {
// There's at least one stream that's not done.
done = false;
}
}
return done;
}
/**
* Buffer the data given by the buffer in parameter in our data source handler
* buffer
* @param buffer - the buffer that provide data
*/
void bufferData(Buffer buffer) {
//System.err.println("Read from stream: " + stream);
/*if (buffer.getFormat() instanceof AudioFormat){
System.err.println("Read audio data: "+buffer.getFormat());
}
else
System.err.println("Read video data:");
System.err.println(" Time stamp: " + buffer.getTimeStamp());
System.err.println(" Sequence #: " + buffer.getSequenceNumber());
System.err.println(" Data length: " + buffer.getLength());*/
Object data=buffer.getData();
if(data instanceof byte[]){
byte[] audioData=(byte[])data;
bufferLengthRead+=audioData.length;
try{
baout.write(audioData);
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
if (buffer.isEOM())
System.err.println(" Got EOM!");
}
/**
* Obtain the collection of objects that
* control the object that implements this interface.
* <p>
*
* No controls are supported.
* A zero length array is returned.
*
* @return A zero length array
*/
public Object [] getControls() {
return new Object[0];
}
/**
* Obtain the object that implements the specified
* <code>Class</code> or <code>Interface</code>
* The full class or interface name must be used.
* <p>
*
* The control is not supported.
* <code>null</code> is returned.
*
* @return <code>null</code>.
*/
public Object getControl(String name) {
return null;
}
/**
* Get the recorded buffer of this data source handler
* @return byte array containing the data recorded
*/
public byte[] getRecordBuffer(){
return baout.toByteArray();
}
/**
* Utility method to write the data source handler buffer to a file
* @param fileName - the file where to write the buffer
*/
public void writeBufferToFile(String fileName){
File f=new File(fileName);
FileOutputStream fos=null;
try{
fos=new FileOutputStream(fileName);
}
catch(FileNotFoundException fnfe){
fnfe.printStackTrace();
}
try{
fos.write(baout.toByteArray());
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -