ios - 使用 Accelerate 和 vDSP_desamp() 进行音频处理
<p><p>我对 vdsp 框架完全陌生,我正在尝试通过构建来学习。我的目标是通过以下方式处理信号:</p>
<ol>
<li>100 阶带通 FIR</li>
<li>按因子下采样:2</li>
</ol>
<p>根据我从 Apple 的文档中了解到的功能 vDSP_desamp() 是我正在寻找的(它可以同时执行两个步骤,对吗?)</p>
<p>我该如何正确使用它?</p>
<p>以下是我的想法:
给定一个 <code>AudioBufferList *audio</code> 和一个长度为 的滤波器系数数组 <code>filterCoeffs</code>:</p>
<pre><code>vDSP_desamp((float*)audio->mBuffers.mData, 2, &filterCoeffs, (float*)audio->mBuffers.mData, frames, 101);
</code></pre>
<p>这是对方法的正确使用吗?
我是否需要为此过程实现循环缓冲区?
非常欢迎任何指向要阅读的内容的指导/方向/指针。
谢谢</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>阅读文档,<code>vDSP_desamp()</code> 确实是一个复合抽取和 FIR 操作。两者一起做是一个好主意,因为它减少了内存访问,并且有消除大量计算的空间。 </p>
<p>这里的假设是 FIR 滤波器已经用 <code>(P-1)/2</code> 群延迟重铸。这样做的结果是要计算 <code>C(n)</code> 函数需要访问 <code>A(n*I+p)</code></p>
<p>在哪里(使用文档的术语):</p>
<pre><code>`A`: input sample array
`C`: output sample array
`P`: number of filter coefficients
`I`: Decimation factor
</code></pre>
<p>很明显,如果您将 CoreAudio 缓冲区传递给它,它将在缓冲区末尾运行 200 个输入样本。最好的情况是产生 100 个垃圾样本,最坏的情况是产生一个 <code>SIGSEGV</code>。</p>
<p>所以,简单的答案是否定的。您不能单独使用 <code>vDSP_desamp()</code>。</p>
<p>您的选择是:</p>
<ul>
<li><p><em>将需要的样本</em>组装到一个缓冲区中,然后为 <code>N</code> 个输出样本调用 <code>vDSP_desamp()</code>。这涉及从两个 CoreAudio 缓冲区复制样本。如果您担心延迟,您可以重铸 FIR 以使用 100 个之前的样本,或者,它们可能来自下一个缓冲区。</p></li>
<li><p><em>尽量使用 <code>vDSP_desamp()</code></em>,当过滤器覆盖两个缓冲区时计算更复杂的情况。</p></p></li>
<li><p><em>对 <code>vDSP_desamp()</code></em> 的两次调用 - 一次使用简单的情况,另一次使用组装的输入缓冲区,其中样本包装相邻的 CoreAudio 缓冲区</p> </li>
</ul>
<p>我不明白如何使用循环缓冲区来解决这个问题:你仍然有缓冲区换行的情况来处理,并且仍然需要将所有样本复制到其中。 </p>
<p>哪个更快取决于 CoreAudio 提供的音频缓冲区的大小。我的直觉是,对于小缓冲区和小滤波器长度,<code>vDSP_desamp()</code> 可能不值得,但您需要进行测量以确定。 </p>
<p>当我过去在 iOS 上实现这种东西时,我发现了一个
手动抽取和过滤操作在总体方案中是相当微不足道的,并且没有费心进一步优化。</p></p>
<p style="font-size: 20px;">关于ios - 使用 Accelerate 和 vDSP_desamp() 进行音频处理,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/28392336/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/28392336/
</a>
</p>
页:
[1]