jogamp.opengl.util.av.JavaSoundAudioSink Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jogl-all Show documentation
Show all versions of jogl-all Show documentation
Java™ Binding for the OpenGL® API
package jogamp.opengl.util.av;
import java.util.Arrays;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import com.jogamp.opengl.util.av.AudioSink;
/***
* JavaSound Audio Sink
*
* FIXME: Parameterize .. all configs .. best via an init-method, passing requested
* audio capabilities
*
*/
public class JavaSoundAudioSink implements AudioSink {
// Chunk of audio processed at one time
public static final int BUFFER_SIZE = 1000;
public static final int SAMPLES_PER_BUFFER = BUFFER_SIZE / 2;
private static final boolean staticAvailable;
// Sample time values
// public static final double SAMPLE_TIME_IN_SECS = 1.0 / DEFAULT_SAMPLE_RATE;
// public static final double BUFFER_TIME_IN_SECS = SAMPLE_TIME_IN_SECS * SAMPLES_PER_BUFFER;
private javax.sound.sampled.AudioFormat format;
private DataLine.Info info;
private SourceDataLine auline;
private int bufferCount;
private byte [] sampleData = new byte[BUFFER_SIZE];
private boolean initialized = false;
private AudioDataFormat chosenFormat = null;
static {
boolean ok = false;
try {
AudioSystem.getAudioFileTypes();
ok = true;
} catch (Throwable t) {
}
staticAvailable=ok;
}
@Override
public String toString() {
return "JavaSoundSink[init "+initialized+", dataLine "+info+", source "+auline+", bufferCount "+bufferCount+
", chosen "+chosenFormat+", jsFormat "+format;
}
@Override
public AudioDataFormat getPreferredFormat() {
return DefaultFormat;
}
@Override
public AudioDataFormat initSink(AudioDataFormat requestedFormat, int bufferCount) {
if( !staticAvailable ) {
return null;
}
// Create the audio format we wish to use
format = new javax.sound.sampled.AudioFormat(requestedFormat.sampleRate, requestedFormat.sampleSize, requestedFormat.channelCount, requestedFormat.signed, !requestedFormat.littleEndian);
// Create dataline info object describing line format
info = new DataLine.Info(SourceDataLine.class, format);
// Clear buffer initially
Arrays.fill(sampleData, (byte) 0);
try{
// Get line to write data to
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
auline.start();
System.out.println("JavaSound audio sink");
initialized=true;
chosenFormat = requestedFormat;
} catch (Exception e) {
initialized=false;
}
return chosenFormat;
}
@Override
public boolean isInitialized() {
return initialized;
}
@Override
public void destroy() {
initialized = false;
chosenFormat = null;
// FIXEM: complete code!
}
public void writeData(AudioFrame audioFrame) {
int data_size = audioFrame.dataSize;
final byte[] lala = new byte[data_size];
final int p = audioFrame.data.position();
audioFrame.data.get(lala, 0, data_size);
audioFrame.data.position(p);
int written = 0;
int len;
while (data_size > 0) {
// Nope: We don't make compromises for this crappy API !
len = auline.write(lala, written, data_size);
data_size -= len;
written += len;
}
}
@Override
public int getQueuedByteCount() {
return auline.available();
}
@Override
public int getQueuedTime() {
return 0; // FIXME
}
@Override
public int getWritableBufferCount() {
return 1;
}
public boolean isDataAvailable(int data_size) {
return auline.available()>=data_size;
}
}