gpt4 book ai didi

java - 在 Java 中生成正弦波时背景噪声

转载 作者:搜寻专家 更新时间:2023-10-31 19:36:27 25 4
gpt4 key购买 nike

当我运行以下代码时,背景中出现轻微失真(听起来像嗡嗡声)。由于其微妙的性质,它让人相信字节转换正在发生某种别名。

AudioFormat = PCM_SIGNED 44100.0 Hz,16 位,立体声,4 字节/帧,大端

注意:代码假设(目前)数据是大端的。

public static void playFreq(AudioFormat audioFormat, double frequency, SourceDataLine sourceDataLine)
{
System.out.println(audioFormat);
double sampleRate = audioFormat.getSampleRate();
int sampleSizeInBytes = audioFormat.getSampleSizeInBits() / 8;
int channels = audioFormat.getChannels();

byte audioBuffer[] = new byte[(int)Math.pow(2.0, 19.0) * channels * sampleSizeInBytes];

for ( int i = 0; i < audioBuffer.length; i+=sampleSizeInBytes*channels )
{
int wave = (int) (127.0 * Math.sin( 2.0 * Math.PI * frequency * i / (sampleRate * sampleSizeInBytes * channels) ) );

//wave = (wave > 0 ? 127 : -127);

if ( channels == 1 )
{
if ( sampleSizeInBytes == 1 )
{
audioBuffer[i] = (byte) (wave);
}

else if ( sampleSizeInBytes == 2 )
{
audioBuffer[i] = (byte) (wave);
audioBuffer[i+1] = (byte)(wave >>> 8);
}
}

else if ( channels == 2 )
{
if ( sampleSizeInBytes == 1 )
{
audioBuffer[i] = (byte) (wave);
audioBuffer[i+1] = (byte) (wave);
}

else if ( sampleSizeInBytes == 2 )
{
audioBuffer[i] = (byte) (wave);
audioBuffer[i+1] = (byte)(wave >>> 8);

audioBuffer[i+2] = (byte) (wave);
audioBuffer[i+3] = (byte)(wave >>> 8);
}
}
}

sourceDataLine.write(audioBuffer, 0, audioBuffer.length);
}

最佳答案

您的评论说代码采用大端。

从技术上讲,您实际上以小端字节序输出,但这似乎并不重要,因为幸运的是,您的最高有效字节始终为 0。

编辑:进一步解释 - 当您的值达到最大值 127 时,您应该写入 (0x00, 0x7f),但您的代码的实际输出是 (0x7f, 0x00),即 32512。发生这种情况接近适当的 16 位 最大值 32767,但底部 8 位全为零。最好始终使用 32767 作为最大值,然后根据需要丢弃低 8 位。

这意味着即使您输出的是 16 位数据,有效分辨率也只有 8 位。这似乎是音质欠佳的原因。

我已经制作了您的代码的一个版本,它只是将原始数据转储到一个文件中,并且看不到位移本身的任何其他错误。没有意外的符号变化或缺失位,但有符合 8 位样本质量的嗡嗡声。

此外,如果您根据样本计数计算波动方程,然后分别担心字节偏移量,那么您的数学会更容易:

int samples = 2 << 19;
byte audioBuffer[] = new byte[samples * channels * sampleSizeInBytes];

for ( int i = 0, j = 0; i < samples; ++i )
{
int wave = (int)(32767.0 * Math.sin(2.0 * Math.PI * frequency * i / sampleRate));
byte msb = (byte)(wave >>> 8);
byte lsb = (byte) wave;

for (int c = 0; c < channels; ++c) {
audioBuffer[j++] = msb;
if (sampleSizeInBytes > 1) {
audioBuffer[j++] = lsb;
}
}
}

关于java - 在 Java 中生成正弦波时背景噪声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/740619/

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