我刚刚在AVAudioEngine上观看了WWDC视频(练习中的Session 502 AVAudioEngine ),我非常兴奋能做一个基于这项技术的应用程序。
我还不知道如何对麦克风输入或混音器的输出进行电平监控。
有人能帮上忙吗?为了清楚起见,我说的是监控当前输入信号(并在UI中显示),而不是声道/音轨的输入/输出音量设置。
我知道你可以用AVAudioRecorder做到这一点,但这不是AVAudioEngine所要求的AVAudioNode。
发布于 2015-10-16 16:52:03
尝试在主搅拌器上安装一个水龙头,然后通过设置帧长度来使其更快,然后阅读示例并获得平均值,类似于:
顶部的
导入框架
#import <Accelerate/Accelerate.h>add属性
@property float averagePowerForChannel0;
@property float averagePowerForChannel1;,然后在same>>下面
self.mainMixer = [self.engine mainMixerNode];
[self.mainMixer installTapOnBus:0 bufferSize:1024 format:[self.mainMixer outputFormatForBus:0] block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
[buffer setFrameLength:1024];
UInt32 inNumberFrames = buffer.frameLength;
if(buffer.format.channelCount>0)
{
Float32* samples = (Float32*)buffer.floatChannelData[0];
Float32 avgValue = 0;
vDSP_meamgv((Float32*)samples, 1, &avgValue, inNumberFrames);
self.averagePowerForChannel0 = (LEVEL_LOWPASS_TRIG*((avgValue==0)?-100:20.0*log10f(avgValue))) + ((1-LEVEL_LOWPASS_TRIG)*self.averagePowerForChannel0) ;
self.averagePowerForChannel1 = self.averagePowerForChannel0;
}
if(buffer.format.channelCount>1)
{
Float32* samples = (Float32*)buffer.floatChannelData[1];
Float32 avgValue = 0;
vDSP_meamgv((Float32*)samples, 1, &avgValue, inNumberFrames);
self.averagePowerForChannel1 = (LEVEL_LOWPASS_TRIG*((avgValue==0)?-100:20.0*log10f(avgValue))) + ((1-LEVEL_LOWPASS_TRIG)*self.averagePowerForChannel1) ;
}
}];然后,获取所需的目标值
NSLog(@"===test===%.2f", self.averagePowerForChannel1);要获取峰值,请使用vDSP_maxmgv而不是vDSP_meamgv。
LEVEL_LOWPASS_TRIG是一个简单的筛选器,值在0.0到1.0之间,如果设置为0.0,您将过滤所有值,并且不会获得任何数据。如果将其设置为1.0,则会获得太多噪波。基本上,值越高,数据的变化就越大。对于大多数应用程序来说,0.10到0.30之间的值似乎是很好的。
发布于 2018-04-12 20:24:43
相当于'Farhad‘答案的Swift 3代码
顶部的
导入框架
import Accelerate全局声明
private var audioEngine: AVAudioEngine?
private var averagePowerForChannel0: Float = 0
private var averagePowerForChannel1: Float = 0
let LEVEL_LOWPASS_TRIG:Float32 = 0.30在您需要的地方使用下面的代码
let inputNode = audioEngine!.inputNode//since i need microphone audio level i have used `inputNode` otherwise you have to use `mainMixerNode`
let recordingFormat: AVAudioFormat = inputNode!.outputFormat(forBus: 0)
inputNode!.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) {[weak self] (buffer:AVAudioPCMBuffer, when:AVAudioTime) in
guard let strongSelf = self else {
return
}
strongSelf.audioMetering(buffer: buffer)
}计算
private func audioMetering(buffer:AVAudioPCMBuffer) {
buffer.frameLength = 1024
let inNumberFrames:UInt = UInt(buffer.frameLength)
if buffer.format.channelCount > 0 {
let samples = (buffer.floatChannelData![0])
var avgValue:Float32 = 0
vDSP_meamgv(samples,1 , &avgValue, inNumberFrames)
var v:Float = -100
if avgValue != 0 {
v = 20.0 * log10f(avgValue)
}
self.averagePowerForChannel0 = (self.LEVEL_LOWPASS_TRIG*v) + ((1-self.LEVEL_LOWPASS_TRIG)*self.averagePowerForChannel0)
self.averagePowerForChannel1 = self.averagePowerForChannel0
}
if buffer.format.channelCount > 1 {
let samples = buffer.floatChannelData![1]
var avgValue:Float32 = 0
vDSP_meamgv(samples, 1, &avgValue, inNumberFrames)
var v:Float = -100
if avgValue != 0 {
v = 20.0 * log10f(avgValue)
}
self.averagePowerForChannel1 = (self.LEVEL_LOWPASS_TRIG*v) + ((1-self.LEVEL_LOWPASS_TRIG)*self.averagePowerForChannel1)
}
}发布于 2020-03-26 15:45:50
Swift 5+
在项目上方下载
导入AVFoundation私有变量麦克风= MicrophoneMonitor(numberOfSamples: 1)私有变量定时器:定时器!override func viewDidLoad() { super.viewDidLoad() timer = Timer.scheduledTimer(timeInterval: 0.1,target: self,selector:#selector(startMonitoring),userInfo: nil,repeats: true) timer.fire() } @objc func startMonitoring() {print(“声音级别:”,normalizeSoundLevel(级别: mic.soundSamples.first!)) }私有函数normalizeSoundLevel(级别:浮点) -> CGFloat { let level = max(0.2,CGFloat(级别)+ 50) /2 //在0.1和25之间返回CGFloat(级别* (300 / 25)) //在300 (我们的条形高度)时缩放到最大}
3.开瓶啤酒庆祝一下吧!
https://stackoverflow.com/questions/30641439
复制相似问题