我一直在研究 Apple 示例代码 (found here) 中的 aurioTouch 2。归根结底,我想自己分析频率。现在我正试图了解这里发生的一些事情。如果这是微不足道的,我深表歉意,只是想了解一些源代码中 float 的一些未注释的魔数(Magic Number)。我现在的主要困惑点是:
- 为什么他们将 FFTBufferManager::ComputeFFT 中的奈奎斯特值清零?这个值真的可以扔掉吗? (~FFTBufferManager.cpp 的第 112 行)。
- 他们将所有内容都缩小了 -128db,因此我假设结果在 (-128, 0) 的范围内。然而,稍后在 aurioTouchAppDelegate.mm(~第 807 行)中,他们通过加 80 并除以 64 将其转换为 0 和 1 之间的值,然后固定为 0 和 1。为什么模糊?另外,我假设值将在 (-128, 0) 附近是否正确?
最佳答案
好吧,这对我来说也不是微不足道的,但这就是我的理解。如果我过度简化,那纯粹是为了我的利益,我并不是要居高临下。
归零对应奈奎斯特频率的结果:
我假设我们正在计算 1024 个输入样本的前向 FFT。在 44100hz 输入时,这在我的情况下通常是正确的(但这不是 AurioTouch 正在做的,我觉得这有点奇怪,但我不是专家)。我更容易理解具体的值(value)观。
给定 1024 (n) 个输入样本,按需要排列(先是偶数索引,然后是奇数索引' { in[0],in[2],in[4],…,in 1,in[3] , in[5], … }) (使用 vDSP_ctoz()
对您的输入进行排序)
FFT 1024 (n) 个输入样本的输出是513 ((n/2)+1) 个复数值。即513个实分量和513个虚分量,总共有1026值。
但是,imaginary[0] 和imaginary[512] (n/2) 始终必然是零。因此,通过将 real[512](奈奎斯特频率仓的实部)置于 imaginary[0] 并忘记 imaginary[512] -它始终为零并且可以推断,结果被打包到一个 1024 (n) 长度的缓冲区中。
因此,为了使返回的结果有效,您必须至少将 imaginary[0] 设置回零。如果您需要所有 513 ((n/2)+1) 个频点,您需要将另一个复数附加到结果中并这样设置。
unpackedVal = imaginary[0]
real[512]=unpackedVal, imaginary[512]=0
imaginary[0] = 0
在 AurioTouch 中,我一直认为他们只是不打扰。 n/2 结果显然使用起来更方便,您几乎无法从可视化工具中分辨出来:-“哦,看,它在奈奎斯特频率上少了一个幅度”
The UsingFourierTransforms docs explain the packing
注意具体值 1024、513、512 等是示例,并非 AurioTouch 的 n、(n/2)+1、n/2 的实际值。
他们将一切缩小了 -128db
不完全是,输出值的范围相对于输入样本的数量,因此必须对其进行归一化。比例为 1.0/(2*inNumberFrames)。
缩放后范围为 -1.0 –> +1.0。然后获取复向量的幅度(忽略相位),为 0 和 1.0
之间的每个频率仓提供标量值此值然后被解释为 -128 和 0 之间的分贝值
绘图的东西……+80/64。……*120…………我不确定。我可能完全错了,也可能是……艺术许可?
关于ios - 了解 aurioTouch2 中的 FFT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8845542/