Java SourceDataLine倍增帧率

Java SourceDataLine倍增帧率,java,javasound,Java,Javasound,从我的研究中,我似乎找不到其他人有同样的问题,这让我相信我只是犯了一个邪恶的愚蠢行为。尽管如此,我正在使用Java采样声音API,并尝试播放一个简单的440Hz正弦波5秒钟。然而,似乎SourceDataLine正在以其给定AudioFormat帧速率的两倍速度吞噬帧。我使用的示例是: AudioFormat audioFormat = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 22050, fa

从我的研究中,我似乎找不到其他人有同样的问题,这让我相信我只是犯了一个邪恶的愚蠢行为。尽管如此,我正在使用Java采样声音API,并尝试播放一个简单的440Hz正弦波5秒钟。然而,似乎
SourceDataLine
正在以其给定
AudioFormat
帧速率的两倍速度吞噬帧。我使用的示例是:

AudioFormat audioFormat = new AudioFormat(
    AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 22050, false);
SourceDataLine outLine;

int bufferByteLength = 4096;
byte[] b = new byte[4];
final float framePeriod = 1.0f / audioFormat.getFrameRate();
int frame = 0;

outLine = AudioSystem.getSourceDataLine(audioFormat);
outLine.open(audioFormat, bufferByteLength);
outLine.start();

System.out.println("Format: " + audioFormat);

double begin = System.nanoTime();
while((frame * framePeriod) < 5){
    short sample = (short)(0.2 * Math.sin(2 * Math.PI * 440 * frame * framePeriod) * Short.MAX_VALUE);
    b[0] = (byte)(sample & 0xFF);
    b[1] = (byte)((sample >> 8) & 0xFF);
    b[2] = (byte)(sample & 0xFF);
    b[3] = (byte)((sample >> 8) & 0xFF);
    ++frame;
    outLine.write(b, 0, 4);
}
double end = System.nanoTime();

System.out.println("True elapsed (seconds): " + (end - begin) * 1e-9);
System.out.println("Line reported elapsed (seconds): " + outLine.getMicrosecondPosition() * 1e-6);

outLine.drain();
outLine.stop();
outLine.close();
因此,正如880Hz音高所预期的那样,线路通过帧的速度确实是原来的两倍。我觉得这特别奇怪,因为我清楚地写了一个帧需要4个字节,但它似乎需要8个?事实上,当我使用大小为8的
b
时(扩展为写入8个字节),确实会将音调降低到440Hz,而且奇怪的是,即使
b
中的后4个字节始终为0,也不会产生任何“pops”

我注意到一件有趣的事情是,该行需要1764或更高的缓冲区大小,否则它将非常显著地断断续续,并使有效帧率显著降低到预期的22050以下。不过,我认为这比任何事情都更依赖于CPU


我很困惑。我不知道这可能是什么原因造成的,所以我希望有人曾经有过这个问题,或者可以提供任何线索来解释为什么会发生这种情况。干杯。

您指定的采样率是帧速率的两倍,因此它期望的采样数是帧速率的两倍。对于PCM,这两个速率通常相同


采样率是每个通道的采样率,而不是所有通道的总采样率。

您指定的采样率是帧速率的两倍,因此它需要两倍的采样率。对于PCM,这两个速率通常相同


采样率是每个通道的采样率,而不是所有通道的总采样率。

您指定的采样率是帧速率的两倍,因此它需要两倍的采样率。这两个比率通常是一样的,我知道这一定是我这方面的愚蠢行为;非常感谢。我在这方面参考了Oracle教程,并且确信帧率应该等于PCM的采样器。我的印象是这两个通道将采样器分开。无论如何,如果你想发布一个答案,我会投票并接受。你指定的采样率是帧速率的两倍,所以它期望的采样数是帧速率的两倍。这两个比率通常是一样的,我知道这一定是我这方面的愚蠢行为;非常感谢。我在这方面参考了Oracle教程,并且确信帧率应该等于PCM的采样器。我的印象是这两个通道将采样器分开。无论如何,如果你想发布一个答案,我会投赞成票并接受。
Format: PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, 22050.0 frames/second, little-endian
True elapsed (seconds): 2.5011672000000003
Line reported elapsed (seconds): 4.901496