将声音帧从 8Khz 重新采样/上采样到 48Khz (Java/Android)
我正在尝试为andriod开发的应用程序,以48Khz(PCM 16位和单声道)记录帧并将它们发送到网络。此外,还有 8Khz 的传入音频流。因此,我接收 8Khz 采样帧并播放它们(我的 AudioTrack 对象设置为 8Khz),但是在播放它们时,一切正常,但延迟很大。大约需要 3 秒才能听到声音。
我认为如果我将接收到的帧从 8Khz 上采样到 48Khz 并播放它们,就不会有这么大的播放延迟。事实上,当我以相同的速率记录和播放帧时,延迟非常低。糟糕的是我被迫这样做:发送到 48Khz 并接收到 8Khz。
如前所述,我尝试将声音帧(16 位 PCM)从 8Khz 上采样到 48Khz。有人知道 Java 中的任何例程/库/API 可以做到这一点吗???
我知道有关对离散信号进行上采样的基础知识,但我认为设计和实现我自己的 FIR 滤波器并将其与音频流进行卷积……太过分了。而且,这超出了我的知识范围。
那么...有人可以帮助我吗?有人知道我可以使用 Java 中的任何库/例程吗?有什么建议或替代方案吗?
The application that I am trying to develop for andriod, records frames at 48Khz (PCM 16bits & mono) and sends them to the network. Also, there is an incoming stream of audio at 8Khz. So, I receive 8Khz sampled frames and play them (my AudioTrack object is set to 8Khz), but when playing them, everything works but the latency is HUGE. It takes like around 3 seconds until you hear something.
I think that if I upsample the received frames from 8Khz to 48Khz and play them, there won't be such a huge playing latency. In fact when I record and play frames at the same rate, the latency is really low. The bad thing is that I am forced to do it this way: send to 48Khz and receive to 8Khz.
As explained before, I'm trying to upsample a sound frame (16bits PCM) from 8Khz to 48Khz. Does anybody know any routine/library/API in Java that does this???
I know the basics about upsampling a discreet signal, but I consider that to design and implement my own FIR filter and convolute it with the audio stream ....is way too much. Also, it is over my knowledge.
So...does anybody can help me with this?? Does anybody know any library/routine in Java that I can use?? Any suggestions or alternatives??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一个快速但肮脏的解决方案是线性插值。因为你总是以六倍的比例进行采样,所以这真的很容易做到:
它的工作原理有点像这样(C代码,未经测试,我没有正确处理最后一次迭代,但它显示了我认为的想法)。
线性插值不会给您带来出色的音质,但它便宜且快速。如果需要,您可以使用三次插值来改进这一点。
如果您想要快速且高质量的重采样,我建议您使用 Android-NDK 编译像 libresample 这样的 ac 重采样库,并使用 JNI 从 java 调用它。这样会快很多。大多数人都回避编写 JNI 代码,但这很容易。NDK 有很多这方面的示例。
http://www.mega-nerd.com/SRC/index.html
A quick and dirty solution would be linear interpolation. Since you're always sampling up by a factor of six this is really easy to do:
It works somewhat like this (C-code, and untested, and I don't handle the last iteration properly, but it shows the idea I think).
Linear interpolation won't give you great sound quality but it is cheap and fast. You can improve this using cubic interpolation if you want to.
If you want a fast and high quality resampling I suggest that you compile a c resampling library like libresample using the Android-NDK and call it from java using JNI. That will be a lot faster. Writing the JNI code is something most people shy away from, but it's quite easy.. The NDK has lots of examples for this.
http://www.mega-nerd.com/SRC/index.html
线性插值引入了伪影。有一个很好的Java库,具有高质量的重采样功能 - JSSRC (http://jssrc.khadkevich.org/) 。
该代码现已在 Github 上提供:
https://github.com/hutm/JSSRC
Linear interpolation introduces artifacts. There is nice java library with high-quality resampling - JSSRC (http://jssrc.khadkevich.org/).
The code is now available on Github:
https://github.com/hutm/JSSRC
我无法使大多数库工作(https://github.com/hutm/JSSRC,< a href="https://github.com/simingweng/android-pcm-resample" rel="nofollow noreferrer">https://github.com/simingweng/android-pcm-resample, https://github.com/ashqal/android-libresample)。它们要么在生成的音频中存在问题,要么只是无法从 48000Hz 转换为 44100Hz(这就是我所需要的)。
不过这个效果很好:
https://github.com/JorenSix/TarsosDSP
这是一个在 Android 上运行的大型纯 Java 库(没有 javax.sound 依赖项)并且它可以做很多事情,但是如果您只使用 be.tarsos.dsp.resample 包中的 FilterKit、Resampler 和 SampelBuffers 类,它的工作效果非常好并且易于使用。
I was unable to make most libraries work (https://github.com/hutm/JSSRC, https://github.com/simingweng/android-pcm-resample, https://github.com/ashqal/android-libresample). They all have problems either in the resulting audio or just failed to convert from 48000Hz to 44100Hz (that's what I needed).
This one though works perfectly:
https://github.com/JorenSix/TarsosDSP
That's a big pure-Java library that works on Android (no javax.sound dependencies) and that is capable of many things, but if you just take the FilterKit, Resampler and SampelBuffers classes in package be.tarsos.dsp.resample, it works extremely well and is easy to use.
TarsosDPS 库对于我的需求来说太重了,但我发现重采样工具首先作为更轻的 3 类库发布:https://github.com/dnault/libresample4j
至于 TarsosDPS 不需要 javax
The TarsosDPS library was too heavy for my needs, but I found out that the resampling tools were first published as a lighter 3-class library: https://github.com/dnault/libresample4j
As for TarsosDPS no need of javax