使用nAudio播放.wav文件

时间:2017-01-11 08:18:20

标签: c# audio visualization playback naudio

我想打开一个波形文件并将其播放回来,同时在图表上绘制它的幅度和频率响应。

我有一个带字节数组或浮点数的函数,并为我做了这个。

我要做的是从上次采样时采样音频,将表示该时间的浮点数组传递给函数。

我正在尝试使用ISampleProvider和它的读取方法,但我似乎无法让它工作。第一次读取工作完美但随后线程在后续读取时崩溃(偶尔也会在第一次读取时崩溃)。

这就是我设置音频的方式,文件播放得很好:

                _waveOut = new WaveOutEvent();
                _waveReader = new WaveFileReader(_cncFilePath.Substring(0, _cncFilePath.Length - 4) + "wav");
                _waveOutSampleProvider = new SampleChannel(_waveReader, true);
                _waveOut.Init(_waveOutSampleProvider);
                _waveOut.Play();

这是在一个100毫秒的计时器上运行,它将在第一个滴答时完美运行,第二个将崩溃,锁定保持打开,所有其他呼叫都会备份,直到整个程序崩溃。

    private void WavOutChartTimeInterrupt(object waveReader)
    {
        lock (AudioLock) //todo add skipto code, use audio lock to do it.
        {
            try
            {
                var curPos = _waveOut.GetPositionTimeSpan(); //get currentPos
                if (curPos <= AudioCurrentPosition)
                {
                    AudioCurrentPosition = curPos;
                    return;
                }
                var bufferLength = (curPos - AudioCurrentPosition);
                var samplesSec = _waveOutSampleProvider.WaveFormat.SampleRate;
                var channels = _waveOut.OutputWaveFormat.Channels;
                var length = (int) (bufferLength.TotalSeconds * samplesSec * channels) % (samplesSec * channels);
                var wavOutBuffer = new float[length];
                _waveOutSampleProvider.Read(wavOutBuffer, 0, length);

                AudioCurrentPosition = curPos; //update for vCNC with where we are
            }
            catch (Exception e)
            {
                string WTF = e.StackTrace;

                throw new ArgumentException(@"Wave out buffer crashed" + e.StackTrace.ToString());
            }
        }

Stack Trace添加(希望我做得正确)

at NAudio.Wave.WaveFileReader.Read(Byte[] array, Int32 offset, Int32 count)\r\n       
at NAudio.Wave.SampleProviders.Pcm16BitToSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count)\r\n       
at NAudio.Wave.SampleProviders.MeteringSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count)\r\n 
at NAudio.Wave.SampleProviders.VolumeSampleProvider.Read(Single[] buffer, Int32 offset, Int32 sampleCount)\r\n   
at RecordCNC.Form1.WavOutChartTimeInterrupt(Object waveReader) in C:\\Cloud\\ITRI\\Visual Studio\\RecordCNC\\RecordCNC\\Form1.cs:line 715

Haydan

1 个答案:

答案 0 :(得分:0)

问题是我没有正确检查我请求的缓冲区的长度。缓冲区总是必须是块对齐的倍数。

 Post["/"] = parameters =>
    {
        try
        {
            var contentTypeRegex = new Regex("^multipart/form-data;\\s*boundary=(.*)$", RegexOptions.IgnoreCase);
            System.IO.Stream bodyStream = null;

            if (contentTypeRegex.IsMatch(this.Request.Headers.ContentType))
            {
                var boundary = contentTypeRegex.Match(this.Request.Headers.ContentType).Groups[1].Value;
                var multipart = new HttpMultipart(this.Request.Body, boundary);
                bodyStream = multipart.GetBoundaries().First(b => b.ContentType.Equals("application/json")).Value;
            }
            else
            {
                // Regular model binding goes here.
                bodyStream = this.Request.Body;
            }

            var jsonBody = new System.IO.StreamReader(bodyStream).ReadToEnd();

            Console.WriteLine("Got request!");
            Console.WriteLine("Body: {0}", jsonBody);
            this.Request.Files.ToList().ForEach(f => Console.WriteLine("File: {0} {1}", f.Name, f.ContentType));

            return HttpStatusCode.OK;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error!!!!!! {0}", ex.Message);
            return HttpStatusCode.InternalServerError;
        }
    };