数学建模社区-数学中国

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

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

6 M; }9 A* m! R% M  然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
3 W+ O0 x# r( D' k2 Z% o- n$ M
9 n8 p$ X2 `4 m1 w' `& k$ u2. 代码介绍. C3 K7 D* {% z. h
  原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:5 B& v. A( @9 s9 C& _. M
function [mcSignals,setup] = multichannelSignalGenerator(setup)0 c- m# k& i$ }+ }" e7 Q$ ^

9 ], m9 {5 W" m/ k" Y+ c/ J" h
! m5 ^- @! X- h# W' t# i. _%-----------------------------------------------------------------------
1 |, I" h, L% y1 w' c. \0 f5 V%  Producing the multi_noisy_signals for Mic array Beamforming.
$ R  _+ G+ m% ~+ T! E4 ?%
; q$ x% O$ n7 q0 a. P: S%  Usage:  multichannelSignalGenerator(setup)  Q0 A0 j$ y, I1 l6 O  k, j
%         , k! N) d& a! C" f6 H4 w9 D
%        setup.nRirLength : The length of Room Impulse Response Filter
( t3 i3 O* k; W%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default# X% `  A  x/ V
%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.; {8 k# u( W, t8 v
%        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
) x. V1 q6 v* R0 V% n* m3 \%           9 R4 a# A1 }( B6 M% A; X  B
%        setup.nSensors : The numbers of the Mic0 T5 Z% Q- z. w1 H+ z4 c9 B7 F% C
%        setup.sensorDistance : The distance between the adjacent Mics (m)
, U4 }2 D4 D' `! L2 T4 L%        setup.reverbTime : The reverberation time of room
- \% n. s: S8 C%        setup.speedOfSound : sound velocity (m/s)
+ l, ^# R! U4 r- N4 U- n%
" J. Q4 t; ]* p( G%        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'1 s; K% z5 |5 H& F- E
%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.0 Y* }1 l+ ]7 [* }; s% }
%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.3 M8 W) a9 k5 u+ p+ _
%6 W7 q$ k8 |* U
%        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
; n+ Y- {6 S/ J3 |( B- L- z%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
7 P( x" t5 x2 R/ u" _6 y" A5 y%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). 4 A" T. ^. Y# S9 m! ~: ]# [* a
%
' d  n6 o# s, V/ _; Y+ N%        srcHeight : The height of target audio source8 T4 f8 s, B" d3 j
%        arrayHeight : The height of mic array
) ~, c1 X7 i5 X: h! {: ]4 y$ F8 \%1 S; a" f" k$ l; ~7 _
%        arrayCenter : The Center Postion of mic array
4 V2 A0 g" V% W5 ^7 n: _0 K2 Q%
% t8 X& ^) _, c7 A, s' H%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis1 d6 E: l% B0 i4 B7 o7 r% _& Q
%
" {6 j$ W% s: {. A5 s2 n%                        & T3 q1 L" [' \
%/ E# l) B. X% K: R9 `0 C0 \; Z( ?
%
; `. L. K# I( h, o% G$ w$ `% _1 q%         
8 N& x" H( K# d- N" C3 a%
4 t5 m& z; I. k, ]4 O%  How To Use : JUST RUN) C7 V% s* s- g$ ~% \# B
%- }9 L/ [( ~8 s
%  ! f& h3 j. Q7 `; N4 U9 f
%   . Y  h; q" x, b
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),1 b9 q5 j; i8 \( n; P6 m' _
%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24# H% F9 y! j8 R9 N, v6 {
%
, h. ^4 l2 l+ c5 _  g% M% Copyright (C) 1989, 1991 Free Software Foundation, Inc.5 l3 G+ u1 b5 x4 _. w! k- F1 M7 r
%-------------------------------------------------------------------------5 d% E6 j# e  E6 O9 {# b
. [' D! n& k7 J0 w1 p# T2 ~% M2 |

0 G) |. a# }" [9 e  l( D5 R4 i3 ^' q+ U
addpath([cd,'\..\rirGen\']);
# M; o$ Q1 m* A6 c1 O* Y
0 [. k7 J* w6 T+ M$ a0 W%-----------------------------------------------initial parameters-----------------------------------
7 |3 P" x7 ~. i5 A; I
: {* F/ e1 {# F" v5 N- g3 E* Lsetup.nRirLength = 2048;
" K* f6 o) }2 _setup.hpFilterFlag = 1;0 v# o+ Y0 r/ }7 }
setup.reflectionOrder = -1;
# w0 V* a: \* u6 t9 Hsetup.micType = 'omnidirectional';
8 B1 Y/ ?% p3 R, E8 Nsetup.nSensors = 4;
0 |3 i- j2 \1 l- _* qsetup.sensorDistance = 0.05;* ?3 _: Z  ~8 l. b5 E8 c5 Q6 |
setup.reverbTime = 0.1;' i, n3 k; }; k8 h6 M& A9 [
setup.speedOfSound = 340;
, H9 M: r) p, Q4 ^, s, k
7 B, L5 g! c  W/ ^setup.noiseField = 'spherical';
! a# J& m" g3 b( isetup.sdnr = 20;
5 B) E8 [  {' g9 usetup.ssnr = 25;) d, \; G4 Y4 K

. d( U' C4 O' K# Z, \setup.roomDim = [3;4;3];
9 X6 G8 d, a7 X2 ~& x7 V. z8 X2 S2 z  X$ K+ b( H
srcHeight = 1;
; W; l9 O7 O' w/ }: TarrayHeight = 1;
+ W% h/ X) `( f6 S/ A  Y: o  @5 M5 e+ U* D) }) Y' s4 N
arrayCenter = [setup.roomDim(1:2)/2;1];
: s$ {! T7 P: ~
7 c) Q7 N+ K, }8 qarrayToSrcDistInt = [1,1];
* y. [# m  |% {9 n/ Y2 D" k8 W: h- F+ y* B+ I
setup.srcPoint = [1.5;1;1];0 }3 o  F) u$ `) R" S$ B- m
! v, S# ]. v6 I- A
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);6 x' r5 Q' e1 z" \' h" s

. ~! I6 e- z( y& Q6 o  s2 Z9 V' y' s% b, F' O  {# r
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
1 _8 H4 M% z. Z: L
2 o# w1 ^$ A, u- X3 b%---------------------------------------------------initial end----------------------------------------
; V9 g2 }3 m6 ?. x* K  s# k6 h1 e7 ?3 _) {; b+ D
6 U7 f3 T! f4 V& X9 i

# Q/ ?9 _: U  z* @6 j%-------------------------------algorithm processing--------------------------------------------------: k: q# R' p7 L3 m1 V
+ l. h( _  s0 y" |% y' L
if setup.reverbTime == 0,
; O* J, Y8 }8 m7 H% T0 [    setup.reverbTime = 0.2;
( B1 I0 |. r! }# H' u9 {    reflectionOrder = 0;, b6 c  d' ~$ t. ]
else
- s8 ]( k* v& u& [$ d. `$ X2 J/ p    reflectionOrder = -1;
0 J+ C$ k$ G; j3 _' L! send
( ]9 ]6 A* }/ N3 j3 d9 [, p  Q" z% y
+ t& x0 c  f9 e7 l4 |! M- L- DrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',.../ S' n7 d) g0 n) f. ~# m1 K9 t
    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);: o2 r& d. z4 u8 m# {7 r
$ `  o( ]0 V9 w2 R: e
for iSens = 1:setup.nSensors,9 o( @0 d  V7 ?8 M# i4 C
    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);# g1 s! C9 S6 I; _' H8 [
end2 |. {. L$ \" n# w9 J$ c
mcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;9 g. I9 j' p! v. z
setup.nSamples = length(mcSignals.clean);5 w& A* s0 v) s; N
/ n& o, W1 p$ A+ ^* c
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);8 o8 ?" R2 C- Z* d6 q* [
4 b9 ~4 r) b7 n* R% t% A% Y; M
%-------produce the microphone recieved clean signals---------------------------------------------
" j8 S) Z2 v4 H% }/ x; M6 \' W; Q, N* l5 z
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold, N6 P& g1 j' ]6 B1 O& i- L
mic_clean2=10*mcSignals.clean(:,2);
, e. Q4 J4 L5 n3 h2 m4 emic_clean3=10*mcSignals.clean(:,3);% b1 ?3 T: L0 L! z3 R0 e
mic_clean4=10*mcSignals.clean(:,4);: r6 S' L) J, F  L5 S% d
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);  B  [. F, u; k2 C) u) y
audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);' S4 l7 X/ h+ `# p
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);7 V  S+ `$ d2 r& y
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
( h; H) n3 N& B8 ~% {: g7 f5 U# q. o0 A) I# B
%----------------------------------end--------------------------------------------------
/ ]5 U6 B8 K8 t- X5 ~* |9 t, f' B+ b  \# `5 Y1 h3 r. l) u6 d
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
% M+ v  E5 v! w8 K7 `' u! T3 \2 g8 h9 m; H/ f( n- H8 R* J
cleanSignalPowerMeas = var(mcSignals.clean);
; g0 e! l4 N4 D$ k. K1 j$ y' I
& U$ m0 f7 m! V9 F" Z0 [
4 l0 s2 F1 M- a/ Q( L$ zmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...( k% s% W, T3 J# P: r" Z, U* `" z
    setup.speedOfSound,setup.noiseField);2 P' q, Z( v9 v$ S2 f
diffNoisePowerMeas = var(mcSignals.diffNoise);
! R( f3 Z. [+ z) gdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);9 Y3 w$ H0 c) _: h6 G- j, Q$ K9 z
mcSignals.diffNoise = mcSignals.diffNoise*...' C4 [% C1 @1 F
    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));! {) V1 E$ c% _- s2 d

4 S/ L$ d3 Y% P/ n7 @$ CmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
, d+ i: m( ~9 T; h$ f+ K! T# D  msensNoisePowerMeas = var(mcSignals.sensNoise);2 c. n+ I4 @  ?: }6 h
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
8 B7 }2 q% C: r9 I5 I" amcSignals.sensNoise = mcSignals.sensNoise*...
: z# @5 i+ V! ^0 h    diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
) A. \5 ~/ }1 T7 R! }. H; O
. M5 ~  l9 B6 K) _; ?mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
0 y+ r5 M3 Z0 u# g$ J) {: A4 q) d( f1 wmcSignals.observed = mcSignals.clean + mcSignals.noise;
# L" N' V) V5 W1 N- }3 i# a. _3 V" V; m, {. ]
%------------------------------processing end-----------------------------------------------------------) C* P. u2 m6 K
1 A. P7 S8 W0 m
3 O# h1 n! \6 F, q2 X, p4 ^

* {+ H0 Z+ u) i4 q1 C- G0 J7 P  n  C5 V$ s3 ^  {  D
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------0 M3 i8 b: a; h) l4 O+ V  @* ?

' z6 W8 @- R2 F. h- Y2 pnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold# E' ?0 l% l! V' F' y5 f
noisy_mix2=10*mcSignals.observed(:,2);( i2 {) `7 O0 |2 @( s
noisy_mix3=10*mcSignals.observed(:,3);7 q" d' w* a1 z. R' ?
noisy_mix4=10*mcSignals.observed(:,4);
7 y( t& {( f+ @5 F* Jl1=size(noisy_mix1);
$ b( H# K6 G' G- A9 @l2=size(noisy_mix2);
* i: {& `& `; m  z. m+ h5 }l3=size(noisy_mix3);
" ~6 O8 L9 k  P- j+ z! {l4=size(noisy_mix4);- {' J6 W* f7 P( h3 V$ K0 W
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);% o& v( F$ Y! e8 a8 Y, Q
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
$ n& v, Y7 r% |& [! saudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);" y" y- H' O$ y' N8 q1 ~* V
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
* \! W6 @1 O: j: X# a0 T; k$ v
8 s* S! Q% J8 P; j4 h: e6 f+ s9 h2 J: g; r5 i
%-----------------------------end-------------------------------------------------------------------------
/ n% D2 O+ p# b" }' d# e; ]* W6 r这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
9 E  w' k( G. l! P直接把它们替换成你想要处理的音频文件即可。% O7 B' z1 r3 [2 _; M* Z
5 e: D3 ]& k+ g% z
  除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。1 Z2 j( G9 ]- K

  c9 X; j3 T* L7 S0 s3 P
9 j5 @6 z1 C! C0 f! C+ p2 A6 G# {9 ^' r) ]
图1 麦克风类型图
4 x4 |8 Y9 a2 l% g( x  M* r& i, u3 Q$ E& C/ U
图二 房间的坐标系+ \. N# M' D& [9 E

( m1 t+ e- y! U8 I* X& `& E  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。, v8 S# K3 e: T! i( @
————————————————
, F0 p3 ~5 `% P. u  S' z0 p6 @版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
8 C7 p" e* o5 T5 {/ l" }% f原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998' x; L8 I$ @, [$ {- Q& }
2 @1 X. U' R& x0 w8 A
& |+ z0 R5 ?9 V1 K1 ]  K& F. V





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