c# - naudio WaveOut 没有播放 iSampleProvider 提供的所有数据

标签 c# .net audio wav naudio

我正在使用 nAudio 开发点击生成器。作为测试,我创建了一个 ISampleProvidor 类来读取/播放音频文件。 iSampleProvider 读入一个 PCM(32 位 ieee)wav 文件,然后使用 WaveOut 播放器播放它。 WaveOut 仅播放通过 IsampleProvidor Read() 方法传递的音频的大约 1/4。这会导致播放不连贯。 ISampleProvider read() 方法以正确的时间间隔请求正确数量的数据,但 WaveOut 仅播放提供回接口(interface)的前 25% 的样本。知道如何解决这个问题,还是我使用错误的类来构建点击轨道(BufferedWaveProvider 也可能有效,但它只缓冲 5 秒的音频)?

 public void TestSampleProvider()
        {
            ISampleProvider mySamples = new MySamples();
            var _waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()) {DeviceNumber = 0};
            _waveOut.Init(mySamples);
            _waveOut.Play();
            Console.ReadLine();
        }

  public class MySamples : ISampleProvider
    {

        private float[] samplesFloats;
        private int position;
        private WaveFileReader clicksound;
        public int Read(float[] buffer, int offset, int count)
        {

            var copyCount = count;
            if (position + copyCount > samplesFloats.Count())
            {
                copyCount = samplesFloats.Count() - position;
            }

            Console.WriteLine("samplesFloats {0} position {1}  copyCount {2} offset {3} time {4}", samplesFloats.Count(), position, copyCount, offset, DateTime.Now.Millisecond);
            Buffer.BlockCopy(samplesFloats, position, buffer, offset, copyCount);

            position += copyCount;

          return copyCount;
        }

        public MySamples()
        {
            clicksound = new WaveFileReader(@"C:\temp\sample.wav");
            WaveFormat = clicksound.WaveFormat;
            samplesFloats = new float[clicksound.SampleCount];
            for (int i = 0; i < clicksound.SampleCount; i++)
            {
                samplesFloats[i] = clicksound.ReadNextSampleFrame()[0];//it;s a mono file
            }
        }
        public WaveFormat WaveFormat { get; private set; }
    }

最佳答案

我认为使用 ISampleProvider 的 WaveOut 可能存在问题,所以我使用 IWaveProvider 接口(interface)来做同样的事情。事实上,这是一个简单的类,用于向 waveout 发送无休止的点击。如果让它运行很长时间,这可能会遇到内存问题,但对于流行歌曲应该没问题。此外,这仅适用于 32 位文件(注意字节缓冲区上的 *4)

  public class MyClick : IWaveProvider
    {
        private int position;
        private WaveFileReader clicksound;
        private byte[] samplebuff;
        MemoryStream _byteStream = new System.IO.MemoryStream();
        public MyClick(float bpm=120)
        {
            clicksound = new WaveFileReader(@"click_sample.wav");
            var bpmsampleslen = (60 / bpm) * clicksound.WaveFormat.SampleRate;
            samplebuff = new byte[(int) bpmsampleslen*4];
            clicksound.Read(samplebuff, 0,(int) clicksound.Length);
            _byteStream.Write(samplebuff, 0, samplebuff.Length);
            _byteStream.Position = 0;
            WaveFormat = clicksound.WaveFormat;

        }
        public int Read(byte[] buffer, int offset, int count)
        {
         //we reached the end of the stream add another one to the end and keep playing
            if (count + _byteStream.Position > _byteStream.Length)
            {
                var holdpos = _byteStream.Position;
                _byteStream.Write(samplebuff, 0, samplebuff.Length);
                _byteStream.Position = holdpos;
            }
        return _byteStream.Read(buffer, offset, count);

        }

        public WaveFormat WaveFormat { get; private set; }
    }

关于c# - naudio WaveOut 没有播放 iSampleProvider 提供的所有数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33727004/

相关文章:

c# - CS0122 : 'System.Configuration.StringUtil' is inaccessible due to its protection level

c# - 如何压缩一个 IEnumerable 自身

audio - 如何在Simple Audio Engine中循环播放声音效果

javascript - 在网络上的Javascript音频应用中播放测试音

c# - 如何强制 DotNet 框架使用 JIT 而不是 NGEN?

c - SDL_Mixer 无法处理部分代码

c# - 基于 DependencyProperty 控制样式

c# - 如何在 clickOnce 部署的开始菜单中对我的应用程序进行分组?

c# - XmlSerializer 不使用由 sgen 创建的 XmlSerializers.dll

c# - 需要帮助使 dotnet Controller 干燥