带有 ISampleProvider 的 NAudio WasapiOut 随机停止

问题描述

我正在为我正在开发的应用程序添加音频播放,并决定使用 NAudio,因为我的团队希望以低延迟将样本流式传输到 wasapi。我让它工作了,但由于某种奇怪的原因,它会随机停止。有时,它几乎是立即的;有时,几秒钟后;有时,它只是按预期工作。

以下是我用来播放的代码

public class AudioPlaybackPlugin
{
    private readonly DataManager _dataManager;
    private readonly int _sampleRate;
    private readonly Func<long> _getPlaybackStartDelegate;

    AudioPlaybackPlugin(DataManager dataManager,int sampleRate,Func<long> getPlaybackStartDelegate)
    {
        _dataManager = dataManager;
        _sampleRate = sampleRate;
        _getPlaybackStartDelegate = getPlaybackStartDelegate;
    }

    public void StartAudioPlayback()
    {
        Task.Run(StartAudioPlaybackBackground);

        void StartAudioPlaybackBackground()
        {
            var source = new AudioSampleProvider(
                WaveFormat.CreateIeeeFloatWaveFormat(_sampleRate,1),_dataManager,_getPlaybackStartDelegate.Invoke()
                );
            var output = new WasapIoUt(AudioClientShareMode.Shared,latency: 125);
            output.Init(new SampletoWaveProvider16(source));
            output.Play();
        }
    }

    private class AudioSampleProvider : ISampleProvider
    {
        private readonly DataManager _dataManager;
        private readonly long _audioStartOffset;
        private int _samplesRead;

        public AudioSampleProvider(
            WaveFormat waveFormat,DataManager dataManager,long audioStartOffset)
        {
            _dataManager = dataManager;
            _audioStartOffset = audioStartOffset;
            WaveFormat = waveFormat;
            _samplesRead = 0;
        }

        public int Read(float[] buffer,int offset,int count)
        {
            if (count == 0)
                return count;

            lock (_dataManager)
            {
                var data = _dataManager.Read(offset: _audioStartOffset + _samplesRead,length: count);
                data.copyTo(buffer.Asspan()[offset..]);
            }

            _samplesRead += count;

            return count;
        }

        public WaveFormat WaveFormat { get; }
    }
}

我知道在获取数据的代码中没有抛出任何异常,当我监听 output.PlaybackStopped 事件时,它停止时没有给出任何异常。

文档说,如果 Read() 返回 0,则假定音频已完成播放并自动停止。但是,从调试中我可以看出 Read() 收到了许多 count 为 0 的请求(大约一半的请求,即使它正在工作)。对于这些,我让它什么都不做并返回零,因为我不确定其他任何事情是否有意义。这可能是停止播放的原因吗?如果是这样,我应该怎么做才能避免收到 count 为 0 的这些请求?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)