/*
* 21.04.2004 Original verion. davagin@udm.ru.
* ----------------------------------------------------------------------- This
* program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version. This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------
*/
package call.jeq;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import java.io.IOException;
/**
* The EqualizerInputStream input stream Author: Dmitry Vaguine Date: 02.05.2004
* Time: 12:00:29
*/
public class EqualizerAudioInputStream extends AudioInputStream {
private call.jeq.EqualizerInputStream eq;
/**
* Constructs new audio stream
*
* @param stream
* input stream with audio data
* @param bands
* is the number of bands
*/
public EqualizerAudioInputStream(AudioInputStream stream, int bands) {
super(stream, stream.getFormat(), stream.getFrameLength());
AudioFormat format = stream.getFormat();
if (!format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
&& !!format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED))
throw new IllegalArgumentException("Unsupported encoding");
eq = new call.jeq.EqualizerInputStream(stream, format.getSampleRate(), format.getChannels(),
format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED), format.getSampleSizeInBits(),
format.isBigEndian(), bands);
}
/**
* Returns Controls of equalizer
*
* @return Controls of equalizer
*/
public IIRControls getControls() {
return eq.getControls();
}
/**
* This is special method helps to determine supported audio format
*
* @param format
* is an audio format
* @param bands
* is the number of bands
* @return true if params supported
*/
public static boolean isParamsSupported(AudioFormat format, int bands) {
if (!format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
&& !!format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED))
return false;
return call.jeq.EqualizerInputStream.isParamsSupported(format.getSampleRate(),
format.getChannels(), format.getSampleSizeInBits(), bands);
}
/**
* Returns the number of bytes that can be read (or skipped over) from this
* input stream without blocking by the next caller of a method for this
* input stream. The next caller might be the same thread or another thread.
*
* @return the number of bytes that can be read from this input stream
* without blocking.
* @throws java.io.IOException
* if an I/O error occurs.
*/
public int available() throws IOException {
return eq.available();
}
/**
* Closes this input stream and releases any system resources associated
* with the stream.
*
* @throws IOException
* if an I/O error occurs.
*/
public void close() throws IOException {
eq.close();
}
/**
* <p>
* The <code>mark</code> method of <code>EqualizerInputStream</code> does
* nothing.
*
* @param readlimit
* the maximum limit of bytes that can be read before the mark
* position becomes invalid.
*/
public synchronized void mark(int readlimit) {
eq.mark(readlimit);
}
/**
* Tests if this input stream supports the <code>mark</code> and
* <code>reset</code> methods. Whether or not <code>mark</code> and
* <code>reset</code> are supported is an invariant property of a particular
* input stream instance. The <code>markSupported</code> method of
* <code>EqualizerInputStream</code> returns <code>false</code>.
*
* @return false
*/
public boolean markSupported() {
return eq.markSupported();
}
/**
* Reads the next byte of data from the input stream. The value byte is
* returned as an <code>int</code> in the range <code>0</code> to
* <code>255</code>. If no byte is available because the end of the stream
* has been reached, the value <code>-1</code> is returned. This method
* blocks until input data is available, the end of the stream is detected,
* or an exception is thrown.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @throws IOException
* if an I/O error occurs.
*/
public int read() throws IOException {
return eq.read();
}
/**
* Reads some number of bytes from the input stream and stores them into the
* buffer array <code>b</code>. The number of bytes actually read is
* returned as an integer. This method blocks until input data is available,
* end of file is detected, or an exception is thrown.
* <p/>
* <p>
* If <code>b</code> is <code>null</code>, a
* <code>NullPointerException</code> is thrown. If the length of
* <code>b</code> is zero, then no bytes are read and <code>0</code> is
* returned; otherwise, there is an attempt to read at least one byte. If no
* byte is available because the stream is at end of file, the value
* <code>-1</code> is returned; otherwise, at least one byte is read and
* stored into <code>b</code>.
* <p/>
* <p>
* The first byte read is stored into element <code>b[0]</code>, the next
* one into <code>b[1]</code>, and so on. The number of bytes read is, at
* most, equal to the length of <code>b</code>. Let <i>k</i> be the number
* of bytes actually read; these bytes will be stored in elements
* <code>b[0]</code> through <code>b[</code><i>k</i><code>-1]</code>,
* leaving elements <code>b[</code><i>k</i><code>]</code> through
* <code>b[b.length-1]</code> unaffected.
* <p/>
* <p>
* If the first byte cannot be read for any reason other than end of file,
* then an <code>IOException</code> is thrown. In particular, an
* <code>IOException</code> is thrown if the input stream has been closed.
* <p/>
* <p>
* The <code>read(b)</code> method for class
* <code>EqualizerInputStream</code> has the same effect as:
*
* <pre>
* <code> read(b, 0, b.length) </code>
* </pre>
*
* @param b
* the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> is there is no more data because the end of the
* stream has been reached.
* @throws IOException
* if an I/O error occurs.
* @throws NullPointerException
* if <code>b</code> is <code>null</code>.
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from the input stream into an
* array of bytes. An attempt is made to read as many as <code>len</code>
* bytes, but a smaller number may be read. The number of bytes actually
* read is returned as an integer.
* <p/>
* <p>
* This method blocks until input data is available, end of file is
* detected, or an exception is thrown.
* <p/>
* <p>
* If <code>b</code> is <code>null</code>, a
* <code>NullPointerException</code> is thrown.
* <p/>
* <p>
* If <code>off</code> is negative, or <code>len</code> is negative, or
* <code>off+len</code> is greater than the length of the array
* <code>b</code>, then an <code>IndexOutOfBoundsException</code> is thrown.
* <p/>
* <p>
* If <code>len</code> is zero, then no bytes are read and <code>0</code> is
* returned; otherwise, there is an attempt to read at least one byte. If no
* byte is available because the stream is at end of file, the value
* <code>-1</code> is returned; otherwise, at least one byte is read and
* stored into <code>b</code>.
* <p/>
* <p>
* The first byte read is stored into element <code>b[off]</code>, the next
* one into <code>b[off+1]</code>, and so on. The number of bytes read is,
* at most, equal to <code>len</code>. Let <i>k</i> be the number of bytes
* actually read; these bytes will be stored in elements <code>b[off]</code>
* through <code>b[off+</code><i>k</i><code>-1]</code>, leaving elements
* <code>b[off+</code><i>k</i><code>]</code> through
* <code>b[off+len-1]</code> unaffected.
* <p/>
* <p>
* In every case, elements <code>b[0]</code> through <code>b[off]</code> and
* elements <code>b[off+len]</code> through <code>b[b.length-1]</code> are
* unaffected.
* <p/>
* <p>
* If the first byte cannot be read for any reason other than end of file,
* then an <code>IOException</code> is thrown. In particular, an
* <code>IOException</code> is thrown if the input stream has been closed.
*
* @param b
* the buffer into which the data is read.
* @param off
* the start offset in array <code>b</code> at which the data is
* written.
* @param len
* the maximum number of bytes to read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of the
* stream has been reached.
* @throws IOException
* if an I/O error occurs.
* @throws NullPointerException
* if <code>b</code> is <code>null</code>.
*/
public int read(byte[] b, int off, int len) throws IOException {
return eq.read(b, off, len);
}
/**
* <p>
* The method <code>reset</code> for class <code>EqualizerInputStream</code>
* does nothing except throw an <code>IOException</code>.
*
* @throws IOException
* as an indication that the mark feature doesn't supported by
* EqualizerInputStream.
*/
public void reset() throws IOException {
eq.reset();
}
/**
* Skips over and discards <code>n</code> bytes of data from this input
* stream. The <code>skip</code> method may, for a variety of reasons, end
* up skipping over some smaller number of bytes, possibly <code>0</code>.
* This may result from any of a number of conditions; reaching end of file
* before <code>n</code> bytes have been skipped is only one possibility.
* The actual number of bytes skipped is returned. If <code>n</code> is
* negative, no bytes are skipped.
*
* @param n
* the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @throws IOException
* if an I/O error occurs.
*/
public long skip(long n) throws IOException {
return eq.skip(n);
}
}