音频降噪在58直播中的研究与实现_二手音频_音频应用论坛 - Powered by AUIOAPP

音频应用论坛

 找回密码
 快速注册

QQ登录

只需一步,快速开始

搜索
热搜: 音频应用

[音频] 音频降噪在58直播中的研究与实现

[复制链接]
羊二羊 发表于 2006-2-25 23:09:00

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?快速注册

x
音频降噪在58直播中的研究与实现
: Z# |7 D6 ~* |9 O% o7 ?5 Q& A  \4 z0 q/ y% p/ P% d4 l
背景) r3 k& L4 s& R2 M6 U0 Y/ e
         
7 a7 {0 O3 s4 L: j* ~0 V$ Z% t1 X4 r& G在直播时主播经常会受到一些外部环境音、噪音等影响,直播时音频采集会一并采集所有音频推流到观众设备上,从而影响观众收听体验。因此需要在直播主播端主动进行降噪处理,提高观众收听体验。; T6 S& p" w1 \* n7 k

! l/ q8 e+ R& T1 J7 O% e% H: N58直播为了实现这个功能,通过综合对比调研常见的开源降噪方案Speex、WebRTC、RNNoise,以及结合降噪之后的处理效果和58直播使用体验,最终选择WebRTC降噪方案。我们对其进行了优化兼容,将其移植应用到58视频直播中,提升直播效果和体验。+ c. v% o$ A( |9 N0 U$ f9 A7 B
; ~/ p" _" k0 W  z+ [1 X# k
降噪方案
# e5 m* v0 V( Q( N2 f6 _1 Y! I: _
" S! d8 o, |) V7 q5 s6 s" s, e, P  O6 ?4 e; y
常见的开源降噪方案6 W) O; m3 A9 z9 C2 w1 d. c/ B/ e
Speex! |8 d. q( c/ D" [! }
Speex是一套主要针对语音的开源免费,无专利保护的应用集合,它不仅包括编解码器,还包括VAD(语音检测)、DTX(不连续传输)、AEC(回声消除)、NS(去噪)等实用模块。6 j* f2 B( B/ k7 `" z
WebRTC
7 S; M0 F4 Q9 F$ gWebRTC提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:Windows、Linux、Mac、Android。我们这里使用的就是WebRTC的音频处理模块audio_processing。
& C$ J, ]- ]0 i, `' aRNNoise
8 u+ s5 U+ N$ ^+ ?/ FRNNoise降噪算法是根据纯语音以及噪声通过GRU训练来做。包含特征点提取、预料等核心部分。5 ]! E) w  m/ i0 E! ^/ `. Q
4 k, a# L9 f( P+ b' q1 H5 d
RNNoise降噪算法与传统算法对比分析
- J7 n; @/ L7 d2 Z/ n6 _传统降噪算法大部分是估计噪声+维纳滤波,噪声估计的准确性是整个算法效果的核心。根据噪声的不同大部分处理是针对平稳噪声以及瞬时噪声来做。9 y! p0 g6 s0 H7 i
RNNoise的优点主要是一个算法通过训练可以解决所有噪声场景以及可以优化传统噪声估计的时延和收敛问题。
4 M& h# d6 l; M* h9 A: J0 mRNNoise的缺点是深度学习算法落地问题。因为相对大部分传统算法,RNNoise训练要得到一个很好的效果,由于特征点个数、隐藏单元的个数以及神经网络层数的增加,导致模型增大,运行效率。
1 I* F) \5 g' R4 c3 \" Y* I, E7 h3 o: p3 V# q' w5 Y: D/ u: ]
现在就WebRTC和RNNoise的降噪集成效果进行对比验证分析。
6 J) o* e2 ]  z) j- r+ R
) Z9 o& s# x" X0 V. U9 D降噪音频数据对比: ?( f# \  u2 L+ e
音频原始PCM数据可通过Audacity软件进行分析$ C+ \9 o$ r: I& i/ f  |: p

/ i4 d  ^; m* a( d) O4 V# s- O9 X8 F下图是58公司司庆直播时的截取一段音频数据,音频为双声道、44100采样率。分别用RNNoise和WebRTC进行降噪处理得出效果对比图如下:
8 I7 j- @* O; |/ u' I4 W* \
' k3 N: E: |% s) N1 j& v
3 A2 Q5 ]: ?) y% _8 G8 m下图是网络下载的一段带有噪音的音频数据,音频为单声道、32000采样率。分别用RNNoise和WebRTC进行降噪处理得出效果对比图如下:/ O+ _8 C" Q/ ^. m& w* u( w

8 t7 E/ N- O& d1 l! d1 c2 C6 k# h' K( @. \3 ~
综合上面两张效果图可以结论出:2 [; J2 m6 ?$ x! c" s% V7 N$ B3 D
RNNoise处理之后的数据更干净些,几乎没有电流音和杂音,但是受限于训练集、特征点问题,在处理一些数据时候会把正常的原声数据一并错误处理掉。8 P) T, Y6 j, T
WebRTC处理之后的数据也相对干净,能更好的保持原有声音的数据,数据丢失较少。
 楼主| 羊二羊 发表于 2006-2-25 23:16:00
降噪方案在直播实现
6 y% D! t. ]4 K5 T1 K& B4 h5 A' i  F" x( Q+ c8 ?4 |* f* M
- o3 e! z2 @6 p' h, b( q7 u7 E
降噪方案调研过程) g2 t* ^3 W3 h

- h' O. q) E  I. y7 r" FRNNoise过程, c! {# V! F: p
RNNoise的代码是基于C开源的,集成到Android中需要使用NDK。) B3 t6 S! H- {5 F
开源项目提供的一个测试方法,但是该方法是针对文件处理的,可以把一个带噪音的PCM文件处理成无噪音文件。直播SDK中的音频数据是分段的byte数组数据,所以中间需要添加一些接口来让RNNoise来支持分段数据的降噪处理。0 r6 e" W# T+ S7 ?) t
根据RNNoise的降噪过程和业务接口流程,把接口定义成init、process、free三个接口。( Q4 h7 N, [" L( Y3 @# U
在process数据时发现RNNosie的处理窗口大小是480,所以传入的数据也必须是480的正整数倍。如果不是的话处理之后会有明显的新引入噪音。4 \8 `  K2 W- o( ^. ?7 k$ t4 b
#define FRAME_SIZE_SHIFT 2
# L2 R$ n8 P* X2 T% ~3 J#define FRAME_SIZE (120<<FRAME_SIZE_SHIFT)
- n. q6 x5 |8 i; c& V" f#define WINDOW_SIZE (2*FRAME_SIZE)
2 o" K7 I2 S) W通过测试发现这个窗口大小是可以进行微调的,为了方便音频数据的处理尝试大小修改长512,虽然通过Audacity分析频谱发现会有一些噪音波出现,但是在实际感观中效果还是可以接受的。这个方案可以临时解决非480整整数据问题。5 g* W# E) [, C- t2 v, n
//强制修改FRAME_SIZE大小* {1 [. @/ Y: \" H
#define FRAME_SIZE (128<<FRAME_SIZE_SHIFT)9 R% ~0 L1 \  k% P% ^
开源代码中的rnn_data.c和rnn_data.h是通过机器学习训练出来的,不是通用的。在处理一个噪音数据时发现有些数据中的原声也会一并处理掉,这个效果如果不通过新的数据集训练那么降噪之后的数据是不可用的。
8 i0 v7 k5 S2 d/*This file is automatically generated from a Keras model*/
& [- H6 z: g2 c; T2 x% a#ifndef RNN_DATA_H
, l* F: M6 ?5 D+ @& ^/ u- A" ~9 e% X#define RNN_DATA_H& Z$ V1 w( J2 ~8 J1 K& b2 u) u; \* Y
#include "rnn.h"
: i* w. A4 ]9 I) Y#define INPUT_DENSE_SIZE 24+ O, |7 W1 D  X! ]
extern const DenseLayer input_dense;! ^+ E$ N5 F- o: b$ M6 v2 A2 s- a
#define VAD_GRU_SIZE 24" l* g0 [' o: f1 b& l8 {+ s; b
extern const GRULayer vad_gru;$ g8 K5 ?% @- {4 l
#define NOISE_GRU_SIZE 48) r# I' l# g) g" j) {. `% y
extern const GRULayer noise_gru;
; e5 g! M2 G* U% G9 m2 r2 B. [#define DENOISE_GRU_SIZE 96
6 _6 U. C0 A8 E  k5 }" _3 G! o9 Textern const GRULayer denoise_gru;
1 c% B( e4 W# a6 E#define DENOISE_OUTPUT_SIZE 22
. I+ }9 Q. L, nextern const DenseLayer denoise_output;
% s9 t# U8 v! @; G#define VAD_OUTPUT_SIZE 1# U( U% \% d) s) K5 J6 \" V
extern const DenseLayer vad_output;: t' Z  b( F' r' ?: }
  
+ n  ?: j& x# l' G+ |: Wstruct RNNState {
" g0 |2 l& b; V5 f  float vad_gru_state[VAD_GRU_SIZE];
- y" ~1 j6 q3 e7 c2 B% Q  float noise_gru_state[NOISE_GRU_SIZE];+ C+ k. k$ ]  L* L
  float denoise_gru_state[DENOISE_GRU_SIZE];+ G" Q7 v- E. [, T! O- b; g
};
8 G2 T# X. n9 O#endif: U" m) t) Z5 A
机器学习和训练是RNNoise的灵魂,需要业务接入方根据自身的使用场景通过大量的数据集来找出最合适的处理集。0 S3 J8 L. c  N3 ]) A
# x4 m6 V" d+ P# m+ F: {
WebRTC过程( J1 c0 B5 C* j7 b5 Q' [
WebRTC的代码是基于C++开源的,集成到Android中需要使用NDK。
9 n/ \+ O2 C1 P3 RWebRTC官方没有提供降噪增益的测试代码,需要查找相关资料找到其中的降噪、增益模块,通过资料去熟悉其中的处理逻辑。( O4 o5 t2 l- B8 V: x" |# _4 S; t
WebRTC只能处理特定的采样率数据,这个是其代码内部是写死的,需要自己实现音频重采样来满足WebRTC的降噪采样率需求。音频的重采样算法有很多,在项目集成中都尝试使用过,效果都是差不多的。: Y+ P7 M' \% q: b1 g' U
// WebRTC处理支持的采样率! b4 Y7 I( a( B( w. X( b" E9 p
// Initialization of struct.
4 i- Q4 F! h% x; \" Hif (fs == 8000 || fs == 16000 || fs == 32000 || fs == 44100 || fs == 48000) {! @5 B/ j) I; A9 Z- A: z
   self->fs = fs;
( h6 S! R* R8 L9 n. B1 f} else {* b8 H& N! I9 [5 C. E" p
   return -1;
; d! L# f4 F. R6 E2 v! F. X}
" c: v0 B7 u) u9 L9 Y根据WebRTC的降噪过程和业务接口流程,把接口定义成init、process、free三个接口。区别RNNoise的是需要在process中做增益处理,WebRTC降噪会降低数据的声音大小,通过增益用来补充声音大小。
/ C( t% E0 @$ b- r; t' R; [- h" a" j在process数据时发现WebRTC的处理窗口大小必须是160或是320个byte,根据采样率不同窗口大小不同。测试发现这个和处理RNNoise是一致都只能传正整数倍数据,要不还是会新引入噪音数据。7 \% P3 A' k$ @
if (fs == 8000) {0 \. V6 z! \9 @% L7 S  p
    self->blockLen = 80;
# i' q7 n+ C$ j  E+ `  h' W    self->anaLen = 128;
& f' n! k, B+ N    self->window = kBlocks80w128;
, x. [4 x8 z' \( U, r% l1 y" U: L} else {
0 S, q+ z. I. J+ D% ]* k    self->blockLen = 160;& d3 d$ ~* w3 R  Y3 c9 F) V$ X
    self->anaLen = 256;8 F0 W5 u0 m7 z9 l# v
    self->window = kBlocks160w256;; |) d3 f7 k) I+ j  o
}
  t3 I# e) h( A- D+ kWebRTC在process时有两种处理数据的方法:一种是需要把原始数据分成高频数据和低频数据给底层逻辑;一种是不用区分高低频数据直接把数据给底层逻辑。资料上的解释是32k以上需要分高低频处理。但是在实际测试中发现分高低频的处理效果不如不分高低频的效果好。5 W, E: E" M( k' `* Y# X5 U) W
WebRTC的降噪NS模块和增益AGC模块是独立的,为了一次数据完成两个过程需要组合数据,边降噪边增益,减少处理耗时。
% L+ U; j) y8 jWebRTC_NS在处理数据时不应该选择高低频分开采样处理,应直接把数据给你WebRTC_NS处理就可以。经过测试发现通过高低频处理之后的音频降噪效果不如不区分高低频的,高低频处理之后会有明显的人声破音出现,且处理的降噪效果不纯净。这个地方走了一些弯路,在发现降噪效果不理想时没有怀疑是api使用的问题,这个高低频操作是很多资料都推荐的使用方法,但是在运用到实际场景时发现效果不如不使用的。: a% S( }* V, o$ |1 @8 J9 L

; Q$ x6 q) ?0 k! x, n两种降噪方案集成优缺点对比
2 W$ R" H2 Y7 G# m7 U! J目前WebRTC最新代码只支持采样率为8000、16000、32000、44100、48000的音频进行降噪,针对其余的采样率需要进行数据重采样到上述采样率之后进行降噪,处理完毕之后需要再次恢复原采样率;RNNoise对采样率没有要求,可以适配常见的采样率。: J9 ^. s$ |- @0 R9 g
WebRTC在降噪之后还需要对数据进行增益处理,但是增益会增大电流音,效果会稍差些。( w$ I5 w) ?0 m- u) f3 w- y- e% ]
WebRTC处理数据的buffer目前代码是320的整数倍;RNNoise处理数据的buffer目前代码是480的整数倍。输入的buffer需是固定大小的,如果不是正整数倍,需要外部在传入时处理下。
; E" B8 I: v5 b! H从代码复杂度看,WebRTC的代码是多于RNNoise代码的。RNNoise支持机器学习,通过机器学习生成rnn\_data.h和rnn\_data.c文件来匹配不同的降噪效果。
! \6 R# c. N/ F4 L降噪耗时对比,RNNoise处理3840字节的buffer数据耗时大概在6ms左右,但在开始时耗时在30ms左右,递减到6ms并稳定;WebRTC处理3840字节的buffer数据耗时大概在2ms左右,但在开始时耗时在10ms左右,递减到2ms并稳定。对比发现WebRTC处理效率更好些。
) O: e; a$ i+ S; d  f7 U, N从处理流程上看都是需要init、process、free操作的,对接入方接入成本是一致的。
 楼主| 羊二羊 发表于 2006-2-26 01:51:00
安卓端58直播SDK接入降噪方案6 l( y  O: b) b
通过上章节的优缺点对比以及58直播中已经在使用了WebRTC相关代码逻辑,综合调研和处理结果验证工作之后,最终选择了WebRTC降噪方案。$ Z, `9 A$ v/ T7 T( T+ ?8 K, ?
. A7 r- H% C! ^5 l/ ], f7 I5 C; E- A
APM模块集成WebRTC降噪功能) D1 I& y$ N  u6 k8 k) n- v' K
在58多媒体整体架构上选择把降噪模块单独解耦提取一个APM module,方便58视频编辑、58直播等需要降噪业务统一调用。对外暴露工具类AudioNoiseHelp方便业务接入。APM module的规划以后会接入更多的音频处理模块,现在已经接入降噪、增益模块。
" x- ?* a7 M9 [: i' {3 W由于58直播SDK支持音频采样率种类大于WebRTC支持的种类,因此需要对数据进行最优音频重采样处理。
( P# S& [! l; K' P# p/**
& G0 A% I  w3 a9 a, M * 音频重采样: Q7 h* r- P) f0 x' e% G$ {
*
. e( F0 l4 w! V2 Y. X+ t * @param sourceData        原始数据
5 V* Y: x$ p: I1 X9 A2 X * @param sampleRate        原始采样率  U: d. z6 j8 k& ]& _
* @param srcSize           原始数据长度
2 W5 |) ^" U  }' k1 q# o' { * @param destinationData   重采样之后的数据
- ^3 ?2 v3 {6 j& S * @param newSampleRate     重采样之后的数据长度  P# ?( `. `2 W4 _3 d1 d
*/: \4 U, E) S7 I; h4 H1 z) i
void resampleData(const int16_t *sourceData, int32_t sampleRate, uint32_t srcSize,' \- D" _( ^  q. R
                  int16_t *destinationData,int32_t newSampleRate){
  _3 F) b) C3 b    if (sampleRate == newSampleRate) {) l; y1 R& U/ M, i! B7 n; z
        memcpy(destinationData, sourceData, srcSize * sizeof(int16_t));
3 [* o" L3 e3 J        return;8 l' ~, t, d" \/ B' E% ~1 N6 ^
    }. s2 j- d; f, {: j8 P7 k" D
1 [6 ^. r" O& r1 q1 O, `+ d
    uint32_t last_pos = srcSize - 1;
: X9 l( S  O2 V7 t6 @$ ]+ U/ @    uint32_t dstSize = (uint32_t) (srcSize * ((float) newSampleRate / sampleRate));$ K0 W4 n2 h" Q
    for (uint32_t idx = 0; idx < dstSize; idx++) {$ P4 R) w1 R2 Q: G9 _; _
        float index = ((float) idx * sampleRate) / (newSampleRate);5 ]1 W4 i! F2 X4 u% |2 q& p
        uint32_t p1 = (uint32_t) index;
  @6 Y: p+ U  f0 }        float coef = index - p1;
, ?7 }3 D% ?8 u' B        uint32_t p2 = (p1 == last_pos) ? last_pos : p1 + 1;
$ G; P3 r2 r" t! X+ h        destinationData[idx] = (int16_t) ((1.0f - coef) * sourceData[p1] + coef * sourceData[p2]);7 d, }; J6 [6 A3 m
    }
' |6 C  m) x0 I: F  p  t}: r, {$ g$ F( t$ t2 h3 v$ W
由于WebRTC只能处理320byte长度正整数倍的数据,但是58直播的音频采集数据在不同手机、不同采样率上得到的音频数据长度是不固定的,需要对数据进行切分处理。录音采集数据如果是byte格式的,假如长度是4096,那么直接把4096数据传入到WebRTC\_NS里处理会出现杂音出现,所以在交给WebRTC\_NS模块之前需要用个缓冲区来处理下,一次最多可以传入(4096/320)*320=3840长度数据,并且在数据处理完毕之后还需要用另外一个缓冲区来保证处理之后的长度仍然是4096个。. l. V5 G( w* Z  D  g4 ]- J
//部分逻辑代码如下所示:
& c2 i  H4 {- R# y( G6 B//这个数据拆分和缓冲区数据逻辑可以由业务方自行出$ P: c- @1 Q; a' Y
/**( j' x" j" v- n# \' G' R
* 降噪处理方法,数据异步处理之后通过回调方法通知给调用方。5 D0 C1 L/ y8 v' d! ?/ M  y& }
*, }4 L" O+ ?4 r
* @param bytes             音频数据
/ [; s  A' |! v: K# ?' h1 h; V3 e1 j; M * @param nsProcessListener 异步方法回调
: E# q, R3 D5 O/ y" m */
) }5 S6 `0 }: [/ X5 q4 {* L% X& kpublic void webRtcNsProcess(byte[] bytes, INsProcessListener nsProcessListener) {
  `+ S1 B7 z5 M    if (isAudioNsInitOk) {
5 U9 J( V4 f8 q! f: D        synchronized (TAG) {; M$ L9 ?5 }8 G( T8 }' Z
            if (null == bytes || bytes.length == 0) {
% O% ~/ ?6 A% W/ A8 e; e3 }% p                return;
( J; O  |, ~* O2 ]/ t% P            }8 E& ?; g/ _6 P7 n$ P& i
            
  p: e  X& I* V/ c9 }            .... x5 m3 Q6 w, `8 `5 j+ c$ O
  u+ @* [3 _$ G, c4 C+ {
            int byteLen = bytes.length;
7 y7 N+ J- |9 c& s" {            if (inByteLen != byteLen) {+ u( [! X3 `7 I( w2 e" ?) i
                inByteLen = byteLen;
* ]+ N( g8 g7 q7 J$ ^                webRtcNsInit(byteLen);
$ G* s% n9 G7 z9 s4 r2 U            }6 z' m3 C( |0 r; |0 m, ^
8 q3 d0 ]/ t' k# \6 K5 C( A# k1 a
            int frames = byteLen / FRAME_SIZE;: T" T$ ^. f+ j9 y% R
            int lastFrame = byteLen % FRAME_SIZE;
7 a; _" \& N$ K8 u+ X) o6 Y1 z            int frameBufferLen = frames * FRAME_SIZE;
- E  {$ N0 w9 g- w. l$ e" e/ i& {            byte[] buf = new byte[frameBufferLen];
) H) P- p! W3 Y) L7 @9 X% j            Log.d(TAG, "webRtcNsProcess inBufferSize:" + inBufferSize);
; u$ E3 w9 r: `            if (inBufferSize >= frameBufferLen) {" Z, U6 \+ q6 M# z
                Log.d(TAG, "webRtcNsProcess mInByteBuffer full");. p/ \, T) q  ?) t! Z, V6 b6 a2 Z
                nsProcessInner(buf, nsProcessListener);
, p/ u; k4 i8 P6 {* c, O8 ?            }
/ B. K3 L6 q5 ~4 f0 ^) Z( q2 ^+ b4 W: x* l; T
            ...& K( j# s; L* c" w
            ! Z4 i( O3 o" `6 l* \+ g3 o1 H
            nsProcessInner(buf, nsProcessListener);
8 L+ p& `. P( E$ S1 C        }
! \3 P# U, r8 X    } else {8 p5 l7 W0 p* ]$ y7 ^
        if (null != nsProcessListener) {
, a: j9 k6 U6 q' {, h# h: o+ x            nsProcessListener.onProcess(bytes);* Z$ f# d. c2 i4 S/ {
        }! f+ h( N$ e  j) H/ w: C9 C+ K4 `* ^
    }  l1 r$ g3 Z* t' F
}$ I6 J0 d3 Z2 I
1 @) G4 _/ }! O! _8 C( \
private void nsProcessInner(byte[] buf, INsProcessListener nsProcessListener) {
" E: T( i; ?) O7 O; e) I    mInByteBuffer.rewind();
& }$ M* s! n  p% G) E0 E! L    mInByteBuffer.get(buf, 0, buf.length);
  Y. Z* J, {! }! t    byte[] inBufferLeft = new byte[inBufferSize - mInByteBuffer.position()];
# Y# ], e. ]0 e; P0 j* {& D
3 a: }% z4 }7 u7 T    ...
! B! g0 G' `  L1 N. C   
( D6 |0 X- h& b! w% _    byte[] nsProcessData = AudioNoiseUtils.webRtcNsProcess(buf);
: h& P7 G5 F; ^+ r" k7 y( O    byte[] outBuf = new byte[inByteLen];
4 b3 h; h" _+ b- T$ a   
: w( d+ X$ }2 ?  I8 b, n    ...- J# A  \& @( C; L2 c4 |0 P6 ]
   
  L: f" x. s8 r4 E& K# T    if (outBufferSize >= inByteLen) {
4 d2 e+ T8 q' I' M7 c) Z. i( d. J- z! S$ I! _
        ...
) ^1 M8 a: r6 F3 R
7 }2 M( _* u3 [$ b7 \0 @& e        byte[] outBufferLeft = new byte[outBufferSize - mOutByteBuffer.position()];
0 f. ]! s7 y/ Q' q& o6 L
! M8 h/ w. z  o/ H* p8 U1 s        ...8 g! O$ x6 C9 }. A. e8 c
        
, ~  `/ T5 a: x! G" ?2 g        mOutByteBuffer.put(outBufferLeft);) X' y( K+ {; I: ^$ h; |. x
        outBufferSize += outBufferLeft.length;
# L1 A( X  d' c$ o8 ^: K! L6 T        if (null != nsProcessListener) {* V1 t4 G+ a  n4 s. U  e
            nsProcessListener.onProcess(outBuf);
. t9 w1 z. v+ H0 T2 w) X1 F        }
" y1 ~& M: T' X4 t6 e& B; l    }4 v0 B/ F2 D8 _7 C  F  j7 I
}& \- s, W% Z. f# v
/ e! v3 F$ U. C6 g( B5 T. N5 @6 Z
 楼主| 羊二羊 发表于 2006-3-8 07:50:00
58直播接入降噪之后的效果对比! }6 u# p5 n& Q6 G
时域对比7 u8 V/ ~6 A# f' X5 |! G
下图中蓝色部分是58直播时截取的一段未开启降噪逻辑的音频波形dB图,绿色部分是58直播时截取的一段开启降噪逻辑的音频波形dB图。从时域波形图对比上可以看到开启降噪逻辑之后波形更加清晰了,降噪效果比较明显。2 T% _9 b: i) s( \& P2 l& D1 H; i7 _
! A, K/ D; F+ }8 ]9 \
      
: N! Y9 a! }0 ^5 X) S: C' |* l 频谱图对比; S  e! V/ c; a$ r7 G2 W; O
下图中上半部分是58直播时截取的一段未开启降噪逻辑音频的频谱图,下半部分是58直播时截取的一段开启降噪逻辑音频的频谱图。从频谱图对比上可以看到开启降噪逻辑之后噪音的频谱被去除掉,音频数据的原始数据更加清晰突出。7 G6 z. X  d9 [, X3 y
* b' x+ D& @5 Q' V7 ~4 T* \
       
- ^3 y1 c+ r0 {" Q) l主观感觉对比$ ]) n! d' n& ^' C
在同样的噪音环境下通过开启和关闭降噪功能,在观众端体验收听效果。未开启降噪功能时观众端可以明显的听到沙沙的杂音,开启降噪功能之后沙沙声音明显减少或没有,对应的主播的声音凸显出来。
  q9 B8 z5 B* n. Q1 V4 v% u( f0 r
总结6 s5 o1 G1 q$ U
         
, e) w7 M! u' ]- P* C9 r本文分享了58直播在降噪方面所做的一些调研实践经验,重点阐述了其中的一些痛点和难点问题以及我们的解决方案。由于RNNoise降噪方案的优势是存在的,在后续研究中会对RNNoise的深度学习继续进行深入了解,期望能更好的解决噪音问题,更好的提升直播体验。也希望能有更多朋友一起来探讨更优的解决方案。
hbsgz 发表于 2007-2-23 00:54:10
点赞,谢谢楼主啊
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

软硬产品代理咨询服务:声卡:雅马哈UR22C、罗兰声卡、福克斯特、艾肯、阿波罗 、M-audio 、普瑞声纳 、福克斯特、 达思冠系列 音箱:吸顶NS-IW560C、吸顶NS-IW660 、NS-AW350、低音NS-SW050、低音NS-SW100;JBL 吸顶8124、CSS-8006BM;香蕉猴 gibbon系列;普瑞声纳E5XT、E4.5、 E3.5BT 有线话筒:舒尔PGA27、PGA48、MV51、mv88、mv88+、SM27 ;森海E945 、MK4、E835S;舒伯乐top248s;罗德NT1-A、VIDEOMIC、VIDEOMIC GO、VideoMicro、VideoMic NTG 无线领夹麦克风:罗德 wireless go II 一拖一、一拖二;猛犸lark150 耳机:森海HD300 pro、美奇 CR-Buds 、索尼7506、爱科技K240S、K240 MKII、K271 MKII、K52、K72、K92、先锋、飞利浦 1:飞利浦会务通/会议摄像头/全向麦克风/执法仪/录音笔 2:洋铭便携式移动演播室 / 切换台 / 摄控一体摄像机 / 虚拟演播室 / 微金课教室 / 色键器 3:逻兰音视频切换台 / 声卡 / 电子鼓 /电钢琴 /耳机 4:Blackmagic专业摄影机 /调色台 / 切换台/ 广播级转换器 / 监视器 / 采集卡 5:索尼专业摄像机/佳能专业摄像机/松下专业摄像机/ insta360专业摄像机 6:话筒:铁三角/ 舒尔/ 森海塞尔 / AKG / RODE/ BBS 7:音响:YAMAHA/ 声艺 / 皇冠 /JBL / 真力/咪宝/BOSE /美奇 8:声卡:RME/羚羊/IXI /艾肯/PreSonus普瑞声纳/Focusrite福克斯特/YAMAHA/雅马哈/ickb 9:耳机:铁三角/beyerdynamic拜亚动力/AKG爱科技/索尼/RunningMan/美技 10:思锐三脚架 /防潮箱 /米泊三脚架/意美捷三脚架/曼富图三脚架 11:XSW系列,300.500代理商,EWD数字系列代理,6000.9000定制产品,还包销了全国三个型号:XSW1-825,EW100 G4-945,EWD- kk 205

小黑屋|手机版|Archiver|音频应用 (鄂ICP备13005321号-1)

Powered by Audio app

快速回复 返回顶部 返回列表