gpt4 book ai didi

java SourceDataLine 正弦波点击

转载 作者:太空宇宙 更新时间:2023-11-04 06:27:03 24 4
gpt4 key购买 nike

我想使用 javax.sound.sampled.SourceDataLine 生成纯正弦波。对于一个恒定的频率,它工作得很好,但是当改变频率时总是有一种咔嗒声。我做错了什么,我能做些什么来避免这种情况?

            line.start();
final byte[] toneBuffer = new byte[SAMPLE_CHUNK];

while(run) {
createSineWaveBuffer(frequency, toneBuffer);
line.write(toneBuffer, 0, toneBuffer.length);
}

line.drain();
line.close();

哪里

private double alpha = 0.0;
private static final double step_alpha = (2.0*Math.PI)/SAMPLE_RATE;

private void createSineWaveBuffer(final double freq, final byte[] buffer) {
for(int i = 0; i < buffer.length; ++i) {
buffer[i] = (byte)(Math.sin(freq*alpha)*127.0);
alpha += step_alpha;

if(alpha >= 2.0*Math.PI) {
alpha = 0.0;
}
}
}

最佳答案

您会感受到点击声,因为当 freq 发生变化时,整个正弦波都会发生变化。以更容易绘制的三角波为例:

1 Hz
/\ /\ /
/ \ / \ /
/ \/ \/

.5 Hz_
/ \
/ \ /
/ \_/

如果您在任意时间在这些之间切换:

  /\  |\
/ \ | \ /
/ \| \_/

出现不连续性,您会听到咔哒声。

这从根本上来说是因为您导致从 sin(freq*alpha) 突然跳跃到 sin(.5*freq*(alpha+step_alpha))。 sin() 输入的导数不仅不连续地变化(这就是您需要更改频率的值),而且该值也在不连续地变化。

解决这个问题的方法是仅更改 sin() 输入的导数。您可以通过保留一个根据频率递增的计数器来做到这一点:

private void createSineWaveBuffer(final double freq, final byte[] buffer) {

for(int i = 0; i < buffer.length; ++i) {
buffer[i] = (byte)(Math.sin(alpha)*127.0);
alpha += freq*step_alpha;

if(alpha >= 2.0*Math.PI) {
alpha -= 2.0*Math.PI;
}
}

return t;
}

在这里,我更改了您的 alpha,以由当前 freq 控制的速率增加。

回到三角形示例,如下所示:

           _
/\ / \
/ \ / \
/ \/ \

关于java SourceDataLine 正弦波点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26652235/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com