- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36450 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13896
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
$ g7 p- k1 _3 t$ O' U 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
5 q: ]/ f. m7 Z# V& p! E( [
. A) D$ C$ T) k0 @' @4 ? 然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
1 B d2 [0 ~0 V. y5 t1 W; }9 f
4 k: s& F, F7 W' C7 [ {2. 代码介绍( Y5 i' m- R% X7 B
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
* v' V4 e4 w5 E$ gfunction [mcSignals,setup] = multichannelSignalGenerator(setup)
3 W0 a' L2 {& G: n/ U' B8 F/ l: S1 Q2 K' F+ Y: c( Z( W. T
0 y1 k3 F6 @6 P- c) b b%-----------------------------------------------------------------------
4 Q+ n/ P7 x. B. {6 k# J( P5 N; W: @6 a% Producing the multi_noisy_signals for Mic array Beamforming.1 L* j5 A* J: C% \+ V5 S
% - [) Y+ a) p. o- C' i
% Usage: multichannelSignalGenerator(setup)
+ y, x; r% y y4 B" u%
0 f7 g3 `$ s- S9 W: |% setup.nRirLength : The length of Room Impulse Response Filter% t" I9 r/ J2 I
% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default3 p1 Z: c) e9 L: H" ]; o p
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order./ s7 q1 e- }: }' @4 i \9 P
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
' i, J5 z A6 N0 z3 X( t- N% 6 e2 w) h/ @* C. m- r( x5 z
% setup.nSensors : The numbers of the Mic& q7 @- e9 D2 U9 C7 c8 _; u
% setup.sensorDistance : The distance between the adjacent Mics (m)5 w$ C9 s& m( M: z( ^2 m( [" t
% setup.reverbTime : The reverberation time of room* j# v8 [5 g! U/ O6 s, |
% setup.speedOfSound : sound velocity (m/s)
' U7 r3 g6 {9 f8 K%
3 H9 m6 w e6 }% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
! @& m$ D! L9 C* S: I" ~( C" e3 Z3 k% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
) F. J/ B [6 d0 [$ |- a' Q% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl." D) f% p0 t+ c: P" h1 O
%
; d0 n N* `7 [4 j( e0 G+ R% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
5 n" T: }) {& I4 ~# I! L% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). 4 ~1 s% f* `, F" b S
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m). 6 z4 ~- c$ h2 L3 ?& m- i5 u
%5 X- y7 F7 e. d5 P) Y9 O
% srcHeight : The height of target audio source+ S: c4 [# Q! G' ^( {
% arrayHeight : The height of mic array
0 y6 Y1 Q1 p+ q7 n- V. \! u%; t3 B8 {, \+ M+ q: |4 o5 J
% arrayCenter : The Center Postion of mic array
& M- K; g9 ?/ x5 Z9 B: l%8 x7 |5 {" G% w# x3 f* E
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis9 f, t, U( a5 i) x/ F7 ^
%
: h3 _9 N6 A7 d7 p%
4 @; r+ U% J! O7 B%
; `& g" {, E7 y. A# \( O%( T: J% [& S/ K
%
! F8 u- m" ~& _%
3 L: v: G* r5 j0 t% How To Use : JUST RUN
" O$ l" t, h# g h s%
/ i& F0 s0 m- {# p$ F% . Z3 [2 X- R: H
% , W- J2 |5 k! J1 _# z
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
( n2 V r; J8 T# A* L. V. o% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.247 O( K7 f# U" ^. j
%5 U5 r5 c" H/ u
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
, n, |+ K/ v% q" K0 f3 Y. U& a%-------------------------------------------------------------------------# e9 B8 Q: J; L& y
, x3 C4 P: a, u/ T% l
}1 Z/ T6 o: S
; Y; A. m" H" p# r/ Daddpath([cd,'\..\rirGen\']);
* ]" M# m' Y9 ^5 X& X- a! A$ h# e6 k. R
%-----------------------------------------------initial parameters-----------------------------------/ }4 q2 a4 }. H/ e9 c4 P
8 ]6 Q* g, l+ a" k0 P! \* Y2 p8 }$ X1 s
setup.nRirLength = 2048;, P/ g$ d B0 c0 e
setup.hpFilterFlag = 1;
4 B) t" y8 L8 y0 J6 t8 C1 usetup.reflectionOrder = -1;) Z' l. k5 s: x" Y
setup.micType = 'omnidirectional';
) V: f0 m6 |+ s E* x3 e) L; |( n5 Ssetup.nSensors = 4;' i3 v" K4 p" _- e' b
setup.sensorDistance = 0.05;
8 B1 K; Q8 U& J& Z7 H1 {% o% Esetup.reverbTime = 0.1;
6 \6 t( k7 G, ^9 L. tsetup.speedOfSound = 340;
* h( i0 v# A$ j# Z/ k9 b0 C7 t5 A; D) F/ ^) \
setup.noiseField = 'spherical';4 o3 @1 I7 c; V7 V0 C
setup.sdnr = 20;
7 ]7 w( F: v" N( v5 I( i6 _# Q+ v, psetup.ssnr = 25;: K% r" d, U" a# t$ c- A( f& O
0 |2 o# i9 |7 t* I, qsetup.roomDim = [3;4;3];1 P4 F9 t- R! v; c
' ^4 \! k& l$ X
srcHeight = 1;0 G: |4 o! `: J! H1 V C5 N) M4 G
arrayHeight = 1;& G. h, X Y, W: T* D6 u
" q5 f; `6 e TarrayCenter = [setup.roomDim(1:2)/2;1];7 c& m9 a' y/ b; i1 u: v
+ {) D( k% N( Z1 i$ n. BarrayToSrcDistInt = [1,1];9 I: q4 \$ a9 w. q
3 @9 c; g5 s& ?6 \; p8 Z, q
setup.srcPoint = [1.5;1;1];
& j; N5 w, |& w( i6 W1 n" y+ r/ `: ^% k
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);8 r( T( @1 \. w
1 A' r2 C5 [0 d
6 U/ y# C( `; c9 U5 _: I& ]& u
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');& h+ b- o$ Z8 v+ D
& H& X+ B Y& y) c+ m" n
%---------------------------------------------------initial end----------------------------------------* R" H) B. T" u5 J' c6 H9 J
& j) C- ~( u- X& {* P7 u# g3 Q G: R1 Z3 a' q3 H& P# W
. _$ A K, _9 v8 u7 l; H%-------------------------------algorithm processing--------------------------------------------------
$ C' F- |% \$ `9 c* {. c. X/ W
! T+ a! F9 n# {! f# p" Zif setup.reverbTime == 0,
; ~$ o( C5 \3 c, E2 d1 L# t setup.reverbTime = 0.2;
K1 P9 k) G2 P9 H2 B reflectionOrder = 0;' T8 r( ?' R* n3 y6 |
else# A7 p6 z3 I) ]$ r$ v4 V
reflectionOrder = -1;
( Q. G: a8 d( d' C' n, l8 R D, X$ Pend
% f# _3 f) o$ J
8 t4 ]! ~ v7 x! i% z2 M/ ErirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...2 Y$ P+ m* k/ e' ^
setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);! t6 ~0 K! [$ I. H8 y
. _7 h; H2 v2 P" `: y5 }, F( Xfor iSens = 1:setup.nSensors,
- B% v) B/ \/ O5 V2 r; u* g" ` tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);
& p$ I, ?" b1 v1 V8 k. n5 y2 q8 `1 Fend
5 b% v/ Y7 L [, ymcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;
s5 Y1 R, s- h0 J6 c) t1 K jsetup.nSamples = length(mcSignals.clean); x5 R8 s% r! W6 j
- O# y) R3 v1 w) a
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
9 I; J0 H% y2 t' I+ i, [
1 k5 n _' J! E5 @# Z. b%-------produce the microphone recieved clean signals---------------------------------------------
1 ]! J; r$ O! P% a5 x$ X' ^; l. d! \3 V: n) k
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold' b- B, o& a- ^% v Q( z* z7 V
mic_clean2=10*mcSignals.clean(:,2);1 ~; f" c$ j* B" I. h
mic_clean3=10*mcSignals.clean(:,3);# q G+ c0 c$ F+ R" Y0 n
mic_clean4=10*mcSignals.clean(:,4);6 j1 Z m# l) H' m
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);7 Z7 Z: T$ A/ r; d" v
audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);0 r2 T2 K) X3 i. H. d
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);- Q. n* `$ P; Y- a4 B' V
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
7 e3 o' m K& \. B# d" `. _6 Z. f6 j, b- p3 b! @9 b' z- Q
%----------------------------------end--------------------------------------------------1 o: S2 A6 c6 l9 T. Y# X" v
( I' l1 K3 b8 X- e! f: w5 H1 Y
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);0 V$ p+ \, x4 j0 h1 G6 A7 J% o2 Z
6 m' B+ l& x* E0 n/ BcleanSignalPowerMeas = var(mcSignals.clean);2 H7 y" d) K. h: H) l+ f
1 M+ c/ f* B B6 z
. X: |$ u n* \& u' s3 T/ X8 \
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
4 f# O P/ M% F S9 g/ v+ _5 H! h, x setup.speedOfSound,setup.noiseField);- C$ L& |$ g/ e7 `% k* P
diffNoisePowerMeas = var(mcSignals.diffNoise);* O) k! p0 i& [% V
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
$ W2 D* i/ H0 n' D! H4 f6 ymcSignals.diffNoise = mcSignals.diffNoise*...5 f1 A5 n U* f; f
diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));8 @& }" r$ n& g& l8 S8 w) s/ M
- Y1 D4 I/ a/ H2 fmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);" I5 P) B# u5 v+ I
sensNoisePowerMeas = var(mcSignals.sensNoise);
+ s* N+ R" y; f1 W/ U3 {) DsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
% A# c: z! c/ WmcSignals.sensNoise = mcSignals.sensNoise*.../ B& ]- w8 X* I6 N9 J
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
' ?# t& W. x) H3 H J& d
( I, R! w# N5 j# m% P2 s( m9 p% r7 ~mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;; ^3 U& ?& l' ^
mcSignals.observed = mcSignals.clean + mcSignals.noise;
) m! m, S n; ]) ? C3 G/ K
, h: }+ b5 v4 Q%------------------------------processing end-----------------------------------------------------------( ]5 u5 S. D/ h: M
3 h7 A, }" w" m& G: R/ D2 G& z7 }/ f' ?# W1 H. P
9 B! f; ?$ M) t! J+ {$ _! O9 O/ o6 q$ k* q
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
& a2 o' _; V! m; a5 |& H& Y, ?/ O- H. M- | r
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
* C4 g2 m) ^9 a* m+ g- wnoisy_mix2=10*mcSignals.observed(:,2);: g* {# X2 S! j
noisy_mix3=10*mcSignals.observed(:,3);6 C2 _4 ?, b4 d9 ?8 T; f) R$ b8 A
noisy_mix4=10*mcSignals.observed(:,4);
5 H% t, ]% M/ ^' G1 T1 Rl1=size(noisy_mix1);/ A; F# ^! C! m3 I5 W& u" c) J
l2=size(noisy_mix2);
+ X! [9 M0 U, ?, U# ?l3=size(noisy_mix3);
. b) \5 |, Q! F! f& V" v+ ml4=size(noisy_mix4);
4 W% v g5 F4 i+ y8 {$ f2 raudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
5 w* T/ M- T. @! f, X. r b+ E* vaudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);( u5 b+ @( ] q( G2 Z
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
8 |. ^& m1 Y* p$ W* X; Y4 L- q. ^$ ]: @audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
) Y) g; X- z7 b2 S4 v0 N5 W3 d' l
8 R* B! h1 T/ b0 `; G
%-----------------------------end-------------------------------------------------------------------------
; i: m9 x; S, c# z8 H5 {5 W0 B2 q这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。7 ?) w3 c3 V4 }
直接把它们替换成你想要处理的音频文件即可。% ]3 \: u& |) c3 D# {$ T4 n( w
1 l; g! W4 c! [# R! i$ [
除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。% x1 W( _. r; D( Q! b9 i0 f9 Z
; [9 l( N& A5 }8 q( M, f0 T
![]()
" k9 L/ ~9 T4 O. C4 P' G. e2 J7 @& w$ C: A+ e; Q( t% Q8 R- w) i: T
图1 麦克风类型图
: a( {9 Z; Q( ~2 V![]()
. a' d. r. i9 B, l- g图二 房间的坐标系
6 d/ S8 J% d" W, ~' ~0 U
9 T& B- C/ h& C 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
! I0 u d1 j5 O/ {& m————————————————
- s6 X' D2 Y. K* p* o n8 r; i+ [版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
; b: t, E2 i* Y4 F原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998% N7 t U( a( h4 I5 d
/ b: I- H( K6 C
; i) a u* ]+ D( I$ D/ i3 V! o' h |
zan
|