重采样/上采样声音帧从8Khz到48Khz(Java/Android)

ara*_*kn0 5 java audio android audio-streaming resampling

我正在尝试为andriod开发的应用程序,以48Khz(PCM 16位和单声道)记录帧并将它们发送到网络.此外,还有一个8Khz的传入音频流.所以,我接收8Khz采样帧并播放它们(我的AudioTrack对象设置为8Khz),但是当它们播放时,一切正常,但延迟是巨大的.你听到的东西大约需要3秒钟.

我认为如果我将接收到的帧从8Khz上采样到48Khz并播放它们,那么就不会有如此巨大的播放延迟.事实上,当我以相同的速率录制和播放帧时,延迟非常低.坏事是我被迫这样做:发送到48Khz并接收到8Khz.

如前所述,我正在尝试将声音帧(16位PCM)从8Khz上采样到48Khz.有人知道Java中的任何例程/库/ API吗?

我知道关于对一个谨慎信号进行上采样的基础知识,但我认为设计和实现我自己的FIR滤波器并将其与音频流进行卷积....太过分了.而且,据我所知.

那么......有人能帮助我吗?有没有人知道我可以使用Java中的任何库/例程?任何建议或替代方案?

Nil*_*nck 5

快速而肮脏的解决方案是线性插值.由于您总是以6倍的方式进行抽样,因此这很容易做到:

它有点像这样(C代码,未经测试,我没有正确处理最后一次迭代,但它显示了我认为的想法).

void resample (short * output, short * input, int n)
{
  // output ought to be 6 times as large as input (48000/8000).

  int i;
  for (i=0; i<n-1; i++)
  {
    output[i*6+0] = input[i]*6/6 + input[i+1]*0/6;
    output[i*6+1] = input[i]*5/6 + input[i+1]*1/6;
    output[i*6+2] = input[i]*4/6 + input[i+1]*2/6;
    output[i*6+3] = input[i]*3/6 + input[i+1]*3/6;
    output[i*6+4] = input[i]*2/6 + input[i+1]*4/6;
    output[i*6+5] = input[i]*1/6 + input[i+1]*5/6;
  }
Run Code Online (Sandbox Code Playgroud)

线性插值不会给你很好的音质,但它便宜又快捷.如果您愿意,可以使用三次插值来改善这一点.

如果您想要快速和高质量的重采样,我建议您使用Android-NDK编译像libresample的交流重采样库,并使用JNI从java调用它.那会更快.编写JNI代码是大多数人回避的事情,但它很容易...... NDK有很多这方面的例子.

http://www.mega-nerd.com/SRC/index.html