首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >N音频WaveOut没有播放iSampleProvider提供的所有数据

N音频WaveOut没有播放iSampleProvider提供的所有数据
EN

Stack Overflow用户
提问于 2015-11-16 00:51:57
回答 1查看 1.5K关注 0票数 0

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

代码语言:javascript
复制
 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; }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-16 17:18:05

我认为WaveOut使用ISampleProvider可能有问题,所以我使用IWaveProvider接口来做同样的事情。实际上,这里有一个基本的类,用于发送无终止点击到波形。如果让它运行很长时间,这可能会遇到内存问题,但是对于流行歌曲来说,应该是可以的。而且,这只适用于32位文件(注意字节缓冲区上的*4 )。

代码语言:javascript
复制
  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; }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33727004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档