Ios 有人能解释一下这段代码是如何使用Accelerate框架将音量转换成分贝的吗?
我正在使用EZAudio构建一个iOS应用程序。它的委托返回一个Ios 有人能解释一下这段代码是如何使用Accelerate框架将音量转换成分贝的吗?,ios,objective-c,accelerate-framework,ezaudio,Ios,Objective C,Accelerate Framework,Ezaudio,我正在使用EZAudio构建一个iOS应用程序。它的委托返回一个float**缓冲区,其中包含指示检测到的卷的浮点值。这个委托经常被调用,它的工作是在不同的线程中完成的 我想做的是从EZAudio中获取浮点值并将其转换为分贝。 代表 以下是我的简写: 问题 问题是,在从下面的链接实施解决方案后,我不明白它是如何工作的。如果有人能解释它是如何将音量转换成分贝的,我将非常感激 代码 该解决方案使用来自的以下方法将音量转换为分贝: 下面是从EZAudio委托调用的方法getD
float**
缓冲区,其中包含指示检测到的卷的浮点值。这个委托经常被调用,它的工作是在不同的线程中完成的
我想做的是从EZAudio中获取浮点值并将其转换为分贝。
代表 以下是我的简写:
问题 问题是,在从下面的链接实施解决方案后,我不明白它是如何工作的。如果有人能解释它是如何将音量转换成分贝的,我将非常感激
代码 该解决方案使用来自的以下方法将音量转换为分贝:
getDecibelsFromVolume
。它从代理传递float**buffer
和bufferSize
- (float)getDecibelsFromVolume:(float**)buffer withBufferSize:(UInt32)bufferSize {
// Decibel Calculation.
float one = 1.0;
float meanVal = 0.0;
float tiny = 0.1;
float lastdbValue = 0.0;
vDSP_vsq(buffer[0], 1, buffer[0], 1, bufferSize);
vDSP_meanv(buffer[0], 1, &meanVal, bufferSize);
vDSP_vdbcon(&meanVal, 1, &one, &meanVal, 1, 1, 0);
// Exponential moving average to dB level to only get continous sounds.
float currentdb = 1.0 - (fabs(meanVal) / 100);
if (lastdbValue == INFINITY || lastdbValue == -INFINITY || isnan(lastdbValue)) {
lastdbValue = 0.0;
}
float dbValue = ((1.0 - tiny) * lastdbValue) + tiny * currentdb;
lastdbValue = dbValue;
return dbValue;
}
我将解释如何使用代码计算信号的dB值,然后展示它与vDSP示例的关系 首先,计算数据块的RMS和 这与示例代码的关系 该行在缓冲区上循环并计算缓冲区中所有元素的平方。如果缓冲区在调用之前包含值
[1,2,3,4]
,那么在调用之后它将包含值[1,4,9,16]
vDSP_meanv(buffer[0], 1, &meanVal, bufferSize);
此行在缓冲区上循环,对缓冲区中的值求和,然后返回总和除以元素数。因此,对于输入缓冲区[1,4,9,16]
,in计算总和30
,除以4
,并返回结果7.5
vDSP_vdbcon(&meanVal, 1, &one, &meanVal, 1, 1, 0);
此行将meanVal
转换为分贝。在这里调用向量化函数是没有意义的,因为它只在单个元素上运行。但是,它所做的是将参数插入以下公式:
meanVal = n*log10(meanVal/one)
其中,n
是10
或20
,具体取决于最后一个参数。在这种情况下,它是10
<代码>10用于功率测量,20
用于振幅测量。我认为20
对您来说更适合使用
最后一段代码看起来是对结果进行了一些简单的平滑处理,以使仪表的弹性有所降低。您是否查看了Accelerate/vDSP.h以了解vDSP函数的功能?非常感谢@jacket!你能解释一下你的意思吗:
“这里调用向量化函数真的没有意义,因为它只在单个元素上运行。”
你说的向量化函数
是指vDSP\u vdbcon
?更改是什么?我的意思是,vDSP\u vdbcon
经过优化,可以将一个值数组转换为dB,但您的代码仅使用单个浮点值调用它。这并不是毫无意义的,只是像meanVal=20*log10(meanVal)那样编写代码不会对性能有任何好处代码>哦,上帝。。苹果真的喜欢把事情复杂化。非常感谢你的解释。
vDSP_vsq(buffer[0], 1, buffer[0], 1, bufferSize);
vDSP_meanv(buffer[0], 1, &meanVal, bufferSize);
vDSP_vdbcon(&meanVal, 1, &one, &meanVal, 1, 1, 0);
meanVal = n*log10(meanVal/one)