You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于C#与NAudio实现音频输入设备实时监听播放功能

C# 使用NAudio实现麦克风实时监听及多通道扩展方案

1. 先解决NAudio引用问题

  • 右键项目 → 选择「管理NuGet程序包」,搜索NAudio安装最新稳定版
  • 或者打开Package Manager控制台,执行命令:Install-Package NAudio

2. 基础版:单麦克风实时监听播放

创建Windows Forms项目,拖入一个按钮(命名为btnStartStop),编写以下代码:

窗体类全局变量声明

using NAudio.Wave;
using System.Windows.Forms;

public partial class MainForm : Form
{
    private WaveInEvent _micInput;
    private WaveOutEvent _speakerOutput;
    private bool _isListening = false;

    public MainForm()
    {
        InitializeComponent();
    }
}

按钮点击事件逻辑

private void btnStartStop_Click(object sender, EventArgs e)
{
    if (!_isListening)
    {
        // 初始化输入输出设备
        _micInput = new WaveInEvent();
        _speakerOutput = new WaveOutEvent();

        // 设置统一音频格式(输入输出必须匹配)
        var audioFormat = new WaveFormat(44100, 16, 2); // 44.1kHz、16位、立体声
        _micInput.WaveFormat = audioFormat;
        _speakerOutput.Init(_micInput);

        // 麦克风数据实时传递给扬声器播放
        _micInput.DataAvailable += (s, args) =>
        {
            _speakerOutput.Write(args.Buffer, 0, args.BytesRecorded);
        };

        // 启动监听
        _micInput.StartRecording();
        _speakerOutput.Play();
        _isListening = true;
        btnStartStop.Text = "停止监听";
    }
    else
    {
        // 停止并释放资源,避免内存泄漏
        _micInput.StopRecording();
        _speakerOutput.Stop();
        _micInput.Dispose();
        _speakerOutput.Dispose();
        _isListening = false;
        btnStartStop.Text = "开始监听";
    }
}

窗体关闭时的资源清理

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (_isListening)
    {
        _micInput.StopRecording();
        _speakerOutput.Stop();
    }
    _micInput?.Dispose();
    _speakerOutput?.Dispose();
}

可选:让用户预选输入设备

如果需要让用户选择特定麦克风,在窗体加载时获取设备列表:

private void MainForm_Load(object sender, EventArgs e)
{
    var deviceSelector = new ComboBox(); // 拖一个ComboBox到窗体
    for (int i = 0; i < WaveIn.DeviceCount; i++)
    {
        var deviceInfo = WaveIn.GetCapabilities(i);
        deviceSelector.Items.Add($"{i}: {deviceInfo.ProductName}");
    }
    deviceSelector.SelectedIndex = 0; // 默认选中第一个设备
}

// 初始化WaveIn时设置设备编号:
// _micInput.DeviceNumber = deviceSelector.SelectedIndex;

3. 后续扩展:多通道输入混合播放

要实现多个麦克风同时输出到扬声器,使用NAudio的MixingSampleProvider完成音频流混合:

核心代码示例

private List<WaveInEvent> _multiMicList = new List<WaveInEvent>();
private WaveOutEvent _multiSpeakerOutput;
private MixingSampleProvider _audioMixer;

// 启动多麦克风监听
private void StartMultiListening()
{
    var targetFormat = new WaveFormat(44100, 16, 2);
    _audioMixer = new MixingSampleProvider(targetFormat.ToSampleProvider().WaveFormat);
    _audioMixer.ReadFully = true; // 确保读取所有输入数据完成混合

    // 假设有两个麦克风设备,编号为0和1
    foreach (int deviceNum in new[] {0, 1})
    {
        var micInput = new WaveInEvent();
        micInput.DeviceNumber = deviceNum;
        micInput.WaveFormat = targetFormat;
        
        // 将麦克风输入转换为SampleProvider,添加到混音器
        var sampleProvider = micInput.ToSampleProvider();
        _audioMixer.AddMixerInput(sampleProvider);
        
        micInput.StartRecording();
        _multiMicList.Add(micInput);
    }

    // 将混音后的流转换为WaveProvider,供扬声器播放
    var mixedWaveProvider = _audioMixer.ToWaveProvider();
    _multiSpeakerOutput = new WaveOutEvent();
    _multiSpeakerOutput.Init(mixedWaveProvider);
    _multiSpeakerOutput.Play();
}

// 停止多麦克风监听
private void StopMultiListening()
{
    foreach (var mic in _multiMicList)
    {
        mic.StopRecording();
        mic.Dispose();
    }
    _multiSpeakerOutput.Stop();
    _multiSpeakerOutput.Dispose();
    _multiMicList.Clear();
}

扩展注意事项

  • 所有输入设备的音频格式必须和混音器目标格式一致,格式不匹配时可使用ResamplerDmoSampleProvider进行转换
  • 多输入叠加可能导致音量失真,可给每个SampleProvider添加VolumeSampleProvider单独调节音量

内容的提问来源于stack exchange,提问作者TTACsniper1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:45:28