【发布时间】:2017-01-11 08:18:20
【问题描述】:
我想打开一个波形文件并播放它,同时在图表上绘制它的幅度和频率响应。
我有一个函数,它接受字节或浮点数组并为我执行此操作。
我要做的是从我上次采样时开始采样音频,将表示该时间的浮点数组传递给函数。
我正在尝试使用 ISampleProvider 和它的 read 方法,但我似乎无法让它工作。第一次读取运行良好,但随后线程在后续读取时崩溃(有时它也会在第一次读取时崩溃)。
这就是我设置音频的方式,文件播放得很好:
_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());
}
}
添加了堆栈跟踪(希望我做得正确)
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
海丹
【问题讨论】:
-
你有崩溃的堆栈跟踪/异常数据吗?
-
你能不能发一下e.ToString(),这样我们也能看到异常类型。
-
啊,是的,我认为您使我能够解决我自己的问题,我没有确保读取长度是块对齐的倍数! (以为我是但我不是) e.ToString() 必须是块对齐的倍数...
-
将此添加到代码中,现在它似乎工作得很好 - "length -= length % (blockAlign / channels);"
-
您能否发布您的解决方案作为答案,然后您可以接受您自己的解决方案。这样,当其他人遇到相同问题时,他们可以找到您的解决方案。
标签: c# audio visualization playback naudio