C#播放short或者byte類型的音頻
一、通過Nuget安裝NAudio包
開發(fā)工具:vs2019
點擊Visual Studio 2019的工具->NuGet包管理器-》管理解決方案的NuGet的程序包-》瀏覽-》在搜索框中輸入NAudio-》點擊安裝
二、獲取short類型或者byte類型的音頻數(shù)據(jù)
我的數(shù)據(jù)是一組short類型的正弦波信號,存儲在txt中,如下圖所示:
通過C#讀取文檔并存儲在short數(shù)組中
string filePath = "20500Left.txt"; // txt文件路徑 short[] audioData = new short[48000 * 2]; //雙聲道數(shù)據(jù) int index = 0; // 讀取txt文檔并按逗號分割文本 using (StreamReader reader = new StreamReader(filePath)) { string line; while ((line = reader.ReadLine()) != null) { string[] parts = line.Split(','); foreach (string part in parts) { //Console.WriteLine(part); audioData[index] = Convert.ToInt16(part); index++; } } }
將short變?yōu)閎yte類型的數(shù)據(jù)(如果本身你的音頻數(shù)據(jù)就是byte類型就不需要執(zhí)行下邊操作)
// 將short[]音頻數(shù)據(jù)轉(zhuǎn)換為byte[]數(shù)據(jù) byte[] byteData = new byte[audioData.Length * 2]; // short類型占2個字節(jié) Buffer.BlockCopy(audioData, 0, byteData, 0, byteData.Length);
三、循環(huán)播放自己的音頻數(shù)據(jù),重寫WaveStream類
主要是重寫了Read這個函數(shù),讀到數(shù)據(jù)流末尾,就從開頭讀取。
class LoopingWaveStream : WaveStream { private WaveStream sourceStream; public LoopingWaveStream(WaveStream sourceStream) { this.sourceStream = sourceStream; } public override WaveFormat WaveFormat => sourceStream.WaveFormat; public override long Length => sourceStream.Length; public override long Position { get => sourceStream.Position; set => sourceStream.Position = value; } public override int Read(byte[] buffer, int offset, int count) { int bytesRead = 0; while (bytesRead < count) { int read = sourceStream.Read(buffer, offset + bytesRead, count - bytesRead); if (read == 0) { // 如果讀取到末尾,重新從頭開始讀取 sourceStream.Position = 0; } bytesRead += read; } return bytesRead; } }
將上邊的byte類型的數(shù)據(jù)轉(zhuǎn)換為Stream類型,并填入WaveOut對象中,進行播放
// 創(chuàng)建內(nèi)存流 using (MemoryStream stream = new MemoryStream(byteData)) { // 從內(nèi)存流中創(chuàng)建RawSourceWaveStream //采樣率設(shè)置為48000,位深設(shè)置位16位,通道為雙聲道 RawSourceWaveStream rawStream = new RawSourceWaveStream(stream, new WaveFormat(48000, 16, 2)); LoopingWaveStream loopingWaveStream=new LoopingWaveStream(rawStream); // 使用WaveOutEvent播放音頻數(shù)據(jù) WaveOut waveOut = new WaveOut(); waveOut.Init(loopingWaveStream);//想要循環(huán)播放 //waveOut.Init(rawStream); //不想要循環(huán)播放 waveOut.Play(); //下邊兩種方式的循環(huán)播放會有爆音,不采用。 //waveOut.PlaybackStopped += (sender, e) => // { // if (waveOut.PlaybackState == PlaybackState.Stopped) // { // rawStream.Position = 0; // waveOut.Play(); // } // }; //while (waveOut.PlaybackState == PlaybackState.Playing) //{ // if (rawStream.Position >= rawStream.Length) // { // rawStream.Position = 0; // //Console.WriteLine("Audio stream reached the end."); // //break; // } //} Console.WriteLine("Press Enter to stop playback."); Console.ReadLine(); //阻塞線程 waveOut.Stop(); //停止播放 waveOut.Dispose(); }
四、完整代碼
using NAudio.Wave; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Media; using System.Text; using System.Threading.Tasks; namespace 播放short { class LoopingWaveStream : WaveStream { private WaveStream sourceStream; public LoopingWaveStream(WaveStream sourceStream) { this.sourceStream = sourceStream; } public override WaveFormat WaveFormat => sourceStream.WaveFormat; public override long Length => sourceStream.Length; public override long Position { get => sourceStream.Position; set => sourceStream.Position = value; } public override int Read(byte[] buffer, int offset, int count) { int bytesRead = 0; while (bytesRead < count) { int read = sourceStream.Read(buffer, offset + bytesRead, count - bytesRead); if (read == 0) { // 如果讀取到末尾,重新從頭開始讀取 sourceStream.Position = 0; } bytesRead += read; } return bytesRead; } } class Program { static void Main(string[] args) { Console.WriteLine("開始"); string filePath = "20500Left.txt"; // txt文件路徑 short[] audioData = new short[48000 * 2]; //雙聲道數(shù)據(jù) int index = 0; // 讀取txt文檔并按逗號分割文本 using (StreamReader reader = new StreamReader(filePath)) { string line; while ((line = reader.ReadLine()) != null) { string[] parts = line.Split(','); foreach (string part in parts) { //Console.WriteLine(part); audioData[index] = Convert.ToInt16(part); index++; } } } // 將short[]音頻數(shù)據(jù)轉(zhuǎn)換為byte[]數(shù)據(jù) byte[] byteData = new byte[audioData.Length * 2]; // short類型占2個字節(jié) Buffer.BlockCopy(audioData, 0, byteData, 0, byteData.Length); //方式1/// // 創(chuàng)建內(nèi)存流 using (MemoryStream stream = new MemoryStream(byteData)) { // 從內(nèi)存流中創(chuàng)建RawSourceWaveStream //采樣率設(shè)置為48000,位深設(shè)置位16位,通道為雙聲道 RawSourceWaveStream rawStream = new RawSourceWaveStream(stream, new WaveFormat(48000, 16, 2)); LoopingWaveStream loopingWaveStream=new LoopingWaveStream(rawStream); // 使用WaveOutEvent播放音頻數(shù)據(jù) WaveOut waveOut = new WaveOut(); waveOut.Init(loopingWaveStream);//想要循環(huán)播放 //waveOut.Init(rawStream); //不想要循環(huán)播放 waveOut.Play(); //下邊兩種方式的循環(huán)播放會有爆音,不采用。 //waveOut.PlaybackStopped += (sender, e) => // { // if (waveOut.PlaybackState == PlaybackState.Stopped) // { // rawStream.Position = 0; // waveOut.Play(); // } // }; //while (waveOut.PlaybackState == PlaybackState.Playing) //{ // if (rawStream.Position >= rawStream.Length) // { // rawStream.Position = 0; // //Console.WriteLine("Audio stream reached the end."); // //break; // } //} Console.WriteLine("Press Enter to stop playback."); Console.ReadLine(); //阻塞線程 waveOut.Stop(); //停止播放 waveOut.Dispose(); } } } }
以上就是C#播放short或者byte類型的音頻的詳細內(nèi)容,更多關(guān)于C#播放音頻的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#記一次http協(xié)議multipart/form-data的boundary問題
這篇文章主要介紹了C#記一次http協(xié)議multipart/form-data的boundary問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06C#設(shè)計模式編程中運用適配器模式結(jié)構(gòu)實戰(zhàn)演練
這篇文章主要介紹了C#設(shè)計模式編程中運用適配器模式結(jié)構(gòu)實戰(zhàn)演練,并總結(jié)了適配器模式的優(yōu)缺點和適用場景以及.NET框架中的應用,需要的朋友可以參考下2016-02-02C#使用CEFSharp獲取動態(tài)網(wǎng)頁源碼的演示步驟
CEFSharp是一個用C#編寫的庫,它是Chromium Embedded Framework (CEF) 的.NET封裝和擴展,CEF允許開發(fā)者在自己的應用程序中嵌入一個功能強大的HTML渲染引擎,從而能夠呈現(xiàn)網(wǎng)頁內(nèi)容,本文介紹了C#如何使用CEFSharp獲取動態(tài)網(wǎng)頁源碼,需要的朋友可以參考下2024-08-08C#結(jié)合JavaScript實現(xiàn)上傳視頻到騰訊云點播平臺的操作方法
這篇文章主要介紹了C#結(jié)合JavaScript實現(xiàn)上傳視頻到騰訊云點播平臺,上傳視頻功能,主要要解決兩個問題,一是在服務端通過C#生成簽名和SDKID,二是在客戶端通過JavaScript上傳視頻到騰訊云點播服務器,感興趣的朋友跟隨小編一起看看吧2023-11-11