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看下

  具體可調試示例如下:示例 (也是粗淺學習,可交流,輕拍磚)

  寫的比較亂,可跳轉到下一篇,寫的相對具體點

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM