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

C#播放short或者byte類型的音頻

 更新時間:2024年12月23日 15:25:04   作者:rbigbearr  
這篇文章主要為大家詳細介紹了如何使用C#實現(xiàn)播放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)文章

  • Unity Blend Tree動畫混合樹使用入門教程

    Unity Blend Tree動畫混合樹使用入門教程

    這篇文章主要為大家詳細介紹了Unity Blend Tree動畫混合樹使用入門教程,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C#中的事件介紹

    C#中的事件介紹

    這篇文章主要介紹了C#中的事件介紹,本文對C#事件的語法、定義方法、調(diào)用方法等做了講解,需要的朋友可以參考下
    2015-01-01
  • WPF中引入WindowsForms控件的方法

    WPF中引入WindowsForms控件的方法

    這篇文章主要介紹了WPF中引入WindowsForms控件的方法,結(jié)合實例形式分析了在WPF中調(diào)用Windows Forms控件的具體步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2016-07-07
  • C#記一次http協(xié)議multipart/form-data的boundary問題

    C#記一次http協(xié)議multipart/form-data的boundary問題

    這篇文章主要介紹了C#記一次http協(xié)議multipart/form-data的boundary問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • VS2015 C#生成dll文件的方法(32/64)

    VS2015 C#生成dll文件的方法(32/64)

    這篇文章主要介紹了VS2015 C#生成dll文件的方法(32/64),需要的朋友可以參考下
    2016-12-12
  • C#設(shè)計模式編程中運用適配器模式結(jié)構(gòu)實戰(zhàn)演練

    C#設(shè)計模式編程中運用適配器模式結(jié)構(gòu)實戰(zhàn)演練

    這篇文章主要介紹了C#設(shè)計模式編程中運用適配器模式結(jié)構(gòu)實戰(zhàn)演練,并總結(jié)了適配器模式的優(yōu)缺點和適用場景以及.NET框架中的應用,需要的朋友可以參考下
    2016-02-02
  • C#使用CEFSharp獲取動態(tài)網(wǎng)頁源碼的演示步驟

    C#使用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-08
  • C#結(jié)合JavaScript實現(xiàn)上傳視頻到騰訊云點播平臺的操作方法

    C#結(jié)合JavaScript實現(xiàn)上傳視頻到騰訊云點播平臺的操作方法

    這篇文章主要介紹了C#結(jié)合JavaScript實現(xiàn)上傳視頻到騰訊云點播平臺,上傳視頻功能,主要要解決兩個問題,一是在服務端通過C#生成簽名和SDKID,二是在客戶端通過JavaScript上傳視頻到騰訊云點播服務器,感興趣的朋友跟隨小編一起看看吧
    2023-11-11
  • C#連接Informix數(shù)據(jù)庫的問題

    C#連接Informix數(shù)據(jù)庫的問題

    這篇文章主要介紹了C#連接Informix數(shù)據(jù)庫的問題,本文給大家介紹的非常詳細,對大家的工作或?qū)W習具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • C# 10分鐘完成百度人臉識別(入門篇)

    C# 10分鐘完成百度人臉識別(入門篇)

    這篇文章主要介紹了C# 10分鐘完成百度人臉識別(入門篇),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-02-02

最新評論