数学建模社区-数学中国

标题: 麦克风阵列仿真环境的搭建 [打印本页]

作者: 浅夏110    时间: 2020-5-15 15:10
标题: 麦克风阵列仿真环境的搭建
1. 引言) F* p! P/ ^: C: I
  之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
0 w( |: R9 n6 K7 K: c0 o! d1 T+ x$ s# n3 ?
  然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。( v8 |, ^' x: C  i/ ~$ v
5 A- N2 Q. P( s& a1 s
2. 代码介绍8 H) z$ b# n* G5 w# |) t& n' d
  原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
4 ]' W) c' m3 m! \. @, u3 _; g! K1 `function [mcSignals,setup] = multichannelSignalGenerator(setup)
1 f1 L' B: k5 _) m5 o. V! n5 ?- m' c8 i, I* o7 J
- s; [0 N6 J, _8 T/ G
%-----------------------------------------------------------------------
' T5 V  B+ J& J( J5 n8 L$ I%  Producing the multi_noisy_signals for Mic array Beamforming.0 H1 n/ ~! _6 ]( G5 a& }
%
" Z! e3 ^% A$ H* a0 b; [; {) K%  Usage:  multichannelSignalGenerator(setup)
  d$ ~" {% q& [! m%         7 f# R- q: ]2 D% z. q' @6 w
%        setup.nRirLength : The length of Room Impulse Response Filter/ H$ ^5 t8 O5 ?/ j
%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default* \) ?7 m! |5 I
%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
1 B# ?( g# u- I( f%        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
4 n9 Q, F+ T1 B& q0 _+ u; F. w%           
1 z5 k5 C2 R' C+ [$ T%        setup.nSensors : The numbers of the Mic
6 W) b4 o! @3 U$ {- J# f: q  H+ r%        setup.sensorDistance : The distance between the adjacent Mics (m)2 O2 d6 f- @& ~$ K# S
%        setup.reverbTime : The reverberation time of room
; r  K+ }  P* H%        setup.speedOfSound : sound velocity (m/s)
) _9 Z# G; x7 d$ w6 }$ x# s%6 ?# ?& G* n% j: u# L+ k: M& E5 |: d
%        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'/ e+ Z- N' L5 B0 {2 }  R6 i" E
%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.2 t3 G+ P3 r% X" W6 r7 |
%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
$ J+ x! Q" G1 O* q; w6 X%, W$ c1 \' r  i4 ~' w
%        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).             I( ^( H" `# h% X* m8 n
%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
. W- Y2 ~% {. U0 O8 L%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). 7 ~% D1 f  X6 _: M
%/ @/ d& w: k: A; ~; D9 K
%        srcHeight : The height of target audio source; W/ m4 Z6 B3 s' [
%        arrayHeight : The height of mic array* a: ^7 q6 h( h: q0 P3 K% \% n* \
%
- C/ o1 E! X! ?3 q%        arrayCenter : The Center Postion of mic array
: t! d8 l4 u5 c* _%' v6 E* y9 ^% o0 n
%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis
- {* i5 h$ w9 C) s1 l%
- m  ]7 Q6 j8 i0 ?%                       
  i3 M+ p3 a! m0 w; ?$ K%
. ^2 }8 b1 u& O& `%
! K' z& m" M/ O& ~1 U, _& c7 H5 G%         
, ~  T0 P4 a; E7 N  X' t3 O%: r2 T$ u' k0 W% @7 Y& K
%  How To Use : JUST RUN
; p+ O& [; O7 D( A  {' s& e%
+ J% Z6 K- _, T%  
$ v# w  N# }5 H: [3 t  R# J* E%   
2 t8 S! W" |5 [; o$ K0 ?% m% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),9 u% M2 V* K. ^5 X/ H
%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
' Y( q6 g7 P. i; K$ s" r%. }* m" m3 k" e4 `) C) V9 W) `4 T
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.! _; s2 S4 R( U; m  ^. d
%-------------------------------------------------------------------------
  M4 @. o5 E% t) N. W5 {/ U
+ p  V: {& y- |# b) [: V/ w8 [  X4 V: e

9 }2 f% n$ p; l: ]addpath([cd,'\..\rirGen\']);
9 e8 [3 j$ @' u8 }( t; S; N0 ?2 ~1 w
%-----------------------------------------------initial parameters-----------------------------------
0 ?- n0 L  ~8 j- n5 c8 ]6 `6 i, W: E6 f. q% z2 A" J/ I# M9 J  d
setup.nRirLength = 2048;4 a7 Y" P1 ?0 D* ?4 R
setup.hpFilterFlag = 1;
! m& g* l$ [/ J# }4 E. b) n1 Dsetup.reflectionOrder = -1;
- U! U; A3 j4 P( c7 Usetup.micType = 'omnidirectional';
7 G; a- z8 j/ M1 g  |' v( v; P" zsetup.nSensors = 4;
/ O+ G8 O5 F9 p0 w/ i" S6 ysetup.sensorDistance = 0.05;, r+ j: ]- q: d5 W, s6 q0 a0 ^
setup.reverbTime = 0.1;4 A5 ]* q$ R4 t
setup.speedOfSound = 340;
# [9 h5 U3 D0 w% M6 x1 b$ L1 \; }% B- o7 [/ _9 `2 w. W4 j
setup.noiseField = 'spherical';: E3 I+ f, ?* O) ]. ?9 b) w
setup.sdnr = 20;
6 ?  ~5 |7 j/ ~' `7 U/ m2 C2 j9 P+ D* Isetup.ssnr = 25;
% z0 B* K! G9 v2 B
* J4 R$ f, u3 T* @' j+ fsetup.roomDim = [3;4;3];$ W0 h2 f! c1 h0 ^- I/ X% c8 S5 [
4 ~8 ?9 Z3 v3 k& w
srcHeight = 1;; b& f9 \  Z* |& m3 G
arrayHeight = 1;. ^; X7 o' p0 u3 D, l: I& ]! L
: M$ C( F  d0 G' S/ @1 y0 _
arrayCenter = [setup.roomDim(1:2)/2;1];
+ |0 ^0 b( J  J6 J1 _
4 ?# z. ^/ J" t# F0 A8 x* A. ~arrayToSrcDistInt = [1,1];
; R1 D6 \: K& [: G* u- S0 O) _8 ~# S/ P5 n: f, w5 X
setup.srcPoint = [1.5;1;1];
6 l9 X3 s, C  h3 H# h8 U9 ?, i8 J+ P& Z- \8 D& v  i0 F4 ?
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
7 h. G1 y3 K7 F$ `8 x2 w# w+ m1 D( y3 C

1 y1 \+ p0 A$ Y5 B: S7 h5 U[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
2 c3 S" M' `* m' i  T: x4 o/ y  X4 j* g9 B
%---------------------------------------------------initial end----------------------------------------
. S/ x8 ~2 g! }+ b! H
9 Y1 E2 _1 t6 [7 ^' N8 X* F0 l: H7 M1 x7 O+ d: J) H

5 N( F, h: v) D, l0 V) T%-------------------------------algorithm processing--------------------------------------------------
" _, z2 w# }4 y7 P4 r- ?% W9 D# c' V* h3 \7 r
if setup.reverbTime == 0,
& b5 a5 b! ?7 I: }& o    setup.reverbTime = 0.2;" q; k! y" G$ d) T2 L- H$ }
    reflectionOrder = 0;
4 s7 J. T% w- ]! }2 |& helse- W0 N9 |; i: B
    reflectionOrder = -1;, d/ o; B3 `' H! E  B: U1 ^8 L6 _
end
. K- A9 m7 j2 @, u; [
; ?. C. J  m' T9 SrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...6 a1 R- @2 e1 Q) ?( X- q
    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);& f( _3 d+ N' f/ {1 G1 Y
3 l4 i& Y9 {$ P3 w8 q6 b
for iSens = 1:setup.nSensors,
4 K3 D1 A2 {5 C" [$ k8 E! F    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);* }* H9 {* a2 w' _" h, |
end
) ?3 X* T- [# ]1 j& TmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;  e" k' o7 v% v/ @# l" r
setup.nSamples = length(mcSignals.clean);' x* n( `) l3 {9 b; D
: G- X9 i) j& f$ o8 a
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
$ r1 C- N3 ]2 z/ J, n% t6 Z  S+ b7 Z; R, R6 _, R6 p! L) K' b
%-------produce the microphone recieved clean signals---------------------------------------------
5 A% y3 w: P7 ^  Z, q1 k. N8 x1 b# Q0 ]7 w+ a* y8 x: F1 _
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
0 b( Y7 \& x; I% g3 ?" [9 Gmic_clean2=10*mcSignals.clean(:,2);
+ r" @( U8 q, |0 P$ Lmic_clean3=10*mcSignals.clean(:,3);' N! T! G9 i! G
mic_clean4=10*mcSignals.clean(:,4);
6 R7 K3 V. o3 V$ [0 N3 K: \' aaudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
3 z+ D: T, ]2 V+ Yaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);' d. G6 F' }* g3 C: L9 Z+ A
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);* j5 ~" O) X  v$ ^  H5 T+ b
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);4 T+ K3 O- l5 \( B; j

; e: w$ f% o6 A" w, u. G" g  P$ ]%----------------------------------end--------------------------------------------------
2 e% k7 J( a0 }8 i- Q* A: |; D$ \1 C+ e+ ^5 b! H
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
% ^6 @: ?: `8 k) s' T, L
- U. G% b; L+ l6 M0 n8 }cleanSignalPowerMeas = var(mcSignals.clean);4 p- h* v5 ~, V8 F8 }+ T3 |
5 d2 E+ [! I5 ~5 ~" @8 i# j! i
9 y- D% W/ H" n; I2 v4 K- O+ u
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
# R, D- p  Q% z2 Q( f3 J5 F    setup.speedOfSound,setup.noiseField);
5 ~" ^$ r; ]" w' @diffNoisePowerMeas = var(mcSignals.diffNoise);
( \: u6 `2 H6 {  l2 ZdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
3 R# Y) F: @7 vmcSignals.diffNoise = mcSignals.diffNoise*...! \! l" U8 l% P, y$ Z$ q; v
    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
! v9 V' s# F4 Z- W! Y4 S  t4 {, h- v4 ]
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);, ?' a+ |  N! w8 G4 e/ ]% g
sensNoisePowerMeas = var(mcSignals.sensNoise);
3 B0 c2 t- e) |( v$ ~sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
7 I2 @9 R' c5 ^mcSignals.sensNoise = mcSignals.sensNoise*...
# s/ W: t% \# `  q% P1 ]- q    diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));, v6 a  D+ `! H
, Y+ K) N, L) x% K7 W% Q- e
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
! x! }9 j7 x. Z' mmcSignals.observed = mcSignals.clean + mcSignals.noise;
" [! g4 z$ d! d& s+ M1 v0 Z4 d
5 p7 C0 Y1 `' z%------------------------------processing end-----------------------------------------------------------' \! X/ _. z. o  M  @9 ?
" a. K+ b+ E* x4 Q# `; d  |
( U7 `' D5 g. j1 k
# e* T' ~% t, r8 I& w5 Y! {) X$ F
' p( E5 j2 ]0 b% G. |+ X
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------9 N1 e" z9 q, D. z) W0 {: f

' m+ ^$ j% ]" f9 P. d: nnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold% F, g4 ~! S: Y3 p
noisy_mix2=10*mcSignals.observed(:,2);
. j" ?# J4 [  `6 l- vnoisy_mix3=10*mcSignals.observed(:,3);+ y. Y% }( Q+ k! y8 R4 n3 \) f( o
noisy_mix4=10*mcSignals.observed(:,4);, ]& q, I0 _( W% @
l1=size(noisy_mix1);) O9 l, W& _) Q" Q* l0 z& f  q% e) F! B
l2=size(noisy_mix2);9 m3 C4 K+ k. I, r+ g! X* N. J2 [
l3=size(noisy_mix3);
2 f) k0 @) D" }! t5 il4=size(noisy_mix4);
& B+ F3 [" _! L3 xaudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);0 `) X6 i$ q+ |8 S+ n* D" [
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);5 ?$ \( e+ X) o" @, I
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
1 F" _3 D! L3 W% maudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
  E; |2 {/ E+ o8 _( D7 V
7 @6 [  _2 G& p' I1 c4 C2 @8 D/ j( J- w9 {" A
%-----------------------------end-------------------------------------------------------------------------# @% ]2 q9 A# h0 l
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。& u# e6 m/ _  G4 L
直接把它们替换成你想要处理的音频文件即可。
  l7 |  u% {8 h8 v- v+ d! y4 k, F4 k/ ?4 z1 a! B9 j
  除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。- S2 v( Q7 x) @$ E, T
9 C# N! s$ I5 e, L
0 l9 C! }4 m0 ?4 {3 P! I
& }, w8 \4 ?/ u/ C
图1 麦克风类型图
9 o% ]6 Y8 e5 @( ?; g% Z+ t5 r9 w' O
图二 房间的坐标系
2 A2 ?: d7 V" s) ?4 ]
/ e6 K* h+ P2 Q' I% ?  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
* g1 M. F- z! \+ Z+ j————————————————
, E4 Z0 I4 C' g* x0 u1 l版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。  y$ o5 ^/ b3 i
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
; A5 w1 _& k: S% t
& d7 N* P- n7 o$ M& c" v/ O; V2 M9 q$ S: {4 C+ q% ]





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5