C# 实现语音预处理:降噪、静音检测、自动增益(含完整Demo源码)

181 阅读4分钟

前言

在现代音视频系统中,无论是音视频录制、实时通话还是视频会议,语音信号的质量直接影响用户体验。从麦克风采集到的声音往往包含背景噪声、音量不均等问题,因此对语音进行预处理是提升音频质量的关键环节。

本文将介绍如何使用 C# 实现一个简单的语音预处理模块,涵盖 降噪(Noise Reduction)静音检测(VAD)自动增益控制(AGC) 三大核心功能,并提供完整的 Demo 源码供学习和实践。

一、语音预处理的作用

语音预处理主要包括三个核心功能:

1、降噪(Noise Reduction)

用于消除背景噪声,如环境杂音、风扇声、键盘敲击声等,以保留清晰的人声。

2、静音检测(Silence Detection / VAD)
又称语音活动检测,用于识别音频流中的静音片段,从而减少无效数据传输,节省带宽资源。

3、自动增益控制(Automatic Gain Control, AGC)

动态调整语音音量,使输出电平保持稳定,避免声音忽大忽小。

这些处理对于提高语音识别准确率、增强通话质量、优化编码效率等方面具有重要意义。

二、实现语音预处理

接下来我们使用 C# 实现一个语音预处理的 Demo,该程序可以从麦克风采集声音,经过降噪、静音检测和自动增益处理后,再实时播放出来。

1、创建采集器、预处理器、播放器

首先设置采样率为 16KHz、单声道,并创建相应的组件对象:

WaveSampleRate sr = WaveSampleRate.S16k;
int channelCount = 1;

// 创建语音预处理器,开启降噪、自动增益、静音检测
this.voicePreprocessor = CapturerFactory.CreateVoicePreprocessor(sr, channelCount, true ,true);

// 创建麦克风采集器
this.microphoneCapturer = CapturerFactory.CreateMicrophoneCapturer(int.Parse(this.textBox_mic.Text), sr);
this.microphoneCapturer.AudioCaptured += new ESBasic.CbGeneric<byte[]>(microphoneCapturer_AudioCaptured);

// 创建声音播放器
this.audioPlayer = PlayerFactory.CreateAudioPlayer(int.Parse(this.textBox_speaker.Text), (int)sr, channelCount, 16, 2);                

this.microphoneCapturer.Start();

CreateVoicePreprocessor 方法的最后两个参数分别表示是否启用静音检测和自动增益功能。

2、预处理语音数据

由于语音预处理器每次处理 10ms 的数据帧,而麦克风采集的是 20ms 的 PCM 数据,因此需要将采集的数据拆分为两帧处理:

void microphoneCapturer_AudioCaptured(byte[] audioData)
{
    if (this.checkBox_enabled.Checked)
    {
        // 麦克风每次采集20ms数据,降噪器每次处理10ms数据。
        byte[] frame10ms1 = new byte[audioData.Length / 2];
        byte[] frame10ms2 = new byte[audioData.Length / 2];
        Buffer.BlockCopy(audioData, 0, frame10ms1, 0, frame10ms1.Length);
        Buffer.BlockCopy(audioData, frame10ms1.Length, frame10ms2, 0, frame10ms2.Length);
        this.HandleData(frame10ms1);
        this.HandleData(frame10ms2);
        return;
    }

    this.audioPlayer.Play(audioData);
}

通过 CheckBox 控制是否启用语音预处理,便于对比测试效果。

3、处理每帧语音数据

调用 IVoicePreprocessor.Process() 方法进行语音处理:

private void HandleData(byte[] frame10ms)
{
    byte[] res = this.voicePreprocessor.Process(frame10ms);            
    if (res == null) // 静音帧
    {
        ++this.silenceFrameCountTotal;
        this.audioPlayer.Play(this.voicePreprocessor.SlienceFrame);
    }
    else
    {
        this.audioPlayer.Play(res);
    }
}

若返回 null,则说明当前为静音帧,播放内置的静音帧即可。

4、统计静音帧数量

为了直观展示静音检测效果,我们统计每秒内的静音帧数并在 UI 中显示:

private volatile int silenceFrameCountTotal = 0;
private volatile int silenceFrameCountPre = 0;

private void timer1_Tick(object sender, EventArgs e)
{
    int delt = this.silenceFrameCountTotal - this.silenceFrameCountPre;
    this.silenceFrameCountPre = this.silenceFrameCountTotal;
    // 显示上一秒静音帧数量
    this.label_silenceFrameCount.Text = delt.ToString();
}

当用户未说话时,每秒钟可检测到约 100 个静音帧,与理论值一致。

三、源码下载

演示截图如下:

完整 Demo 源码已开源,欢迎下载体验:

dl.oraycn.com/DownLoadFil…

使用建议

  • 直接运行 Debug 目录下的 Oraycn.VoicePreprocessDemo.exe 即可运行程序;

  • 推荐使用耳麦测试,效果更明显;

  • 开启预处理后,能明显感受到背景噪音消失,人声更清晰,且无讲话时静音帧数量增加。

总结

本文介绍了语音预处理的三大核心功能:降噪、静音检测和自动增益控制,并通过一个 C# 编写的 Demo 展示了其实现方式。该方案适用于各种语音通信或语音识别场景,具备良好的实用性和扩展性。

通过本项目的学习,开发者不仅可以掌握语音处理的基本原理,还能了解如何在实际工程中应用相关技术。希望这篇文章能帮助你快速入门语音信号处理领域。

关键词

语音预处理、降噪、静音检测、自动增益、C#、Demo源码、语音处理、AGC、VAD、音视频开发

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:搬砖工具人

出处:cnblogs.com/wangshunyun/p/16463258.html

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!