使用Accelerate和vDSP_desamp()进行音频处理

3

我完全不熟悉vdsp框架,但我想通过构建来学习。我的目标是按以下方式处理信号:

  1. 100阶带通FIR滤波器
  2. 下采样因子:2

从苹果的文档中我所能理解的是,函数vDSP_desamp()就是我要找的(它可以同时完成上述两个步骤,对吗?)

我该如何正确使用它呢?

以下是我的想法: 给定一个AudioBufferList *audio和一个长度为[101]的滤波器系数数组filterCoeffs:

vDSP_desamp((float*)audio->mBuffers[0].mData, 2, &filterCoeffs, (float*)audio->mBuffers[0].mData, frames, 101);

这个方法的使用是否正确?我需要为此过程实现循环缓冲区吗?任何指导/方向/指针可以阅读的内容都将不胜感激。谢谢。

1个回答

1
阅读文档,vDSP_desamp() 确实是一个复合降采样和 FIR 操作。同时进行这两个操作是个好主意,因为它减少了内存访问,并且有很多计算可以被消除。
这里的假设是 FIR 过滤器已经被重新设计成 (P-1)/2 组延迟。这意味着为了计算 C(n),函数需要访问 A(n*I+p)
其中(使用文档中的术语):
`A[0..x-1]`: input sample array
`C[0..n-1]`: output sample array
`P`: number of filter coefficients
`I`: Decimation factor

显然,如果你将一个CoreAudio缓冲区传递给此函数,它将会超出200个输入样本的缓冲区末尾。最好情况下,会产生100个垃圾样本,最坏情况下可能会触发 SIGSEGV

所以,简单的答案是NO。你不能仅使用 vDSP_desamp()

你有以下几个选择:

  • 将所需样本组装到缓冲区中,然后对N输出样本调用 vDSP_desamp()。这涉及从两个CoreAudio缓冲区复制样本。如果您担心延迟,可以将FIR重新调整为使用前100个样本,或者它们可以来自下一个缓冲区。

  • 在能够使用vDSP_desamp()的情况下使用它,并计算当滤波器在两个缓冲区之间跨越时更复杂的情况。

  • 调用两次vDSP_desamp() - 一次是简单情况,另一次是组装输入缓冲区的情况,其中样本相邻地包装在CoreAudio缓冲区中

我不认为您可以使用循环缓冲区来解决这个问题:您仍然需要处理缓冲区包装的情况,并且仍然需要将所有样本复制到其中。
哪种方法更快取决于CoreAudio提供的音频缓冲区的大小。 我的直觉是,对于小缓冲区和小滤波器长度,vDSP_desamp()可能不值得,但是您需要进行测量以确保。
过去在iOS上实现这种操作时,我发现手动减采样和滤波操作在整体方案中相当微不足道,并且没有进一步优化。

谢谢澄清!我想我也会选择手动解决方案。 - Kaitis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接