为什么这段代码会产生非常嘈杂的正弦波?
Why does this code produce a very noisy sine wave?
我正在尝试在 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赫兹,但还有一些不应该出现的其他频率。为什么会这样?我该如何解决?
这是您的正弦波:
它非常参差不齐,因为您使用的是低位深度和低振幅。您只有 25 个不同的样本值可供选择。
如果您将振幅设置为 1.0,则使用 8 位样本的整个范围,这里是您的正弦波:
此处将振幅保持在 0.1,但改为使用 16 位样本:
这两个选项显然都会减少噪音。
我正在尝试在 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赫兹,但还有一些不应该出现的其他频率。为什么会这样?我该如何解决?
这是您的正弦波:
它非常参差不齐,因为您使用的是低位深度和低振幅。您只有 25 个不同的样本值可供选择。
如果您将振幅设置为 1.0,则使用 8 位样本的整个范围,这里是您的正弦波:
此处将振幅保持在 0.1,但改为使用 16 位样本:
这两个选项显然都会减少噪音。