- 在线时间
- 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. 引言
! b& ]4 T& K* F& ~2 b: I 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。) ~3 z7 P4 |" C1 `9 h Q2 n
- F7 x3 |! U' Z; Q$ C5 a1 l
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
. w$ U4 i( ]/ e* F/ f7 j. |; ~+ W/ \4 ?. s* f& }: Q& |
2. 代码介绍
& u5 |8 h6 K3 |6 w* u/ H8 s 原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:- E( J' e9 y, X1 H2 ?0 ^+ Y
function [mcSignals,setup] = multichannelSignalGenerator(setup)" S9 ?2 O5 X- C/ L6 e; M
2 _- k' P$ M; `* O! R4 A
+ W; i3 l K! a7 M D%-----------------------------------------------------------------------2 B) j. N r. @/ l
% Producing the multi_noisy_signals for Mic array Beamforming.. G7 D1 t, h9 h# f o& j4 z" Y4 l
%
+ P8 S& E4 |3 r% Usage: multichannelSignalGenerator(setup)! q, r! t* j. G1 q( v' _
%
5 A+ l- |2 l; `% setup.nRirLength : The length of Room Impulse Response Filter
2 M% m( F0 f l6 [% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
. h8 ^ Z5 s7 S$ i% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
! v! j: a# Z) q A$ F% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
7 T$ B# M1 w" O4 r+ ~. ^% L% 6 }$ c8 x% x) M7 Z* d; u
% setup.nSensors : The numbers of the Mic
6 h+ k) _" Y) K! v& Z: r% setup.sensorDistance : The distance between the adjacent Mics (m)8 P* r: M- p( j% A q9 r+ ~3 e2 i3 \ l
% setup.reverbTime : The reverberation time of room2 x& c3 c6 H7 J% W; S& ?$ J2 N
% setup.speedOfSound : sound velocity (m/s) m% l0 `' r! h* s( r
% s- Q0 W& P6 @, L
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
/ }. [' P3 e8 f& B, p% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.: K* c1 @6 k3 k# V; K% N
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
0 w( C/ `- f# L7 G! h5 a6 F%
- P* W: T9 `3 @ M% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). $ a$ Q% j" m4 ?7 S) P5 D, E
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
: {6 b; t u6 B$ J1 D8 a4 |+ h8 V% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
, Q8 G! k5 a7 {& o5 J0 Q3 j%
0 z7 U% V' p$ t# F$ i# |/ s% srcHeight : The height of target audio source
+ b' S9 \! S C: m# v; N% arrayHeight : The height of mic array# C; t% N' _, F( K* J% X
%3 k h# W% p C2 U' k- J
% arrayCenter : The Center Postion of mic array 6 A3 Y \* A. |2 t
%5 d1 H' B2 M3 D
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis
2 O- q/ E' J; R: d% t: U0 L%. b, Y* m$ y; U7 B' `7 q3 Z
% 8 Z, Z& {$ o8 U" o$ r1 a1 U/ A8 A
%: y$ ?0 ?8 M' e; P' f G
%8 v; D4 g( d7 {; p) J4 [
%
& N' h/ L! |" F5 s4 f; d# x4 J. j%
- _: F/ z/ C" w% How To Use : JUST RUN
* [+ `8 ?0 c+ O0 o/ v: t! c8 n%
; g9 m4 C. g- ?& a6 D% H% 3 T' k9 G+ w: }* ^% ~! }
%
' ~6 i0 O2 D8 B- ]$ Z% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
% H1 M2 |! Q" O8 G: R; ]0 w% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
6 S" Z4 B, A: V4 \; k: }6 G2 [%
4 ~' h! j# R$ m$ h% Copyright (C) 1989, 1991 Free Software Foundation, Inc., N, y1 @9 ~/ ^! t
%-------------------------------------------------------------------------
5 V: i! p: }/ p% E
; D- H: D) ^! \7 K# j9 h$ a/ f' X/ v0 k+ U9 f% w
$ L K+ m$ ?# t4 |6 saddpath([cd,'\..\rirGen\']);
" ?1 L; O; J+ y. `- u7 B0 Y6 |) D3 c* @3 L! J0 Q x/ G$ {, A
%-----------------------------------------------initial parameters-----------------------------------
+ |5 b, J8 |: C, |# m) F0 o# V$ _, A3 S2 h- |* ]9 a6 a* F
setup.nRirLength = 2048;
$ i4 e7 ]- E, u0 x6 t) S3 _setup.hpFilterFlag = 1;* ~5 V$ x) m+ \; T
setup.reflectionOrder = -1;
; k4 n& c( R7 }& C J1 ~& N5 Msetup.micType = 'omnidirectional';8 X$ a1 E6 d3 J: v4 k; t
setup.nSensors = 4;
8 Y) C+ {0 K( C0 f+ n& |setup.sensorDistance = 0.05;) V) ]2 D# W* s7 u3 D6 ^4 c
setup.reverbTime = 0.1;
9 D8 N- K5 |) O1 Isetup.speedOfSound = 340;* ^1 s( Z8 J5 E Z* q/ o
9 Z- q, T3 U" W* j% V8 _! }
setup.noiseField = 'spherical';1 T! I, `* d* Y3 G% R
setup.sdnr = 20;
6 H- g0 x q. I2 P* bsetup.ssnr = 25;- ?. m( z% m" L; N' b
9 f9 V: q; H5 b/ }( R* jsetup.roomDim = [3;4;3];
: n; W9 i8 f3 f4 W f0 S/ r7 N$ K3 A* }; r9 Y& @
srcHeight = 1;
* G7 Z( F2 E9 a5 j7 R4 karrayHeight = 1;
+ h$ [* G' e4 _$ ]
+ X$ }1 Z7 q7 c6 c4 sarrayCenter = [setup.roomDim(1:2)/2;1];
6 c3 P: t7 j7 g4 M& m9 ]2 { S3 C3 }' q6 W6 Y
arrayToSrcDistInt = [1,1];
, n# S+ i$ @; d. n5 N9 P! ~6 ^/ B! ~
setup.srcPoint = [1.5;1;1];# n5 {7 ~* Y7 G; @
( g9 C' l7 _$ s1 r1 X' S# `setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight); M5 S4 p# u; U3 B
4 B' ]! @) F& I' R2 d6 l' U7 Y- Q9 z, T9 a" f
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
7 @. M3 l3 r6 W6 s3 S3 _6 H9 o6 E+ r3 B8 f
%---------------------------------------------------initial end----------------------------------------# W, C2 V' Y) B% G
# R4 l- Y5 o' U" q( f% a2 p; ~6 |! c" x! U/ h
4 |& {6 ?' s: ^ Q%-------------------------------algorithm processing--------------------------------------------------, l( i3 \* z8 N% ]# ]
2 t# d! y: r" A$ Q9 a+ Z# f: F- g# d9 uif setup.reverbTime == 0,8 } \6 X* S/ D _* N0 v" E
setup.reverbTime = 0.2;
; u% O9 B3 B7 v* ]( G1 v reflectionOrder = 0;# p" |& y! |7 `8 Z8 Y4 p8 z
else& D7 p5 E# [* U1 [) h4 h& x
reflectionOrder = -1;/ K9 D2 ]1 |& C
end
/ N" ~' Z/ X- A& S% x+ N* O. L4 o6 F) A" K
rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
" _0 G) _1 A' D! S: x9 c# G# x setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
) Y& z$ z5 E; F* H0 d* c5 }# `
7 E; S! e' l$ ?! k8 ufor iSens = 1:setup.nSensors,; n r" E* s- i5 V; r5 F
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);, V3 K6 Q2 i; y1 ]0 p- C1 r
end
) c, O6 d0 X7 @5 P$ N* S5 MmcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;8 @% s. s: _4 u2 K, I4 v; {! ~
setup.nSamples = length(mcSignals.clean);/ O, Z! u8 `0 S* o( H5 h) I
# ~" V- Q3 n& n/ [ O
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
% Y& z: Z4 N- t! |' D- H5 p6 A) c4 c/ v
%-------produce the microphone recieved clean signals---------------------------------------------3 ?! Y# e1 e+ M/ G9 O
& V+ O" b! q' {9 ?& P7 Gmic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold- M0 W g% f& e0 P0 V9 v
mic_clean2=10*mcSignals.clean(:,2);$ Z! x9 {$ F' m
mic_clean3=10*mcSignals.clean(:,3);0 M- d/ G& P! I
mic_clean4=10*mcSignals.clean(:,4);. M4 e F2 O/ }* N
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);1 T8 ^) r- a& ?; ^, S
audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);; x) }1 ~6 P E3 d; N# d) N
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
6 M; @6 W8 N5 Z8 |% Waudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);+ O% f/ F% k) o- y) y2 ]+ ?
! \% I' {( V0 t5 Q' ]5 q
%----------------------------------end--------------------------------------------------5 Z% N. `0 d5 e
& `9 G7 N! U) G+ }
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);8 B$ O: ^: k, K. e( S
5 H' D9 t/ p, c
cleanSignalPowerMeas = var(mcSignals.clean);, c4 ]- L2 M+ N$ ?9 P' F+ i/ ?
- J' O, c8 `! t, Y1 D# c8 y3 A$ E. P, Q* O9 P9 o+ z
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,.... X( G x9 [& V! q( w5 t6 a. G
setup.speedOfSound,setup.noiseField);
9 i$ h. D% }1 N( h- f" odiffNoisePowerMeas = var(mcSignals.diffNoise);
' a0 ^6 o3 h& c3 L, ydiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);" i, y* q7 k& k" J/ @" g
mcSignals.diffNoise = mcSignals.diffNoise*...* b6 V/ Z9 }$ L
diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));& ?. E p( y% I' q6 G
+ z% k- y/ g' Z7 t7 S
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);! W4 T' R8 P0 f) [
sensNoisePowerMeas = var(mcSignals.sensNoise);
* y: h' W) u8 y" YsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);+ @7 H4 v) q- m/ f7 l) e( O- o, o
mcSignals.sensNoise = mcSignals.sensNoise*...
7 i; t8 n* t& S, M- y* ^1 t: i, H diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));1 S. x$ a6 S# T7 |, k# ^1 b7 Y
5 |1 I: u2 i6 |/ j: J# DmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;! t2 ~" Q/ q- f2 L( F' n8 Q" G+ k
mcSignals.observed = mcSignals.clean + mcSignals.noise;# E: _* M( y" I4 j
( Y' m; {0 c( b$ r) x, h%------------------------------processing end-----------------------------------------------------------3 c8 t6 B+ b! S. b/ N# b
( Q0 y* @( ]! E; x4 ?' P7 U% a+ e
6 N3 |+ Q0 V. X( D' u
8 p0 s- L" o4 g: R/ V; S+ c$ L. }3 q6 Z4 v
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------ v- s) n; }; L/ {" n6 i# d
% K+ Y! a5 O3 l8 x6 L
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
9 l, k# D7 d( E5 {4 r) U" Tnoisy_mix2=10*mcSignals.observed(:,2);
7 Z6 x9 ]( K0 F: Q0 mnoisy_mix3=10*mcSignals.observed(:,3);+ B6 b+ x* @- h
noisy_mix4=10*mcSignals.observed(:,4);
s& O' W" ~" m7 ^7 Rl1=size(noisy_mix1);
5 h& G. w Z Gl2=size(noisy_mix2);
( G' h4 ?9 h2 Cl3=size(noisy_mix3);
& ?+ G4 T: }1 B2 l0 X0 cl4=size(noisy_mix4);
' R$ ^& J9 z ?! [audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
$ p# M9 {( V, c7 n+ q' H$ oaudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
' l/ ~1 K! _+ l9 J: J j* qaudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
( t4 E4 o6 [# f- ?. ^. ^. Saudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
) [' q! P+ K4 d ~: ]
5 j: T: |+ \$ ?9 Q; O4 t5 O& ?6 Y+ b% k' I) V# y& ^
%-----------------------------end-------------------------------------------------------------------------; R: }$ H* e) \7 {( n ]
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
& C u) B7 v B# u- B直接把它们替换成你想要处理的音频文件即可。7 l, z6 H4 D) B2 @0 {- y
' D5 ]& R, ~' o3 F( ~* A9 a 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
" E: _/ f% Q9 Q- V" `# `6 U: x( b7 }' w
![]()
1 d2 y0 d/ l2 f% |- `4 D8 Y3 S& F! I7 D, k: W
图1 麦克风类型图( Q* k0 J+ N9 f
$ Q2 a2 S$ O# x: z# d A0 x+ h
图二 房间的坐标系
1 C$ `( B& P9 m- E, M4 p
( V8 d& j+ l% c1 c7 R# p 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
: L/ N1 X" o! p9 h————————————————
& i. ?+ p/ ]) B5 y) g版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 r1 G2 [( \3 ?6 ?; W6 Z8 y
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998) J3 e# N2 |' w, F* D- C
1 P- i8 B( O7 d6 ~8 J8 G8 p
$ p5 L. w0 A- G. y6 i7 ~# i |
zan
|