short[] outputBuffer = new short[BLOCK_SIZE * NUM_OUTPUT_CHANNELS];
byte[] bInputBuffer = new byte[inputBuffer.length * 2]; // 2 bytes per sample
byte[] bOutputBuffer = new byte[outputBuffer.length * 2];
TargetDataLine targetDataLine = null;
SourceDataLine sourceDataLine = null;
try {
// TODO(mhroth): ensure that stereo input and output lines are actually being returned
// by the system.
// open the audio input (line-in or microphone)
targetDataLine = (TargetDataLine) AudioSystem.getLine(inputLineInfo);
targetDataLine.open(inputAudioFormat, bInputBuffer.length);
targetDataLine.start();
// open the audio output
sourceDataLine = (SourceDataLine) AudioSystem.getLine(outputLineInfo);
sourceDataLine.open(outputAudioFormat, bOutputBuffer.length);
sourceDataLine.start();
} catch (LineUnavailableException lue) {
lue.printStackTrace(System.err);
System.exit(1);
}
// load the Pd patch
File pdFile = new File(args[0]);
ZenGarden pdPatch = null;
ZenGardenAdapter zgAdapter = new ZenGardenAdapter();
try {
pdPatch = new ZenGarden(pdFile, BLOCK_SIZE, NUM_INPUT_CHANNELS, NUM_OUTPUT_CHANNELS,
(float) SAMPLE_RATE);
pdPatch.addListener(zgAdapter);
} catch (NativeLoadException nle) {
nle.printStackTrace(System.err);
System.exit(2);
}
while (shouldContinuePlaying) {
// run the patch in an infinite loop
targetDataLine.read(bInputBuffer, 0, bInputBuffer.length); // read from the input
// convert the byte buffer to a short buffer
for (int i = 0, j = 0; i < inputBuffer.length; i++) {
inputBuffer[i] = (short) (((int) bInputBuffer[j++]) << 8);
inputBuffer[i] |= ((short) bInputBuffer[j++]) & 0x00FF;
}
pdPatch.process(inputBuffer, outputBuffer);
// convert short buffer to byte buffer
for (int i = 0, j = 0; i < outputBuffer.length; i++) {
bOutputBuffer[j++] = (byte) ((outputBuffer[i] & 0xFF00) >> 8);
bOutputBuffer[j++] = (byte) (outputBuffer[i] & 0x00FF);
}
// write to the output
sourceDataLine.write(bOutputBuffer, 0, bOutputBuffer.length);
}
// release all audio resources
targetDataLine.drain();
targetDataLine.close();
sourceDataLine.drain();
sourceDataLine.close();
}
}