Xamarin.iOS 中的 AVAudioSinkNode 无法连接到 InputNode

AVAudioSinkNode in Xamarin.iOS can't connect to InputNode

使用 Xamarin,我想使用 AVAudioSinkNode 以尽可能低的延迟存储并最终传输来自麦克风的传入音频数据(无需直接进入 AudioUnits 和已弃用的 AUGraphs)。请参阅下面我的注释代码,其中 SinkNode 连接到默认的 InputNode。这让我很伤心。我正在使用 Xamarin.Forms 和一个简单的 iOS 依赖项 class。我可以通过 fx 节点(例如 Reverb)成功连接 InputNode,然后连接到 OutputNode。在这种情况下,我已将代码最小化以专注于手头的问题:

public unsafe class AudioEngine : IAudioEngine
{
    AVAudioEngine engine;
    AVAudioInputNode input;
    AVAudioSinkNode sink;

    public AudioEngine()
    {
        ActivateAudioSession();
    }

    protected void ActivateAudioSession()
    {
        var session = AVAudioSession.SharedInstance();
        session.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.DuckOthers);
        session.SetActive(true);
        session.SetPreferredIOBufferDuration(0.0007, out error); // 32 byte buffer, if possible!

        engine = new AVAudioEngine();

        input = engine.InputNode; // to save on typing
        input.Volume = 0.5f;

        var format = input.GetBusInputFormat(0); // used for fx connections, but not used in this snippet. If I use this in the Input -> Sink connection, it crashes.

        sink = new AVAudioSinkNode(sinkReceiverHandler);
        engine.AttachNode(sink);

        try
        {
            //-----------------------------------------------------
            // Param #3 (format) is nil in all the Apple Documentation and multiple examples
            // In place of nil, **NSNull.Null** isn't accepted.
            // In place of nil, **null** throws a System.NullReferenceException. (see stack dump)
            // In place of nil, using the **InputNode's format** crashes with
            // something about missing the Trampolines.g.cs file... no clue...

            engine.Connect(input, sink, **null**); // null doesn't work in place of nil.
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.StackTrace); // Exception messages included below
        }

        engine.Prepare();
        engine.StartAndReturnError(out error);
    }

    private unsafe int sinkReceiverHandler(AudioToolbox.AudioTimeStamp timeStamp, uint frames, ref AudioToolbox.AudioBuffers inputData)
    {
        // Do stuff with the data...
        return 0;
    }
}

我发现一个 post 与 nil 的使用有关 Xamarin.iOS 中的参数,它说库的作者需要包含 [ NullAllowed] 参数:

我的问题是:我是否漏掉了一些明显的东西,或者这是 Xamarin 库定义中的一个疏忽?我总是认为这是我缺乏专​​业知识,但如果这是一个错误,我该如何向 Xamarin 报告它?

后续问题:如果这个一个故障,是否有可行的解决方法?我可以进入并手动调整 Xamarin 库定义吗? (这会破坏任何更新,我敢肯定。)或者我可以使用 Swift 创建一个小库,然后将其导入我的 Xamarin 项目吗?

只是在想办法。谢谢阅读! 下面是当我使用 null 代替 nil 时的堆栈转储(再次... NSNull.Null 在这种情况下不被视为有效类型。它只是不编译):

{System.NullReferenceException: 对象引用未设置为对象的实例 在 AVFoundation.AVAudioFormat.op_Equality (AVFoundation.AVAudioFormat a, AVFoundation.AVAudioFormat b) [0x00000] 在 /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.3.2/src/Xamarin.iOS/AVFoundation/AVAudioFormat.cs:27 在 AVFoundation.AVAudioEngine.Connect(AVFoundation.AVAudioNode sourceNode,AVFoundation.AVAudioNode targetNode,AVFoundation.AVAudioFormat 格式)[0x00024] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13。 18.3.2/src/Xamarin.iOS/AVAudioEngine.g.cs:120 在 udptest.iOS.AudioEngine.ActivateAudioSession () [0x0009b] 在 /Users/eludema/dev/xamarin/udptest/udptest.iOS/AudioEngine.cs:43 }

谢谢!

这已被确认为一个错误:格式参数为 [NullAllowable],但实际处理该 null 的当前代码未 link 包装代码中。这是 Xamarin 上的问题跟踪器。Mac/iOS github 存储库:

https://github.com/xamarin/xamarin-macios/issues/9267

感谢 github 问题提交 link,@SushiHangover!