c# - NAudio Wasapi录音和转换

标签 c# mono naudio wasapi

我正在使用 NAudio 并尝试使用 WasapiLoopbackCapture 记录我的电脑上正在播放的内容。我遇到的问题是我需要将录制的数据作为 PCM 16bit 44100khz Mono。 为此,我构建了这个:

using System;
using System.Diagnostics;

using NAudio.Wave;
using NAudio.CoreAudioApi;

namespace soundtest
{
    class Program {

        static void Main(string[] args) {
            try {
                var deviceToRecord = (new MMDeviceEnumerator().EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active))[0];

                var recorder = new CustomWasapiLoopbackCapture(deviceToRecord, false, 1000 / 5);
                recorder.ShareMode = AudioClientShareMode.Shared;
                recorder.DataAvailable += recorderDataAvailable;

                var inprov = new WaveInProvider(recorder);
                var fto16prov = new WaveFloatTo16Provider(inprov);
                var stomprov = new StereoToMonoProvider16(fto16prov);

                Console.WriteLine("Press something to stop recording.");
                recorder.StartRecording();
                Console.ReadKey();
                recorder.StopRecording();

            } catch (Exception e) {
                Console.WriteLine("!!! EXCEPTION !!!" + 
                    "\nMessage:\n   " + e.Message + 
                    "\nSource:\n   " + e.Source + 
                    "\nStack:\n" + e.StackTrace);
            }

            Console.WriteLine("Press something to close.");
            Console.ReadKey();
        }

        static void recorderDataAvailable(object sender, WaveInEventArgs args) {
            // how do I access PCM 16bit here?
            // It's not args.Buffer, or am I wrong?
            // additional calculation is done here with the PCM data
        }
    }


    class CustomWasapiLoopbackCapture : WasapiCapture
    {
        public CustomWasapiLoopbackCapture() 
            : this(GetDefaultLoopbackCaptureDevice()){ }
        public CustomWasapiLoopbackCapture(MMDevice captureDevice)
            : this(captureDevice, false){ }
        public CustomWasapiLoopbackCapture(MMDevice captureDevice, bool useEventSync)
            : this(captureDevice, useEventSync, 100){ }
        public CustomWasapiLoopbackCapture(MMDevice captureDevice, bool useEventSync, int audioBufferMillisecondsLength)
            : base(captureDevice, useEventSync, audioBufferMillisecondsLength){ }

        public static MMDevice GetDefaultLoopbackCaptureDevice() {
            MMDeviceEnumerator devices = new MMDeviceEnumerator();
            return devices.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
        }

        public override WaveFormat WaveFormat
        {
            get { return base.WaveFormat; }
            set { throw new InvalidOperationException("WaveFormat cannot be set for WASAPI Loopback Capture"); }
        }

        protected override AudioClientStreamFlags GetAudioClientStreamFlags() {
            return AudioClientStreamFlags.Loopback;
        }
    }
}

如何访问转换后的录音?我认为通过添加这些提供者我可以获得数据以进行进一步计算。我认为 args.Buffer 未提供预期的 PCM 16 位 44100 kHz 单声道数据的假设来自于我在 recorderDataAvailable 方法中进行的附加处理的不切实际的结果。我在混音器板的另一个输入上使用简单的 WaveInEvent 对此进行了测试,并用它循环播放声音。

最佳答案

WASAPI 始终将音频记录为 IEEE 浮点样本。因此,在回调中获得的记录缓冲区中,每 4 个字节都是一个 float。访问单个示例的简单方法是使用 BitConverter.ToSingle。这将为您提供 +/- 1.0 范围内的值。因此乘以 32767,然后转换为 Int16 将其转换为 16 位样本值。

关于c# - NAudio Wasapi录音和转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45535659/

相关文章:

image - 使用 mvvmcross 和 mono touch 将照片上传到网络服务

c# - NAudio PlaybackState 永不停止?

c# - 从 WaveStream 将 2 channel 样本读入数组的最简单方法

c# - 引用的库未被复制

c# - Visual Studio 2012 部分发布

c# - roslyn 编译器未使用 msbuild 复制到 AspnetCompileMerge 文件夹

javascript - 如何在ASP MVC中使用sweet Alert确认用户数据的编辑

c# - 在单声道上获取带有转义斜杠的 Uri

c# - 在Linux上为Windows服务器开发asp.net应用程序

c# - 使用 NAudio 播放自定义文件格式