Нулевая ссылка при попытке воспроизведения звука с помощью NAudio на выходе ASIO

#c# #naudio #dante

Вопрос:

У меня есть 6 аудиоисточников, которые мне нужно воспроизводить на 6 отдельных каналах с помощью ASIO.

Мне удалось заставить это работать, используя WaveOutEvent в качестве вывода, но когда я переключаюсь на AsioOut , я получаю ошибку с нулевой ссылкой, и я не могу понять, что я делаю неправильно.

Мне нужно использовать ASIO, так как мне требуется 6 выходных каналов и потому что я должен транслировать аудио по сети, используя протокол Данте. Устройство вывода-виртуальная звуковая карта Данте.

Ошибка в том, что:

 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 amp; 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;
    }
}
 

Возможно, у меня есть непонимание того, как работает ASIOUT, но я не уверен, с чего начать или как отладить ошибку.

Ответ №1:

Вы можете использовать многоканальный аудиоресурс с низкой задержкой для unity для воспроизведения многоканального аудио с помощью asio. Он сделан специально для unity, в отличие от naudio, и работает без проблем!

Комментарии:

1. Спасибо, но я уже пробовал это, и это не подходит для моего варианта использования. Мне нужно иметь возможность воспроизводить аудиоданные из буфера, и этот ресурс может считывать только локальные файлы, предварительно определенные заранее.