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)文章
WPF利用TextBlock實現(xiàn)查找結(jié)果高亮顯示效果
在應(yīng)用開發(fā)過程中,經(jīng)常遇到這樣的需求:通過關(guān)鍵字查找數(shù)據(jù),把帶有關(guān)鍵字的數(shù)據(jù)顯示出來,同時在結(jié)果中高亮顯示關(guān)鍵字,所以本文就來和大家介紹一下如何利用TextBlock實現(xiàn)查找結(jié)果高亮顯示效果吧2023-08-08
C# Winform實現(xiàn)表格復(fù)制粘貼效果
這篇文章主要為大家學習介紹了如何通過C# Winform實現(xiàn)表格復(fù)制粘貼效果,文中的示例代碼講解詳細,具有一定的參考價值,需要的可以了解一下2023-07-07

