private void perform() throws LineUnavailableException {
// JavaSound setup.
int sampleSize = 2;
AudioFormat audioFormat = new AudioFormat(sampleRate, 8 * sampleSize, outChans, true, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
sourceDataLine.open(audioFormat);
sourceDataLine.start();
// Buffer setup for exchanging samples between libpd and JavaSound.
// Question: Is this the best possible solution? It seems to involve too
// much copying.
int frames = PdBase.blockSize() * ticks;
short[] dummy = new short[0];
short[] samples = new short[frames * outChans];
byte[] rawSamples = new byte[samples.length * sampleSize];
ByteBuffer buf = ByteBuffer.wrap(rawSamples);
ShortBuffer shortBuf = buf.asShortBuffer();
while (!terminated) { // Note: sourceDataLine.write seems to clear the interrupted flag, and so Thread.interrupted() doesn't work here.
PdBase.process(ticks, dummy, samples);
shortBuf.rewind();
shortBuf.put(samples);
sourceDataLine.write(rawSamples, 0, rawSamples.length);
}
// Shutdown.
sourceDataLine.drain();
sourceDataLine.stop();
sourceDataLine.close();
}