/**
* Copyright 2013 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package com.jogamp.opengl.util.av;
import java.nio.ByteBuffer;
import jogamp.opengl.Debug;
public interface AudioSink {
public static final boolean DEBUG = Debug.debug("AudioSink");
/** Specifies the audio data type. Currently only PCM is supported. */
public static enum AudioDataType { PCM };
/**
* Specifies the audio data format.
*/
public static class AudioDataFormat {
public AudioDataFormat(AudioDataType dataType, int sampleRate, int sampleSize, int channelCount, boolean signed, boolean littleEndian) {
this.dataType = dataType;
this.sampleRate = sampleRate;
this.sampleSize = sampleSize;
this.channelCount = channelCount;
this.signed = signed;
this.littleEndian = littleEndian;
}
/** Audio data type. */
public final AudioDataType dataType;
/** Sample rate in Hz (1/s). */
public final int sampleRate;
/** Sample size in bits. */
public final int sampleSize;
/** Number of channels. */
public final int channelCount;
public final boolean signed;
public final boolean littleEndian;
public String toString() {
return "AudioDataFormat[type "+dataType+", sampleRate "+sampleRate+", sampleSize "+sampleSize+", channelCount "+channelCount+
", signed "+signed+", "+(littleEndian?"little":"big")+"endian]"; }
}
/** Default {@link AudioDataFormat}, [type PCM, sampleRate 44100, sampleSize 16, channelCount 2, signed, littleEndian]. */
public static final AudioDataFormat DefaultFormat = new AudioDataFormat(AudioDataType.PCM, 44100, 16, 2, true /* signed */, true /* littleEndian */);
public static class AudioFrame {
public final ByteBuffer data;
public final int dataSize;
public final int audioPTS;
public AudioFrame(ByteBuffer data, int dataSize, int audioPTS) {
if( dataSize > data.remaining() ) {
throw new IllegalArgumentException("Give size "+dataSize+" exceeds remaining bytes in ls "+data+". "+this);
}
this.data=data;
this.dataSize=dataSize;
this.audioPTS=audioPTS;
}
public String toString() { return "AudioFrame[apts "+audioPTS+", data "+data+", payloadSize "+dataSize+"]"; }
}
/**
* Returns the initialized state
of this instance.
*
* The initialized state
is affected by this instance
* overall availability, i.e. after instantiation,
* as well as by {@link #destroy()}.
*
* The preferred format shall reflect this sinks most native format, * i.e. best performance w/o data conversion. *
* @see #initSink(AudioDataFormat) */ public AudioDataFormat getPreferredFormat(); /** * Initializes the sink. *
* Implementation shall try to match the given requestedFormat
{@link AudioDataFormat}
* as close as possible, regarding it's capabilities.
*
* A user may consider {@link #getPreferredFormat()} and pass this value * to utilize best performance and behavior. *
* The {@link #DefaultFormat} should be supported by all implementations. * * @param requestedFormat the requested {@link AudioDataFormat}. * @param bufferCount number of buffers for sink * @return if successful the chosen AudioDataFormat based on therequestedFormat
and this sinks capabilities, otherwise null
.
*/
public AudioDataFormat initSink(AudioDataFormat requestedFormat, int bufferCount);
/** Destroys this instance, i.e. closes all streams and devices allocated. */
public void destroy();
/**
* Returns the number of bytes queued for playing.
* * {@link #initSink(AudioDataFormat)} must be called first. *
*/ public int getQueuedByteCount(); /** * Returns the queued buffer time in milliseconds for playing. ** {@link #initSink(AudioDataFormat)} must be called first. *
*/ public int getQueuedTime(); /** * Returns the number of buffers in the sink available for writing. ** {@link #initSink(AudioDataFormat)} must be called first. *
*/ public int getWritableBufferCount(); /** * Returns true if data is available to be written in the sink. ** {@link #initSink(AudioDataFormat)} must be called first. *
*/ public boolean isDataAvailable(int data_size); /** * Writes the remaining bytes of the given direct ByteBuffer to this sink. ** The data must comply with the chosen {@link AudioDataFormat} as returned by {@link #initSink(AudioDataFormat)}. *
*/ public void writeData(AudioFrame audioFrame); }