- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36311 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13854
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
/ c0 q% b9 r2 ?9 [8 Q; Z 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。7 x" k, U8 q! e: {
" z/ o4 Q, B7 l8 D4 M
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。& o! |) W5 Y: C
! g$ J/ {2 `7 m; p2. 代码介绍$ n: T0 Q, `, b, T3 n: _5 F' K6 b6 u
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:. {6 {7 H$ x! Q. x/ `
function [mcSignals,setup] = multichannelSignalGenerator(setup)
9 S+ P: ~+ i3 P) A
6 `5 R" i+ X8 _4 X* I; e
/ _8 t( g& ?! A$ v%-----------------------------------------------------------------------! a- V9 F9 o1 [ ^" ~
% Producing the multi_noisy_signals for Mic array Beamforming.
n% J, l" s2 d3 e4 s%
- ?8 P3 o+ O1 J- v. S8 D% Usage: multichannelSignalGenerator(setup)
' v' x8 k$ ~9 ]6 C7 u7 \ I% + f$ l4 C' R, l G# o* |! L4 K7 u9 q
% setup.nRirLength : The length of Room Impulse Response Filter8 n+ t0 l6 k0 V5 s
% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
o% q6 Z" k" ?2 @% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
! U, [2 |% c0 k& o% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
! K3 _4 Q' v, I% 8 w# o$ i. |5 T, g/ r) c6 V" |
% setup.nSensors : The numbers of the Mic
9 b; p# ^! I" @) h3 t% setup.sensorDistance : The distance between the adjacent Mics (m)* w+ H3 V" x- X; y) Z% K: I3 d6 o
% setup.reverbTime : The reverberation time of room
! R$ Y8 t. @2 r, P s/ z% setup.speedOfSound : sound velocity (m/s)' g# ?0 y3 T% v/ a) A
%
$ g0 I# W8 E* ^1 X9 b% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
' E" Q& Z. C& m% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
- Z ~( K, @: ^! b% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
. H9 ?0 _8 S4 L) G2 I$ @%
7 ~+ t+ U, `' G- e. Y( t% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
) q; Y8 z6 [9 [3 ] F& s8 R: f) `% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
9 V2 b9 |' a1 T1 l% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m). * P& I+ U/ T" ?$ t) f. f
%* v6 v# r$ j1 B. ?& F
% srcHeight : The height of target audio source
# X; R/ a* x; f9 ~0 Q, v4 [- ~% arrayHeight : The height of mic array ^' M- c/ h( l: N. [ v/ {
%! O- |) F; a! }. G, k4 j! M5 T& ?
% arrayCenter : The Center Postion of mic array
# E8 `8 h3 o( p, U# k: N%3 Z: r9 z1 |, }# p, E4 g6 H3 C( i
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis" ]* l0 g# P: a4 A2 E' [
%4 Z# ]# r) s( f
% ; {2 ~4 K e& k0 s. L$ J; }$ [5 u
%
2 m. r5 D/ `4 X) Q%% {$ q( s& L+ I4 Y
%
6 H' ?2 T( i, t%( E2 Y' o2 W0 H9 J$ F$ i: d
% How To Use : JUST RUN
& x3 T& l7 c1 ^9 s s( d+ H8 |%3 d' z* ~2 u; u. [7 w4 Q* F& w
% * e O* W$ D |
% 7 t5 B' E0 x9 R, y; \" p3 D
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
1 q( L i/ \* Y% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
3 E1 t8 H: s9 Z0 K3 s% e# c%; M& P6 x# c- \8 n& ^' N' S
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.9 _ u1 L. x0 F2 y' {/ r) R8 H
%-------------------------------------------------------------------------6 t, X$ R% H: M/ h2 F
' j2 h7 \+ r( M9 c/ z
0 j3 E) N* H0 n* H5 K4 [" g6 y+ T0 m& y6 N( d) K- T
addpath([cd,'\..\rirGen\']);
' Z' H0 R# T2 a" d. z9 q$ \% V b& b( ^& r3 ^/ _# c
%-----------------------------------------------initial parameters-----------------------------------
) Q3 ?: q* Z* K* r5 e: j5 y7 a
6 j7 B/ J& O. p2 }7 Ysetup.nRirLength = 2048;
; ^+ _% i; f esetup.hpFilterFlag = 1;
9 S+ x: Y4 w( x$ ?* G! usetup.reflectionOrder = -1;
1 T( Y, i, g6 |4 p c+ `setup.micType = 'omnidirectional';: c. r% {! O O! B
setup.nSensors = 4;* V' Y6 ~# J9 ? Q# S5 Z
setup.sensorDistance = 0.05;" D n+ M) x1 X( X4 h
setup.reverbTime = 0.1;
9 @8 r* Q: l3 dsetup.speedOfSound = 340;/ F5 a* _: N t' H
1 [6 `7 Y& \) _, msetup.noiseField = 'spherical';
$ R3 [. |4 \, M4 E$ Z( f% d! ~setup.sdnr = 20;# Q9 f3 ]# m+ o; O) f$ E2 J# `
setup.ssnr = 25;( i6 O2 _7 F, X& G
& x: {- {. O5 ^
setup.roomDim = [3;4;3];
1 C+ B) P; c) C1 p& M3 R" W( a0 e$ s% x' f9 n1 }# e3 b
srcHeight = 1;
1 t: n; A0 k4 {/ ^7 e" o5 CarrayHeight = 1;6 \. w1 \$ w- e
6 {$ W' `" w$ ~# x! G! T& U; X w
arrayCenter = [setup.roomDim(1:2)/2;1];
y! S. s/ }9 I5 W* H- V- y( @" k9 e; Q, t. E4 C% I5 D+ X5 r
arrayToSrcDistInt = [1,1];
; d) o, x; k* x* V* a ^& Y
( g* ?! K: e2 l. P& j4 {setup.srcPoint = [1.5;1;1];
, p7 |4 b" |5 E z# A4 A
5 t' v A, o$ ?7 ksetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);/ M2 T0 ]) G* v# E* T/ ^7 \6 }8 K
, E0 F! X' Z$ l
4 b% s" W6 u! l. {7 h! y8 N& z/ [
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
6 g# D! F5 {% ^. a( t* f
* ]5 h n' d) k* u8 S t# d%---------------------------------------------------initial end----------------------------------------
& f( d( ~1 s9 {+ \* N7 r
* q" D0 [6 m% s+ v+ i, ~' | l; ^3 [5 C+ D# ^- D& x
8 v" ? n4 l, C# |$ V
%-------------------------------algorithm processing--------------------------------------------------6 P$ I1 @" i2 s5 z: }; s
* _1 B) K6 e p* K: n3 R n" c! u
if setup.reverbTime == 0,. L- V6 D% T4 u0 D- E/ G" |
setup.reverbTime = 0.2;1 d/ @# f" M4 T7 X6 E, j0 j- x4 [
reflectionOrder = 0;
( J( j! f5 I: {1 v+ [else
. T- U6 W2 x8 o A; C# @ reflectionOrder = -1;$ L3 }" w+ L+ N
end3 @3 M' _; C3 W7 m$ E+ F
% S B; C: K# Z; X' a, C0 O
rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
6 i% S* @: V0 Z% C6 q' p% S setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);, ^3 @5 e7 w0 w4 B/ x
5 a) g. }: X1 G" r/ x3 u7 j. c5 ?5 N+ p
for iSens = 1:setup.nSensors,
/ x8 p7 ]" J& C tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);1 B, V% `8 X) P0 J% m4 e8 n, V6 ?$ \
end- ?3 W2 P% [# H6 K2 y/ q
mcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;7 h( ^- b$ j) ]7 x
setup.nSamples = length(mcSignals.clean);
- q$ l3 U; n" E$ Q) {2 P8 Z* i) K( S+ m8 |
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);9 W0 K8 M* \' z% W4 l3 J3 @
1 j# z# Z) ~/ p& Z%-------produce the microphone recieved clean signals---------------------------------------------
/ r6 _/ u2 H: Q& y/ B! K8 z: s7 j& k" L
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
. ^! o+ Z0 ^. Y jmic_clean2=10*mcSignals.clean(:,2);# y' g$ g3 o8 v% x
mic_clean3=10*mcSignals.clean(:,3);
2 o) J% f, R2 g' I4 h! u, vmic_clean4=10*mcSignals.clean(:,4);
9 d' A& S2 F2 m( J. J+ l7 xaudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
9 b1 e/ T% o0 N/ b( eaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);; w7 i- O+ D% I4 J: A
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);* [. Y& m# P* I8 L9 }
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq); @4 u! n- [3 D _7 f' d4 \; a
) h, D) U" V- T! V; s2 t9 ?/ g
%----------------------------------end--------------------------------------------------, v9 G9 F- M: `3 q) F
5 z: Z" ~$ c. [0 i7 ]8 j) x) Yaddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
" E% H+ S$ n$ b0 v( f9 C0 R( \* R; L. S2 g) h
cleanSignalPowerMeas = var(mcSignals.clean);; B* k* _2 } h5 ^4 A* Y8 s n* O
( X3 F9 v" n5 M. i! B
9 ~+ J$ u4 m, H# K' A. ]' u& K8 smcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
0 T" R6 J4 I& L setup.speedOfSound,setup.noiseField);: T# z$ n8 _! n" ^4 a8 d
diffNoisePowerMeas = var(mcSignals.diffNoise);
# T8 ~3 n5 X) J3 n* a- u2 c9 B- gdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
% p- @6 c, l/ jmcSignals.diffNoise = mcSignals.diffNoise*...
) h" A# F1 e2 ]1 x+ o diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));: m- g8 t1 D4 Z6 Y. C2 s# i5 q5 `
5 G+ w1 {" i5 _! E4 hmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);: q9 q( o& `& c
sensNoisePowerMeas = var(mcSignals.sensNoise);5 A @# Q* \+ M. \0 c1 |3 O4 T
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);& @, @4 U3 G! N
mcSignals.sensNoise = mcSignals.sensNoise*...
: _; a7 l: E- G; s: J$ K/ F diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
~: B6 e5 `0 }5 `6 S, v$ a' `# I
! \. g0 ?9 O& m, N# \1 M! o3 qmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise; ~- x: c# b$ m) Y* T7 z5 V+ `
mcSignals.observed = mcSignals.clean + mcSignals.noise;
- ?& \. Y) R# j' n3 Q) ~# m5 d: b
%------------------------------processing end-----------------------------------------------------------' t' J/ j/ k( O. S" l- G
5 d0 k+ C' w: \ Y1 T. f1 x
0 H+ k7 N. n8 l* ?; J5 U
% `8 l4 ?# a6 W% A' _; u5 q. t
0 ]: Q1 [3 H7 X%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------# j3 V& G9 q: _& D
+ u4 l" Q* `1 M, T1 c* L. Q4 u
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold7 q1 N; u& R1 S- m& f
noisy_mix2=10*mcSignals.observed(:,2);" m5 O( G7 d& o- ^/ E- T
noisy_mix3=10*mcSignals.observed(:,3);6 t9 R& q* \7 N- {" y
noisy_mix4=10*mcSignals.observed(:,4);) j" Q: c9 y1 y# e
l1=size(noisy_mix1);
( c6 W4 [& C, Wl2=size(noisy_mix2);1 B6 {$ ^; B$ H
l3=size(noisy_mix3);5 L7 m" b/ d( m; X2 b3 ` |
l4=size(noisy_mix4);
0 o1 ~' o% G: p% Iaudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
2 r( i: K4 F1 s; T: Z1 oaudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
/ |% s. |, |: X, T+ m4 ~audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
* }! l" {: \6 T: i6 `( h1 _audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);) C; d# k' M" c' o% o
7 F6 }( i* L; T2 D" s/ B: Y) c% k0 @
2 r5 k. r6 H+ C% r# w9 E# o9 X%-----------------------------end-------------------------------------------------------------------------
?9 D) {7 K! ^$ i6 N这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
, h. q! B- k7 a, O直接把它们替换成你想要处理的音频文件即可。
' W- l5 o9 l6 G1 @5 E3 m4 p
# |) V8 v1 s+ b0 q7 w# d 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 `6 |; \% [0 `! q: ]9 }
5 c# }2 }& [- J) V. n8 C. J ( e/ f- k+ h1 l- F0 u% O
& O% u: a8 i- U6 O) Z. Q! g图1 麦克风类型图" M& P# K; H3 n9 k9 J
9 k! k9 t' ?# ?+ d$ H/ H$ r
图二 房间的坐标系- T( C% F4 F* X5 @
+ l; h: w! f4 b5 t+ T! |0 g
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。5 R$ w1 p% G: T, M
————————————————+ p7 a; k9 Q0 L. l+ ^- i; f
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& v9 O8 M0 L4 l
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
[: b4 V& b% g% w3 g2 n n2 F5 s# X9 u$ _9 e% Y
5 q2 [: q) D2 n7 K2 r |
zan
|