Generating a sinusoid sound signal in Java

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;
}


There's probably good room for performance gain regarding the Math.sin call itself. You could easily create a lookup-table - there's no faster way than just taking the values straight from an array. (The link's benchmark measures a factor ~6 speed difference.)

It may be problematic because it may cause audible distortions, but that would depend on how much memory you're willing to invest in the lookup-table. Also, you could invest a few more cycles by obtaining both array entries addressed by (_tone*i) and then adding them up, both multiplied by 0.x and respectively (1-0.x), effectively fading over between values.

I don't know how much it will optimize it but this:

double dVal = Math.sin(_tone * i);


Shouldn't be needed.

Replace:

final short val = (short) ((dVal * 32767));


With:

final short val = (short) ((Math.sin(_tone * i) * 32767));


The compiler may be able to optimize it well enough that this doesn't matter, but it may help.

A few optimisation:

• Using bitwise operators

byte output[] = new byte[samples << 1];
double _tone = (Math.PI << 1) / (sampleRate / frequency);

final short val = (short) ((dVal<<15) - dVal);

• Reducing variables

short val = (short) ((Math.sin(_tone * i) * 32767));