数学建模社区-数学中国

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

作者: 浅夏110    时间: 2020-5-15 15:10
标题: 麦克风阵列仿真环境的搭建
1. 引言$ @$ X5 }0 n8 [' m' P( }+ P& Y; ?
  之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。/ B6 n& M7 g% ^& d

% t: {/ W$ A/ W  然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。1 z6 r* v( l( a7 q; P

$ }: f( |, z+ P( ^* M2. 代码介绍4 p6 u% x+ v3 ?$ [" u0 G; A
  原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:  O6 G2 C. D9 f* M* K3 p8 @3 J
function [mcSignals,setup] = multichannelSignalGenerator(setup)
. D) h$ Y/ x7 l9 T  D( f  t. S7 t" e
# P& T# ~, l/ y# b, `% Y
%-----------------------------------------------------------------------) y  _3 V9 M6 v+ p  e7 m
%  Producing the multi_noisy_signals for Mic array Beamforming.+ \, _7 }. h- {7 ?# Y. ?7 t( J
% + c* u* c5 C. ~5 D
%  Usage:  multichannelSignalGenerator(setup)  U4 a0 N& \( @! p! o# M
%         3 j! a/ O, X$ g8 \( L
%        setup.nRirLength : The length of Room Impulse Response Filter  X1 \+ m$ K! o1 }$ G, F
%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default; B7 Q$ d2 M* s; O
%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.7 t% k/ A7 |# d8 n( o
%        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional., d  ]2 a2 _- }1 ^
%           * T3 ?2 v5 r) V
%        setup.nSensors : The numbers of the Mic0 {# }" E) r. A. B& m1 h& R: o0 ^
%        setup.sensorDistance : The distance between the adjacent Mics (m)
, n/ D) B: l1 H%        setup.reverbTime : The reverberation time of room* n! D" p1 ~8 n! o
%        setup.speedOfSound : sound velocity (m/s)# H6 P7 |2 U  m' u
%
1 F7 L1 x6 c) d1 U* w5 o' N%        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical': x1 B! y" y& x! o
%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
9 X0 ^4 d8 M3 k" P5 s%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.) j+ ~2 u* U- V1 W8 n1 M
%
/ |7 m8 U; v; q%        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
% s% J+ S7 w2 J6 r1 l; k%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
% [$ {$ r  [3 {: j) ~4 W0 x%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m).
8 n; w6 \( }6 s, p9 d' u1 e%, e3 H9 @- r" N5 J( g1 i' _8 O
%        srcHeight : The height of target audio source
0 @: }) [6 C3 h; t2 C%        arrayHeight : The height of mic array$ f8 o( V7 ^  x( k
%2 j; p1 v. q9 L4 N" s7 |, I* ~
%        arrayCenter : The Center Postion of mic array ' I5 k6 J) T6 n$ _0 z
%
! W$ N6 M; c: `%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis
' z+ p9 z$ \  T1 H( W%
$ w) M( J$ l, y+ u$ r%                       
& y& k: o! x5 j/ S) ~%6 E& h7 P+ u( j' m% i# l
%4 o* G' D* I6 N; |
%         ( S- y  H& u9 Y( j' O0 t
%
' G: r2 C0 K5 m8 w$ i# j" |( A%  How To Use : JUST RUN. z7 d0 Z+ ?& X4 w
%
, K' A! }" Z/ }6 U  M0 K0 H%  
8 @6 ]+ \- P* j6 Z%   
* u5 `. U( w0 b" h& W; U( \' p% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
8 o" X% v& L; R%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
2 |$ N3 v# I& |5 S7 I. Z# k%3 w0 ~8 v( x, U
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.. J  L' k$ `, ]6 |; k. ?
%-------------------------------------------------------------------------' }% O  O& E6 K: H

; G+ M/ D9 h) ~$ q. z$ h( K9 u# A' E% _' i  A
0 i+ d4 [$ N3 f* \+ F  \
addpath([cd,'\..\rirGen\']);
/ v9 y. d2 j* R6 {
+ H4 ]/ g% w8 p5 Y4 a%-----------------------------------------------initial parameters-----------------------------------
$ l1 i: o9 ?/ _# F- f) h; y( D2 M& V! J( n
setup.nRirLength = 2048;
1 y/ |/ D: P: H' ]; p5 e7 xsetup.hpFilterFlag = 1;
' y( D; D8 o: D! U, r( Jsetup.reflectionOrder = -1;
0 S5 G4 W4 I# m; W4 csetup.micType = 'omnidirectional';; @( Q5 m# M& m" ~0 d) h
setup.nSensors = 4;# I# W5 D& w9 @
setup.sensorDistance = 0.05;9 [/ k, \* f) S
setup.reverbTime = 0.1;: f' G3 F9 k" i8 j8 X
setup.speedOfSound = 340;" w6 W4 o% u- ~" z/ u, ~0 E, K  a7 W

% |  d- Y8 d# v+ Z* \setup.noiseField = 'spherical';  g) L' H% S: a: L) S
setup.sdnr = 20;6 ?) d3 W, C+ ~$ ?. k/ ?
setup.ssnr = 25;" H+ u% `( f# A3 X' M5 }
) U. ^5 N" O$ u" h3 u; ^3 _
setup.roomDim = [3;4;3];+ Z. o/ v! F$ h! t( M

0 q9 `& o* z7 \- LsrcHeight = 1;6 R1 N& Q) K$ o; d1 a# Q
arrayHeight = 1;
& ^- x7 p  D# B1 |3 c* f; p
" T% A; f, a3 y, n  sarrayCenter = [setup.roomDim(1:2)/2;1];, h7 t$ t& e( p' ~! V2 z4 w. _& v

' q6 b! \- x3 m" T" darrayToSrcDistInt = [1,1];
, Q0 V# ^2 D3 W* l8 x5 Y" ~# ~5 g+ c7 f7 Y6 g4 E. F
setup.srcPoint = [1.5;1;1];' C5 E2 I  r4 q8 R1 p* Y+ L

& x( F( ^- `9 f6 Rsetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
# N) T) ]/ y% P7 W
1 x- \. P+ C5 t+ P' t& Y' D$ i0 B8 k0 g" c/ {, d# r( g
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
7 y0 f& ^  M2 b2 |* R' A  E% W' z4 ?. h1 y  K: u
%---------------------------------------------------initial end----------------------------------------
) L; L3 ?. P, j. ^3 M+ H: A& w6 r
, G( Q. B5 w+ K6 b2 E! j3 s: F3 ?) j/ P
! t/ c4 P" b( j9 {: F
%-------------------------------algorithm processing--------------------------------------------------" o  X, Q4 |1 d2 f( \

2 X$ l6 Z- k+ U; pif setup.reverbTime == 0,- d" h5 n( L9 V6 ]
    setup.reverbTime = 0.2;
1 G0 u0 Z. W& o* u1 O    reflectionOrder = 0;
2 j, I# F6 h/ s0 ]* `else
# {6 @; P6 E* g& |& o    reflectionOrder = -1;
$ `! ]% N& F( ^" @3 }" r1 {5 |end8 o: x+ R9 O* W9 z* y

7 o6 J8 S" a  M" ^- irirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...) b. h% R8 t% T! R& @  r
    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
0 j+ I0 i9 Q0 Z. @0 Q: q6 `6 p- ?3 l( M! O, v
for iSens = 1:setup.nSensors,
- c/ B; b2 K! L+ I+ D& u    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);. `! N" c  ?% C* R
end
9 r4 o2 t1 i; GmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;& g$ E# Y2 S3 v+ a0 g! h
setup.nSamples = length(mcSignals.clean);8 q% Y0 [* X2 o4 ?* q) m$ J: i3 v
) Q  B4 C" A! e, w* ~! V7 T
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
9 J+ h7 {9 q, A1 g1 ]8 i, R& p7 N- o% P1 _" t+ `
%-------produce the microphone recieved clean signals---------------------------------------------9 d1 O5 L! q) ^$ [7 G0 N2 S

& q+ L, T+ P: P# Cmic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
5 }0 L5 J# _# F0 zmic_clean2=10*mcSignals.clean(:,2);/ O( Q1 |4 }# J
mic_clean3=10*mcSignals.clean(:,3);
) y7 U9 V' G  e0 |; n/ q# ^7 S3 tmic_clean4=10*mcSignals.clean(:,4);$ _) \* }2 n! L. X3 P0 j
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);! X' r9 F0 m) v& e0 v3 X
audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);8 B2 X. n/ [% C7 I
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);. Y) F9 m" ]6 ]! h) R' r2 Z$ {% j
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);& t- r, |) r' G5 s5 s

  M" M  Q& z" Z3 n4 h%----------------------------------end--------------------------------------------------
# R$ h0 ~* L* X3 N  I8 t& X5 q; i5 o7 e2 j# I2 H) N
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);$ E9 y9 E% C( L5 z4 Q/ M" e3 P' J
7 P* m5 L+ y! x6 P! D& `7 e
cleanSignalPowerMeas = var(mcSignals.clean);
+ E% H6 q2 e) X5 ?* Q; z, h* h$ F, w4 l% J2 B( @+ u: r' [: [

3 ?1 L* y! E& I6 t( D4 }( C  dmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...4 `% e% C; b# j* G+ o0 I
    setup.speedOfSound,setup.noiseField);* l6 W' x& k/ ?0 {. b5 z+ d
diffNoisePowerMeas = var(mcSignals.diffNoise);8 `( O+ J. H2 a. x! z. }
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
1 }2 v- k! s& a3 K' LmcSignals.diffNoise = mcSignals.diffNoise*...+ C( x1 A$ `9 E
    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
& O# f6 n# r5 v  s9 k
1 ^2 e0 P& f7 ]2 F5 M4 @3 s* imcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
8 X8 w0 G( T) _. o' v* nsensNoisePowerMeas = var(mcSignals.sensNoise);2 D) W' _5 x8 u
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);7 Q* V6 ?. O+ i7 e4 v
mcSignals.sensNoise = mcSignals.sensNoise*...
$ |! r6 _' m/ Z% K7 |5 {8 ^9 C. Z# _    diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));% ?3 E+ v7 A( I- j3 S% E1 k

1 c0 P5 j7 O  B, `+ I0 `' fmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;7 z8 m9 y& F0 A: k, h8 J, Y8 {7 i
mcSignals.observed = mcSignals.clean + mcSignals.noise;% H8 G  F3 u: M5 n, P" K0 H' s
4 T3 I1 ~7 T" r- x: p5 z  I
%------------------------------processing end-----------------------------------------------------------
8 s1 X3 x! }. \( H$ O* x4 a9 T  t1 B8 W. c8 e$ Z' |( M, ]

9 U( W* l6 z$ i1 G! X* J9 `  Z5 @  @/ F' b& w' F$ p
1 f% @+ c' c# v5 c" }
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------% m- T( e9 t" F5 T# L; h
+ s" m, M6 T4 g3 x+ E& x; x3 W
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold) Z! e( o* ~& F
noisy_mix2=10*mcSignals.observed(:,2);! _; A9 x/ S' r/ s; R$ q7 N: c
noisy_mix3=10*mcSignals.observed(:,3);2 o/ V! S9 B- M# J; `
noisy_mix4=10*mcSignals.observed(:,4);' r5 I6 `, J9 o/ H0 c/ o5 T& r! ~
l1=size(noisy_mix1);
, h( Z5 \$ F5 Y6 r2 Il2=size(noisy_mix2);5 j& A$ I9 L1 k* r. g& ]; C
l3=size(noisy_mix3);
6 I- Y. o+ ~; zl4=size(noisy_mix4);& o6 `# s3 Z1 T7 Z& f4 ?
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
- w, o/ c1 }3 V5 p. oaudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);) |- v0 u& _# v. \
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
2 E) R' V* n6 A( F# \( W+ `! Eaudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
. x1 u- J, X6 a2 o
; u7 {+ b# C5 n
/ e! O5 n; R) b6 w; \%-----------------------------end-------------------------------------------------------------------------
% R/ _- C/ K9 z! d  q, K/ S这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。7 W5 o& u( c, p9 v4 w( q2 M5 n
直接把它们替换成你想要处理的音频文件即可。
; D% V" r7 i* ~( F8 _# l+ Z! l
7 G4 ~  t8 d' ]: A1 H! |5 n: C* g9 v  除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
8 n, a! W$ \1 ?" o" j% K( k) Y8 v& a5 H  ?) J6 C/ ?

. N% o1 d# Q$ Y1 a- X9 ?$ N* ?& g1 A- ~# A( g# Z
图1 麦克风类型图" m; G* V4 _" F) A
. l8 t& B4 o( U$ \
图二 房间的坐标系/ o, A( u& M% b

$ f; b/ \3 ^5 y+ C' f  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
0 N5 ?5 w  T) W$ ^& |6 g  C————————————————
2 c4 v# [6 {# J* ^( m7 ?( g! ?版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
( W; l8 v- c: l; b. d原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749986 H  `6 \2 w+ A+ D6 a% V

1 P! O8 o4 i' w$ i; c3 `1 `3 T4 K! h/ ]





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