NAudio的录音和播放录音都有对应的类,我在使用Wav格式进行录音和播放录音时使用的类时WaveIn和WaveOut,这两个类是对功能的回调和一些事件触发。

  在WaveIn和WaveOut之外还有对音频流读写使用的WaveFileWriter和WaveFileReader类,具体细节可查看其源码进行分析。

  其中绘制音频波形图根据录制和播放需要不同途径实现。


  1.录音时实时显示波形图,在录音时实时获取需要使用WaveIn.DataAvailable回调事件,在这个回调事件中会传递出音频流数据,数据类型Byte[],这就是音频内容


  但这个Byte数组需要还原为真实的数据,它的真实数据类型需根据PCM写入时的数据格式定,主要有8bit、16bit、24bit、32bit,如写入时是16bit就需将其转换为16bit数据

  然后根据WaveIn.WaveFormat的channels去获取音频波形值,然后输出出来,具体示例如下:
private void waveSource_DataAvailable(object sender, WaveInEventArgs e) { if
(waveFile !=null) { waveFile.Write(e.Buffer, 0, e.BytesRecorded);
waveFile.Flush();float[] sts = new float[e.Buffer.Length / channels]; int
outIndex =0; for (int n = 0; n < e.Buffer.Length; n += channels) { sts[outIndex
++] = BitConverter.ToInt16(e.Buffer, n) / 32768f; } for (int n = 0; n <
sts.Length; n += channels) { Add(sts[n]); } } }
  其中Add()方法就是添加波形值到UI控件上的方法,可根据自己需求实现。 

 

 2.播放录音文件时显示波形图


  播放录音时需初始化AudioFileReader类,并传入需要播放的文件路径,并将这个类传入WaveOut类中,最后用继承自ISampleProvider的类加载和初始化调用Play方法,然后会调用到WaveOut类Read方法时,会可以使用AudioFileReader.Read()方法进行获取参数,获取的是float数组,可直接用于绘制波形图
private void AnalysisRecord_Click(object sender, RoutedEventArgs e) { var
inputStream =new AudioFileReader(recordList[0]); ISampleProvider aggregator =
new NAudioReader(inputStream); aggregator.MaximumCalculated +=
Aggregator_MaximumCalculated; aggregator.Start();
waveOutDevice.Init(aggregator); waveOutDevice.Volume= 0;
waveOutDevice.PlaybackStopped+= WaveOutDevice_PlaybackStopped;
waveOutDevice.Play(); }
 
public int Read(float[] buffer, int offset, int count)///这个函数是
ISampleProvider调用的函数 { var samplesRead = source.Read(buffer, offset, count); for
(int n = 0; n < samplesRead; n += channels) { Add(buffer[n + offset]); } return
samplesRead; }

  至于绘制波形的WPF细节就在Demo中看吧,主要要注意WaveIn和WaveOut、WaveFileReader和WaveFileWriter相关内容,具体可下源码和Demo看下

  具体可调试示例如下:示例 <https://download.csdn.net/download/qq_17005083/11644031>
 (也是粗浅学习,可交流,轻拍砖)

  写的比较乱,可跳转到下一篇 <https://www.cnblogs.com/Khan-Sadas/p/11435536.html>,写的相对具体点