Is there any legroom left for optimization (without switching to C)?
static byte[] generateSound(double frequency, int sampleRate, int samples) {
byte output[] = new byte[2 * samples];
int idx = 0;
double _tone = 2 * Math.PI / (sampleRate / frequency);
for (int i = 0; i < samples; ++i) {
double dVal = Math.sin(_tone * i);
final short val = (short) ((dVal * 32767));
output[idx++] = (byte) (val & 0x00ff);
output[idx++] = (byte) ((val & 0xff00) >>> 8);
}
return output;
}