- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 35373 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13555
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 621
- 主题
- 542
- 精华
- 10
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
---|
签到天数: 74 天 [LV.6]常住居民II
群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
P5 v# Q8 q5 j: o/ y: [) c; \ 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
% M4 q1 [4 n9 f. f0 X
1 y9 d* U2 E3 \- a 然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。0 S0 ^' V `6 w" ]; |
8 a7 E- i" Z( M: b6 }! K8 V, I
2. 代码介绍
w' S+ G$ T" `" K# k e 原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:8 [1 G( r' j+ f% C! b1 v) L$ K
function [mcSignals,setup] = multichannelSignalGenerator(setup)
$ u) r$ A/ n* {+ ?. Z
+ l( q9 J& u3 G6 ^$ B
. E, [" L3 _) L. g% E%-----------------------------------------------------------------------7 A" u6 \! G$ ?; v
% Producing the multi_noisy_signals for Mic array Beamforming.) h: J$ V% L8 m1 G
%
" m) p M6 U1 |& T; V% Usage: multichannelSignalGenerator(setup), \2 Y G' h: C4 M& k
%
, ~* M- b; c5 ^5 b4 J% setup.nRirLength : The length of Room Impulse Response Filter
" Y; W# l+ c3 x" C, c% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
7 x! ~0 H; t, Z' C F% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.9 E$ ~. |2 P6 V+ [
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
' Z( ^8 `+ ~7 _2 V%
5 h; w q( d: M: ?7 J% setup.nSensors : The numbers of the Mic
% Y1 b. b# r, w. n( r/ U# } Y% setup.sensorDistance : The distance between the adjacent Mics (m)- i5 c/ [" |4 _8 V0 y( s- P
% setup.reverbTime : The reverberation time of room
: x" Y% x( j! X1 ~% setup.speedOfSound : sound velocity (m/s)
; F- p( m9 }% c$ J9 b# e( U%
6 b/ M# O' }. b {# _% k6 a7 c4 J( D! l% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
1 D5 S; w# k* A' c% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.: W& q6 _ |! S; R; }
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.6 e7 G6 T: }. f9 ]6 @
%! M, e! r/ [4 e& N6 w$ `1 K3 ^( h
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). ' w2 Q* z: Y1 K) d3 \$ X4 {
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
, x7 X/ y ^1 u% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m). * C) J2 C; P: V- N
%& y% T4 o! N+ v0 s
% srcHeight : The height of target audio source
\8 r8 ~' R3 m% arrayHeight : The height of mic array
7 J/ i) a+ g- O! k' e$ A4 ]%! M4 r. s9 w' p3 N* O
% arrayCenter : The Center Postion of mic array $ T1 r, z. Y' J+ n1 _
%
' |! c$ ~: H1 W) p' Q0 p9 s8 k8 m% arrayToSrcDistInt :The distance between the array and audio source on the xy axis. {6 D' L' \" A6 u) p4 E* g
%3 Z" w r$ a! F: ]
% 2 M* R: C$ b O+ s5 l
%9 w0 r9 D1 N" o& k* ]% \7 T# V
%
% F6 n/ C5 l- y% I' j7 R [% ; x, |) I! n; c6 P
%: o3 X. N4 x$ G( x' ~" a7 w
% How To Use : JUST RUN
4 T$ p2 L+ K9 u! \%' q$ ?1 k# q- i
%
# g8 D4 j/ W' S _ k0 C7 I* l%
# Y' Q0 w$ c* s! d% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),; e9 @; q% _) h9 [# ?) F5 C
% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24: f- m# I0 o' h \! d# O- s P9 ~
%
. Z, d* U) y* W- s5 f" w% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
/ e( G6 H( x+ s9 K, u4 Z: A%-------------------------------------------------------------------------
; S! C; s1 `& ]
- z: R: x8 s% c( x) S3 h, h7 \* j( H; _1 P& s' e
! V& I7 A1 A2 l) x
addpath([cd,'\..\rirGen\']);9 P$ S! s% `7 y8 W, f% @
% K C7 O0 s9 ?5 Y% N6 r
%-----------------------------------------------initial parameters-----------------------------------2 g' R. `+ A& ~
5 X/ X% B$ Y) A7 c: B5 jsetup.nRirLength = 2048;
8 J T y- H& o/ i+ y! x# z7 c1 _5 ?setup.hpFilterFlag = 1;2 G1 R. Z- x4 u8 a: K
setup.reflectionOrder = -1;1 Q1 g9 h7 ^6 A9 N
setup.micType = 'omnidirectional';" X+ l- J0 P% V/ y9 n% C: s
setup.nSensors = 4;
8 u3 ^3 I7 H) Q3 m3 p* \setup.sensorDistance = 0.05;+ } p4 v) s% f# c
setup.reverbTime = 0.1;3 m9 J+ `/ b3 o, m1 d. e
setup.speedOfSound = 340;
5 r9 M5 d; U* I9 i1 C. G3 t' u+ |
setup.noiseField = 'spherical';
% x. i1 S$ A b4 J" osetup.sdnr = 20;: t% F. K/ }# b( o/ H
setup.ssnr = 25;
* V% C# v- i, a% Y" A
' R8 ^! Y+ ]$ w. V1 ysetup.roomDim = [3;4;3];/ C( p: `/ i1 p4 b- b: I
& Y T) f7 S0 a7 V4 U
srcHeight = 1;( @/ \: o. b" x% L- h( `7 Q
arrayHeight = 1;
. ?3 l& E; r8 @& p2 i4 o) W: k
$ i5 m9 U4 Y4 |/ ~+ aarrayCenter = [setup.roomDim(1:2)/2;1]; j5 N9 l/ W3 o' K; `1 a
0 _# S3 v* g2 Z% j0 {2 harrayToSrcDistInt = [1,1];
6 g9 u: @+ W; k+ [1 E! U3 q4 v, D" Y' t8 p0 Q1 n% P4 ?& L
setup.srcPoint = [1.5;1;1];
$ V: K& O! a8 Z$ U9 S% c5 P. L$ e0 T' P
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);7 F9 l. k! A" Z
( ~" Y2 q6 r1 m" i% R& c* P4 b: V* R# N3 V
4 B7 X2 O, k w: M& W6 [" Z* G8 s
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
1 f- B N, U- I/ v2 y+ \$ _6 u, O0 \! s; N) o: M5 ?
%---------------------------------------------------initial end---------------------------------------- [4 h' |6 ?8 j' O/ U" I1 `3 w
4 {7 U. u' E. m- k Y* I$ D+ p
6 I+ @7 l( I7 r, c& J' s5 `# z y( b' y, @ @/ Y
%-------------------------------algorithm processing--------------------------------------------------
4 q+ m% w8 u$ R0 e0 v1 p8 w) A" \0 k; V p- P7 Y# k
if setup.reverbTime == 0,
. A1 V7 d* [) P) k( G1 w+ N. Q/ E setup.reverbTime = 0.2;
% n+ s8 j3 G$ |! z: P2 b7 J' D( ~; I reflectionOrder = 0;6 A5 F# n0 D' V/ Y7 \
else
, ?2 ? j/ d& [ reflectionOrder = -1;9 P. d. [3 u/ m' x- L5 J7 Y
end
: D3 U" B+ ~" o$ g3 p1 {: D
. P7 K! O( T @/ Z7 {" M4 B+ \rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...1 A0 \4 R3 r2 B' [* a- q) X7 M8 i
setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);; D* D$ P6 c6 k1 l B
( n4 V1 R+ f7 I- |, T
for iSens = 1:setup.nSensors,
% g {- h X( H! s/ i8 k* Y& ` tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);$ Z$ P5 o( }+ F( a: v/ F; E/ J: ~! S# Z
end
7 w" d. e$ d+ }/ H3 q% t6 c3 PmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;* Z6 H2 d! k, y- e# h
setup.nSamples = length(mcSignals.clean);
: e0 r% y% I5 Y& s
3 w! K; G8 x v9 [9 ImcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);) Q! M2 f( P9 Y0 E% @- n
1 K5 N. @$ x" }+ P$ p%-------produce the microphone recieved clean signals---------------------------------------------; o& Y+ H4 c. \' \; j* o
% \3 v( w9 l; f/ j) w# f) Smic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold. B$ @# V0 h( y$ i+ v
mic_clean2=10*mcSignals.clean(:,2);" H9 ^ I( Q, f* o4 L: I
mic_clean3=10*mcSignals.clean(:,3);2 s* d# I/ V& k7 t/ q
mic_clean4=10*mcSignals.clean(:,4);
% T& D% ^# O9 T% B* P7 laudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
& U7 L, O) n- Q& a2 m8 r, Saudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
! O' J2 a. V$ t3 _audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);9 i/ b* P5 G9 T, d" j D
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
9 G. G" S' m6 I9 [6 b2 U/ K* q0 B# K" K* V" g* P h$ @* }+ e
%----------------------------------end--------------------------------------------------
2 R4 p, _+ q6 S; k1 C2 {0 E0 g, | W/ [
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
( m- P" \- X; L
7 E* {! Q; N e! W& }& wcleanSignalPowerMeas = var(mcSignals.clean);* k) P0 _ e* b8 ^. ]- [( \9 _; P# T3 a
, ?8 g% T+ I9 e1 B
: I% L) E- E3 dmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...& r: l+ ^! X* Y: b
setup.speedOfSound,setup.noiseField);% C% a$ i/ \$ Y& ^- N
diffNoisePowerMeas = var(mcSignals.diffNoise);6 s" N7 c4 p; j% `
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
' N2 r& N0 _- ~! ~' p+ s8 l0 S$ ]mcSignals.diffNoise = mcSignals.diffNoise*...
1 M( Q% U7 r1 m2 W2 B0 F diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));# R$ c4 y+ _7 J- X
6 E% _6 Y2 {4 G/ k6 ^ M7 kmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);5 E7 E1 v+ W+ ^* @5 O. H3 F5 T: @
sensNoisePowerMeas = var(mcSignals.sensNoise);& Q' f! J) b0 \* g* D; `9 j8 ?( h: J
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);2 \4 K4 s) \: R! G
mcSignals.sensNoise = mcSignals.sensNoise*...
5 A% z7 Q2 N5 `0 M8 l# ` diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));2 K; G7 X) c( W' T
8 d" ]9 u0 l. _$ z6 T! C/ @mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;" b6 F, U* ]* _; R. ^% \
mcSignals.observed = mcSignals.clean + mcSignals.noise; q) w/ t: _: Z( @: `0 h7 w) M+ e6 j) s
5 @0 B+ g( i3 k+ ?+ z- h* }%------------------------------processing end-----------------------------------------------------------% l! B4 r: a2 r1 x
: v" S2 A4 |; |1 V
4 m0 m: X5 h. g: A1 k. k% t
1 ]6 J1 L3 r- c9 B. c9 x
2 k" W& U2 N- h2 I e8 G%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
( }. H! c1 @- h" g$ @" `8 d: ^6 L
) U1 ]7 j* p' U9 Hnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
5 A- r' }( |2 t2 Q1 ~1 [noisy_mix2=10*mcSignals.observed(:,2);* L4 n: J: G5 h1 _+ d
noisy_mix3=10*mcSignals.observed(:,3);
& I9 |, o" ~( [6 `' p& enoisy_mix4=10*mcSignals.observed(:,4);
5 _! a6 j7 S% pl1=size(noisy_mix1);: C; t6 S1 f% V% T
l2=size(noisy_mix2);
3 J, P1 h6 f& Y; Y- k& p( ]l3=size(noisy_mix3);
" `3 I% q) V. a+ Z, _ cl4=size(noisy_mix4);! S% Z4 _: m5 `
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
* C& o$ G: Q8 i% d5 f! a& Daudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);1 o+ X7 D4 O: e; V2 x
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);' E6 a! W' W! O0 h0 W$ `! O
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);" {9 j3 U6 m2 t
3 z( e# G3 b6 T: V
' N6 [; h7 f3 B, _' f6 o
%-----------------------------end-------------------------------------------------------------------------
) v, n2 `! }9 D; M- g这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。- e2 F& z7 G1 J/ y! s% a: o
直接把它们替换成你想要处理的音频文件即可。
( j% C: H# w T4 i f
& d7 h% @7 b, q* [5 r 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
: p5 ~1 b$ h" j3 k9 F$ x4 |( u6 B$ V9 `6 o. G
6 b! }* B+ f8 ]
/ u6 q+ a$ d6 m0 V$ b, D
图1 麦克风类型图
" p$ b) N$ E0 n$ t- n
: N5 f3 i* f/ B+ m$ P$ { F图二 房间的坐标系
7 I [; G5 w% `+ O, }
4 _2 @* L% q7 l6 ^6 H 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。. G+ B( J& x9 ^3 K2 s* y: P8 ^
————————————————
0 D- e3 d e5 G9 y* I$ c' C版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 K2 f ~0 Z; p! T
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
1 h; I7 j @7 O: }0 Z. I
/ t8 [* k8 _- H' ^+ z' U& K+ R* ^) ~: m& m0 u
|
zan
|