iPhone - 如何测量 PCM 编码信号的幅度

发布于 2024-08-20 04:31:12 字数 429 浏览 4 评论 0原文

这是我手头的问题:

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

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

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

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

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

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

方法

here's my problem at hand:

  1. I need to analyze audio data in realtime to find out the amplitude of the signal
  2. I can't use the AudioQueue metering functionality because it has too much delay for detecting peaks
  3. I have studied the aurioTouch example..... however...

I simply don't understand how the PCM coded buffer is converted back to the waveform displayed in the oscilloscope view. It would be exactly this wavefore I want to analyze for amplitude.

In my callback when I analyze the buffer it only has 0 and -1 in it - when using NSLog(@"%d"). This makes sense I guess because it is PCM.

I can't find the place in aurioTouch where the magic of transforming the 0 / -1 stream into a waveform happens :-((

Also once I have the waveform in memory how do I analyze the amplitude and how to convert this reading into dB?

I don't want to use FFT because I am not interested in the frequency and I hope there are other ways.

Cheers

Mat

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嗫嚅 2024-08-27 04:31:12

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

amplitude_dB = 20 * log10(amplitude) +calibration_dB;

其中,amplitude 是经过整流和滤波的幅度,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 开始并进行实验

Once you have a chunk of the waveform in memory then it's fairly easy to calculate magnitude values in dB (although you'll need to decide what you reference magnitude for 0 dB is). Typically if you want the kind of short term magnitude that you might see displayed on a VU meter then you need to rectify the instantaneous values of the waveform (you can use abs for this) and then pass these rectified values through a simple low pass filter with a time constant of the order of, say, 100 ms. To convert the values to dB you'll do this:

amplitude_dB = 20 * log10(amplitude) + calibration_dB;

where amplitude is the rectified and filtered magnitude, and calibration_dB is an offset to give you the correct amplitude for 0 dB, whatever that might be in your particular application (e.g. dB re full scale, or a calibrated dBV or dBm value).

A simple but effective low pass filter can be implemented as follows. This will be a single pole IIR (recursive) filter. Each output is dependent on the previous output value and the current input value. We have a constant factor, alpha, which effectively determines the time constant or cut-off frequency of this low pass filter.

y = alpha * x + (1.0 - alpha) * y_old;
y_old = y;
  • x = current input value
  • y = new output value
  • y_old = previous output value
  • alpha = constant which determines response of filter - a small positive number - try 0.001 to start off with and experiment
又爬满兰若 2024-08-27 04:31:12

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

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

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

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

AurioTouch is the right example to look at. Unfortunately the code is just terrible. Make sure that you only use it to get to know the concepts behind working with the RemoteIO audio unit.

The actual drawing of the waveform is happening right in the renderProc callback which is called by CoreAudio when PCM data becomes available. Look at PerformThru() in aurioTouchAppDelegate.mm:197... further down, in line 237

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

... that's where the actual PCM data is accessed. This is the data you would need to analyze in order to get peak/average power of the signal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文