- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36349 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13865
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
1 g: m6 m6 M: a K2 f8 A$ }6 J 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。3 u" |) f+ _4 x3 ~
! f/ p; h/ A' Y3 K
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。: P3 W2 N$ `& O |- N
Y' I5 P8 _" p7 E+ z& o' C
2. 代码介绍
( W+ Z) A$ u6 o4 p 原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:7 ~* Y0 U% h7 _
function [mcSignals,setup] = multichannelSignalGenerator(setup)' y0 V, T/ n' B; i4 ~" B
) {/ i6 @/ Z3 Y3 l I. f5 }
1 h/ J- R! V! i7 c0 D% P
%-----------------------------------------------------------------------
/ G$ p+ K O* K% Producing the multi_noisy_signals for Mic array Beamforming.' ], u# z' ]6 z' \
%
g1 o$ j: [) c9 Q" B/ n# J% Usage: multichannelSignalGenerator(setup)+ x; @% H; ?4 b5 A6 W( |) C8 C
% % J" e J' ]6 X0 Z
% setup.nRirLength : The length of Room Impulse Response Filter& p0 d; [- K7 j" \. f r
% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
& N% @9 `5 {( x: M# m1 x" z Y" C% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.+ e+ z a) H8 S
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.& o: \; I2 |, N3 J; g$ r/ t
%
& {/ |( ?8 C/ Q9 {* G: c- n" N% setup.nSensors : The numbers of the Mic
* F# u# G% _. q3 i5 `% setup.sensorDistance : The distance between the adjacent Mics (m)
- N! \. ]8 h! D _% setup.reverbTime : The reverberation time of room
* U4 u# x6 K) Y* L9 `% setup.speedOfSound : sound velocity (m/s): e* T+ f, C2 r2 a0 _
%. x# p1 D' C' ~8 G
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical', k9 X3 k3 Z9 f$ s+ S# {& D
% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.- @$ _. Z9 T$ y# _: `6 T
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.8 ~5 J* ]: p$ I/ @3 W( H+ E5 j
%" j3 u4 j4 c. C
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
/ ~3 W* S2 _; T. o% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). 6 t1 T( \7 T; H0 \( W
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
7 W% R1 b! Y# `$ u: E%1 g7 X' A0 q# ~4 h, l% a: i' L2 `1 U
% srcHeight : The height of target audio source w( ~* w" H4 U
% arrayHeight : The height of mic array
. a5 W/ `9 n5 T' x) k%
; v8 S4 @0 D1 r; n, O% arrayCenter : The Center Postion of mic array 1 U1 u. M4 E9 e" s
%
$ E; P' m. j/ L; j7 l% arrayToSrcDistInt :The distance between the array and audio source on the xy axis5 ]8 m. c2 V% I- o
%) P1 y" r& G% p( {1 o
% 8 o; d( j- N$ A2 P8 N5 [# M: y
%
1 A" g0 e3 N6 [8 Z7 A. @9 d0 M%
D5 A. Q; u# \/ y- @5 u) K& b. m( R%
5 S9 J( N( d7 |1 \%
( u9 ~0 u# g7 x, l# T6 p% How To Use : JUST RUN4 n& ]& J1 m1 s4 W6 `
%) n7 B4 ?7 e2 {( y7 \0 C7 f" |, y
%
& G6 S* a, D3 r9 |6 j& y# I%
4 l5 W) ^/ J" Q: Q7 Y% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),& O5 @% N; t L( b/ v( V5 I9 X
% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
. L& Z. w! ~" y% |/ [8 J* S2 X%
4 C7 l$ V+ b, R% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
( c0 B5 f: W. {& \% R( c! H%-------------------------------------------------------------------------+ I; b9 z5 M: Q1 _9 {
) W( J, l# m6 k) y
% A7 m; R# G& `+ t7 n
! ]' V* k$ ^# }' G3 Waddpath([cd,'\..\rirGen\']);
: R) i: d" a9 r/ B4 r" G; ~ c4 H
! k) l5 k G4 E; N% S1 ~%-----------------------------------------------initial parameters-----------------------------------# H2 L. k w9 D/ k% ~; n, B
: S: p Q6 k; u- Q0 t9 H, P! Y# y
setup.nRirLength = 2048;
) c, e5 y' |- A7 o4 t# _setup.hpFilterFlag = 1;
& Y. Z) b. V- E( G! k" _6 I- wsetup.reflectionOrder = -1;
, _2 I. z' {. \ I; c7 qsetup.micType = 'omnidirectional';
" ]1 E; W5 T# z' j7 }7 ksetup.nSensors = 4;
% K. w' m* @$ \7 ?3 }setup.sensorDistance = 0.05;# d& h- Z1 D6 Y) d: s9 u R
setup.reverbTime = 0.1;6 J7 m4 z5 T: P. z
setup.speedOfSound = 340;
" W8 L# a% l* r# v2 C
% T0 d- q# H* _: z {: C& X% Isetup.noiseField = 'spherical';7 C/ h( `6 h: T4 W" f
setup.sdnr = 20; M# N C; [! f7 u9 l, Z5 E9 d
setup.ssnr = 25;
" Y* p0 z; m" D- y, M' p) H( f, e/ r7 d
setup.roomDim = [3;4;3];- e) E/ k% ]" c1 m
& A( N' d `$ p6 I) x
srcHeight = 1;7 l a, N2 [* {4 @) i9 w x" h
arrayHeight = 1;7 X3 S$ e6 a E
: p5 W* E% Q$ C7 u3 c3 z! parrayCenter = [setup.roomDim(1:2)/2;1];
# T- J) D4 r- A3 V7 U; o8 |- ?& B( q0 {0 D( O- o7 ]1 x: s/ e# ], [% V
arrayToSrcDistInt = [1,1]; G+ ? k1 R4 g) O/ o; M7 }% E
. k7 Z4 x. [/ u9 x- C
setup.srcPoint = [1.5;1;1];) S) D8 _5 W$ [% u
) }5 a1 s1 A# e1 Z8 n: l0 w. Rsetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
; \( u/ ^* r4 D5 {" [
; ^6 p- V# ^) k L6 Q, S& E' H- i0 d* l1 P: `+ |; @' W, l
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');% M; w2 Y& }& s$ N& q
8 B- g# }; q! g" W2 p9 K%---------------------------------------------------initial end----------------------------------------
. x! t' Q( `. c6 y' N5 S1 y" W0 p7 V9 j
& P! Z1 C' H1 A4 R
, H& A5 u* D' h
%-------------------------------algorithm processing--------------------------------------------------
9 m$ n, z& D& f# N; K
6 z' _) @4 h1 @- S6 Lif setup.reverbTime == 0,1 t0 m0 C) |, Y4 w' [& W7 M8 |
setup.reverbTime = 0.2;
/ w G( E7 u" M reflectionOrder = 0;
3 R# ?# Z5 f- V* c2 @- ?& K5 welse) P8 a+ I: ?1 R7 E8 \
reflectionOrder = -1;" y; D/ o! P: k$ G0 m: u$ e
end
: b A) X/ g* @9 F" r; y* j
e6 O* _6 f |! ?rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',.../ ^. s" E$ D- l0 q7 z: w5 r
setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
# n3 I* Z1 |9 u$ {# K/ Q$ o" _! N7 F# n6 U
for iSens = 1:setup.nSensors, J* _" j( ^9 Q) {+ w9 U
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);3 @. T* Y4 y; _# e
end
3 @. G2 y! m, R% Z; g+ BmcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;
% |2 Z1 P' k G4 r/ Y* ?setup.nSamples = length(mcSignals.clean);
7 `4 g, Z* G1 b) x! U6 ?7 P5 ~/ z1 k2 h
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);2 Q* {! ?4 r, i
5 Y+ {3 o8 A6 ]- _
%-------produce the microphone recieved clean signals---------------------------------------------
; I: ?$ S; k* `4 V# _5 W- l1 e: A% t* ^/ P
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold Q) B6 r/ c0 a3 n) d
mic_clean2=10*mcSignals.clean(:,2);
2 Q6 k( }* b# {$ P8 Smic_clean3=10*mcSignals.clean(:,3);
4 v& q. c, @- i% W; n9 Vmic_clean4=10*mcSignals.clean(:,4);0 _9 Q4 E. f; b5 F* E8 r+ C$ c
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
b: H0 S$ L6 `$ I9 C* F8 Waudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
4 t S2 }% u# Q7 c* E1 iaudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);5 e& |' c6 K7 x" d/ a
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
* O O. C' N& @6 Q% S* {3 S8 ^' Y6 T! T( N, c! d+ ?$ g! e
%----------------------------------end--------------------------------------------------7 o8 i; I: s6 q
8 X- o1 T' ]% D3 P; d( S5 y7 Y
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
+ S; b+ f: I6 c
& h# B' x; p) R: Q5 y" ucleanSignalPowerMeas = var(mcSignals.clean);
; d' l0 y/ t9 D' K+ h+ w- H \* l; ^( a; o4 O8 v
6 a1 h/ o1 P! T8 @ [! WmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
% G) Z+ k% V) W setup.speedOfSound,setup.noiseField);
4 S( t% d3 w& S7 s9 g. adiffNoisePowerMeas = var(mcSignals.diffNoise);2 a% h* S1 u% [$ o4 I0 N, A; n
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);. P# {5 m* O! X; F* d Y i
mcSignals.diffNoise = mcSignals.diffNoise*...
b, P0 O( x9 F diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));. P) `% C" Z4 @
! H d9 O2 p; z
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);5 c2 T( g5 k" r+ j z1 [; d
sensNoisePowerMeas = var(mcSignals.sensNoise);
3 n# E2 m/ ~" @8 q3 YsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
- T# w- }9 ~2 S, cmcSignals.sensNoise = mcSignals.sensNoise*...' O0 c0 G6 u- C# d) b
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));( E5 M/ S @+ [) Y9 w$ l
0 `; q: o! D5 v$ E. A7 @3 `6 U
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
8 b5 s+ i1 _" w7 |" tmcSignals.observed = mcSignals.clean + mcSignals.noise;
# m, {4 x/ E% p# B( U+ w) E7 v$ l1 I& i, T. h' X/ P) f
%------------------------------processing end-----------------------------------------------------------
9 `0 Z% t& m. M
, |: v8 u* i. ~9 v! o& Q G* Y' U+ O. |. P! P* t& d! ?) O
3 K/ J6 j. a4 P: L
) E! [9 T/ O, X: z Y
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------. r6 a& T" P( S) [3 H
" c# X+ B( l3 [3 ~: X7 J. w
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold4 w2 u9 k) V2 \. I5 }) D5 M
noisy_mix2=10*mcSignals.observed(:,2);* Y; `/ j$ T E: @4 I" A
noisy_mix3=10*mcSignals.observed(:,3);
) z3 T; R3 c8 V* s6 |noisy_mix4=10*mcSignals.observed(:,4);
2 [: F) ^# ~6 H( s5 Pl1=size(noisy_mix1);
6 v5 ^- | |: ]! ~# l# J- X* ll2=size(noisy_mix2);
4 N$ e/ C* i: dl3=size(noisy_mix3);+ A" |' d# d$ u
l4=size(noisy_mix4);' ~) ^2 `' k, X5 S+ u
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);+ A- u I$ k) i) f3 y" }( w
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
& {% Q2 g# j# ]) w: Gaudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
7 @9 j, d k1 [+ E. Q) }audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);* W" N+ V, \! L' _1 q
- h: G; g. j: x" {2 `8 e
7 u. P* \. h2 o
%-----------------------------end-------------------------------------------------------------------------
& k, q4 }" R& Z1 l$ {! G! y+ E* t这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。4 m- i, ]+ q8 p
直接把它们替换成你想要处理的音频文件即可。# h4 t& w' c. i0 n& j
( M$ }1 W8 ]2 }7 U* n' Q
除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
3 O% y+ x" @7 { E# x" I
) f% c z2 a: M+ L- I5 E: |7 w![]()
4 v* z8 \6 X4 a
% T2 T* F+ l! C/ t% x& h. d$ S( e图1 麦克风类型图
- ?# p! [/ J, l/ g7 D) a![]()
) y$ M- r5 P/ K5 j图二 房间的坐标系7 b- U% C) R7 W$ P/ f( `" l
& [% C& S; ^: o% r. y: ?
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。$ A. ?8 H$ t/ B; x$ ~
————————————————/ V: y4 @* Q, v& V* V
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# o8 I! `. [3 d4 S: `, G7 j# U. h原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749981 i. g2 a- Y& Y R$ j6 `( c
. {. Y( F8 l( V. R
3 c- S2 O% I$ R" J0 _6 b+ g |
zan
|