我正在使用EZAudio构建iOS应用程序。它的代理返回一个float **
缓冲区,其中包含指示检测到的音量的浮点值。此代理会不断地调用,并在不同的线程中完成其工作。
我试图做的是将EZAudio中的浮点值转换为分贝。
EZAudioDelegate
这是我简化过的获取麦克风数据的EZAudio代理:
- (void)microphone:(EZMicrophone *)microphone hasAudioReceived:(float **)buffer withBufferSize:(UInt32)bufferSize withNumberOfChannels:(UInt32)numberOfChannels {
/*
* Returns a float array called buffer that contains the stereo signal data
* buffer[0] is the left audio channel
* buffer[1] is the right audio channel
*/
// Using a separate audio thread to not block the main UI thread
dispatch_async(dispatch_get_main_queue(), ^{
float decibels = [self getDecibelsFromVolume:buffer withBufferSize:bufferSize];
NSLog(@"Decibels: %f", decibels);
});
}
问题
问题在于我在实施以下链接中的解决方案后,我不理解它是如何工作的。如果有人能够解释一下如何将音量转换为分贝,我会非常感激。
代码
该解决方案使用Accelerate Framework中的以下方法将音量转换为分贝:
以下是从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;
}