【问题标题】:Why does this code produce a very noisy sine wave?为什么这段代码会产生非常嘈杂的正弦波?
【发布时间】:2019-07-28 15:03:15
【问题描述】:

我正在尝试用 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);
}

我把生成的声音放到一个 EQ 中,来验证声音是否真的很嘈杂,果然:

主要频率是 440 赫兹,但还有一些其他频率不应该出现。为什么会这样?我该如何解决?

【问题讨论】:

  • 有趣。我在 Java 中处理过一些声音输出。您可以打印以控制台计算进入样本变量的结果吗?我愿意猜测这是一个浮点精度问题,因为您的结果将是一个近似值。
  • 查看您的代码,样本量可能是问题所在吗?将该样本放入 8 位会导致精度下降。
  • 你乘以0.1有什么原因吗?如果你去掉 0.1 的乘法,然后将该信号输入你的 EQ,会发生什么?
  • 这里是前 100 个样本pastebin.com/tMCK5MUH
  • 我乘以 0.1 以便幅度不会太高。如果我不乘同样的事情发生,信号只会变得更响。

标签: java sound-synthesis sine-wave


【解决方案1】:

这是你的正弦波:

它非常参差不齐,因为您使用的是低位深度和低幅度。您只有 25 个不同的样本值可供选择。

如果您将振幅设置为 1.0,则使用 8 位样本的全部范围,这是您的正弦波:

这里将幅度保持在 0.1,但改用 16 位样本:

这两个选项显然都会减少噪音。

【讨论】:

  • 好答案。你用的是什么绘图工具?
  • 我没有可用的 gnuplot,所以很普通的 Excel
  • 这是一个很好的解释。从字节更改为短样本解决了这个问题。谢谢:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 2016-02-08
  • 1970-01-01
相关资源
最近更新 更多