尝试在 ASIO 输出上使用 NAudio 播放音频时的空引用

Posted

技术标签:

【中文标题】尝试在 ASIO 输出上使用 NAudio 播放音频时的空引用【英文标题】:Null reference when trying to play audio using NAudio on ASIO output 【发布时间】:2021-03-22 15:09:23 【问题描述】:

我有 6 个音频源,需要使用 ASIO 在 6 个单独的通道上播放。

我设法使用WaveOutEvent 作为输出来完成这项工作,但是当我切换到AsioOut 时,我得到一个空引用错误,我无法弄清楚我做错了什么。

我需要使用 ASIO,因为我需要 6 个输出通道,而且我必须使用 Dante 协议通过网络广播音频。 输出设备是 Dante Virtual Soundcard。

错误是:

NullReferenceException: Object reference not set to an instance of an object
NAudio.Wave.AsioOut.driver_BufferUpdate (System.IntPtr[] inputChannels, System.IntPtr[] outputChannels) (at <7b1c1a8badc0497bac142a81b5ef5bcf>:0)
NAudio.Wave.Asio.AsioDriverExt.BufferSwitchCallBack (System.Int32 doubleBufferIndex, System.Boolean directProcess) (at <7b1c1a8badc0497bac142a81b5ef5bcf>:0)
UnityEngine.<>c:<RegisterUECatcher>b__0_0(Object, UnhandledExceptionEventArgs)

这是播放音频的(简化的)代码。缓冲区由外部类中的其他方法填充。

using NAudio.Wave;
using System;
using System.Collections.Generic;

public class AudioMultiplexer

    MultiplexingWaveProvider multiplexer;
    AsioOut asioOut;

    public List<BufferedWaveProvider> buffers;
    public int outputChannels = 6;
    public int waveFormatSampleRate = 48000;
    public int waveFormatBitDepth = 24;
    public int waveFormatChannels = 2;

    public void Start()
    
        buffers = new List<BufferedWaveProvider>();
        var outputFormat = new WaveFormat(waveFormatSampleRate, waveFormatBitDepth, waveFormatChannels);

        for (int i = 0; i < outputChannels; i++)
        
            var buffer = new BufferedWaveProvider(outputFormat);
            buffer.DiscardOnBufferOverflow = true;
            // Make sure the buffers are big enough, just in case
            buffer.BufferDuration = TimeSpan.FromMinutes(5);
            buffers.Add(buffer);
        

        multiplexer = new MultiplexingWaveProvider(buffers, outputChannels);

        for (int i = 0; i < outputChannels; i++)
        
            // Each input has 2 channels, left & right, take only one channel from each input source
            multiplexer.ConnectInputToOutput(i * 2, i);
        

        var driverName = GetDanteDriverName();

        if (string.IsNullOrEmpty(driverName))
        
            return;
        

        asioOut = new AsioOut(driverName);
        asioOut.AudioAvailable += AsioOut_AudioAvailable;
        asioOut.Init(multiplexer);
        asioOut.Play();
    

    private void AsioOut_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
    
        // Do nothing for now
        Console.WriteLine("Audio available");
    

    private string GetDanteDriverName()
    
        foreach (var driverName in AsioOut.GetDriverNames())
        
            if (driverName.Contains("Dante Virtual Soundcard"))
            
                return driverName;
            
        
        return null;
    

    private void OnDestroy()
    
        asioOut.Stop();
        asioOut.Dispose();
        asioOut = null;
    

我可能对 AsioOut 的工作方式有误解,但我不确定从哪里开始或如何调试错误。

【问题讨论】:

【参考方案1】:

您可以使用 Low-latency Multichannel Audio Asset for unity 使用 asio 播放多声道音频。与 naudio 不同,它是专为统一而设计的,而且它可以毫无问题地工作!

【讨论】:

谢谢,但我已经尝试过了,这对我的用例不利。我需要能够从缓冲区播放音频数据,并且该资产只能读取提前预定义的本地文件。

以上是关于尝试在 ASIO 输出上使用 NAudio 播放音频时的空引用的主要内容,如果未能解决你的问题,请参考以下文章

NAudio:使用 ASIO 录制音频并用吉他输出

Naudio Asio 在多个通道上同时录制和播放

NAudio - ASIO 播放到设备(仅限静态)

如何使用 NAudio 和 ASIO 直接读取输入缓冲区和播放?

NAudio Asio 录制播放和保存(仅限噪音)

NAudio Asio 同时录制和播放