gpt4 book ai didi

ios - 低通音频滤波器,在iOS上计算RMS

转载 作者:可可西里 更新时间:2023-11-01 04:09:16 27 4
gpt4 key购买 nike

我正在为iPad开发一个应用程序,我想从正在播放的视频中分析音频。使用MTAudioProcessingTap,一切顺利。
目前,我有一些测试代码可以测试/测量左右声道的音量。一切进展顺利:

void process(MTAudioProcessingTapRef tap, CMItemCount numberFrames,
MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut,
CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut)
{
OSStatus err = MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut,
flagsOut, NULL, numberFramesOut);

if (err)
NSLog(@"Error from GetSourceAudio: %ld", err);

float leftVolume, rightVolume;

for (CMItemCount i = 0; i < bufferListInOut->mNumberBuffers; i++)
{
AudioBuffer *pBuffer = &bufferListInOut->mBuffers[i];
int cSamples = numberFrames * pBuffer->mNumberChannels;

float *pData = (float *)pBuffer->mData;

float rms = 0.0f;

for (int j = 0; j < cSamples; j++)
{
rms += pData[j] * pData[j];

}

if (cSamples > 0)
{
rms = sqrtf(rms / cSamples);
}

if (0 == i)
{
leftVolume = rms;
}

if (1 == i || (0 == i && 1 == bufferListInOut->mNumberBuffers))
{
rightVolume = rms;
}
}

NSLog(@"Left / Right Volume: %f / %f", leftVolume, rightVolume);
}

但是出于这个应用程序的目的,我希望它仅测量0-80Hz范围内的RMS(“强度”)(例如)。因此,我需要一个低通滤波器。

我已经使用谷歌搜索系统很长时间了,但是我的问题是我找不到明显的清晰文章,教程或解决方案。几乎每一个听起来像我的问题,在其下都有一个随机的代码,上面充斥着肮脏或缺乏注释,因此我无法弄清楚所有神奇数字在做什么以及它们的含义。

有人可以在这里将我推向正确的方向吗?请注意,在我的情况下,我 希望理解代码,而不只是尝试工作示例。

谢谢

最佳答案

如果您可以通过一个可行的示例来解决问题,那么您将很幸运。 :-)

信号处理是一个复杂而深入的领域。从理论上讲,它很复杂,而从实践上讲,它也很复杂。

您想要一个低通滤波器。有许多不同的优点和缺点的选择。

当您想了解正在发生的事情时,您需要处理的最基本的概念是:

频域和时域:频域是当您谈论频率间隔(例如0..80Hz)时。时域是正常时间,例如是采样缓冲区中的单个采样值。上面的代码计算时域中的RMS。

基本规则:频域和时域完全等效。

您可以在任何一个域中执行许多操作,结果相同。您始终可以在频域和时域之间切换。由于某些操作在特定域中是微不足道的,因此首先切换到所需的域,进行微不足道的操作,然后再切换回原始域(如果有必要)通常是有用的。

使用 FT(傅立叶变换)完成频域和时域之间的切换。以编程方式,通常使用缓冲区的特殊情况,该缓冲区包含两个样本的幂和 FFT 算法(快速傅立叶变换)。

卷积定理是另一个有趣的特性:FT在一个域中的函数乘法与另一域中的函数卷积之间转换。

现在,这与您的低通滤波器有什么关系?

建议的低通滤波器0-80Hz在频域中是一个矩形函数。您想将其乘以您在频域中的输入。这意味着让所有低于80Hz的频率部分通过,并将所有其他部分设置为零。

现在,您可以在频域中进行所有操作,这很容易,但是出于效率方面的考虑,您希望在时域中进行操作以避免来回FFT。 (在您的情况下,您只想拥有可以像现在一样在频域中计算出的能量(平方和)。)

要在时域中进行低通滤波,而不是FT乘以FT,也可以使用FT(矩形函数)进行卷积。 FT(矩形函数)是理想的低通滤波器:sinc()函数。

sinc(x) := sin(pi*x) / pi*x

这个sinc(x)是矩形函数的脉冲响应。这种具体的脉冲响应是无限的,这是不切实际的。这意味着您将需要使用无限数量的值来计算输入的卷积。

您想要的是具有有限脉冲响应的滤波器: FIR 。这将导致滤波器出现错误,具体来说,您将不会看到具有相同权重的所有<80Hz频率,并且您还将看到能量中超过80Hz的某些频率。

这种折衷是不可避免的。

顺便说一句:当您使用FFT方法时,您可以在没有任何错误的情况下应用完美的矩形函数,并且在进行FFT之前加窗输入信号时,也会间接遭受此错误的影响。 (开窗意味着切掉输入的各个部分(窗口)以进行FFT。)这将对输出产生相同的负面影响,并且需要与滤波功能和结果相同的折衷。

您可能需要某种FIR滤波器作为低通滤波器。而且您在代码中从其他代码中看到的奇数很可能就是这种FIR滤波器的系数。

问题在于,没有“最佳”折衷方案,因为折衷方案很大程度上取决于您在过滤器中定义“错误”的方式。有些人必须以任何方式避免超过82 Hz的频率分量(在您的示例中),因此他们需要非常陡峭的滤波器边缘。这通常会在80Hz边界附近造成较大的伪影,然后需要接受这些伪影。其他人很好,有些能量来自高达120Hz的频率,并保持高于120Hz的10%以下,以减少80Hz边界附近的伪像(较软的低通滤波器)。

整个主题在这里很好地涵盖了:
https://ccrma.stanford.edu/~jos/sasp/FIR_Digital_Filter_Design.html

或者,如果您想从头开始:
https://ccrma.stanford.edu/~jos/sasp/sasp.html

还可以看一下FIR滤波器和Sinc的Wikipedia页面。

我承认,以上内容不足以设计和实现您自己的过滤器。但是它应该为您提供足够的背景知识和入门指南。

而且不要因有时奇怪的数学而推迟。

想法:一种可视化滤波器工作状况的方法是在应用滤波器并查看频谱后进行FFT。仅查看RMS值就很难判断该滤波器是否正常工作。您的iPad具有足够的处理能力来执行此操作。

(我刚刚看到也有 http://dsp.stackexchange.com用于信号处理。)

关于ios - 低通音频滤波器,在iOS上计算RMS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15479785/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com