Почему этот код производит очень шумную синусоидальную волну? - PullRequest
4 голосов
/ 06 марта 2019

Я пытаюсь написать очень простой звуковой синтезатор на Java.Я использую пакет javax.sound.sampled.Код ниже работает, но синусоида очень шумная и звучит так, будто рядом с волной играет какой-то тихий теплый шум.

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

Я поместил сгенерированный звук в эквалайзер, чтобы убедиться, что звук действительно шумный и достаточно уверенный:

this is what I got

Доминирующая частота составляет 440 Гц, но есть и другие частоты, которые не должны присутствовать.Почему это происходит?Как мне это исправить?

1 Ответ

5 голосов
/ 07 марта 2019

Вот ваша синусоида:

Jagged sine wave

Это очень зазубренно, потому что вы используете низкую битовую глубину в сочетании с низкой амплитудой.У вас есть только 25 различных значений сэмплов на выбор.

Вот вместо этого синусоида, если вы установите амплитуду на 1,0, используя полный диапазон 8-битного сэмпла:

Smooth sine wave

И здесь мы сохраняем амплитуду на уровне 0,1, но вместо этого используем 16-битные выборки:

Equally smooth sine wave

Обе эти опции будутявно быть менее шумным.

...