hor*_*oe7 18 macos objective-c avfoundation ios avaudioengine
我刚看了WWDC视频(AVAudioEngine实践中的会话502 )AVAudioEngine,我非常高兴能够建立一个基于这种技术的应用程序.
我无法弄清楚如何对麦克风输入或调音台输出进行电平监控.
有人可以帮忙吗?为了清楚起见,我所说的是监控当前输入信号(并在UI中显示),而不是通道/轨道的输入/输出音量设置.
我知道你可以做到这一点AVAudioRecorder,但是这不是AVAudioNode它的AVAudioEngine需要.
Far*_*our 17
尝试在主混音器上安装一个水龙头,然后通过设置帧长度使其更快,然后读取样本并获得平均值,如下所示:
进口框架在上面
#import <Accelerate/Accelerate.h>
Run Code Online (Sandbox Code Playgroud)
添加属性
@property float averagePowerForChannel0;
@property float averagePowerForChannel1;
Run Code Online (Sandbox Code Playgroud)
那么下面的相同>>
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) ;
}
}];
Run Code Online (Sandbox Code Playgroud)
然后,获得您想要的目标值
NSLog(@"===test===%.2f", self.averagePowerForChannel1);
Run Code Online (Sandbox Code Playgroud)
要获取峰值,请使用vDSP_maxmgv而不是vDSP_meamgv.
LEVEL_LOWPASS_TRIG是一个介于0.0到1.0之间的简单过滤器,如果设置为0.0,您将过滤所有值而不获取任何数据.如果将其设置为1.0,则会产生太多噪音.基本上,值越高,您将获得更多的数据变化.对于大多数应用来说,似乎0.10到0.30之间的值是好的.
She*_*shy 11
等同的Swift 3代码'Farhad Malekpour '的回答
进口框架在上面
import Accelerate
Run Code Online (Sandbox Code Playgroud)
全球宣布
private var audioEngine: AVAudioEngine?
private var averagePowerForChannel0: Float = 0
private var averagePowerForChannel1: Float = 0
let LEVEL_LOWPASS_TRIG:Float32 = 0.30
Run Code Online (Sandbox Code Playgroud)
在您需要的地方使用以下代码
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)
}
Run Code Online (Sandbox Code Playgroud)
计算
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)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7529 次 |
| 最近记录: |