C# NAudio錄音和播放音訊檔案-實時繪製音訊波形圖(從音訊流資料獲取,而非裝置獲取)
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看下
具體可除錯示例如下:示例 (也是粗淺學習,可交流,輕拍磚)
&n