I'm trying to write a very simple sound synth in Java. I'm using the javax.sound.sampled
package.
The code below works, but the sine wave is very noisy and sounds like there's some kind of quiet warm noise played alongside the wave.
try {
double sampleRate = 44100;
//8 bits per sample, so a byte.
AudioFormat audioFormat = new AudioFormat((float) sampleRate, 8, 1, true, false);
SourceDataLine line = AudioSystem.getSourceDataLine(audioFormat);
line.open(audioFormat);
line.start();
//A4
double freq = 440.0;
byte[] buf = new byte[1];
//the formula for a sample is amplitude * sin(2.0 * PI * freq * time)
for (int i = 0; i < sampleRate; i++) {
double t = (i / (sampleRate - 1));
double sample = 0.1 * Math.sin(2.0 * Math.PI * freq * t);
//scaling the sound from -1, 1 to -127, 127
buf[0] = (byte) (sample * (double) Byte.MAX_VALUE);
line.write(buf, 0, 1);
}
line.drain();
line.stop();
line.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
I put the generated sound into an EQ, to verify that the sound was actually noisy, and sure enough:
The dominant frequency is 440 hz, but there are some other frequencies which shouldn't be present. Why is this happening? How do I fix it?
Here's your sine wave:
It's very jagged because you're using a low bit depth combined with a low amplitude. You only have 25 different sample values to choose from.
Here's instead your sine wave if you set your amplitude to 1.0, using the full range of your 8bit sample:
And here's keeping the amplitude at 0.1, but using 16bit samples instead:
Both of these options will clearly be less noisy.