数学建模社区-数学中国
标题:
麦克风阵列仿真环境的搭建
[打印本页]
作者:
浅夏110
时间:
2020-5-15 15:10
标题:
麦克风阵列仿真环境的搭建
1. 引言
) L, u8 h- y# M0 I0 f
之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
( H `3 g+ K/ ]) i, i
- V" i6 K" J% @4 Z
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
5 o: ?# r6 h& N
2 M, Y( I1 S7 c, L; U* \6 o
2. 代码介绍
# \2 f1 j+ @& H( F. R5 y
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
5 @8 h5 t0 `; l$ M! {
function [mcSignals,setup] = multichannelSignalGenerator(setup)
- Y! x/ J% I- y7 {7 A
( A6 _+ Y8 a! S5 v
4 h/ Y5 c. z" U% h
%-----------------------------------------------------------------------
7 q2 I) X* Y$ Z9 F; _/ ]1 Q$ h3 S
% Producing the multi_noisy_signals for Mic array Beamforming.
7 O* c* q4 ]( q0 J
%
3 {+ {% a! w- N1 o7 R8 R
% Usage: multichannelSignalGenerator(setup)
6 F3 h; r: r& i/ d0 X3 W+ Y A" m
%
, W1 u1 q1 e# X
% setup.nRirLength : The length of Room Impulse Response Filter
! L3 w7 o6 s8 n* k; v1 A
% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
2 g) [' D$ |4 f7 Z: T% l/ K" D5 Y
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
/ G, R: ^' m) R2 O/ f. m
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
& ]0 x4 O) F) s) M2 q2 r+ L0 E
%
; Y: h) L- V/ p/ Z) u: d+ [) L
% setup.nSensors : The numbers of the Mic
' ~4 x2 C/ a. E& { y* _2 e3 r
% setup.sensorDistance : The distance between the adjacent Mics (m)
, |% U) x/ M0 P7 v9 q3 ?& L
% setup.reverbTime : The reverberation time of room
% g* Q6 Y0 ~4 ~) i/ J8 n" D n
% setup.speedOfSound : sound velocity (m/s)
1 [8 \7 y u) K
%
9 X/ r/ F4 J! Q/ n
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
7 y: f, Q" W# g" v, g
% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
' }7 D+ A& A9 u1 f9 H% K
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
. u1 T I7 x7 @! L8 a
%
& y6 {/ _6 g; n9 e9 g! q9 {8 }
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
1 ?; }( n/ w. M( E8 N
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
& ^' p( ?! ~5 ~; ~7 I9 N4 _
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
) }! m! |/ a7 ^# ^
%
( ~4 m+ @9 h7 q* U5 B
% srcHeight : The height of target audio source
$ |4 I+ B- \* ?! f! V7 G2 C
% arrayHeight : The height of mic array
$ B: p' x' g+ ^9 c3 T
%
& } y' w/ u+ h2 p$ f: q$ e K5 C
% arrayCenter : The Center Postion of mic array
# f i- l% r% ?. ?. Y/ E
%
, T7 p7 x& X4 C- H
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis
2 P/ C6 p! ?: G
%
+ W8 P- ]( ^5 [- B; m+ s" I
%
. Q6 p* A' Z/ _ T6 l
%
; @ r! [. n8 _; f
%
1 i* s. D6 B0 i* ]" N
%
3 Z* ^: J* z, J8 q4 R
%
- B, O$ ]5 e- T3 u" c T
% How To Use : JUST RUN
2 [6 i/ ^7 S+ M4 X
%
, O5 ]( y! S9 F* X3 M
%
0 ]! k b0 E: l2 w. z' n; E& i
%
! l$ ?. n5 ~9 u* a. e5 P0 x
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
6 T8 d. e3 X+ e: ^% {
% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
: e2 ~3 d3 R6 {( n. } h$ O
%
0 @) l0 B; y& S
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
% u) l, E7 E# \3 e8 ^
%-------------------------------------------------------------------------
% S- |+ X1 E2 R* m7 ]2 Y r
: |8 y" T) q4 v* j
9 ^4 `" W% r# ~/ E7 y# u2 ~
5 U; E! p% v: l& ~
addpath([cd,'\..\rirGen\']);
* C: X9 k1 y2 T n& M
2 A7 Y8 n) ^( j/ \# S9 P( x( {9 U2 _
%-----------------------------------------------initial parameters-----------------------------------
* G: [" u4 O& f! `8 H# N
* X" D/ x3 d; F
setup.nRirLength = 2048;
0 C8 y0 M/ g6 t1 b) i
setup.hpFilterFlag = 1;
. [8 _) @+ F4 v, f" M
setup.reflectionOrder = -1;
) S' I" _5 Y1 i5 {& M$ e
setup.micType = 'omnidirectional';
) J8 o% k. Q7 N9 {: W
setup.nSensors = 4;
8 Y# y5 a, L2 N) G/ W7 G* y
setup.sensorDistance = 0.05;
! \" X y e+ I) x+ @6 N/ I; n6 f
setup.reverbTime = 0.1;
) _ K3 p% n; p8 q* K) q& @
setup.speedOfSound = 340;
# N4 ~# [2 b+ h8 o% }. ]( r
- [8 Q* H, B& G: v4 Q, C5 {, V
setup.noiseField = 'spherical';
* }& E: ?% @" g8 F0 W
setup.sdnr = 20;
& J2 F4 ^8 s7 g U a
setup.ssnr = 25;
* q$ i9 Q4 I ]1 } [2 b* P; Y- I$ X
h6 `7 v0 z7 Q+ N' \& f2 Z
setup.roomDim = [3;4;3];
8 c7 c% _ r! B* U2 @6 x
: h: u9 ?4 m& B' t# q
srcHeight = 1;
8 g4 d* H# a0 P2 m* D1 k. B
arrayHeight = 1;
/ U' K& y" |# n0 u7 `
! ^( D' r/ C3 U: L
arrayCenter = [setup.roomDim(1:2)/2;1];
6 u5 P+ @- g# o$ H/ }: p
+ b9 b: n$ W4 J) p6 S0 R
arrayToSrcDistInt = [1,1];
' |, r- G% g7 L
+ _, q" b* c2 v
setup.srcPoint = [1.5;1;1];
5 p( _1 I+ s2 s+ z E i: m( S: j) r2 X
`! d. H1 f) ?3 X
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
0 i8 {* E W: v
- W) \- R0 M. @; U1 D5 a
* `5 Y, N2 L& n1 R- x
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
7 ~0 [* Q$ }2 d ^, ~, o; _# _
4 S3 F4 S9 {1 `6 A" u; y; X+ N
%---------------------------------------------------initial end----------------------------------------
; T& `$ ~3 x) k
4 s i4 F5 |' w4 L" X; N
2 M6 S5 `2 Y. b8 V
# a4 I3 T& s& g
%-------------------------------algorithm processing--------------------------------------------------
# C; Q# G* I( R5 t2 ~
; {8 j$ { @3 E/ \. [9 [
if setup.reverbTime == 0,
7 d5 ^+ n: P1 B8 c/ @8 W1 s" B
setup.reverbTime = 0.2;
: w6 F, C, U P) x
reflectionOrder = 0;
7 P# ]2 w9 D% d3 X! Q% E( b
else
4 j ^" ]% {9 F8 }
reflectionOrder = -1;
! j) z% y. B: [2 s4 q; S
end
; Z4 j/ G' x, p
4 }$ I6 X3 I B, B1 ^1 t
rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
/ g; ^* f) f& Y! i! [) }# [' H
setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
0 P' U4 Z, @$ l! r8 W3 A
# K4 x9 q; v8 C
for iSens = 1:setup.nSensors,
d f$ ^) J: t: x/ V4 P
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,
',cleanSignal);
/ M3 i, C7 P5 m1 L
end
- W7 z# _1 s9 A% {+ Q# Z5 T
mcSignals.clean = tmpCleanSignal(setup.nRirLength:end,
;
% l" [9 \9 a) C3 U8 P& ^- V
setup.nSamples = length(mcSignals.clean);
2 c6 `9 d3 @2 V# a- v4 ]" n
* Z# q% h2 \, q6 W9 _. s
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
9 q* t- i7 J7 B" a3 x
- K; B" ~* l3 T, {- ^/ ]7 G
%-------produce the microphone recieved clean signals---------------------------------------------
8 I% N3 O5 A5 N
2 Y6 _! j; j& r( v/ j
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
* o8 C' P5 e! ~; Y8 N) ^9 `) q7 d
mic_clean2=10*mcSignals.clean(:,2);
) e, B1 Y( M8 x
mic_clean3=10*mcSignals.clean(:,3);
- A* y8 Z4 Y5 m, P: |! I
mic_clean4=10*mcSignals.clean(:,4);
( J5 X1 o6 J1 a9 [0 m# U0 \
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
- P% V8 [7 {7 | d1 ?
audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
$ E) V6 g% z' B- q3 I
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
% \9 M0 {1 ~5 x$ o
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
* e0 _# Q3 K# f6 X. M' o) T$ T
2 Z9 h8 }, X8 h6 N0 c
%----------------------------------end--------------------------------------------------
c: X1 N* K5 v- o
0 U$ V" ` F0 Y8 E
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
- }, @ w! l2 |5 q. i5 P# V0 F& T
# m9 I- q; x, {9 s# @
cleanSignalPowerMeas = var(mcSignals.clean);
+ o% w9 n/ M- ?: j$ N) W, U
9 w! w" R, a; x
6 ^' c, |) q" `! Z
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
" u& q" `# t/ o+ j& D/ C
setup.speedOfSound,setup.noiseField);
5 {' s3 U" R! w6 h$ F. X1 t: e/ v
diffNoisePowerMeas = var(mcSignals.diffNoise);
$ a3 t0 d3 H# j' @& _2 v
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
8 X6 r4 {' r/ l. B ]' G6 V6 W" h) x
mcSignals.diffNoise = mcSignals.diffNoise*...
% g* g9 ~4 A7 _. t! p4 l+ t
diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
9 A8 J0 l `: o. k& C8 x: ~
& h+ R' W) t4 N I3 @# y: n9 O8 U% U9 L' K
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
- K* J6 w5 ~( P6 i( {4 K
sensNoisePowerMeas = var(mcSignals.sensNoise);
2 ~/ U, l* m% W; G
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
8 R& e- p5 b( c: o& p
mcSignals.sensNoise = mcSignals.sensNoise*...
" z5 t3 ^4 u! E2 n$ v; ]
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
( z; Q' x" F- ^% t% E- z6 o
8 E& C( ?! \( s. c* Q7 ~$ i3 m
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
) k6 B2 W/ e' \$ }
mcSignals.observed = mcSignals.clean + mcSignals.noise;
9 Y/ \: [' u( d. A
% F. |. ^) k+ V! t" i+ B
%------------------------------processing end-----------------------------------------------------------
. C8 E4 S J) [; E3 _" V
* s5 x( m6 c& s) H; P% g+ D! X
* ~# J& q6 b8 L# _& x7 {0 F
3 m+ v! \$ `4 N7 Z. r0 \: R
3 N0 J) n4 U$ L$ d
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
6 y. h K& q" ]6 B: O% Z% h' y* k
# X" j) C; i9 S" R# _
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
$ g! {' g5 f! T8 U) C
noisy_mix2=10*mcSignals.observed(:,2);
! l* F5 K2 ~) i; T
noisy_mix3=10*mcSignals.observed(:,3);
: I- r2 k0 s; \9 C9 l
noisy_mix4=10*mcSignals.observed(:,4);
+ P. T( s! I: ^( K# e0 ]
l1=size(noisy_mix1);
' Q6 f; z$ P# J
l2=size(noisy_mix2);
' L3 a, I0 Y2 M- }0 G
l3=size(noisy_mix3);
- I" u6 y3 a3 @+ d/ z; m Q2 P$ A
l4=size(noisy_mix4);
: T+ E& r! O, R7 Q0 [) f
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
7 @8 ]+ c) H8 P4 a3 Q* |
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
+ J. l: [# D. s$ }
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
0 T: L; U9 _9 N) w1 r
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
7 L- R; O M' H$ I& a. ?! o5 G
& ^8 K8 ]1 X* ^$ F* r) F7 G% y
' f6 I% u( {* C [' _
%-----------------------------end-------------------------------------------------------------------------
0 Q' B0 P" O) ?1 X. [6 b/ Y$ }0 {2 E
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
1 u" G9 k$ {9 B% [8 [/ Y
直接把它们替换成你想要处理的音频文件即可。
5 h2 C- P) E0 [( P
$ g! U$ s$ b. F ?/ d$ j1 N
除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
! q3 x, c. S' ~- ]
0 R" ~1 } g; e! a" n, i
- ~' ?2 {/ E2 d j+ U
( N% {0 a& f: z2 d+ O% h) {
图1 麦克风类型图
. e0 \" F' V( O5 o" o2 |7 b) O
' x% G& B- j2 t# V/ o4 k7 `
图二 房间的坐标系
' e R+ C3 M! h2 q' A1 B( C l4 @
7 l5 q8 j7 w3 o0 o& L
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
4 X5 \( J) V9 r
————————————————
3 a! X9 {6 R7 g" F' `5 I
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
5 `! ^6 H! A5 L) Q- q1 G
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
8 X @8 ~3 o2 }" H( @! b- N& e
& m: t- U% |" I- _3 A8 y
) e9 B% Y& X4 z+ O3 b
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5