⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datasourcehandler.java

📁 It is Java for SIP phone
💻 JAVA
字号:
/* * DataSourceHandler.java * * Created on March 20, 2003, 10:56 AM */package gov.nist.applet.phone.media.messaging;import java.util.Enumeration;import java.util.Vector;import java.io.ByteArrayOutputStream;import java.io.IOException;import javax.media.DataSink;import javax.media.MediaLocator;import javax.media.Control;import javax.media.datasink.DataSinkErrorEvent;import javax.media.datasink.DataSinkEvent;import javax.media.datasink.DataSinkListener;import javax.media.datasink.EndOfStreamEvent;import javax.media.protocol.SourceTransferHandler;import javax.media.protocol.PushDataSource;import javax.media.protocol.PushSourceStream;import javax.media.protocol.PullDataSource;import javax.media.protocol.DataSource;import javax.media.protocol.SourceStream;import javax.media.IncompatibleSourceException;/** * 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 DataSourceHandler        implements DataSink, SourceTransferHandler, Runnable{    //DataSink listeners		protected Vector listeners = new Vector(1);	    final private static   boolean DEBUG = false;    //states    final protected static int NOT_INITIALIZED = 0;    final protected static int OPENED = 1;    final protected static int STARTED = 2;    final protected static int CLOSED = 3;    //current state    protected int state = NOT_INITIALIZED;    protected DataSource source;    protected SourceStream [] streams;    protected SourceStream stream;    protected boolean push;       protected Control [] controls;        //protected MediaLocator locator = null;    protected String contentType = null;    protected int bytesWritten = 0;    protected static final int BUFFER_LEN = 128 * 1024;    protected boolean syncEnabled = false;	long lastSyncTime = -1;	ByteArrayOutputStream baout=null;    protected byte [] buffer1 = new byte[BUFFER_LEN];    protected byte [] buffer2 = new byte[BUFFER_LEN];    protected boolean buffer1Pending = false;    protected long    buffer1PendingLocation = -1;    protected int     buffer1Length;    protected boolean buffer2Pending = false;    protected long    buffer2PendingLocation = -1;    protected int     buffer2Length;    protected long    nextLocation = 0;    protected Thread  writeThread = null;    private   Integer bufferLock = new Integer(0);    private   boolean receivedEOS = false;        public  int WRITE_CHUNK_SIZE = 16384;    private boolean streamingEnabled = false;        /**     * Constructs a new DataSourceHandler     */    public DataSourceHandler(){    	baout=new ByteArrayOutputStream();    }        /**     * 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 ds) throws IncompatibleSourceException {			if (!(ds instanceof PushDataSource) &&		    !(ds instanceof PullDataSource)) {			    throw new IncompatibleSourceException("Incompatible datasource");		}		source = ds;				if (source instanceof PushDataSource) {		    push = true;		    try {				((PushDataSource) source).connect();		    } catch (IOException ioe) {		    }		    streams = ((PushDataSource) source).getStreams();		} else {		    push = false;		    try {				((PullDataSource) source).connect();		    } catch (IOException ioe) {		    }		    streams = ((PullDataSource) source).getStreams();		}				if (streams == null || streams.length != 1)		    throw new IncompatibleSourceException("DataSource should have 1 stream");		stream = streams[0];				contentType = source.getContentType();		if (push)		    ((PushSourceStream)stream).setTransferHandler(this);    }    /**     * Set the output <code>MediaLocator</code>.     * This method should only be called once; an error is thrown if     * the locator has already been set.     * @param output <code>MediaLocator</code> that describes where      * 		the output goes.     */    public void setOutputLocator(MediaLocator output) {		//locator = output;    }    /*public void setEnabled(boolean b) {		streamingEnabled = b;    }    public void setSyncEnabled() {		syncEnabled = true;    }*/    /**	 * Our DataSink does not need to be opened.     */	public void open() {		    }	/**	 * @see javax.media.DataSink#getOutputLocator()	 */    public MediaLocator getOutputLocator() {    	return null;		//return locator;    }	/**	 * @see javax.media.DataSink#start()	 */    public void start() throws IOException {				//System.out.println("DATASOURCEHANDLER: start : source: "+source);			    if (source != null)			source.start();	    if (writeThread == null) {			writeThread = new Thread(this);			writeThread.setName("DataSourceHandler Thread");			writeThread.start();	    }	    setState(STARTED);    }    /**     * Stop the data-transfer.     * If the source has not been connected and started,     * <CODE>stop</CODE> does nothing.     */    public void stop() throws IOException {    	//System.out.println("DATASOURCEHANDLER: stop");		if (state == STARTED) {		    if (source != null)				source.stop();										    setState(OPENED);		}    }	/**	 * Set the state of this data source handler	 */    protected void setState(int state) {		synchronized(this) {		    this.state = state;		}    }   	/**	 * @see javax.media.DataSink#close()	 */    public final void close() {		synchronized(this) {		    if ( state == CLOSED )			return;		    setState(CLOSED);		}			if (push) {		    for (int i = 0; i < streams.length; i++) {				((PushSourceStream)streams[i]).setTransferHandler(null);		    }		}				try {		    source.stop();		} catch (IOException e) {		    System.err.println("IOException when stopping source " + e);		}			    // 	Disconnect the data source 	    if (source != null)			source.disconnect();	   			removeAllListeners();		//writeBufferToFile("d://temp//test.mp3");      }	/**	 * 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 contentType;    }	/**	 * 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() {		if (controls == null) {		    controls = new Control[0];		}		return controls;    }	/**	 * 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 controlName) {		return null;    }	/*	 * @see javax.media.protocol.SourceTransferHandler#transferData(javax.media.protocol.PushSourceStream)	 */    public synchronized void transferData(PushSourceStream pss) {    	if(state==STARTED){			int totalRead = 0;			int spaceAvailable = BUFFER_LEN;			int bytesRead = 0;						if (buffer1Pending) {			    synchronized (bufferLock) {				while (buffer1Pending) {				    if (DEBUG) System.err.println("Waiting for free buffer");				    try {					bufferLock.wait();				    } catch (InterruptedException ie) {				    }				}			    }			    if (DEBUG) System.err.println("Got free buffer");			}						//	System.err.println("In transferData()");			while (spaceAvailable > 0) {			    try {				bytesRead = pss.read(buffer1, totalRead, spaceAvailable);				//System.err.println("bytesRead = " + bytesRead);				if (bytesRead > 16 * 1024 && WRITE_CHUNK_SIZE < 32 * 1024) {				    if (  bytesRead > 64 * 1024 &&					  WRITE_CHUNK_SIZE < 128 * 1024  )					WRITE_CHUNK_SIZE = 128 * 1024;				    else if (  bytesRead > 32 * 1024 &&					       WRITE_CHUNK_SIZE < 64 * 1024  )					WRITE_CHUNK_SIZE = 64 * 1024;				    else if (  WRITE_CHUNK_SIZE < 32 * 1024  )					WRITE_CHUNK_SIZE = 32 * 1024;				    //System.err.println("Increasing buffer to " + WRITE_CHUNK_SIZE);						}			    } catch (IOException ioe) {				// What to do here?			    }			    if (bytesRead <= 0) {				break;			    }			    totalRead += bytesRead;			    spaceAvailable -= bytesRead;			}					if (totalRead > 0) {			    synchronized (bufferLock) {				buffer1Pending = true;				buffer1PendingLocation = nextLocation;				buffer1Length = totalRead;				nextLocation = -1; // assume next write is contiguous unless seeked				// Notify availability to write thread				if (DEBUG) 					System.err.println("Notifying consumer");				bufferLock.notifyAll();			    }			}			// Send EOS if necessary			if (bytesRead == -1) {			    if (DEBUG) System.err.println("Got EOS");			    receivedEOS = true;	    			}    	}    }    /**     *  Asynchronous write thread     */    public void run() {    			while (!(state == CLOSED)){			if(state==STARTED){ 				    synchronized (bufferLock) {		    			    						// Wait for some data or error					while (!buffer1Pending && !buffer2Pending && 					       state != CLOSED && !receivedEOS) {				    	if (DEBUG) 				    		System.err.println("Waiting for filled buffer");					 	try {							bufferLock.wait(500);					    } catch (InterruptedException ie) {					    }					    if (DEBUG) 					    	System.err.println("Consumer notified");					}			    }			    // Something's pending			    if (buffer2Pending) {					if (DEBUG) 						System.err.println("Writing Buffer2");					// write that first					write(buffer2, buffer2PendingLocation, buffer2Length);					if (DEBUG) 						System.err.println("Done writing Buffer2");					buffer2Pending = false;			    }					    synchronized (bufferLock) {					if (buffer1Pending) {					    byte [] tempBuffer = buffer2;					    buffer2 = buffer1;					    buffer2Pending = true;					    buffer2PendingLocation = buffer1PendingLocation;					    buffer2Length = buffer1Length;					    buffer1Pending = false;					    buffer1 = tempBuffer;					    if (DEBUG) System.err.println("Notifying producer");					    bufferLock.notifyAll();					} else {					    if (receivedEOS)						break;					}			    }			}			if (receivedEOS) {			    if (DEBUG) 			    	System.err.println("Sending EOS: streamingEnabled is " + streamingEnabled);	    			    if (!streamingEnabled) {					sendEndofStreamEvent();			    }			}		}	    }	/**	 * seek a specific location in the dataSource	 * @return the location where the data source is now placed	 */    public synchronized long seek(long where) {		nextLocation = where;		return where;    }	/**	 * Write the data in parameter in the data source handler buffer	 * @param buffer - data to write into the data source handler buffer	 * @param location - location to start 	 * @param length - length to write	 */    private void write(byte [] buffer, long location, int length) {		int offset, toWrite;		    offset = 0;	    while (length > 0) {			toWrite = WRITE_CHUNK_SIZE;			if (length < toWrite)			    toWrite = length;			baout.write(buffer, offset, toWrite);			bytesWritten += toWrite;			length -= toWrite;			offset += toWrite;					    									Thread.yield();	    }	    }    /**     * @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);				}			}		}	}	/**	 * remove All the listeners from this data source handler	 */	protected void removeAllListeners() {		listeners.removeAllElements();	}		/**	 * Send an end of stream event to the listeners	 */    	protected final void sendEndofStreamEvent() {		sendEvent(new EndOfStreamEvent(this));	}	/**	 * Send a data sink error event to the listeners	 * @param reason - the reason of the error	 */	protected final void sendDataSinkErrorEvent(String reason) {		sendEvent(new DataSinkErrorEvent(this, reason));	}		/**	 * Get the recorded buffer of this data source handler	 * @return byte array containing the data recorded	 */	public byte[] getRecordBuffer(){		byte[] recordedBuffer= baout.toByteArray();		baout.reset();		return recordedBuffer;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -