- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36393 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13879
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
# v( a$ ~+ A @! \6 c 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。% m3 u+ `* ^2 w' ~( f5 l& E
0 v0 E2 n" Z3 n# m: Z' R# ^
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。( ?- `: p2 ]: U0 c/ {
- l0 C- G2 L% P" F9 v# e
2. 代码介绍5 k; i5 a' h+ x/ p _5 w( r
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:/ T( ]2 i: o2 G6 D1 y% w( a
function [mcSignals,setup] = multichannelSignalGenerator(setup)
- M# ^8 S6 v! k& O. {
! X" b% n+ }6 e- t& ?
) \: l( E% C& V%-----------------------------------------------------------------------1 Y" O2 s$ X; o, ^
% Producing the multi_noisy_signals for Mic array Beamforming.9 o$ G8 j U5 E9 ~/ n, l6 o5 o
% ; Y& H" E1 N/ w4 ~2 s
% Usage: multichannelSignalGenerator(setup)
: F) H: a" U+ a' c) g q! z%
) L j; H- x1 B/ j- m- Z9 d. ?" }) n" S) k% setup.nRirLength : The length of Room Impulse Response Filter
, s' Y' I5 V |" X2 T; S; I% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
! G; h L# J. O' v3 d9 U% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
* c3 J, z3 \+ g% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
9 W7 b' y& k ?! c; L: d: A) o% , R" H4 h8 r7 `: v; R& }- K
% setup.nSensors : The numbers of the Mic
% l* E* S3 t4 f @! o% setup.sensorDistance : The distance between the adjacent Mics (m)
) ~5 S$ e6 D; N# c k1 [% setup.reverbTime : The reverberation time of room
& ?+ _, Z/ d% y0 u" |1 I% setup.speedOfSound : sound velocity (m/s)
. l. k% j# s: L- n%
# k: N4 z' ~3 k: _ d% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'- L* |; g, {" f: i
% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
! Y* z$ W( ]/ A4 Z% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
+ p2 C2 P7 G; | D$ G( B+ m; t' j%- a4 Y! z6 d2 y
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
' L' k) x2 q" A" e8 g% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). 1 R* P0 d+ e, X }3 Y, F
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
4 X1 u. y: |& ]4 T4 V4 ]5 ?%
4 x4 A( t( m9 r4 V3 C2 k% srcHeight : The height of target audio source' p3 J* a5 V$ ~$ P8 W5 x
% arrayHeight : The height of mic array
+ m. T+ R2 H* f) m. K2 p3 M _, C' S%- J% |* P7 `6 r
% arrayCenter : The Center Postion of mic array
: @" y. C$ ]& {+ g8 \; m%& s. H' @0 s0 I5 V9 J7 \% L* i( V
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis
M( U9 x- e) f, d" F5 e%3 c9 S1 \$ e, ?7 ~3 Q: \8 L2 b
%
# d& `/ {9 @! l$ `. `%" o/ g9 P$ G! V1 u' L
% G* U* b, H' w' F. k! R3 o1 p* w6 `5 z
%
" `- I- a: h& G9 |- d4 f/ x+ g%
% s: l8 ]! F* w- l& Q5 ^) G7 E% How To Use : JUST RUN
: w" R4 ?- t4 M2 f# D; `$ a%
8 W, v1 v- E$ ?2 Q s% 6 y1 I* h# E, }6 e/ W4 u1 p
% - J5 O \/ j& u9 Y# I5 N) }
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),$ T" q: j. s) |- b8 I& c
% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
! f1 U% u) X4 M! q1 `%) u5 L& D |: y! i2 N$ P$ W
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
; ]; P- B' d1 C7 }% @( i& V. z( N%-------------------------------------------------------------------------$ q g# @* _) F& w
7 \+ D# _4 |# W1 R& ~4 }( Z; c' P7 U' J U1 g' X0 a5 f
5 W5 L/ ~9 W! N+ t% y# U
addpath([cd,'\..\rirGen\']);
+ f( W9 L# P" L0 Y
0 o. j' w) ?1 \( b%-----------------------------------------------initial parameters-----------------------------------; g. \! o! E( U: b3 K
+ S6 k, F1 q# Q" J. Asetup.nRirLength = 2048;
8 L, T- d$ D1 S% V. x! q" E$ Wsetup.hpFilterFlag = 1;
+ a% ~: i J5 Bsetup.reflectionOrder = -1;
. i& t+ q& t3 x* I: S0 h7 H4 {setup.micType = 'omnidirectional';" [( M7 ?" X% p6 j
setup.nSensors = 4;
9 R% r6 o1 x7 |4 @setup.sensorDistance = 0.05;6 {% J, k* }0 E) P9 G d0 X
setup.reverbTime = 0.1;
: f/ H# X% G/ G: i* J) V6 psetup.speedOfSound = 340;
4 f6 O) W: t5 S& @
6 z) x9 B( W: ?+ D% dsetup.noiseField = 'spherical';
$ W6 h- o1 ~1 D" Q4 C6 Psetup.sdnr = 20;9 p Q8 L4 q2 K" c
setup.ssnr = 25;) g/ w( ^( O; p! a; G% e
# H8 g5 m7 O) @$ Lsetup.roomDim = [3;4;3];
$ |+ u- `/ D1 l% u. l
9 L( k7 f, C+ Q0 [! l1 ^' esrcHeight = 1;
0 i/ |9 {4 h; v+ Q9 {! varrayHeight = 1;0 N; j5 r8 Q0 c9 J! s. R
- b% @0 k" ?( }; n$ a
arrayCenter = [setup.roomDim(1:2)/2;1];% f' d9 H* w9 [& n$ @
9 e/ `+ }+ z4 |( VarrayToSrcDistInt = [1,1];; s9 S9 Q" I! H4 x( f
: [3 z$ A% [) G! K, z- g7 lsetup.srcPoint = [1.5;1;1];2 o1 @4 f; |+ M. w) W/ U! k. u" g! [
( t( I5 X0 Y2 z) O0 F
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);, E3 n$ D: u: E" J( x- v1 ?
0 E! q8 O, ?) n. [
+ E' { i/ ]' h& j2 D/ O; j: i[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');) j# ^2 B, i+ t( J# J2 ~4 R) X
& v) `2 H0 r2 ~%---------------------------------------------------initial end----------------------------------------
5 u% ~( z+ V, v' {& K6 ?1 z" y; s6 w1 d$ \
+ I* w2 p) ]' T! V$ X# j; E# z2 j
* V, _$ W5 d# f, H%-------------------------------algorithm processing--------------------------------------------------
' O- k+ |5 g* w; f* O
: \. o4 w# A* xif setup.reverbTime == 0,. B2 N6 ?- J5 H7 I' {
setup.reverbTime = 0.2;
" U( i5 |* e. W1 w/ ]& K reflectionOrder = 0;+ Y; Q6 F/ J; y8 ^' _1 Z# J% q
else
$ X: J7 b: N5 u4 k! G1 H0 r j reflectionOrder = -1;1 g0 r+ z) ^. l/ I( A2 o
end8 N F/ k% B- s3 `$ M$ U
$ W& r5 D# N) g7 w5 p; a
rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...* E+ Y$ Y) `5 ]5 p b" ^
setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
4 x. ]7 b8 ?8 i. W# Y+ C. m; L+ _/ ?- C0 \% D/ y! _4 F
for iSens = 1:setup.nSensors,
; @2 L) H; ~* P0 L, \1 [3 o tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);; F- a8 n) j0 K2 ?) Q0 N6 Z
end
1 s+ q8 x; ], w L5 ZmcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;
9 A- v& j# m' \1 O1 Qsetup.nSamples = length(mcSignals.clean);2 B. g3 O- e, x$ u( o
" |; v* p/ H- F: ]4 ~! d4 EmcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
% Y7 Q3 F6 M2 n+ `' E. A& s8 A ` v
%-------produce the microphone recieved clean signals---------------------------------------------
) Z1 Q4 V7 l% B4 B& s1 Q, d. n, z1 `& I, ~7 i) [% [
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
M- j* Y, b, u0 s" |: _1 i; }5 E" @mic_clean2=10*mcSignals.clean(:,2);0 L; T! q+ s& ~1 r
mic_clean3=10*mcSignals.clean(:,3);2 n. H) B6 ~1 ?9 j. z# H- ?$ @
mic_clean4=10*mcSignals.clean(:,4);
( ?! j5 z# V) B1 Uaudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);3 O% G! }7 W3 T8 p
audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);* ~) D! E2 H, s8 u; ~. Q7 m
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
8 q! Z) }4 ~# ^3 Q# J0 E5 maudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
# H/ j2 i5 m" D
( {6 s( l0 F7 f" w5 E0 \3 a- C' \, }. ~%----------------------------------end--------------------------------------------------, v7 _& m+ T+ H6 O/ b: u9 L7 r
^" L2 }! H% k0 e" k9 {
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
) U" N/ @' U0 p6 g( s( S
; u4 m) O8 `: v8 Y8 pcleanSignalPowerMeas = var(mcSignals.clean);7 v" w5 J+ m/ H+ O6 L4 {, ?+ ^
: Y7 \5 r, p7 f: A$ }0 x, U; l+ q* R k, t' D! S* R7 u
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...2 E" ~ P2 \% }) F* w; N
setup.speedOfSound,setup.noiseField);
' }5 y* M1 H3 g( Q- Q2 qdiffNoisePowerMeas = var(mcSignals.diffNoise);3 G4 w* T9 O3 c3 O. _
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
6 v) ]) L6 {; b. ymcSignals.diffNoise = mcSignals.diffNoise*...
! Y; Y+ v0 X- Q/ o6 N diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
7 l% |. V1 c( w) b. M& `
3 x! Z- t- X L" ymcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);% Y- Z+ A* m* ]! N N
sensNoisePowerMeas = var(mcSignals.sensNoise);
, E" o/ b* u4 @sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
5 J6 J7 }( O& pmcSignals.sensNoise = mcSignals.sensNoise*...
) C+ ^; {$ N& s2 y- Y diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));$ U r2 q7 P% X
J( C5 {+ W' ^3 C
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
; |( `2 n& i0 o- H- rmcSignals.observed = mcSignals.clean + mcSignals.noise;. Q! X) l. i! G, @/ H+ Y
8 P% Y" V- Y& c, m4 x%------------------------------processing end-----------------------------------------------------------" P9 P4 t# K( J# s* C b
. W# o- L7 V8 v6 f" Q
* _* E; L6 u2 c6 U
" x$ B/ Z+ ?: \- g1 {9 X4 a
* m% X, h( i7 M% f( E2 c%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------1 {/ l+ l# `8 z, U9 \' T7 z4 @
/ ^' f! n# Q9 c0 t- X3 d
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold& F7 d+ v7 Z5 X F& A* i0 h8 V% B& b
noisy_mix2=10*mcSignals.observed(:,2);! d: g. A* C" b \; O
noisy_mix3=10*mcSignals.observed(:,3);
/ H5 b6 i" P% y3 U& A4 _4 jnoisy_mix4=10*mcSignals.observed(:,4);( ~- C( r5 O: d2 ^+ e& q+ Y
l1=size(noisy_mix1);
7 U, I: f* a6 M4 N3 J0 H% Il2=size(noisy_mix2);
+ c3 X& X. l8 }l3=size(noisy_mix3);
; @8 Q9 M9 @% rl4=size(noisy_mix4);1 T+ s5 ?" @7 N6 b" ` o0 \( B
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);: k3 G$ r6 h' Z
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
6 f' N8 |% o/ {# @8 I5 iaudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);3 y, {) n' j( U4 A9 g n* o
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
# u; y+ Z7 V% R% _5 N& p4 C+ Z; N" ~- x2 q! F
( p6 y8 v% Q% k) R) J9 L/ s8 m" B! k/ i%-----------------------------end-------------------------------------------------------------------------! Q6 f4 ]3 c( p8 k: |8 v
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
% x# ^$ {; S/ }直接把它们替换成你想要处理的音频文件即可。/ ?" @( e8 x) z5 L
2 l0 I2 \( C0 }1 y 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
* z, u3 H- ?& ?& S; }2 X; ~: C% e: M1 ?5 H
![]()
* q9 ^5 \% Y$ @" i% l( {( Q
2 }4 @# m9 o0 f1 _, |, H# I图1 麦克风类型图
8 k% f3 T& o. h( m- _![]()
. y- l: m( q7 A) c' l图二 房间的坐标系
4 Y& \4 L2 ?. H( B/ R9 [6 ]$ ~, h( _5 f
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
* C8 g0 b F$ D3 ^6 G" H% ]————————————————5 A P% n4 P$ ]0 w$ [/ w2 l
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 I6 E4 w) b8 Z' ~$ Q
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998# r4 e( u/ f% b; F7 V- B
% o, \; y- u3 A, u! P0 D: Y4 N1 P. U7 V2 h/ I# K
|
zan
|