C# 使用NAudio播放原始PCM(输出噪音,但打开时大胆)

C# 使用NAudio播放原始PCM(输出噪音,但打开时大胆),c#,.net,audio,naudio,pcm,C#,.net,Audio,Naudio,Pcm,我正在使用NAudio(1.7.1.17)WasapiLoopbackCapture,它工作正常,我可以使用以下格式在Audacity中打开保存的原始PCM: 调用以.NET 4 x86为目标的代码。该文件为10秒记录,总计为[3515904字节] 捕获: var device = WasapiLoopbackCapture.GetDefaultLoopbackCaptureDevice(); using (var capture = new WasapiLoopbackCapture(de

我正在使用NAudio(1.7.1.17)WasapiLoopbackCapture,它工作正常,我可以使用以下格式在Audacity中打开保存的原始PCM:

调用以.NET 4 x86为目标的代码。该文件为10秒记录,总计为[3515904字节]

捕获:

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.
}
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();
}
播放:

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.
}
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();
}
播放代码会产生最多一秒长的噪波。我仔细检查了字节顺序,除了大小(理想情况下应该是[3528000字节])之外,其他一切看起来都很好。我不确定这里是否存在填充问题,我需要能够在不预先知道完整大小的情况下流式传输此原始PCM数据


但首先要做的是。任何关于如何让NAudio播放此文件的提示都将不胜感激。

您的
波形编码需要是IEEE浮点编码,而不是PCM编码(目前是这样)


解决方案是将waveOut.Play()移动到单独的线程

此外,由于代码中有一个“using”语句,因此在播放完成之前,会处理播放所需的对象

首先,我会这样做:

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();
    }
}
公共部分类PlayPerform:表单
{
WaveOut WaveOut;
螺纹t;
文件流;
波形波形;
rawsourcewavestreamrawsource;
公共表格1()
{
初始化组件();
waveOut=新的waveOut();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
var file=newfileinfo(@“”);
stream=file.Open(FileMode.Open,FileAccess.Read,FileShare.Read);
waveFormat=新的waveFormat(16000,16,1);//格式相同。
rawSource=新NAudio.Wave.RawSourceWaveStream(流,波形);
waveOut.Init(rawSource);
t=新线程(新线程开始(播放));
t、 Start();
}
私人虚空游戏()
{
waveOut.Play();
}
}

当然,这不是最终的生产质量代码,因为它不考虑按钮被点击两次时发生的事情。

谢谢。已经有一段时间了,但我想知道是否有一种方式直接记录为PCM。没有听到IEEE浮动格式,直到您的答案。这是可能的任何驱动程序/协议。(WASAPI、ASIO等)?谢谢。虽然不是核心问题,但正如您所指出的,这确实是一个范围问题。