欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# NAudio 庫的各種常見使用方式之播放 錄制 轉(zhuǎn)碼 音頻可視化

 更新時間:2021年05月10日 08:34:43   作者:SlimeNull  
這篇文章主要介紹了C# NAudio 庫的各種常見使用方式之播放 錄制 轉(zhuǎn)碼 音頻可視化,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

概述

在 NAudio 中, 常用類型有 WaveIn, WaveOut, WaveStream, WaveFileWriter, WaveFileReader, AudioFileReader 以及接口: IWaveProvider, ISampleProvider, IWaveIn, IWavePlayer

  • WaveIn 表示波形輸入, 繼承了 IWaveIn, 例如麥克風輸入, 或者計算機正在播放的音頻流.
  • WaveOut 表示波形輸出, 繼承了 IWavePlayer, 用來播放波形音樂, 以 IWaveProvider 作為播放源播放音頻, 通過拓展方法也支持以 ISampleProvider 作為播放源播放音頻
  • WaveStream 表示波形流, 它繼承了 IWaveProvider, 可以用來作為播放源.
  • WaveFileReader 繼承了 WaveStream, 用來讀取波形文件
  • WaveFileWriter 繼承了Stream, 用來寫入文件, 常用于保存音頻錄制的數(shù)據(jù).
  • AudioFileReader 通用的音頻文件讀取器, 可以讀取波形文件, 也可以讀取其他類型的音頻文件例如 Aiff, MP3
  • IWaveProvider 波形提供者, 上面已經(jīng)提到, 是音頻播放的提供者, 通過拓展方法可以轉(zhuǎn)換為 ISampleProvider
  • ISampleProvider 采樣提供者, 上面已經(jīng)提到, 通過拓展方法可以作為 WaveOut 的播放源

播放音頻

常用的播放音頻方式有兩種, 播放波形音樂, 以及播放 MP3 音樂

播放波形音樂:

// NAudio 中, 通過 WaveFileReader 來讀取波形數(shù)據(jù), 在實例化時, 你可以指定文件名或者是輸入流, 這意味著你可以讀取內(nèi)存流中的音頻數(shù)據(jù)
// 但是需要注意的是, 不可以讀取來自網(wǎng)絡流的音頻, 因為網(wǎng)絡流不可以進行 Seek 操作.

// 此處, 假設 ms 為一個 MemoryStream, 內(nèi)存有音頻數(shù)據(jù).
WaveFileReader reader = new WaveFileReader(ms);
WaveOut wout = new WaveOut();
wout.Init(reader);             // 通過 IWaveProvider 為音頻輸出初始化
wout.Play();                   // 至此, wout 將從指定的 reader 中提供的數(shù)據(jù)進行播放

播放 MP3 音樂:

// 播放 MP3 音樂其實與播放波形音樂沒有太大區(qū)別, 只不過將 WaveFileReader 換成了 Mp3FileReader 罷了
// 另外, 也可以使用通用的 Reader, MediaFoundationReader, 它既可以讀取波形音樂, 也可以讀取 MP3

// 此處, 假設 ms 為一個 MemoryStream, 內(nèi)存有音頻數(shù)據(jù).
Mp3FileReader reader = new Mp3FileReader(ms);
WaveOut wout = new WaveOut();
wout.Init(reader);
wout.Play();

音頻錄制

錄制麥克風輸入

// 借助 WaveIn 類, 我們可以輕易的捕獲麥克風輸入, 在每一次錄制到數(shù)據(jù)時, 將數(shù)據(jù)寫入到文件或其他流, 這就實現(xiàn)了保存錄音
// 在保存波形文件時需要借助 WaveFileWriter, 當然, 如果你想保存為其他格式, 也可以使用其它的 Writer, 例如 CurWaveFileWriter 以及
// AiffFileWriter, 美中不足的是沒有直接寫入到 MP3 的 FileWriter
// 需要注意的是, 如果你是用的桌面程序, 那么你可以直接使用 WaveIn, 其回調(diào)基于 Windows 消息, 所以無法在控制臺應用中使用 WaveIn
// 如果要在控制臺應用中實現(xiàn)錄音, 只需要使用 WaveInEvent, 它的回調(diào)基于事件而不是 Windows 消息, 所以可以通用

WaveIn cap = new WaveIn();   // cap, capture
WaveFileWriter writer = new WaveFileWriter();
cap.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded);    // 訂閱事件
cap.StartRecording();   // 開始錄制

// 結(jié)束錄制時:
cap.StopRecording();    // 停止錄制
writer.Close();         // 關閉 FileWriter, 保存數(shù)據(jù)

// 另外, 除了使用 WaveIn, 你還可以使用 WasapiCapture, 它與 WaveIn 的使用方式是一致的, 可以用來錄制麥克風
// Wasapi 全稱 Windows Audio Session Application Programming Interface (Windows音頻會話應用編程接口)
// 具體 WaveIn, WaveInEvent, WasapiCapture 的性能, 筆者還沒有測試過, 但估計不會有太大差異.
// 提示: WasapiCapture 和 WasapiLoopbackCapture 位于 NAudio.Wave 命名空間下

錄制聲卡輸出

// 錄制聲卡輸出, 也就是錄制計算機正在播放的聲音, 借助 WasapiLoopbackCapture 即可簡單實現(xiàn), 使用方式與 WasapiCapture 無異

WasapiLoopbackCapture cap = new WasapiLoopbackCapture();
WaveFileWriter writer = new WaveFileWriter();
cap.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded);
cap.StartRecording();

高級應用

獲取計算機實時播放音量大小

// 既然我們已經(jīng)知道了, 那些數(shù)據(jù)都是一個個的采樣, 自然也可以通過它們來繪制頻譜, 只需要進行快速傅里葉變換即可
// 而且有意思的是, NAudio 也為我們準備好了快速傅里葉變換的方法, 位于 NAudio.Dsp 命名空間下
// 提示: 進行傅里葉變換所需要的復數(shù)(Complex)類也位于 NAudio.Dsp 命名空間, 它有兩個字段, X(實部) 與 Y(虛部)
// 下面給出在 IeeeFloat 格式下的音樂可視化的簡單示例:
WasapiLoopbackCapture cap = new WasapiLoopbackCapture();
cap.DataAvailable += (s, args) =>
{
    float[] samples = Enumerable
                          .Range(0, args.BytesRecorded / 4)
                          .Select(i => BitConverter.ToSingle(args.Buffer, i * 4))
                          .ToArray();   // 獲取采樣
    
    int log = (int)Math.Ceiling(Math.Log(samples.Length, 2));
    float[] filledSamples = new float[(int)Math.Pow(2, log)];
    Array.Copy(samples, filledSamples, samples.Length);   // 填充數(shù)據(jù)
    
    int sampleRate = (s as WasapiLoopbackCapture).WaveFormat.SampleRate;    // 獲取采樣率
    Complex[] complexSrc = filledSamples.Select(v => new Complex(){ X = v }).ToArray();  // 轉(zhuǎn)換為復數(shù)
    FastFourierTransform.FFT(false, log, complexSrc);     // 進行傅里葉變換
    double[] result = complexSrc.Select(v => Math.Sqrt(v.X * v.X + v.Y * v.Y)).ToArray();    // 取得結(jié)果
};

音頻格式轉(zhuǎn)換

// 對于 Wave, CueWave, Aiff, 這些格式都有其對應的 FileWriter, 我們可以直接調(diào)用其 Writer 的 Create***File 來
// 從 IWaveProvider 創(chuàng)建對應格式的文件. 對于 MP3 這類沒有 FileWriter 的格式, 可以調(diào)用 MediaFoundationEncoder

// 例如一個文件, "./Disconnected.mp3", 我們要將它轉(zhuǎn)換為 wav 格式, 只需要使用下面的代碼, CurWave 與 Aiff 同理
using (Mp3FileReader reader = new Mp3FileReader("./Disconnected.mp3"))
	WaveFileWriter.CreateWaveFile("./Disconnected.wav", reader);

// 從 IWaveProvider 創(chuàng)建 MP3 文件, 假如一個 WaveFileReader 為 src
MediaFoundationEncoder.EncodeToMp3(src, "./NewMp3.mp3");

提示

對于剛剛所說的音頻錄制, 采樣的格式有一點需要注意, 將數(shù)據(jù)轉(zhuǎn)換為一個 float 數(shù)組后, 其中還需要區(qū)分音頻通道, 例如一般音樂是雙通道, WaveFormat 的 Channel 為 2, 那么在 float 數(shù)組中, 每兩個采樣為一組, 一組采樣中每一個采樣都是一個通道在當前時間內(nèi)的采樣.

以雙通道距離, 下圖中, 采樣數(shù)據(jù)中每一個圓圈都表示一個 float 值, 那么每兩個采樣時間點相同, 而各個通道的采樣就是每一組中每一個采樣

所以對于我們剛剛進行的音樂可視化, 嚴格意義上來講, 還需要區(qū)分通道

對于采樣的大小, BitsPerSample, 可以是 8, 16, 32, 其中 8 和 16 都是整數(shù)存儲采樣, 32 是浮點數(shù)存儲采樣.

另外, 對于音樂可視化部分的傅里葉變換結(jié)果, 我們只需要其中一部分, 取前 256 個足矣. (我也不知道它這個運算結(jié)果是如何分布的)

示例

本文提到的部分內(nèi)容在 github.com/SlimeNull/AudioTest 倉庫中有示例, 例如音頻可視化, 音頻錄制, 以及其他零星的示例

到此這篇關于C# NAudio 庫的各種常見使用方式之播放 錄制 轉(zhuǎn)碼 音頻可視化的文章就介紹到這了,更多相關C# NAudio 庫用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Unity實現(xiàn)聊天室功能

    Unity實現(xiàn)聊天室功能

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • C#刪除最后一個結(jié)尾逗號的方法

    C#刪除最后一個結(jié)尾逗號的方法

    這篇文章主要介紹了C#刪除最后一個結(jié)尾逗號的方法,涉及C#、操作字符串的技巧,簡單實用,非常具有實用價值,需要的朋友可以參考下
    2015-03-03
  • Http上傳與Ftp上傳的區(qū)別詳解

    Http上傳與Ftp上傳的區(qū)別詳解

    本篇文章是對Http上傳與Ftp上傳的區(qū)別進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C#線程開發(fā)之System.Thread類詳解

    C#線程開發(fā)之System.Thread類詳解

    本文詳細講解了C#線程開發(fā)之System.Thread類,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • async and await 的入門基礎操作

    async and await 的入門基礎操作

    本篇文章對async and await 的入門基礎操作進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Winform中進行MD5加密的實例

    Winform中進行MD5加密的實例

    下面小編就為大家?guī)硪黄猈inform中進行MD5加密的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • C#實現(xiàn)洗牌算法

    C#實現(xiàn)洗牌算法

    洗牌算法的要求是這樣的:將N個數(shù)亂序后輸出.由于和撲克牌的洗牌過程比較相似所以我也就稱為洗牌算法了.很多地方都不自覺的需要這個算法的支持.也可以將這個算法擴展為從N個數(shù)中取出M個不重復的數(shù)(0<M<=N).今天我們看下如何用C#來實現(xiàn)
    2015-03-03
  • C#?使用com獲取Windows攝像頭列表

    C#?使用com獲取Windows攝像頭列表

    本文主要介紹了C#?使用com獲取Windows攝像頭列表,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • C#使用晚綁定來實現(xiàn)壓縮Access數(shù)據(jù)庫的方法

    C#使用晚綁定來實現(xiàn)壓縮Access數(shù)據(jù)庫的方法

    這篇文章主要介紹了C#使用晚綁定來實現(xiàn)壓縮Access數(shù)據(jù)庫的方法,項目開發(fā)中有一定的實用價值,需要的朋友可以參考下
    2014-08-08
  • 解決安裝VS2008無法更改默認路徑的問題

    解決安裝VS2008無法更改默認路徑的問題

    這篇文章主要介紹了安裝VS2008無法更改默認路徑的解決方法,需要的朋友可以參考下。
    2016-06-06

最新評論