首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AVAudioEngine进行电平测量

使用AVAudioEngine进行电平测量
EN

Stack Overflow用户
提问于 2015-06-04 18:30:18
回答 6查看 10.9K关注 0票数 20

我刚刚在AVAudioEngine上观看了WWDC视频(练习中的Session 502 AVAudioEngine ),我非常兴奋能做一个基于这项技术的应用程序。

我还不知道如何对麦克风输入或混音器的输出进行电平监控。

有人能帮上忙吗?为了清楚起见,我说的是监控当前输入信号(并在UI中显示),而不是声道/音轨的输入/输出音量设置。

我知道你可以用AVAudioRecorder做到这一点,但这不是AVAudioEngine所要求的AVAudioNode

EN

回答 6

Stack Overflow用户

发布于 2015-10-16 16:52:03

尝试在主搅拌器上安装一个水龙头,然后通过设置帧长度来使其更快,然后阅读示例并获得平均值,类似于:

顶部的

导入框架

代码语言:javascript
复制
#import <Accelerate/Accelerate.h>

add属性

代码语言:javascript
复制
@property float averagePowerForChannel0;
@property float averagePowerForChannel1;

,然后在same>>下面

代码语言:javascript
复制
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) ;
    }
}];

然后,获取所需的目标值

代码语言:javascript
复制
NSLog(@"===test===%.2f", self.averagePowerForChannel1);

要获取峰值,请使用vDSP_maxmgv而不是vDSP_meamgv。

LEVEL_LOWPASS_TRIG是一个简单的筛选器,值在0.0到1.0之间,如果设置为0.0,您将过滤所有值,并且不会获得任何数据。如果将其设置为1.0,则会获得太多噪波。基本上,值越高,数据的变化就越大。对于大多数应用程序来说,0.10到0.30之间的值似乎是很好的。

票数 21
EN

Stack Overflow用户

发布于 2018-04-12 20:24:43

相当于'Farhad‘答案的Swift 3代码

顶部的

导入框架

代码语言:javascript
复制
import Accelerate

全局声明

代码语言:javascript
复制
private var audioEngine: AVAudioEngine?
    private var averagePowerForChannel0: Float = 0
    private var averagePowerForChannel1: Float = 0
let LEVEL_LOWPASS_TRIG:Float32 = 0.30

在您需要的地方使用下面的代码

代码语言:javascript
复制
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)
}

计算

代码语言:javascript
复制
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)
            }
    }
票数 14
EN

Stack Overflow用户

发布于 2020-03-26 15:45:50

Swift 5+

I got help from this project.

在项目上方下载

  1. 并将'Microphone.swift‘类复制到您的项目中。
  2. copy将以下回收代码粘贴到您的项目中:

导入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.开瓶啤酒庆祝一下吧!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30641439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档