gpt4 book ai didi

ios - 关于从 AVAudioPCMBuffer 中提取声压级

转载 作者:可可西里 更新时间:2023-11-01 03:29:53 28 4
gpt4 key购买 nike

我对信号处理几乎一无所知,目前我正在尝试在 Swift 中实现一个函数,当 sound pressure level 增加时触发一个事件。 (例如,当人尖叫时)。

我正在使用这样的回调进入 AVAudioEngine 的输入节点:

let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat){
(buffer : AVAudioPCMBuffer?, when : AVAudioTime) in
let arraySize = Int(buffer.frameLength)
let samples = Array(UnsafeBufferPointer(start: buffer.floatChannelData![0], count:arraySize))

//do something with samples
let volume = 20 * log10(floatArray.reduce(0){ $0 + $1} / Float(arraySize))
if(!volume.isNaN){
print("this is the current volume: \(volume)")
}
}

将其转换为 float 组后,我尝试通过计算平均值来粗略估计声压级。

但这给我的值(value)波动很大,即使 iPad 只是放在一个安静的房间里也是如此:

this is the current volume: -123.971
this is the current volume: -119.698
this is the current volume: -147.053
this is the current volume: -119.749
this is the current volume: -118.815
this is the current volume: -123.26
this is the current volume: -118.953
this is the current volume: -117.273
this is the current volume: -116.869
this is the current volume: -110.633
this is the current volume: -130.988
this is the current volume: -119.475
this is the current volume: -116.422
this is the current volume: -158.268
this is the current volume: -118.933

如果我在麦克风附近拍手,这个值确实有显着增加。

所以我可以做一些事情,比如在准备阶段首先计算这些体积的平均值,然后比较在事件触发阶段差异是否显着增加:

 if(!volume.isNaN){
if(isInThePreparingPhase){
print("this is the current volume: \(volume)")
volumeSum += volume
volumeCount += 1
}else if(isInTheEventTriggeringPhase){
if(volume > meanVolume){
//triggers an event
}
}
}

在从准备阶段到触发事件阶段的过渡期间计算 averageVolume:meanVolume = volumeSum/Float(volumeCount)

....

但是,如果我在麦克风之外播放响亮的音乐,似乎没有显着增加。在极少数情况下,volume 大于 meanVolume,即使环境音量没有显着增加(人耳可听见)也是如此。

那么从AVAudioPCMBuffer中提取声压级的正确方法是什么?

维基百科给出了这样一个公式

math!

p 是均方根声压,p0 是引用声压。

但我不知道 AVAudioPCMBuffer.floatChannelData 中的浮点值代表什么。 The apple page只说

The buffer's audio samples as floating point values.

我应该如何与他们合作?

最佳答案

感谢@teadrinker 的回复,我终于找到了解决这个问题的方法。我分享了输出 AVAudioPCMBuffer 输入音量的 Swift 代码:

private func getVolume(from buffer: AVAudioPCMBuffer, bufferSize: Int) -> Float {
guard let channelData = buffer.floatChannelData?[0] else {
return 0
}

let channelDataArray = Array(UnsafeBufferPointer(start:channelData, count: bufferSize))

var outEnvelope = [Float]()
var envelopeState:Float = 0
let envConstantAtk:Float = 0.16
let envConstantDec:Float = 0.003

for sample in channelDataArray {
let rectified = abs(sample)

if envelopeState < rectified {
envelopeState += envConstantAtk * (rectified - envelopeState)
} else {
envelopeState += envConstantDec * (rectified - envelopeState)
}
outEnvelope.append(envelopeState)
}

// 0.007 is the low pass filter to prevent
// getting the noise entering from the microphone
if let maxVolume = outEnvelope.max(),
maxVolume > Float(0.015) {
return maxVolume
} else {
return 0.0
}
}

关于ios - 关于从 AVAudioPCMBuffer 中提取声压级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40031738/

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