【发布时间】:2018-03-09 16:01:17
【问题描述】:
我正在打开一个 targetdataline 以接受给定格式的音频输入。 我开始并打开线路,我有一个填充字节的缓冲区。这在一个恒定循环上运行,直到外部参数发生更改。
现在对于固定的采样率和缓冲区大小,我希望这总是需要相同的时间来填充,即如果我的缓冲区大小是 8 位流的 48000,并且我的采样率为 48kHz,我会期望我的缓冲区总是需要 1 秒才能填满。但是我发现这变化很大。
以下是我用过的代码:
DataLine.Info info1 = new DataLine.Info(TargetDataLine.class, format1);
try (TargetDataLine line = (TargetDataLine) m1.getLine(info1)) {
line.open(format1);
line.start();
while (!pauseInput){
long time1 = System.currentTimeMillis();
int numBytesRead1 = line.read(buffer1, 0, buffer1.length);
//chan1double = deinterleaveAudio(buffer1, chan1selectedchannel, chan1totalchannels);
long time2 = System.currentTimeMillis();
System.out.println(threadName + " Capture time = " + (time2-time1));
}
line.stop();
}
注释行是每次缓冲区满时我想运行的进程。我意识到我不能把它放在这里,因为它会中断流,所以我需要找到一种不同的方式来调用它,因此我已经注释掉了。
出于测试目的,我的缓冲区大小为 4096。我的音频格式是 48kHz 16 位,所以我希望我的字节缓冲区在 42.6 毫秒内被填充。 ((1/48000) * 2048)。 (这是乘以缓冲区大小的一半,因为每个样本是两个字节)。然而,使用 currentTimeMillies 来测量每次通过时,它会以 123 毫秒和 250 毫秒的时间返回,并且在这些时间之间变化。
这里有什么我没有做的遗漏吗?
编辑:我只将代码复制到了一个全新的应用程序中,该应用程序甚至没有 GUI 或任何附加的东西。纯粹是为了输出到控制台看看发生了什么,确保没有后台线程干扰,果然同样的事情发生了。预计填充时间为 250 毫秒的缓冲区有 95% 的时间在 255-259 毫秒内填充。但是偶尔这会下降到 127 毫秒(这在物理上是不可能的,除非发生了一些奇怪的缓冲区事情。这是 java 中的某个错误吗?
【问题讨论】:
标签: java audio byte buffer bytebuffer