4
votes

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:

this is what I got

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?

1
Interesting. I've worked with sound output a bit in Java. Can you print to console the result of the calculation going into the sample variable? I'd be willing to guess this is a floating point precision problem, as your result will be an approximation.Scuba Steve
Looking at your code, could the sample size be the problem? You're losing precision by putting that sample into 8 bits.Scuba Steve
Is there a reason you're multiplying by 0.1? What happens if you get rid of the multiplication by 0.1 and then feed that signal into your EQ?Luke Woodward
Here are the first 100 samples pastebin.com/tMCK5MUHabababab
I'm multiplying by 0.1 so that the amplitude isn't too high. If I don't multiply the same thing happens, the signal just gets louder.abababab

1 Answers

5
votes

Here's your sine wave:

Jagged 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:

Smooth sine wave

And here's keeping the amplitude at 0.1, but using 16bit samples instead:

Equally smooth sine wave

Both of these options will clearly be less noisy.