有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在通过SourceDataLine播放音频时发出一致的爆裂声

我现在正在写一个基本的synth,遇到了一个奇怪的问题。在通过SourceDataLine播放一组字节(代表16位单声道音频)时,我会听到持续的爆裂声

流行音乐以恒定的速度播放,从我所能听到的,音调。不过,pops的频率略有不同(同样,从我听到的情况来看),有些音符的pops是低通的,而另一些音符的pops是高通的。不过,POP并不是压倒性的,你仍然可以在背景中听到想要的声音

除了采样率,POP的速率、音符间距、SourceDataLine缓冲区大小、每次写入的字节数都不会改变

降低采样率会降低持久性有机污染物的检出率,反之亦然

为了测试我的程序,我打印了写入SourceDataLine的数据大约半秒,并查看了大约15个周期的正弦波,结果完全正常;没有突然的跳跃、剪断或其他任何事情

我使用采样率值的唯一两件事是一些基本的数学知识,以帮助我的采样器以正确的频率采样,每个音符只计算一次,并且在音高完美的情况下,以及在创建SourceDataLine时,它肯定起到了作用

下面是我如何启动SourceDataLine(取自main方法的多个部分):

AudioFormat format = new AudioFormat(AudioEnvironment.SAMPLE_RATE, AudioEnvironment.BIT_DEPTH, 1, true, true);

SourceDataLine line = AudioSystem.getSourceDataLine(format);
line.open(format, 8000);
line.start();

我的数据在big endian中是正确的,我在构造函数中更改endian标志并用白噪声对耳朵进行了测试

在程序设置好所有内容后,它会在这个无限循环中将数据不断写入SourceDataLine:

while (true) {              
    for (Channel channel : channelSystem.getChannels()) {
        if (channel.pitch != 0) {
            wave.sample(channel, buffer);

            line.write(buffer, 0, AudioEnvironment.SUB_BUFFER_SIZE * 2);
        }
    }
}

(AChannel是我创建的一个类,它包含一个音符的所有数据(尽管目前显然没有为复调正确设置程序),buffer是一个字节数组,wave.sample()是我将数据采样到buffer的地方,AudioEnvironment.SUB_BUFFER_SIZE * 2buffer的大小)

我不一定需要一个如何在代码中解决这个问题的例子,但是解释一下为什么会发生这种情况会很好

编辑:我可能还应该补充一点,我曾尝试在无限写循环中放入一个print语句,以打印出SourceDataLine中的可用字节数,它一直保持在500-2000左右,偶尔会达到5000左右,但从来不会接近8000,所以缓冲区永远不会耗尽数据


共 (1) 个答案

  1. # 1 楼答案

    事实证明,这个问题与我的想法完全无关

    事实证明,我在取样器中写的一个等式是完全错误的

    播放完2048个样本后,我会回到波形的开头,导致弹出

    我真的不知道我为什么写这篇文章,但是,嘿,它现在起作用了