文|网易智慧企业资深客户端开发工程师

年初因为工作须要,开始学习WebRTC,被其简单的编译环境和微小的代码量所折服,注定是一块难啃的骨头。俗话说万事开头难,保持一个恒心,究竟能学习到WebRTC的设计精华。

明天和大家聊聊WebRTC中音频的那些事。WebRTC由语音引擎,视频引擎和网络传输三大模块组成,其中语音引擎是WebRTC中最具价值的技术之一,实现了音频数据的采集、前解决、编码、发送、承受、解码、混音、后处理、播放等一系列解决流程。

音频引擎次要蕴含:音频设备模块ADM、音频编码器工厂、音频解码器工厂、混音器Mixer、音频前解决APM。

音频工作机制

想要零碎的理解音频引擎,首先须要理解外围的实现类和音频数据流向,接下来咱们将简略的剖析一下。

音频引擎外围类图

音频引擎WebrtcVoiceEngine次要蕴含音频设备模块AudioDeviceModule、音频混音器AudioMixer、音频3A处理器AudioProcessing、音频治理类AudioState、音频编码器工厂AudioEncodeFactory、音频解码器工厂AudioDecodeFactory、语音媒体通道蕴含发送和承受等。

1.音频设备模块AudioDeviceModule次要负责硬件设施层,包含音频数据的采集和播放,以及硬件设施的相干操作。

  1. 音频混音器AudioMixer次要负责音频发送数据的混音(设施采集和伴音的混音)、音频播放数据的混音(多路承受音频和伴音的混音)。
  2. 音频3A处理器AudioProcessing次要负责音频采集数据的前解决,蕴含回声打消AEC、自动增益管制AGC、噪声克制NS。APM分为两个流,一个近端流,一个远端流。近端(Near-end)流是指从麦克风进入的数据;远端(Far-end)流是指接管到的数据。
  3. 音频治理类AudioState蕴含音频设备模块ADM、音频前解决模块APM、音频混音器Mixer以及数据流转核心AudioTransportImpl。
  4. 音频编码器工厂AudioEncodeFactory蕴含了Opus、iSAC、G711、G722、iLBC、L16等codec。
  5. 音频解码器工厂AudioDecodeFactory蕴含了Opus、iSAC、G711、G722、iLBC、L16等codec。

    音频的工作流程图

1. 发动端通过麦克风进行声音采集

2. 发动端将采集到的声音信号输送给APM模块,进行回声打消AEC,乐音克制NS,自动增益管制解决AGC

3. 发动端将解决之后的数据输送给编码器进行语音压缩编码

4. 发动端将编码后的数据通过RtpRtcp传输模块发送,通过Internet网路传输到接收端

5. 接收端承受网络传输过去的音频数据,先输送给NetEQ模块进行抖动打消,丢包暗藏解码等操作

6. 接收端将解决过后的音频数据送入声卡设施进行播放

NetEQ模块是Webrtc语音引擎中的外围模块

在 NetEQ 模块中,又被大抵分为 MCU模块和 DSP 模块。

MCU 次要负责做延时及抖动的计算统计,并生成对应的管制命令。

DSP 模块负责接管并依据 MCU 的管制命令进行对应的数据包解决,并传输给下一个环节。

音频数据流向

依据下面介绍的音频工作流程图,咱们将持续细化一下音频的数据流向。将会重点介绍一下数据流转核心AudioTransportImpl在整个环节中表演的重要角色

数据流转核心AudioTransportImpl实现了采集数据处理接口RecordDataIsAvailbale和播放数据处理接口NeedMorePlayData。

RecordDataIsAvailbale负责采集音频数据的解决和将其散发到所有的发送Streams。

NeedMorePlayData负责混音所有接管到的Streams,而后输送给APM作为一路参考信号处理,最初将其重采样到申请输入的采样率。

RecordDataIsAvailbale外部次要流程:

  1. 由硬件采集过去的音频数据,间接重采样到发送采样率
  2. 由音频前解决针对重采样之后的音频数据进行3A解决
  3. VAD解决
  4. 数字增益调整采集音量
  5. 音频数据回调内部进行内部前解决
  6. 混音发送端所有须要发送的音频数据,包含采集的数据和伴音的数据
  7. 计算音频数据的能量值
  8. 将其散发到所有的发送Streams

NeedMorePlayData外部次要流程:

  1. 混音所有接管到的Streams的音频数据

    1.1 计算输入采样率CalculateOutputFrequency()

    1.2 从Source收集音频数据GetAudioFromSources(),选取没有mute,且能量最大的三路进行混音

    1.3 执行混音操作FrameCombiner::Combine()

  2. 特定条件下,进行噪声注入,用于采集侧作为参考信号
  3. 对本地伴音进行混音操作
  4. 数字增益调整播放音量
  5. 音频数据回调内部进行内部前解决
  6. 计算音频数据的能量值
  7. 将音频重采样到申请输入的采样率
  8. 将音频数据输送给APM作为一路参考信号处理

由上图的数据流向发现,为什么须要FineAudioBuffer和AudioDeviceBuffer?

因为WebRTC 的音频流水线只反对解决 10 ms 的数据,不同的操作系统平台提供了不同的采集和播放时长的音频数据,不同的采样率也会提供不同时长的数据。

例如iOS上,16K采样率会提供8ms的音频数据128帧;8K采样率会提供16ms的音频数据128帧;48K采样率会提供10.67ms的音频数据512帧。

AudioDeviceModule 播放和采集的数据,总会通过 AudioDeviceBuffer 拿进来或者送出去 10 ms 的音频数据。

对于不反对采集和播放 10 ms 音频数据的平台,在平台的 AudioDeviceModule 和 AudioDeviceBuffer 还会插入一个 FineAudioBuffer,用于将平台的音频数据格式转换为 10 ms 的 WebRTC 能解决的音频帧。

在AudioDeviceBuffer 中,还会10s定时统计一下以后硬件设施过去的音频数据对应的采样点个数和采样率,能够用于检测以后硬件的一个工作状态。

音频相干改变

1. 音频Profile的实现,反对Voip和Music 2种场景,实现了采样率、编码码率、编码模式、声道数的综合性技术策略。iOS实现了采集和播放线程的拆散,反对双声道的播放。

2. 音频3A参数的兼容性下发适配计划。

3. 耳机场景的适配,蓝牙耳机和一般耳机的适配,动静3A切换适配。

4. Noise_Injection噪声注入算法,作为一路参考信号,在耳机场景的回声打消中的作用特地显著。

5. 反对本地伴音文件file和网络伴音文件http&https。

6. Audio Nack的实现,进步音频的抗丢包能力,目前正在进行In-band FEC。

7. 音频解决在单讲和双讲方面的优化。

8. iOS在Built-In AGC方面的钻研:

(1)Built-In AGC对于Speech和Music无效,对于noise和环境底噪不会产生作用。

(2)不同机型的麦克风硬件的增益不同,iPhone 7 Plus > iPhone 8 > iPhone X;因而会在软件AGC和硬件AGC都敞开的状况下,远端听到的声音大小体现不一样。

(3)iOS除了提供的可开关的AGC以外,还有一个AGC会始终工作,对信号的level进行微调;猜测这个始终工作的AGC是iOS自带的analog AGC,可能和硬件无关,且没有API能够开关,而可开关的AGC是一个digital AGC。

(4)在大部分iOS机型上,外放模式“耳机再次插入后”,input的音量会变小。以后的解决方案是在耳机再次插入后,减少一个preGain来把输出的音量拉回正常值。

音频问题排查

和大家分享一下音频最常见的一些景象以及起因

以上就是我对于语音引擎的一些分享,欢送大家留言与我探讨。