1

我有一个 48 kHz 的 PCM 流,并且想将它流式传输到一个 44.1 kHz 兼容的播放器(Apple 的 AirPlay)。

有人知道这是否“只是因为某些字节会丢失而起作用”,还是我必须先进行转换/下采样?

如果它不是“正常工作”,那么在 java 中执行此操作的任何提示?

编辑:

它不仅会起作用,因为声音会结结巴巴(“信息溢出”)。我必须对 pcm 流进行重新采样/下采样。

因为在这种情况下这不是那么简单(48 kHz 到 44.1 kHz),所以我应该使用一个库来执行此操作:

我想我会尝试 libresample。因为我在 Android 上,所以我可以使用native implementationjava implementation

您认为 java 实现是否足够高效?

4

3 回答 3

1

The process needed in your case is called "downsampling by a rational factor". It is not a trivial problem, so I suggest you use a library to do that - implementing this by yourself requires a lot of DSP-knowledge. You could instead use libresample, a C library, for which you would have to write JNI bindings.

To do a very rough approximation, you could just create a new buffer, in which you copy most of the old samples, but dropping every 10th sample. It will not be exactly 44.1 kHZ, but better than playing it as it is.

于 2012-06-19T22:52:11.140 回答
1

好的,最简单的方法是获取每一个48/44.1样本(这等于每 12 个样本踢出一次)。您最终将不得不这样做。

问题在于混叠。如果您进行下采样,您实际上是在将下采样率之外的频谱镜像到您的样本中(请参阅此 wiki 页面以获得很好的解释),这称为混叠。您显然不希望这样(您可以尝试一下,看看您的音频会发生什么)。

那么我们该如何预防呢?最常见的方法是以某种方式降低那些镜像频率块的频谱幅度。通过这种方式,它们镜像的,但不再那么重要了,因为它们的幅度非常低。这可以通过使用截止频率接近采样率的低通滤波器来完成。所以步骤是:

  • 对您的样本进行低通滤波以去除 44.1kHz 以上的高频振幅(注意不要去除低于 44.1kHz 的高频振幅)
  • 对您的数据进行二次抽样(在您的情况下,每 12 个样本退出一次)

那么该过滤器的要求是什么?重要的要求之一是不应触及低于截止频率的频率幅度,因此非常低的通带纹波和 1 的通带增益会很好。然后应尽可能抑制阻带。这显然取决于您的数据。我不知道特殊的音频处理,但通常在DSP中,使用的低通滤波器是FIRIIR. 当然还有很多其他的,但这些都非常容易实现,并且在一定程度上甚至能够处理实时约束。

所以我建议你阅读这两个过滤器实现(或只关注FIR)。如果您真的对我刚刚写的内容感到困惑,那么使用具有某种低通滤波能力的给定库可能会更好。但是,如果您经常使用这些东西,那么我建议您阅读该问题,这确实有助于理解发生了什么……;)

于 2012-06-20T07:47:41.957 回答
0

您需要对输入信号应用抽取。首先,您需要将输入通过低通滤波器(将其视为抗混叠)。

然后你需要通过一个合理的因素进行下采样。互联网上有很多关于这两个过程的文章。所以,如果你真的能胜任这项任务,那就去做一些研究吧。

例如,一种简单的低通滤波器方法是使用两个样本的平均值作为输出样本。即y(n)=(x(n)+x(n-1))/2;其中 y - 是输出,x - 输入,n - 当前样本位置。

于 2012-06-20T02:03:55.890 回答