- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36444 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13894
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
1 f1 I% s( L" c/ b 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
5 L P8 v0 J5 h$ o: d: b$ F8 b$ C- W* W: |! J
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。, V, d# H% f& W* [
( n6 y5 q- ^0 d. C, x6 E
2. 代码介绍
0 {- x" p1 ]- R; L7 z6 k 原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
8 L7 o* [5 i) C% {7 A' l( g' Ufunction [mcSignals,setup] = multichannelSignalGenerator(setup), V8 ~) H; F; o; C8 P6 `
% A' |8 z# h4 q* K3 k
& l! U4 Y/ G. m+ U1 x! |%-----------------------------------------------------------------------# y3 J; Q3 Y0 u$ L) g% r' i! L
% Producing the multi_noisy_signals for Mic array Beamforming.
/ v' ~6 S6 k; G0 x% Y% 6 J5 @! T/ R. d; W9 ~
% Usage: multichannelSignalGenerator(setup)
6 o' \7 e8 r" X% - d1 L/ x- o! {6 M6 h) f
% setup.nRirLength : The length of Room Impulse Response Filter
3 p. }/ J, }' v; ^0 ~% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default% N, K, ]6 k' e0 { T
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.. Q0 \' O; T0 S5 x4 G# I
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
* e. g$ m% q! u8 y% * O: G' g) R8 c; L$ `. G- c
% setup.nSensors : The numbers of the Mic+ {& P* Q+ Y6 t: V& Y- t: B
% setup.sensorDistance : The distance between the adjacent Mics (m) K9 V. C3 Z8 H5 R
% setup.reverbTime : The reverberation time of room3 m. Y8 C7 x- S; ` ]* P
% setup.speedOfSound : sound velocity (m/s), `& h$ W+ I1 b4 x: [; N) F
%
$ n9 L, w9 ^ i$ y3 C5 p3 |" c% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
( D4 V4 ^8 Q/ p. Y% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
5 L4 `+ T* s8 H+ R5 p% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.5 K( p" L X8 K9 D/ ]/ Y
%
" q) F9 R- k. ~4 V2 \+ @# a& ^% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
# Z. R% Q, V/ u' C* y. e- Y% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
: ]* d7 X/ E, n; ?$ Q$ Z( A9 S% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m). & ?5 L* u x7 ~# E& [
%, j6 x$ B' r- X6 }& `
% srcHeight : The height of target audio source
0 |; u) |5 b' S5 H" J6 j, ?4 K8 l6 j1 A% arrayHeight : The height of mic array
0 u( R. p6 {' z%
6 ?+ [1 b3 ?! S( e% arrayCenter : The Center Postion of mic array
$ e9 \6 T: i6 O" F6 Z8 ]- d%
( ?; i1 t6 F$ l' B0 A" H7 S% arrayToSrcDistInt :The distance between the array and audio source on the xy axis
6 M. D) a( Y3 [%
- z& u* t/ w9 w4 a5 S8 `2 ]6 Z% ; r4 I7 G" V; m' J% g6 E& y# Q) S# [! i
%0 H) n! U |' \* F" `) W# Q- D6 x7 M
%% j/ n5 X! D$ I: E
% . d5 h. x$ M: o- h0 ^/ o5 Q
%1 m% N- R7 z. ~; W; X
% How To Use : JUST RUN
8 e6 b: b Z$ j) i+ a/ {%
& [0 Y: L3 ~& F' o6 i1 ]%
b. V7 _; d' P5 w: j5 N/ s, k) r& p%
) W9 K4 x& C1 ?8 c. n+ Y/ }% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
7 Y6 S- h# b- u; V' d2 w- q% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
+ p" i# [8 d" K. I3 ?%
9 Y% D1 j/ G# X- v% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- R5 ?. b- X! l) Y%-------------------------------------------------------------------------; G; Z+ I$ A J$ o: G
. P! E' ^6 i, V
0 p4 k7 d1 @; z0 h$ h x; z$ ]2 @
) R- J/ [/ E; w+ s% A# e( @addpath([cd,'\..\rirGen\']);
& o1 v S6 |9 w5 K9 l a0 n$ Q3 o8 S$ D" v% @" a
%-----------------------------------------------initial parameters-----------------------------------
' n. T. c: r# T% b* a& N, P% b. {4 C; J; v9 L4 K i) j
setup.nRirLength = 2048;) U) R# d( [/ F k
setup.hpFilterFlag = 1;
0 C" f2 k) o) ^( ^0 [/ {( dsetup.reflectionOrder = -1;
6 E) e* X- B! W9 N2 Ysetup.micType = 'omnidirectional';
$ ] \$ s* _2 {5 @' l( esetup.nSensors = 4;( r1 p |5 J# w* @ N
setup.sensorDistance = 0.05;+ t+ ]! |1 u9 u4 g% ?8 g
setup.reverbTime = 0.1;6 @9 L' S' I4 t- d2 `5 r( s1 Q
setup.speedOfSound = 340;3 t# t& Q' G1 \- U
- }9 u* Z, o$ v5 X, Y8 [' V
setup.noiseField = 'spherical';
! V4 q8 l, z7 o; U% Qsetup.sdnr = 20;
7 P$ L' B$ R4 y8 q0 Vsetup.ssnr = 25;% F# C. l9 z6 r8 y' [- s* v
6 C) i* |* o r9 l/ A
setup.roomDim = [3;4;3];, V% N( I9 Y4 a A3 g3 L# r
* @4 O2 ^# X* w+ AsrcHeight = 1;
" V* D1 t" o( V" ~1 narrayHeight = 1;5 l" o" r8 b) J) M( O' i Q
+ s% E1 l5 P, k' B9 R6 z/ _arrayCenter = [setup.roomDim(1:2)/2;1];
4 c& w5 P# p1 m3 F, O; s9 T- N
8 c7 ]) G8 T, ?% A4 TarrayToSrcDistInt = [1,1];; n0 ?/ I$ K! V+ d- e/ X
4 T! v( W, i: ^. O; l$ B/ ]1 f% r- d
setup.srcPoint = [1.5;1;1];, L8 W, c h( j
0 W9 k$ f# U1 I( e* Esetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);) v5 w9 b, O& L
( ?4 @! W; |0 q
. a6 P1 A2 h, H7 M3 [4 l, I6 ~[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
1 P, @& K$ ]" V7 J* Z ?6 p- U7 v$ U* a& Q+ o0 `
%---------------------------------------------------initial end----------------------------------------
\+ f# N c6 K% b
0 s0 `3 {- @$ t( Y7 O$ \
3 I6 B5 r; n D' H7 c) m$ o/ [5 }
. m& J' ~" F' T" h. Z%-------------------------------algorithm processing--------------------------------------------------5 k% V$ |# }" l. I9 a& i$ {
2 I3 Y Z6 [+ V: x" T! t$ T3 _& G1 `if setup.reverbTime == 0," R, K W' Z: B* O5 }$ N8 v. K: q- R
setup.reverbTime = 0.2;, j8 V' C: p$ L2 x; l. r
reflectionOrder = 0;
/ z' e. A* L% d- lelse: a" C6 I" t* l# V
reflectionOrder = -1;$ p/ v0 h+ @% |5 ^ N0 V' @
end3 w, o- D1 Y7 B% ~8 E" T
7 ?- [* |! h" L- \( m( s# hrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...0 _# Y/ `& P5 d# D4 g) l4 F
setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);6 o) w3 A8 \: N* e9 ^+ _3 ^
2 i5 |' a% y8 G* l, L' `( a' nfor iSens = 1:setup.nSensors,& \9 t6 v$ d5 q* q: B5 F
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);
+ P& A! {8 ` n$ y+ [end
: a! _$ H$ N0 H/ D+ J/ smcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;4 j/ y" F, C2 h' c( y+ _! g/ J
setup.nSamples = length(mcSignals.clean);- t# C: s" ~; l! ~; |: h c( L
( o% I5 O6 [7 n7 zmcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);2 ^( r" g9 Y" ]2 G* P- W
, h" d \. ^0 w% k& D, O' U
%-------produce the microphone recieved clean signals---------------------------------------------
* V: ?4 c; E) \# r; m& E4 ~. z7 c6 l2 p) j+ g1 k0 c( g- e
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
0 {$ [ f9 o! V1 N1 \3 K- D1 omic_clean2=10*mcSignals.clean(:,2);6 N! `4 b& ?9 c! M2 U
mic_clean3=10*mcSignals.clean(:,3);
5 M+ E0 z! e5 Y# N) `+ \mic_clean4=10*mcSignals.clean(:,4);0 Q1 \9 L* y6 C1 U5 s" ]2 M
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
5 Z- l% I& H* z# G) i! Q7 R8 Daudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);! `# {; ~; L" D$ _& T# n
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
( W5 g6 s+ n$ a# m0 aaudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);0 u' C, _4 L" Y; u( z4 ~- ~6 N' T* A& v
, J1 R: h$ [4 P: ?$ c/ {, W/ P9 Q%----------------------------------end--------------------------------------------------
( H# _- d4 T3 d2 P6 J( j W8 v- E/ l, B
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
" m; u, {6 n- [, u3 b
% n: L/ M. R- J7 g* a/ scleanSignalPowerMeas = var(mcSignals.clean);* X: Y) A) r. A1 y5 {& ]( ~* ?
& X$ N! f, i/ D$ q0 Y( B2 |: X! e: T" b( ?* q
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
+ x6 ]7 |0 J5 H9 Q setup.speedOfSound,setup.noiseField);
2 M+ g+ @; K1 TdiffNoisePowerMeas = var(mcSignals.diffNoise);7 u- P# e2 W2 g- R* M# h5 m. G
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
# h; K+ M* _$ p' _mcSignals.diffNoise = mcSignals.diffNoise*...
; z: Y9 w0 S& Q0 Y$ b# R diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
- C3 z- C( E2 z) G$ l! m7 ~9 S- m/ |4 V
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);8 k& R5 a+ {7 K0 V4 i
sensNoisePowerMeas = var(mcSignals.sensNoise);
5 \! B6 f' j8 E6 H2 `$ o" S* fsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);. X& Q: ]1 h- C) D1 t
mcSignals.sensNoise = mcSignals.sensNoise*...
5 V' R: B" L9 G6 |3 U& O! _; W diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));2 R# i7 N# ]+ c) t& v2 _( G
' C) t a9 ?5 j
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;8 r4 {" h! y7 F. H% ]
mcSignals.observed = mcSignals.clean + mcSignals.noise;
0 I- S6 l/ i3 b8 t8 T- X4 ~. N! }2 \$ F1 [
%------------------------------processing end-----------------------------------------------------------: f( x0 t' Q: H3 X8 S) T2 ^/ D
K: @4 k5 ], b! m/ @9 c& z2 H9 T0 D, @8 O9 b
0 i6 j: ]6 l ~+ B+ x% C
) q3 x" I+ R, Z t%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------* ~# n3 ]2 M, h5 D
, R& ^' W }" W! G
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
9 Y( A5 c* ^; q1 Ynoisy_mix2=10*mcSignals.observed(:,2);
9 {8 G3 W' U1 w# F( a1 v+ x! @noisy_mix3=10*mcSignals.observed(:,3);
, {* v6 j( \: A& U. _noisy_mix4=10*mcSignals.observed(:,4);3 i- |8 d6 y' G
l1=size(noisy_mix1);
# x& B5 _2 K5 p3 n! kl2=size(noisy_mix2);
; G0 B' `2 ]" j. Al3=size(noisy_mix3);
) l3 `+ X! m6 W* D2 h0 b2 Hl4=size(noisy_mix4); p. ~2 K; z" @; |6 W$ j
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
# u$ P& Z7 b. R' naudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);0 y! f( V/ b2 R( i+ C4 H: ]; x8 }
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
/ Y. t# l) R: m' B; `7 D9 Kaudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);5 P% |1 R4 M) k- s
: c+ X) v6 n8 A' N. O. H( C. w7 C( a/ X$ a( _- m
%-----------------------------end-------------------------------------------------------------------------9 S; X! q! C7 i
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
7 |- Y9 M3 J, J L* {0 ?! ], x直接把它们替换成你想要处理的音频文件即可。
. i3 |2 e8 \. H. V
% Y1 D7 x% ?1 O: q: ~ 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(micType),有全指向型(omnidirectional),心型指向(cardioid),亚心型指向(subcardioid,不知道咋翻译,请见谅) , 超心型(hypercardioid), 双向型(bidirectional),一般默认是全指向型,如下图1所示;麦克风的数量(nSensors);各麦克风之间的间距(sensorDistance);麦克风阵列的中心位置(arrayCenter),用(x,y,z)坐标来表示;麦克风阵列的高度(arrayHeight),感觉和前面的arrayCenter有所重复,不知道为什么还要设置这么一个参数;目标声源的位置(srcPoint),也是用(x,y,z)坐标来表示;目标声源的高度(srcHeight);麦克风阵列距离目标声源的距离(arrayToSrcDistInt),是在xy平面上的投影距离;房间的大小(roomDim),另外房间的(x,y,z)坐标系如图2所示;房间的混响时间(reverbTime);散漫噪声场的类型(noiseField),分为球形场(spherical)和圆柱形场(cylindrical)。
6 S: Y0 J( B X3 Z6 h, }& y6 c# r- i q! }. X% ~% n
![]()
3 p, y1 g1 ?0 J2 c$ _. K1 Y6 q
- D: A7 E* W3 X8 j图1 麦克风类型图
. q& b0 B/ q0 p! ]( O; |8 K# ~ $ v$ N b. i: k! b+ y
图二 房间的坐标系
8 ^' a( B( c/ N$ i% z T1 _! g; P; ~5 K
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
' ~( m+ t1 H) b) J0 U1 Y' i! F- o+ P————————————————5 s. v/ E8 a: K, p: D6 Y* Y
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。! S9 r: ^+ B0 f A( k
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998' H3 \9 ^/ D* ]
W: S r. P; O: X( X; {9 X1 F% V. g1 Q D
|
zan
|