简体   繁体   English

将 WasapiLoopbackCapture 缓冲区转换为 PCM

[英]Converting WasapiLoopbackCapture buffer to PCM

I am currently writing a Discord bot using D#+, that is supposed to send all audio that's coming through an output sound device to a voice channel.我目前正在使用 D#+ 编写 Discord 机器人,它应该将通过 output 声音设备发送到语音通道的所有音频。

Using NAudio, I can successfully capture the audio from a device, and my current code looks somewhat like this:使用 NAudio,我可以成功地从设备捕获音频,我当前的代码看起来有点像这样:

Capture.StartRecording(); // 'Capture' is a WasapiLoopbackCapture object
Capture.DataAvailable += async (s, a) =>
{
    await stream.WriteAsync(a.Buffer); // 'stream' is the transmit stream for the Discord connection
};

Unfortunaltey however, D#+ is very specific about requiring 16bit stereo PCM at a sample rate of 48000 Hz, which is not quite the same as the IEEE Floating Point format that the Wasapi Capture Buffer produces, as I found out through some reading.然而不幸的是,D#+ 非常具体地要求 16 位立体声 PCM 的采样率为 48000 Hz,这与 Wasapi Capture Buffer 产生的 IEEE 浮点格式并不完全相同,正如我通过阅读发现的那样。 So I know by now that I have to convert the buffer to said PCM format before being able to write it into the Transmit Stream.所以我现在知道我必须先将缓冲区转换为所述 PCM 格式,然后才能将其写入 Transmit Stream。

After some research, I found some articles like this one and questions on here like this one , that all generally seem to go into the right direction of what I want to achieve, but not quite , or at least I am too unskilled with audio processing to apply it properly and make it work.经过一番研究,我发现了一些类似this的文章和类似this one的问题,这一切似乎都朝着我想要实现的正确方向发展,但并不完全如此,或者至少我对音频处理不太熟练正确应用它并使其工作。

So my question is, essentially, how can I constantly convert the data that I get from the WasapiLoopbackCapture buffer into a new buffer with said PCM format?所以我的问题是,本质上,我怎样才能不断地将我从 WasapiLoopbackCapture 缓冲区获取的数据转换为具有所述 PCM 格式的新缓冲区? Any help is much appreciated!任何帮助深表感谢!

Thanks to @GoodNightNerdPride for pointing me to this issue on the NAudio GitHub Page.感谢@GoodNightNerdPride 在 NAudio GitHub 页面上向我指出这个问题 With the code snippets posted in there, I was able to write this method, which can convert the buffer from an WasapiLoopbackCapture object into 16bit PCM format.通过那里发布的代码片段,我能够编写此方法,该方法可以将缓冲区从 WasapiLoopbackCapture object 转换为 16 位 PCM 格式。

/// <summary>
/// Converts an IEEE Floating Point audio buffer into a 16bit PCM compatible buffer.
/// </summary>
/// <param name="inputBuffer">The buffer in IEEE Floating Point format.</param>
/// <param name="length">The number of bytes in the buffer.</param>
/// <param name="format">The WaveFormat of the buffer.</param>
/// <returns>A byte array that represents the given buffer converted into PCM format.</returns>
public byte[] ToPCM16(byte[] inputBuffer, int length, WaveFormat format)
{
    if (length == 0)
        return new byte[0]; // No bytes recorded, return empty array.

    // Create a WaveStream from the input buffer.
    using var memStream = new MemoryStream(inputBuffer, 0, length);
    using var inputStream = new RawSourceWaveStream(memStream, format);

    // Convert the input stream to a WaveProvider in 16bit PCM format with sample rate of 48000 Hz.
    var convertedPCM = new SampleToWaveProvider16(
        new WdlResamplingSampleProvider(
            new WaveToSampleProvider(inputStream),
            48000)
        );

    byte[] convertedBuffer = new byte[length];

    using var stream = new MemoryStream();
    int read;
            
    // Read the converted WaveProvider into a buffer and turn it into a Stream.
    while ((read = convertedPCM.Read(convertedBuffer, 0, length)) > 0)
        stream.Write(convertedBuffer, 0, read);

    // Return the converted Stream as a byte array.
    return stream.ToArray();
}

With this, streaming the audio captured via WasapiLoopbackCapture to Discord using D#+ is as simple as this:有了这个,使用 D#+ 将通过WasapiLoopbackCapture捕获的音频流式传输到 Discord 就像这样简单:

var stream = connection.GetTransmitSink();

Capture.StartRecording();
Capture.DataAvailable += async (s, a) =>
{
    await stream.WriteAsync(ToPCM16(a.Buffer, a.BytesRecorded, Capture.WaveFormat));
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM