1

我正在尝试使用该vDSP_desamp()例程对不断捕获的音频信号进行下采样。根据 Accelerate-framework 文档,该例程执行 FIR 滤波和抽取。

但是我有一个冲突,因为 API 没有为循环缓冲区提供输入参数,据我所知,需要保留样本历史记录以执行 FIR 过滤。这使我相信样本历史记录在每次函数调用期间都会被重置,或者可能正在应用与我所知道的算法不同的算法。

不幸的是,该功能是一个完整的黑匣子,没有给出关于如何执行滤波或如何确保信号连续性的提示。

你认为如果我用前一个缓冲区的最后 N 个样本(N 是滤波器抽头的数量)填充每一帧来获得滤波连续性就足够了吗? 我会在调用后丢弃那些填充样本输出vDSP_desamp(),但我猜在处理填充样本后应该正确初始化样本历史记录行。

欢迎任何关于内脏的提示vDSP_desamp()

4

1 回答 1

5

为什么说函数是一个完整的黑匣子?该文档显示了以下伪代码vDSP_desamp(A, I, F, C, N, P)

for (n = 0; n < N; ++n)
{
    sum = 0;
    for (p = 0; p < P; ++p)
        sum += A[n*I+p] * F[p];
    C[n] = sum;
}

您还可以查看/System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Headers/vDSP.h任何最新的 OS X 系统,以获取有关几乎所有 vDSP 例程的信息。它以不同的形式显示相同的东西:

for (n = 0; n < N; ++n)
    C[n] = sum(A[n*I+p] * F[p], 0 <= p < P);

由此可见,每个输出值都是从到的输入值C[n]的函数。假设您希望下一次调用中的第一个输出值以与当前调用相同的模式继续,只需考虑当前调用中的最后一个输出值(最后一个将是,因此最后一个输出值将是)以及什么会是下一个值,。这将是从 开始的输入值的函数,即。PA[n*I + 0]A[n*I + P-1]nN-1C[N-1]C[N]C[N]A[N*I + 0]A[N*I]

C[0]然后在下一次调用中将其与第一个输出值 匹配。C[0]将是从 开始的输入值的函数A[0*I + 0],即A[0]

因此,要使下一次调用从当前调用结束的地方继续,您可能希望将值从A[N*I]和超出复制到A[0]和超出。(这假定您A通过在其中移动数据然后附加新数据来重用数组。您也可以通过将数据A+N*I作为第一个参数传递给vDSP_desamp.)

要复制的值的数量将是您在Aafter (和包括)中的值的数量A[N*I]。例如,如果您在 中有NumberA,则可以使用:

memcpy(A+N*I, A, (Number - N*I) * sizeof *A);

然后将新数据放入A[Number - N*I]及以后。(如果源和目标范围重叠,则需要使用memmove而不是memcpy,但这对于 vDSP_desamp 来说是不寻常的;通常连续调用共享的数据只是整个缓冲区的一小部分。)


注意:伪代码表达了操作的基本数学。出于性能原因,vDSP 例程中的实际算术可能安排不同。因此,实际结果可能存在与直接使用伪代码计算的值不同的舍入误差。

于 2013-10-15T15:02:58.747 回答