Я создаю приложение для iOS, используя EZAudio. Его делегат возвращает буфер float**
, который содержит значения с плавающей запятой, указывающие обнаруженный объем. Этот делегат вызывается постоянно, и его работа выполняется в другом потоке.
Что я пытаюсь сделать, так это взять значение с плавающей запятой из EZAudio и преобразовать его в децибелы.
ЭЗАудиоделегат
Вот мой упрощенный делегат 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, чтобы преобразовать громкость в децибелы:
Ниже показан метод getDecibelsFromVolume
, который вызывается из EZAudio Delegate. Он передается 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;
}