我正在使用NAudio(1.7.1.17)WasapiLoopbackCapture工作正常,我可以使用以下格式在Audacity中打开保存的原始PCM:
调用面向.NET 4 x86的代码。该文件是一个10秒的记录总共[3,515,904字节]。
CAPTURE:
var device = WasapiLoopbackCapture.GetDefaultLoopbackCaptureDevice();
using (var capture = new WasapiLoopbackCapture(device))
{
capture.ShareMode = AudioClientShareMode.Shared;
capture.DataAvailable += WasapiCapture_DataAvailable;
capture.RecordingStopped += WasapiCapture_RecordingStopped;
// Verified that [capture.WaveFormat] is [44.1KHz, 32 bit 2 ch].
capture.StartRecording();
Thread.Sleep(TimeSpan.FromSeconds(10));
capture.StopRecording();
}
private void WasapiCapture_DataAvailable (object sender, WaveInEventArgs e)
{
// Write [e.BytesRecorded] number of bytes from [e.Buffer] to a file.
}
private void WasapiCapture_RecordingStopped (object sender, StoppedEventArgs e)
{
// Verified that e.Exception was null.
}
PLAYBACK:
var file = new FileInfo(/* Same file that was just recorded. */);
using (var stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
{
var waveOut = new WaveOut();
var waveFormat = new WaveFormat(44100, 32, 2); // Same format.
var rawSource = new RawSourceWaveStream(stream, waveFormat);
waveOut.Init(rawSource);
waveOut.Play();
}
播放代码会产生最多一秒钟的噪音。我仔细检查了字节顺序,除了大小(理想情况下应该是[3,528,000字节])之外,一切看起来都很好。我不确定填充是否是这里的问题我需要能够在不知道的情况下传输这个原始PCM数据提前全尺寸。
但首先要做的事情。关于如何让NAudio播放这个文件的任何指示都将不胜感激。
答案 0 :(得分:5)
您的WaveFormat
编码需要是IEEE浮动而不是PCM(它当前是)
WaveFormat.CreateIeeeFloatWaveFormat(44100,2)
答案 1 :(得分:1)
解决方案是将waveOut.Play()移动到一个单独的线程。
此外,因为你有"使用"在代码中声明,播放所需的对象在播放完成之前处理。
对于初学者,我会这样做:
public partial class PlayerForm: Form
{
WaveOut waveOut;
Thread t;
FileStream stream;
WaveFormat waveFormat;
RawSourceWaveStream rawSource;
public Form1()
{
InitializeComponent();
waveOut = new WaveOut();
}
private void button1_Click(object sender, EventArgs e)
{
var file = new FileInfo(@"<your file here>");
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
waveFormat = new WaveFormat(16000,16,1); // Same format.
rawSource = new NAudio.Wave.RawSourceWaveStream(stream, waveFormat);
waveOut.Init(rawSource);
t = new Thread(new ThreadStart(Play));
t.Start();
}
private void Play()
{
waveOut.Play();
}
}
当然,这不是最终的生产质量代码,因为它没有考虑按两次按钮时会发生什么。