gpt4 book ai didi

ios - iOS音频单元-是否与图表连接?

转载 作者:行者123 更新时间:2023-12-02 22:36:04 25 4
gpt4 key购买 nike

我跳出了深渊,并决定使用Audio Units在iOS上找出低延迟音频。我已经找到了尽可能多的文档(来自Apple和论坛论坛),并且总体概念很有意义,但是我仍在探索一些需要帮助的概念:

  • 我在某处看到不赞成使用AU图形,而应该直接连接音频单元。我很酷...但是如何?我是否只需要使用音频单元的Connection属性将其连接到源AU,然后就可以了?初始化并启动单位,然后看魔术发生了吗? (因为它不适合我...)
  • 如果我只是想从麦克风中获取音频,对音频数据进行一些处理,然后将音频数据存储而不将发送到RemoteIO扬声器,总线0输出,该如何使用最佳音频单元设置?我尝试连接GenericOutput AudioUnit以在回调中捕获数据,而没有任何运气...

  • 而已。我可以根据要求提供代码,但为时已晚,这使我不知所措。如果知道简单的答案,那很酷。我会随意发送任何代码段。可以这么说,我可以轻松地获得一个简单的RemoteIO,麦克风输入,扬声器输出设置,而且效果很好。延迟似乎不存在(至少在我看来)。我只想对麦克风数据进行处理,然后将其存储在内存中,而不会发送给扬声器。最终,卡在均衡器和混音器上会很费劲,但一次只能一步。
    FWIW,我正在Xamarin Forms / C# Realm 中进行编码,但是在Objective C,Swift或其他任何情况下都可以使用代码示例。我停留在概念上,不一定是确切的代码。
    谢谢!

    最佳答案

    您的问题涉及音频单位和图表。如评论中所述,图形概念已由将“节点”附加到AVAudioEngine的想法代替。这些节点然后“连接”到其他节点。连接节点会创建信号路径,而启动引擎会使这一切发生。这可能很明显,但是我在这里尝试做出一般性的答复。
    您可以在Swift或Objective-C中完成所有这些操作。
    iOS音频要考虑的两个高级观点是“主机”和“插件”的概念。主机是一个应用程序,它托管插件。该插件通常创建为“应用程序扩展”,您可以根据需要查找音频单元扩展以获取更多信息。您说您有一个做自己想做的事,所以这一切都解释了主机中使用的代码
    将AudioUnit附加到AVaudioEngine

    var components = [AVAudioUnitComponent]()

    let description =
    AudioComponentDescription(
    componentType: 0,
    componentSubType: 0,
    componentManufacturer: 0,
    componentFlags: 0,
    componentFlagsMask: 0
    )

    components = AVAudioUnitComponentManager.shared().components(matching: description)
    .compactMap({ au -> AVAudioUnitComponent? in
    if AudioUnitTypes.codeInTypes(
    au.audioComponentDescription.componentType,
    AudioUnitTypes.instrumentAudioUnitTypes,
    AudioUnitTypes.fxAudioUnitTypes,
    AudioUnitTypes.midiAudioUnitTypes
    ) && !AudioUnitTypes.isApplePlugin(au.manufacturerName) {
    return au
    }
    return nil
    })

    guard let component = components.first else { fatalError("bugs") }

    let description = component.audioComponentDescription

    AVAudioUnit.instantiate(with: description) { (audioUnit: AVAudioUnit?, error: Error?) in

    if let e = error {
    return print("\(e)")
    }
    // save and connect
    guard let audioUnit = audioUnit else {
    print("Audio Unit was Nil")
    return
    }
    let hardwareFormat = self.engine.outputNode.outputFormat(forBus: 0)

    self.engine.attach(au)
    self.engine.connect(au, to: self.engine.mainMixerNode, format: hardwareFormat)
    }
    一旦加载了AudioUnit,就可以连接下面的Athe AVAudioNodeTapBlock,它具有更多的功能,因为它需要是二进制文件或其他非您需要的宿主应用程序可以加载的东西。
    记录AVAudioInputNode
    (您可以将音频单元替换为输入节点。)
    在应用程序中,您可以通过创建AVAudioInputNode来录制音频,也可以只引用AVAudioEngine的'inputNode'属性,该属性将默认连接到系统的选定输入设备(麦克风,线路输入等)
    一旦有了要处理音频的输入节点,接下来在该节点上“安装水龙头”。您也可以将输入节点连接到混音器节点,然后在其中安装水龙头。
    https://developer.apple.com/documentation/avfoundation/avaudionode/1387122-installtap
    func installTap(onBus bus: AVAudioNodeBus, 
    bufferSize: AVAudioFrameCount,
    format: AVAudioFormat?,
    block tapBlock: @escaping AVAudioNodeTapBlock)
    安装的分接头基本上会将您的音频流分成两个信号路径。它将继续将音频发送到AvaudioEngine的输出设备,还将音频发送到您定义的功能。此功能(AVAudioNodeTapBlock)从AVAudioNode传递到“installTap”。 AVFoundation子系统调用AVAudioNodeTapBlock并一次将输入数据和数据到达的时间一起传递给您一个缓冲区。
    https://developer.apple.com/documentation/avfoundation/avaudionodetapblock
    typealias AVAudioNodeTapBlock = (AVAudioPCMBuffer, AVAudioTime) -> Void
    现在,系统正在将音频数据发送到可编程上下文,您可以使用它来完成您想做的事情。
    要在其他地方使用它,您可以创建一个单独的AVAudioPCMBuffer并将每个传入的缓冲区写入到AVAudioNodeTapBlock中。

    关于ios - iOS音频单元-是否与图表连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63213753/

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