【问题标题】:How to get real-time microphone input in macOS?如何在 macOS 中获取实时麦克风输入?
【发布时间】:2019-11-25 08:37:51
【问题描述】:

我正在尝试使用以下代码访问实时麦克风数据:

import AVFoundation // for AVAudioEngine

class Mic
{
    public let audioEngine = AVAudioEngine()

    func startRecording() throws
    {
        // https://forums.developer.apple.com/thread/44833
        //audioEngine.mainMixerNode  // causes DIFFERENT crash!

        audioEngine.prepare()  // CRASHES


        let inputNode = audioEngine.inputNode
        if inputNode.inputFormat(forBus: 0).sampleRate == 0 {
            exit(0);
        }

        let recordingFormat = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
            print( "YES! Got some samples!")
        }

        audioEngine.prepare()

        try audioEngine.start()
    }

    //public
    func stopRecording()
    {
        audioEngine.stop()
    }
}

但是它崩溃了:

        audioEngine.prepare()  // CRASHES

2019-07-16 17:51:34.448107+0300 realtime_mic[8992:386743] [avae]

AVAEInternal.h:76 所需条件为假:

[AVAudioEngineGraph.mm:1318:Initialize: (inputNode != nullptr || outputNode != nullptr)]

realtime_mic[8992:386743] 所需条件为假:inputNode != 空指针 || outputNode != nullptr2019-07-16 17:51:34.449214+0300

可以看出,我已尝试应用 hack/patch:

        // https://forums.developer.apple.com/thread/44833
        audioEngine.mainMixerNode

但这会导致不同的崩溃:

2019-07-16 17:50:34.315005+0300 realtime_mic[8901:385699] [插件] AddInstanceForFactory:

没有工厂注册 id F8BB1C28-BAE8-11D6-9C31-00039315CD46 2019-07-16

17:50:34.349337+0300 realtime_mic[8901:385699]

HALC_ShellDriverPlugIn::Open: 无法获得指向 Open 例程的指针

2019-07-16 17:50:34.354277+0300 realtime_mic[8901:385699] [ddagg]

AggregateDevice.mm:776 无法获取默认输入设备,ID = 0, 错误 = 0!

我已发送权利以防万一:macOS Entitlements audio-input vs. microphone -- 但无济于事。

这样做的正确方法是什么?

测试用例地址:https://github.com/p-i-/macOS_rt_mic

【问题讨论】:

  • 顺便说一下,AVAudioEngine 不是最适合实时的。有明显的延迟。对于 (milliSecond) 低延迟音频,您需要使用 Audio Units。
  • 这里的问题是我在执行audioEngine.prepare() 之前设置输入或输出节点。所以这个错误很有意义。

标签: swift macos core-audio microphone avaudioengine


【解决方案1】:

在 testRecord.swift 中输入以下代码:

import Foundation
import AVFoundation 

print("starting")

public let audioEngine = AVAudioEngine()

var flag = 0

func startRecording() throws {

    let inputNode = audioEngine.inputNode
    let srate = inputNode.inputFormat(forBus: 0).sampleRate
    print("sample rate = \(srate)")
    if srate == 0 {
        exit(0);
    }

    let recordingFormat = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, 
        bufferSize: 1024, 
        format: recordingFormat) { 
            (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
            let n = buffer.frameLength
            let c = buffer.stride
            if flag == 0 { 
                print( "num samples  = \(n)") ; 
                print( "num channels = \(c)") ; 
                flag = 1 
            }
        }

    try audioEngine.start()
}

func stopRecording() {
    audioEngine.stop()
}

do {
    try startRecording()
} catch {
    print("error?")
}

usleep(UInt32(1000*1000))         // sleep 1 second before quitting
stopRecording()
print("done")
exit(0)

在 macOS 10.14.5 / Xcode 10.2.1 上使用 swiftc 编译 testRecord.swift ;然后尝试从终​​端运行结果。第一次运行时,macOS 询问终端是否可以拥有麦克风权限。回答是,但没有输出。

但是在随后的运行中它会输出:

开始

采样率 = 44100.0

样本数 = 4410

频道数 = 1

完成

因此,您可能需要在系统偏好设置:隐私:麦克风中为您的应用授予一些权限

【讨论】:

  • 嗨,我总是得到 srate == 0。在 macos 10.15.7 上运行
猜你喜欢
  • 2023-01-31
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
  • 2018-11-21
  • 1970-01-01
相关资源
最近更新 更多