三、核心引擎层------音频引擎
1. 音频引擎概述
音频引擎是WebRTC的核心模块之一,位于核心模块层(位于API层和底层实现层之间),负责处理所有音频相关的事务。它集成了先进的音频处理技术,包括编解码、回声消除、降噪、静音检测等,确保音频在实时通信中的高质量传输。
它包含以下关键组件:
- 音频编解码器:iSAC、iLBC、Opus等
- 音频处理模块:AEC(回声消除)、AGC(自动增益)、NS(降噪)、VAD(静音检测)
- 网络适应模块:NetEQ(自适应抖动控制算法和语音包丢失隐藏算法)
2. 关键源码文件及作用
音频引擎的核心代码位于webrtc/modules/audio_processing目录下,以下是关键文件及其作用:
2.1 audio_processing.h 和 audio_processing_impl.h
cpp
// webrtc/modules/audio_processing/audio_processing.h
// 音频处理模块的接口类,提供音频处理功能的公共接口
class AudioProcessing {
public:
// 初始化音频处理模块
virtual int Initialize() = 0;
// 设置回声消除
virtual int set_echo_cancellation(bool enable) = 0;
// 设置降噪
virtual int set_noise_suppression(bool enable) = 0;
// 处理音频数据
virtual int ProcessAudio(AudioFrame* audio_frame) = 0;
// 其他音频处理功能
virtual int set_volume(AutoGainControl* agc) = 0;
virtual int set_voice_detection(bool enable) = 0;
};
作用:定义音频处理的公共接口,是音频处理模块的抽象层,实现对音频数据的处理。
2.2 echo_cancellation.h 和 echo_cancellation_impl.h
cpp
// webrtc/modules/audio_processing/echo_cancellation.h
// 回声消除模块的接口类
class EchoCancellation {
public:
// 初始化回声消除
virtual int Initialize() = 0;
// 启用/禁用回声消除
virtual int enable(bool enable) = 0;
// 处理音频数据
virtual int Process(const AudioFrame* input, AudioFrame* output) = 0;
// 设置回声消除参数
virtual int set_routing_mode(EchoCancellation::RoutingMode mode) = 0;
};
作用 :实现回声消除功能,通过频域分块处理,利用FftManager类进行高效的FFT变换,实时消除因扬声器声音被麦克风再次拾取而产生的回声。
2.3 noise_suppression.h 和 noise_suppression_impl.h
cpp
// webrtc/modules/audio_processing/noise_suppression.h
// 降噪模块的接口类
class NoiseSuppression {
public:
// 初始化降噪
virtual int Initialize() = 0;
// 设置降噪级别
virtual int set_level(Level level) = 0;
// 处理音频数据
virtual int Process(const AudioFrame* input, AudioFrame* output) = 0;
// 设置降噪模式
virtual int set_mode(Mode mode) = 0;
};
作用:实现降噪功能,去除背景噪声,提升语音的纯净度,包括消除嘶嘶声、风扇噪音等。
2.4 neteq.h 和 neteq_impl.h
cpp
// webrtc/modules/audio_processing/neteq.h
// 网络适应模块的接口类
class NetEq {
public:
// 初始化网络适应
virtual int Initialize() = 0;
// 添加音频数据包
virtual int InsertPacket(const uint8_t* payload, size_t payload_length,
uint32_t timestamp) = 0;
// 获取解码后的音频数据
virtual int GetAudio(AudioFrame* audio_frame) = 0;
// 处理丢包
virtual int ProcessPacketLoss() = 0;
};
作用:实现网络适应功能,包括抖动缓冲(Jitter Buffer)平滑网络抖动,丢包隐藏(PLC)以插值或预测算法生成缺失的音频数据,时间戳调整同步音频流与播放时钟。
2.5 voice_engine.h 和 voice_engine_impl.h
cpp
// webrtc/modules/voice_engine/voice_engine.h
// 语音引擎的主接口类
class VoiceEngine {
public:
// 创建语音引擎实例
static VoiceEngine* Create();
// 销毁语音引擎实例
virtual void Destroy() = 0;
// 获取音频处理模块
virtual AudioProcessing* audio_processing() = 0;
// 获取音频编解码器
virtual AudioEncoder* audio_encoder() = 0;
// 获取音频解码器
virtual AudioDecoder* audio_decoder() = 0;
// 音频数据处理
virtual int ProcessAudio(const AudioFrame* input, AudioFrame* output) = 0;
};
作用:语音引擎是音频处理的总控模块,管理音频处理的整个流程,协调音频处理、编解码和网络适应等子模块。
3. 音频引擎在整个系统中的作用
音频引擎在WebRTC架构中扮演着关键角色:
- 音频质量保障:通过AEC、NS、AGC等技术提升音频质量
- 网络适应性:通过NetEQ处理网络抖动和丢包,确保音频流畅播放
- 带宽优化:通过Opus等编解码器优化带宽使用,适应不同网络条件
- 实时处理:处理音频数据的实时性,确保低延迟通信
WebRTC的音频网络对抗同时体现在发送端和接收端:
- 发送端:通过Opus编解码器和QoS模块实现网络适应
- 接收端:通过NetEQ模块处理抖动、丢包和延迟
4. 与其他模块的交互
4.1 与媒体引擎(MediaEngine)的交互
核心引擎层 音频引擎 媒体引擎 核心引擎层 音频引擎 媒体引擎 获取音频数据 传递原始音频数据 处理音频(AEC, NS, VAD等) 返回处理后的音频数据 返回处理后的音频数据
音频引擎与媒体引擎紧密交互,媒体引擎负责音频数据的采集和渲染,音频引擎负责对采集的音频数据进行处理。
4.2 与网络传输模块的交互
核心引擎层 音频引擎 网络传输模块 核心引擎层 音频引擎 网络传输模块 编码后的音频数据 发送编码后的音频数据 接收编码后的音频数据 传递接收的音频数据 解码并处理音频数据 返回处理后的音频数据
音频引擎与网络传输模块交互,将处理后的音频数据交给网络传输模块进行发送,同时从网络传输模块接收接收到的音频数据。
4.3 与ICE/STUN模块的交互
核心引擎层 音频引擎 ICE/STUN模块 核心引擎层 音频引擎 ICE/STUN模块 获取网络信息 返回网络信息 传递网络信息 优化音频传输
音频引擎通过ICE/STUN获取网络信息,优化音频传输参数,确保在不同网络条件下都能获得良好的音频体验。
5. 音频引擎工作流程
5.1 音频处理流程
原始音频数据
音频处理模块
回声消除
降噪
静音检测
处理后的音频数据
音频编解码
编码后的音频数据
网络传输
5.2 音频编解码流程
原始音频数据
音频编码器
编码后的音频数据
网络传输
音频解码器
解码后的音频数据
音频处理
播放的音频
5.3 音频网络适应流程
接收到的编码音频数据
网络适应模块
抖动缓冲
丢包隐藏
处理后的音频数据
音频解码器
播放的音频
6. 源码示例
6.1 音频处理流程(AudioProcessing)
cpp
// webrtc/modules/audio_processing/audio_processing_impl.cc
// 音频处理实现类
class AudioProcessingImpl : public AudioProcessing {
public:
AudioProcessingImpl() :
echo_cancellation_(EchoCancellation::Create()),
noise_suppression_(NoiseSuppression::Create()),
voice_detection_(VoiceDetection::Create()) {
// 初始化各音频处理模块
echo_cancellation_->Initialize();
noise_suppression_->Initialize();
voice_detection_->Initialize();
}
int ProcessAudio(AudioFrame* audio_frame) override {
// 1. 回声消除
echo_cancellation_->Process(audio_frame, audio_frame);
// 2. 降噪
noise_suppression_->Process(audio_frame, audio_frame);
// 3. 静音检测
voice_detection_->Process(audio_frame);
// 4. 返回处理后的音频帧
return 0;
}
private:
std::unique_ptr<EchoCancellation> echo_cancellation_;
std::unique_ptr<NoiseSuppression> noise_suppression_;
std::unique_ptr<VoiceDetection> voice_detection_;
};
AudioProcessingImpl是音频处理模块的实现类- 通过组合模式管理多个音频处理子模块
ProcessAudio()方法处理音频数据的完整流程
6.2 音频编解码流程(VoiceEngine)
cpp
// webrtc/modules/voice_engine/voice_engine_impl.cc
// 语音引擎实现类
class VoiceEngineImpl : public VoiceEngine {
public:
VoiceEngineImpl() :
audio_processing_(AudioProcessing::Create()),
audio_encoder_(AudioEncoder::Create()),
audio_decoder_(AudioDecoder::Create()) {
// 初始化音频处理、编码和解码模块
audio_processing_->Initialize();
audio_encoder_->Initialize();
audio_decoder_->Initialize();
}
int ProcessAudio(const AudioFrame* input, AudioFrame* output) {
// 1. 处理输入音频
audio_processing_->ProcessAudio(const_cast<AudioFrame*>(input));
// 2. 编码音频
if (audio_encoder_->Encode(input, output) != 0) {
return -1;
}
// 3. 返回编码后的音频
return 0;
}
int DecodeAudio(const AudioFrame* input, AudioFrame* output) {
// 1. 解码音频
if (audio_decoder_->Decode(input, output) != 0) {
return -1;
}
// 2. 处理输出音频
audio_processing_->ProcessAudio(output);
// 3. 返回处理后的音频
return 0;
}
private:
std::unique_ptr<AudioProcessing> audio_processing_;
std::unique_ptr<AudioEncoder> audio_encoder_;
std::unique_ptr<AudioDecoder> audio_decoder_;
};
VoiceEngineImpl是语音引擎的实现类ProcessAudio()处理音频发送流程DecodeAudio()处理音频接收流程- 通过
audio_processing_统一处理音频
6.3 网络适应流程(NetEq)
cpp
// webrtc/modules/audio_processing/neteq_impl.cc
// 网络适应实现类
class NetEqImpl : public NetEq {
public:
NetEqImpl() :
jitter_buffer_(JitterBuffer::Create()),
packet_buffer_(PacketBuffer::Create()),
fec_decoder_(FecDecoder::Create()) {
// 初始化网络适应模块
jitter_buffer_->Initialize();
packet_buffer_->Initialize();
fec_decoder_->Initialize();
}
int InsertPacket(const uint8_t* payload, size_t payload_length,
uint32_t timestamp) override {
// 1. 将数据包插入缓冲区
packet_buffer_->InsertPacket(payload, payload_length, timestamp);
// 2. 处理抖动
jitter_buffer_->ProcessPacket(packet_buffer_->GetPacket());
// 3. 处理丢包
if (packet_buffer_->IsPacketMissing()) {
fec_decoder_->RecoverPacket(packet_buffer_->GetMissingPacket());
}
return 0;
}
int GetAudio(AudioFrame* audio_frame) override {
// 1. 从抖动缓冲区获取音频
if (jitter_buffer_->GetAudio(audio_frame) != 0) {
return -1;
}
// 2. 返回处理后的音频帧
return 0;
}
private:
std::unique_ptr<JitterBuffer> jitter_buffer_;
std::unique_ptr<PacketBuffer> packet_buffer_;
std::unique_ptr<FecDecoder> fec_decoder_;
};
NetEqImpl是网络适应模块的实现类InsertPacket()处理接收到的数据包GetAudio()提供处理后的音频数据- 通过
jitter_buffer_、packet_buffer_、fec_decoder_实现网络适应功能
7. 时序图:音频引擎工作流程
Network 音频引擎 核心引擎层 API层 应用层 Network 音频引擎 核心引擎层 API层 应用层 创建RTCPeerConnection 初始化VoiceEngine 创建音频引擎实例 初始化音频处理模块 初始化完成 返回音频引擎实例 返回音频引擎实例 添加本地音频流 获取音频数据 处理原始音频数据 回声消除 降噪处理 静音检测 音频编码 返回编码后的音频数据 发送编码后的音频数据 接收编码后的音频数据 传递接收的音频数据 音频解码 处理解码后的音频 返回处理后的音频数据 返回处理后的音频数据 处理后的音频数据 播放音频