在线时间 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. 引言
- m. k7 V) A. N9 Z/ f 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。& S- U( p0 x6 o
: v# Q8 U) T3 [7 `6 I 然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。- c/ W) s1 e2 J" K; G. l1 t
2 }1 ^8 P% {7 [% k! h 2. 代码介绍' C: x$ {. r' C6 u8 t
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
; Y3 Y/ W) ~) Q3 p, M5 S, [$ g function [mcSignals,setup] = multichannelSignalGenerator(setup)2 y7 l' X' d- i# a0 l8 B+ q
4 l& i; M, g5 l! B# h
: y( `# |# U2 g5 { %-----------------------------------------------------------------------" o# u2 e5 B6 X9 n& | L( ]" g
% Producing the multi_noisy_signals for Mic array Beamforming.
6 i0 R* q' N* G0 j% }9 g8 H" u % ; F% F& T: C* z% o( R! E& I3 {6 W- v
% Usage: multichannelSignalGenerator(setup)
7 {9 ?0 n# F- n9 F % * \2 W2 ], S2 H7 n) U8 ?4 |
% setup.nRirLength : The length of Room Impulse Response Filter
, Y Y9 e% h) l0 {! p j5 e( F % setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default$ y6 k S7 p# t% L T
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
0 N0 P5 @) [' J$ L: D/ Y* \1 D- v2 o# i% ` % setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
- |/ f4 P4 V( q %
, z8 j9 s! q/ ^! y$ Z. a, n % setup.nSensors : The numbers of the Mic0 J/ u" _7 {0 }* i. N- T7 ]0 j
% setup.sensorDistance : The distance between the adjacent Mics (m)
0 F+ ^5 C0 s( F % setup.reverbTime : The reverberation time of room4 ]5 Z t# R9 S' Y/ L' Y
% setup.speedOfSound : sound velocity (m/s)
) C$ ^7 |; M# y: o %
, E$ N2 y* A) D9 B+ A; C % setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'+ S1 F) U; m, p5 K
% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.' V r, i) v6 u
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
: V% l$ v1 M6 n9 x %
) K9 z/ y' o5 w % setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). & N- W& b2 l2 m) j
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). 4 W4 t, M2 f1 B
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m). " l G( }, K% o" q
%- }7 B# u$ l2 N. y+ P0 h
% srcHeight : The height of target audio source
& F6 ~* ~, [. l0 I; d % arrayHeight : The height of mic array
8 T+ r9 F7 K L1 E %8 ]# V& J2 u* {1 M6 |0 f
% arrayCenter : The Center Postion of mic array
6 I0 g( d/ w: g$ u- N %) N2 \: J8 H% T3 _" @" ?& j- Q
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis1 ^" Z& c. U u1 Y
%2 b1 h# {" N! j/ \) {7 ~3 [, ~2 _
% , }" ?0 p2 F; I; @* ?* |: |6 w/ j
%
; S6 d4 {. J- a/ P3 E1 I& L5 M% Y7 Y %
* m1 H4 ?" ^. y [6 H3 K9 p! V %
, b; E4 t) i& v %
5 j( v6 O. M& `; D % How To Use : JUST RUN
1 ?( V2 q5 D+ W4 h- A; i %
2 b+ G7 B* h+ e3 R! H. i % 1 R" d \7 {* [! z& c. j
% , b. a) P+ n- l+ q. k
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
! W* w/ Y( w6 C2 @3 y % slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24: i& W, t/ D$ v1 }. E; B: a
%) y9 A7 {" x" `. j3 h
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
0 |( v. c8 G: G; C& H8 C5 B %-------------------------------------------------------------------------
8 r+ B9 r8 x" f8 K. }) Y }3 W9 C ! V2 a3 g0 J3 k9 `
8 F4 a( z1 v8 Z2 U! I$ N3 ?4 i 1 [) }4 V$ o9 m2 F, f1 U6 N) l1 Q
addpath([cd,'\..\rirGen\']);6 E( K: @% a5 q* t
- k( ^/ x/ [& }; l %-----------------------------------------------initial parameters-----------------------------------0 o8 h7 A, g. \1 N5 U) z1 K0 I4 V
) x) U, ]) V1 B, o3 o. a; [) `6 ]
setup.nRirLength = 2048;
* j/ R% H% h& l3 } setup.hpFilterFlag = 1;
- ~; i9 X$ ]6 s% @2 X. P* Y/ T) t setup.reflectionOrder = -1;
$ _4 y1 O6 u# ^ setup.micType = 'omnidirectional';4 h( ]. E* e/ m
setup.nSensors = 4;
2 W5 }7 H4 e- e- ^ setup.sensorDistance = 0.05;
y& e1 G3 f$ @. Y/ F1 J setup.reverbTime = 0.1;$ ]! c1 r' l6 F: O
setup.speedOfSound = 340;
- e# u- K% t4 y . ~" t0 Q6 [$ g% Z$ D
setup.noiseField = 'spherical';; w; j! y( w, Q, K- [/ [
setup.sdnr = 20;) I& P3 p6 ^$ y" S* a0 o8 e
setup.ssnr = 25;
- W5 g8 W5 j" p0 n. Q
! n; _" k! U d/ G: M) r* d setup.roomDim = [3;4;3];. Q% O! [7 o; h. b9 D
, n+ j/ k; k2 w+ U, j srcHeight = 1;+ E( m: i0 C6 Z% f. C% d; T
arrayHeight = 1;
% Z1 l1 o$ ]+ v3 `
( x! C ?& Y4 G! ^# k! E arrayCenter = [setup.roomDim(1:2)/2;1];
" @* \3 {3 C* X5 O - `& Y6 E0 m8 t8 x
arrayToSrcDistInt = [1,1];& i+ y* Y8 w2 Z$ {
$ d6 `3 G! ~% O, ~ setup.srcPoint = [1.5;1;1];! q/ G6 R. e' G2 K# J1 z
' H/ Z3 G( s2 Q/ t1 ]+ |5 l$ [
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);, t( c8 j* X) H; X9 f% c
# k- e* }" P! d v: o. n
3 c) y& P( N+ ?5 h
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
8 C# d9 r Y8 W# C* t( k 9 G* m& O* Y, K4 `+ x4 Q z) m
%---------------------------------------------------initial end----------------------------------------
" ^8 b7 X$ h/ g; ^- i2 g
5 J) s9 l8 K* }: z. X : Q& Z/ e/ P) F! q4 }
! V$ Y! R8 q8 ]$ a& d
%-------------------------------algorithm processing--------------------------------------------------3 ~" s$ \5 O) a b
. H7 K( P# j2 ~# x! }0 C
if setup.reverbTime == 0,
+ {. z9 O" \4 m5 ~! \. e, I, b setup.reverbTime = 0.2;
9 ~2 n. I3 v7 w" ]- O8 U reflectionOrder = 0;5 V B# C4 j% V% [( v
else
8 d* A4 p4 O' W4 W reflectionOrder = -1;7 l7 @! v5 [4 j7 C$ ]) l
end
; L8 n H& @6 b/ N
0 d6 o. c u8 y, x% ]1 L7 ]! x rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
# w. V% v( F' z+ r! O2 b setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
9 W& b6 ~# o+ h: p8 o# F
% D/ Q4 o8 g) } for iSens = 1:setup.nSensors,
! p# y( a! B8 [$ M tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);7 M# o4 j& X+ I5 [9 J9 d! w) g
end
8 b3 p, h# W" ?9 Y2 G6 Y2 ? mcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;; Q8 K" g1 f% ` R- F% z! [" R2 J
setup.nSamples = length(mcSignals.clean);
* J. S. o2 Z4 u5 R
! z3 h8 C9 n% v+ ?* U mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
; w& a( f" Q8 u* o1 W% f5 A# o
! k# m w7 k: u8 m. A %-------produce the microphone recieved clean signals---------------------------------------------% v: t4 o9 a6 P4 \' b* D
0 Z9 P4 i' f. f( i
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
' m' X5 q5 l% ~/ o. U. B: n mic_clean2=10*mcSignals.clean(:,2);
$ O& k- R S0 y1 ~+ @& i9 K, Q mic_clean3=10*mcSignals.clean(:,3);+ L& g9 z2 l( y
mic_clean4=10*mcSignals.clean(:,4);
* x2 @+ b' J; Y9 A( C1 g& [6 Y7 L audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
# x! y( c; e- {) f+ p audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
7 @0 ]$ c6 \3 ?+ d6 ^, w! L( j audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
" s; m8 n$ P4 p# t- v1 I' t audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
I4 B- ?0 y, m6 u ( P- _( x3 e. o" _
%----------------------------------end--------------------------------------------------
3 U& M8 O/ L& m' T" n
4 ~/ |: U$ } P: w2 _: O addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);- \3 m, C$ R, A* Z$ A
6 _% Q v+ J/ r2 j2 L
cleanSignalPowerMeas = var(mcSignals.clean);; |+ d& \! G* k2 k# q
$ K6 y/ i- R7 Z- I* X
x I G6 T" Q" F
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
/ E4 l" Z O% u# K" t setup.speedOfSound,setup.noiseField);
) Y, _# V# T3 E/ x( i @% Y8 O diffNoisePowerMeas = var(mcSignals.diffNoise);" ^% ?+ L# M' e4 h: `7 a
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);' Y/ Z+ F' ^5 n1 u: V3 q+ e$ c
mcSignals.diffNoise = mcSignals.diffNoise*.../ ]- c9 ?1 Q, Q1 J9 l N- J
diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
. {+ } p1 c8 \ J) e/ O7 i 1 S) E, a" I& H) L
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);+ T) _, k3 C1 I9 p! B& K, A- H% h- Z
sensNoisePowerMeas = var(mcSignals.sensNoise);
2 Y4 L' E' N& x L/ Q3 S: {! x: p sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
9 h& r+ k" c5 q mcSignals.sensNoise = mcSignals.sensNoise*...# K$ l+ x, d- `
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));+ M% f/ m* |) q' N4 H
; n7 E( u* y( N. H, M+ S
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
m; e+ O, E4 R8 L+ S mcSignals.observed = mcSignals.clean + mcSignals.noise;
9 {1 e' p3 G5 F$ v 0 Z9 H7 A6 T* j
%------------------------------processing end-----------------------------------------------------------
7 L: x. A3 R4 k6 ?
7 H7 G& ?8 Z- L$ A3 B8 [" T2 C
5 X4 N$ _7 ~! _ ; P9 f. u% p+ J
8 E6 p8 |: c5 l z* m1 y' \
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------$ {6 E) V. `; Y" I% A i
+ O6 F7 `! o! D9 O b& ] noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold, \' p. R% a& b. [# z% h6 m4 n9 D
noisy_mix2=10*mcSignals.observed(:,2);
0 _6 v! L q' L+ R noisy_mix3=10*mcSignals.observed(:,3);5 ]2 t0 |( H f% f& p+ s
noisy_mix4=10*mcSignals.observed(:,4);4 W+ c% b, [7 L
l1=size(noisy_mix1);6 f! m% a/ g* p& h/ Y' e( H8 y
l2=size(noisy_mix2);( U% {1 L$ v Z
l3=size(noisy_mix3);
1 S, U* H: Z, Z& l d' u8 k( T l4=size(noisy_mix4);+ _9 Y; d' j) b# p
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
4 M- N8 u% w2 f. I3 T audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
# p/ X: \9 f: x3 e9 q' j" @' \5 K audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
$ E( j( a, E( _; ~: i( U audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
8 c* y% _. ^( Y7 o. M$ u* `
5 a6 ]9 r- E* A5 Y8 p$ `
6 Q. O% M# X1 O4 G7 P& @ %-----------------------------end------------------------------------------------------------------------- G* E$ e; H1 O7 `0 S! Q7 r
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
& d$ J: q. X$ ^+ h9 i 直接把它们替换成你想要处理的音频文件即可。( h6 Q0 g* ^, M s- h
3 |5 ?* m' h( w0 |7 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)。
$ x, N. @# s# `. q 9 y4 O6 n5 I' f) t
) f8 ^, [' s. Q! p
) F& a: Y/ E, B0 q* c 图1 麦克风类型图 * Y6 j+ a6 w* s$ B- a: C
3 ~0 o& Z3 m" G$ m 图二 房间的坐标系9 G8 T- _! v0 m% m
/ s- D2 C2 i5 H
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
/ ]% F5 A6 C t* y ————————————————7 U9 l- Z& {7 s. s+ n f; O
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
. O/ Z& O4 y8 A b0 {7 ^ 原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749982 h9 h2 E1 w, J. f# P
! x1 W7 Z4 o {0 C
! O0 l o) f4 i! S! ~
zan