package org.intellimate.izou.system.sound;
import org.intellimate.izou.addon.AddOnModel;
import org.intellimate.izou.main.Main;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.DataLine;
/**
* the delegation to DataLine.
* @author LeanderK
* @version 1.0
*/
public class IzouSoundDataLine extends IzouSoundLineBaseClass implements DataLine {
private final DataLine dataLine;
public IzouSoundDataLine(DataLine dataLine, Main main, boolean isPermanent, AddOnModel addOnModel) {
super(dataLine, main, isPermanent, addOnModel);
this.dataLine = dataLine;
}
/**
* Drains queued data from the line by continuing data I/O until the
* data line's internal buffer has been emptied.
* This method blocks until the draining is complete. Because this is a
* blocking method, it should be used with care. If <code>drain()</code>
* is invoked on a stopped line that has data in its queue, the method will
* block until the line is running and the data queue becomes empty. If
* <code>drain()</code> is invoked by one thread, and another continues to
* fill the data queue, the operation will not complete.
* This method always returns when the data line is closed.
*
* @see #flush()
*/
@Override
public void drain() {
dataLine.drain();
}
/**
* Flushes queued data from the line. The flushed data is discarded.
* In some cases, not all queued data can be discarded. For example, a
* mixer can flush data from the buffer for a specific input line, but any
* unplayed data already in the output buffer (the result of the mix) will
* still be played. You can invoke this method after pausing a line (the
* normal case) if you want to skip the "stale" data when you restart
* playback or capture. (It is legal to flush a line that is not stopped,
* but doing so on an active line is likely to cause a discontinuity in the
* data, resulting in a perceptible click.)
*
* @see #stop()
* @see #drain()
*/
@Override
public void flush() {
dataLine.flush();
}
/**
* Allows a line to engage in data I/O. If invoked on a line
* that is already running, this method does nothing. Unless the data in
* the buffer has been flushed, the line resumes I/O starting
* with the first frame that was unprocessed at the time the line was
* stopped. When audio capture or playback starts, a
* <code>LineEvent.Type#START START</code> event is generated.
*
* @see #stop()
* @see #isRunning()
*/
@Override
public void start() {
dataLine.start();
}
/**
* Stops the line. A stopped line should cease I/O activity.
* If the line is open and running, however, it should retain the resources required
* to resume activity. A stopped line should retain any audio data in its buffer
* instead of discarding it, so that upon resumption the I/O can continue where it left off,
* if possible. (This doesn't guarantee that there will never be discontinuities beyond the
* current buffer, of course; if the stopped condition continues
* for too long, input or output samples might be dropped.) If desired, the retained data can be
* discarded by invoking the <code>flush</code> method.
* When audio capture or playback stops, a <code>LineEvent.Type#STOP STOP</code> event is generated.
*
* @see #start()
* @see #isRunning()
* @see #flush()
*/
@Override
public void stop() {
dataLine.stop();
}
/**
* Indicates whether the line is running. The default is <code>false</code>.
* An open line begins running when the first data is presented in response to an
* invocation of the <code>start</code> method, and continues
* until presentation ceases in response to a call to <code>stop</code> or
* because playback completes.
* @return <code>true</code> if the line is running, otherwise <code>false</code>
* @see #start()
* @see #stop()
*/
@Override
public boolean isRunning() {
return dataLine.isRunning();
}
/**
* Indicates whether the line is engaging in active I/O (such as playback
* or capture). When an inactive line becomes active, it sends a
* <code>LineEvent.Type#START START</code> event to its listeners. Similarly, when
* an active line becomes inactive, it sends a
* <code>LineEvent.Type#STOP STOP</code> event.
* @return <code>true</code> if the line is actively capturing or rendering
* sound, otherwise <code>false</code>
* @see #isOpen
* @see #addLineListener
* @see #removeLineListener
*/
@Override
public boolean isActive() {
return dataLine.isActive();
}
/**
* Obtains the current format (encoding, sample rate, number of channels,
* etc.) of the data line's audio data.
*
* <p>If the line is not open and has never been opened, it returns
* the default format. The default format is an implementation
* specific audio format, or, if the <code>DataLine.Info</code>
* object, which was used to retrieve this <code>DataLine</code>,
* specifies at least one fully qualified audio format, the
* last one will be used as the default format. Opening the
* line with a specific audio format (e.g.
* SourceDataLine#open(AudioFormat)) will override the
* default format.
*
* @return current audio data format
* @see AudioFormat
*/
@Override
public AudioFormat getFormat() {
return dataLine.getFormat();
}
/**
* Obtains the maximum number of bytes of data that will fit in the data line's
* internal buffer. For a source data line, this is the size of the buffer to
* which data can be written. For a target data line, it is the size of
* the buffer from which data can be read. Note that
* the units used are bytes, but will always correspond to an integral
* number of sample frames of audio data.
*
* @return the size of the buffer in bytes
*/
@Override
public int getBufferSize() {
return dataLine.getBufferSize();
}
/**
* Obtains the number of bytes of data currently available to the
* application for processing in the data line's internal buffer. For a
* source data line, this is the amount of data that can be written to the
* buffer without blocking. For a target data line, this is the amount of data
* available to be read by the application. For a clip, this value is always
* 0 because the audio data is loaded into the buffer when the clip is opened,
* and persists without modification until the clip is closed.
* <p>
* Note that the units used are bytes, but will always
* correspond to an integral number of sample frames of audio data.
* <p>
* An application is guaranteed that a read or
* write operation of up to the number of bytes returned from
* <code>available()</code> will not block; however, there is no guarantee
* that attempts to read or write more data will block.
*
* @return the amount of data available, in bytes
*/
@Override
public int available() {
return dataLine.available();
}
/**
* Obtains the current position in the audio data, in sample frames.
* The frame position measures the number of sample
* frames captured by, or rendered from, the line since it was opened.
* This return value will wrap around after 2^31 frames. It is recommended
* to use <code>getLongFramePosition</code> instead.
*
* @return the number of frames already processed since the line was opened
* @see #getLongFramePosition()
*/
@Override
public int getFramePosition() {
return dataLine.getFramePosition();
}
/**
* Obtains the current position in the audio data, in sample frames.
* The frame position measures the number of sample
* frames captured by, or rendered from, the line since it was opened.
*
* @return the number of frames already processed since the line was opened
* @since 1.5
*/
@Override
public long getLongFramePosition() {
return dataLine.getLongFramePosition();
}
/**
* Obtains the current position in the audio data, in microseconds.
* The microsecond position measures the time corresponding to the number
* of sample frames captured by, or rendered from, the line since it was opened.
* The level of precision is not guaranteed. For example, an implementation
* might calculate the microsecond position from the current frame position
* and the audio sample frame rate. The precision in microseconds would
* then be limited to the number of microseconds per sample frame.
*
* @return the number of microseconds of data processed since the line was opened
*/
@Override
public long getMicrosecondPosition() {
return dataLine.getMicrosecondPosition();
}
/**
* Obtains the current volume level for the line. This level is a measure
* of the signal's current amplitude, and should not be confused with the
* current setting of a gain control. The range is from 0.0 (silence) to
* 1.0 (maximum possible amplitude for the sound waveform). The units
* measure linear amplitude, not decibels.
*
* @return the current amplitude of the signal in this line, or
* <code>AudioSystem#NOT_SPECIFIED</code>
*/
@Override
public float getLevel() {
return dataLine.getLevel();
}
}