8

这是我手头的问题:

  1. 我需要实时分析音频数据以找出信号的幅度
  2. 我无法使用 AudioQueue 计量功能,因为它检测峰值的延迟太长
  3. 我研究了 aurioTouch 的例子.....但是......

我只是不明白如何将 PCM 编码缓冲区转换回示波器视图中显示的波形。在我想分析振幅之前,正是这个波。

在我分析缓冲区时的回调中,它只有 0 和 -1 - 当使用 NSLog(@"%d") 时。我猜这是有道理的,因为它是 PCM。

我在 aurioTouch 中找不到将 0 / -1 流转换为波形的神奇之处:-((

此外,一旦我将波形保存在内存中,我如何分析幅度以及如何将此读数转换为 dB?

我不想使用FFT,因为我对频率不感兴趣,希望有其他方法。

干杯

4

2 回答 2

10

一旦您在内存中有一大块波形,那么以 dB 为单位计算幅度值就相当容易了(尽管您需要确定 0 dB 的参考幅度是多少)。通常,如果您想要在 VU 表上显示的那种短期幅度,那么您需要校正波形的瞬时值(您可以为此使用 abs),然后将这些校正值通过一个简单的低通滤波器时间常数约为 100 ms。要将值转换为 dB,您将执行以下操作:

amplitude_dB = 20 * log10(amplitude) + calibration_dB;

其中幅值​​是经过整流和滤波的幅值,calibration_dB 是一个偏移量,可为您提供 0 dB 的正确幅值,无论您的特定应用中可能是什么(例如 dB 重新满量程,或校准的 dBV 或 dBm 值)。

一个简单但有效的低通滤波器可以如下实现。这将是一个单极点 IIR(递归)滤波器。每个输出取决于先前的输出值和当前的输入值。我们有一个常数因子 alpha,它有效地确定了这个低通滤波器的时间常数或截止频率。

y = alpha * x + (1.0 - alpha) * y_old;
y_old = y;
  • x = 当前输入值
  • y = 新输出值
  • y_old = 先前的输出值
  • alpha = 决定过滤器响应的常数 - 一个小的正数 - 尝试 0.001 开始并进行实验
于 2010-01-30T15:07:13.937 回答
1

AurioTouch 是一个很好的例子。不幸的是,代码很糟糕。确保您仅使用它来了解使用 RemoteIO 音频单元背后的概念。

波形的实际绘制发生在当 PCM 数据可用时由 CoreAudio 调用的 renderProc 回调中。查看 aurioTouchAppDelegate.mm:197 中的 PerformThru()... 再往下看,在第 237 行

SInt8 *data_ptr = (SInt8 *)(ioData->mBuffers[0].mData);

...这就是访问实际 PCM 数据的地方。这是您需要分析的数据,以获得信号的峰值/平均功率。

于 2010-01-30T10:31:16.613 回答