- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36354 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13867
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
" d* V) l+ Y2 r8 l( O# ~( ^, u+ ^ 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
( M; U) m( q3 t$ i* `5 }0 {! d$ z& C8 g3 A" Q$ l! t! t* E u
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。6 y1 {2 u" f/ U7 Q8 x1 i) J
( \5 b. c1 _( O& h; z5 R: n
2. 代码介绍$ Y* d$ a# e( g: K) [# ^9 ^: T& r3 k
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
% J. c8 p" R3 p8 `* p8 j- r# ~function [mcSignals,setup] = multichannelSignalGenerator(setup)2 Q' ~' U% k6 s
! f, I" c! L7 v Y) U/ ^) G& c, e* x
" G4 h8 q& `; ]%-----------------------------------------------------------------------
6 `, d, T( N4 ^! ~' s2 ?% Producing the multi_noisy_signals for Mic array Beamforming.
2 r9 I) i5 l( A' s% / x" ~/ t( K Q) x0 Y$ I% ]: ~4 n: X
% Usage: multichannelSignalGenerator(setup)
' o8 e" W! I. }0 g' w%
+ t1 p0 g3 T1 h- \9 @ p' ?% setup.nRirLength : The length of Room Impulse Response Filter* [. U! W& C- Q8 e
% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default! c& k2 i# E" `; O$ [1 D, D
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
$ ]; j0 U( o l0 t0 f8 E* d( H% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
6 g8 v. q9 i6 }3 P' P' L, j: W. d%
: x, h3 w) r5 ]% setup.nSensors : The numbers of the Mic$ i2 z2 Q5 g5 ]% x/ Z
% setup.sensorDistance : The distance between the adjacent Mics (m)( c9 d$ ]! A: ]# j
% setup.reverbTime : The reverberation time of room: E4 N7 L- ]& C: E4 v& m
% setup.speedOfSound : sound velocity (m/s)5 o! h7 K7 T5 q/ h- |+ q3 H7 ?
%, V" d, {3 r' y0 m% C
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
2 J* A$ y9 ^9 x) q, ]; Q2 M% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
( H% r% X. q, b. _, z% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.( u9 T( p9 m% r E" ^
%# @6 b" v1 E$ W: W o
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). # Z5 E8 Z( Y! E9 }. r. z$ K
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
. `, v- X4 L4 s6 K% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m). , |1 d1 |, Q' U1 F3 F
%
2 } V. W+ e; Y4 H% srcHeight : The height of target audio source+ U2 H V ]1 k6 ^! u1 m
% arrayHeight : The height of mic array
8 o4 }% C- a: u( J%* I h0 e6 _; X1 v' f; I
% arrayCenter : The Center Postion of mic array , U! |8 i# H4 g( L- Q& h9 b9 r* Q8 K
%+ G5 F3 @6 I& e* x7 x
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis4 F" M9 A, Z1 M- ]" |- h
%# g/ m" Q i- [% ]
% ! E- g& c" L7 a
%
- X# x: D- s B7 l%: {+ l {5 C8 L5 \. Q
% ( ]2 J, V! r# G; B
%" }: {* O9 A* r% v* j, v
% How To Use : JUST RUN6 P& j2 Y" z( K$ t) H; V5 g
%- |2 {& g6 x. ]2 I) E
% 7 B' \1 @! W- z5 l2 A* ^1 K
% 1 w7 C8 G7 U' j+ S! }9 G: V! G
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
1 Y/ x3 X' r' d1 G% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
, _" ]* H9 ^9 g! w( @, ~0 K%9 }/ ?0 Z s c. V+ B+ \; w# q
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.2 [9 v/ @6 F2 ~$ C, T
%-------------------------------------------------------------------------
" S4 v/ M) @ r( f7 ^1 f, c
6 j8 n/ O% y* ` ~" P
& b2 I; Q4 ^# g9 |' o7 U2 u; U7 Y% t+ j* P$ ?
addpath([cd,'\..\rirGen\']);
- U+ K8 s/ f. T6 L% V% O8 R4 v1 k" ^: I- A% ^
%-----------------------------------------------initial parameters-----------------------------------3 o, f6 ?$ a2 ]. l, P
8 K, e! i# o# i Q: S/ `setup.nRirLength = 2048;. D' i3 r- C4 ?, a# V2 M1 ]
setup.hpFilterFlag = 1;- O2 E3 ^% {: a$ I0 s1 a' n
setup.reflectionOrder = -1;
$ O0 c' u3 l# J/ w! Y1 N4 }setup.micType = 'omnidirectional';
% J& K. p# c: |* y! h7 ~setup.nSensors = 4;
* j: B( L" M% R/ s! W/ V, n* K4 Wsetup.sensorDistance = 0.05;' m4 g2 G9 p( j e9 g0 u
setup.reverbTime = 0.1;
/ a/ T0 c1 [& j# R" t+ h6 Ksetup.speedOfSound = 340;/ p2 y, [, v2 j# C) f% \
9 k# x# f. e/ u4 [ }" f# [+ ~
setup.noiseField = 'spherical';
' u: r3 L6 f7 t6 osetup.sdnr = 20; J7 q1 C+ I" c2 G: ?
setup.ssnr = 25;
@2 V3 V: U: A- ^' C% v
9 ~1 p! ?. X" }$ f0 _, A7 ^6 }2 @setup.roomDim = [3;4;3];
/ }5 e$ f( e/ p/ q$ L5 {; W0 n. U5 W$ G
: C q; r! Q/ c! T+ OsrcHeight = 1;
% w: V7 y" Z `& \9 ^& a/ tarrayHeight = 1;
5 T0 U# q' S1 f% }7 V2 i+ S% Y) A. h+ c
arrayCenter = [setup.roomDim(1:2)/2;1]; w- l( x' I; T& j6 Z
( {) k/ D( {- b0 v# ^. OarrayToSrcDistInt = [1,1];" l3 }) V" w8 R# X5 A1 [) W' u* v, s
7 o& C& I) A6 Lsetup.srcPoint = [1.5;1;1];1 f9 M2 T! U5 z" `- B/ c& ]2 Q& ~
8 R4 S0 K, g* Q- `7 esetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
) ]! _+ V- l d8 ~
4 T9 X" F) W* h1 J$ Q) s
& C( o' c) R- a! M/ G* k5 p: M3 w[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
5 t( X: I- q- \) h8 Z, ^) c! h3 x X) C) A
%---------------------------------------------------initial end----------------------------------------
8 t$ c% m3 K9 J- f: {% X, V% T$ m; o9 G# ]' P2 R: o* {8 k' J
: j( u' `; z5 h$ q; D
0 L ?; e( l3 p, ]
%-------------------------------algorithm processing--------------------------------------------------
' S% }6 Y% ~2 b) L9 P4 a; r' M3 r& _8 _' r; \8 X7 x
if setup.reverbTime == 0,: X; t7 z+ c7 B$ i' O
setup.reverbTime = 0.2;
$ G, w ~ p1 }* J. w+ r2 g reflectionOrder = 0;1 |$ ~# s$ }, v! K4 H
else
4 [9 |8 C d# d+ a" ~( X reflectionOrder = -1;
9 w; ?9 D& M3 H- @8 {end- Y/ _: z. G" b8 f. }$ E
~; P+ k0 l" u; ?0 k! Y2 q
rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
0 B5 ^# I% u0 a setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
' {/ V$ i: K/ a
3 z$ O. R W2 s# i, ?( _for iSens = 1:setup.nSensors,- E9 h. I2 P4 q) M; d* T
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);" n" F* ~3 [; l* t$ ^3 w
end3 D+ X$ S5 F( y! r; L- N
mcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;
$ Q, q4 T) \/ f7 C7 i" P, N$ Nsetup.nSamples = length(mcSignals.clean);6 Z' P! J# U3 G3 K+ ~ ~
0 ?( E+ a: Y/ z6 {5 q8 b( l; _
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
* |% Y4 [8 ?: M r) v4 `: D
! d9 L; E. I P+ o# Q0 C s%-------produce the microphone recieved clean signals---------------------------------------------
/ b) z2 P- v7 z3 q( P: \ Y- V* k& @4 C5 u
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold3 v7 I, o- ~5 c, r6 f
mic_clean2=10*mcSignals.clean(:,2);
! D) x# C9 W# e! dmic_clean3=10*mcSignals.clean(:,3);
# p6 g& z& ^) v5 Z0 t2 j/ ?mic_clean4=10*mcSignals.clean(:,4);
7 D. q+ ^6 e4 |" Z5 T4 @6 p/ C8 yaudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
! h: }- z' L$ N( y8 Q9 G8 laudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
& M( t+ o0 ]8 h0 E/ ^) b4 S0 |; o! Baudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);6 @. p k9 }. w0 _" g( U
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);0 u; e; A5 Z* {
5 F9 K, M- M3 t1 A- Q) R%----------------------------------end--------------------------------------------------
6 d1 @4 j, C9 e Q" g/ a
1 R2 @# R9 t- ]4 v' P* v1 Laddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);! W5 l! C: ]3 S: P+ w
2 L1 I' e, D# T% y
cleanSignalPowerMeas = var(mcSignals.clean);
7 `2 {9 a; H" h' R! B8 L9 h
* v6 d6 c. E+ M3 }
, e7 [) l. N4 O) R3 O! VmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...2 n5 ?2 ` V* e" k) t
setup.speedOfSound,setup.noiseField);$ W! g; S$ Z; J
diffNoisePowerMeas = var(mcSignals.diffNoise);* D$ t6 Z' a8 U
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);; N% d/ D4 A; r
mcSignals.diffNoise = mcSignals.diffNoise*...4 w ]6 ~7 b& p3 g, f: b
diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
+ n9 ]9 k! h5 _; _# I# W$ B
/ Q& p* G4 C, C* y* z3 q# W4 z5 B. pmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);$ ~7 p3 U# T* V0 \3 Z
sensNoisePowerMeas = var(mcSignals.sensNoise);6 X7 b5 f4 @+ p- @& k
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
8 F# c5 d* w# A1 P6 A( |mcSignals.sensNoise = mcSignals.sensNoise*...7 a H5 A& n# Q* s7 ]" ^
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));# V# q M+ c% U+ J
/ s# @; n, S6 k6 |; w+ }mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
& b2 l# W8 V* a2 [) ]! P( fmcSignals.observed = mcSignals.clean + mcSignals.noise;
) Y- D, }) b, w; t1 |
4 M! I3 J! A5 |" ^! }% g%------------------------------processing end-----------------------------------------------------------
- a8 n, w0 d: ?3 `
. J8 C3 c1 M7 P2 v9 Z" W' T4 \9 Y
6 H3 a5 L1 b, G9 V" H" T. b) F+ W# S$ l; j: i' b' X/ j& ]: V
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
: r& \/ I( a# d6 n- I* O
' H0 U) ^& Q' M3 S# znoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
0 o+ j9 J0 S; R' F' B# I& e% X/ ]noisy_mix2=10*mcSignals.observed(:,2);8 p7 B, @$ ~9 w1 F2 `& D
noisy_mix3=10*mcSignals.observed(:,3);3 O- e4 M6 H/ M$ {2 i
noisy_mix4=10*mcSignals.observed(:,4);
* L C' n$ ?, x9 `3 k' yl1=size(noisy_mix1);
- R4 E) A& _9 t. @2 k/ ql2=size(noisy_mix2);- `8 p0 t1 Y8 R' u5 }( q0 i. m( ?7 Y
l3=size(noisy_mix3);$ e0 I; a* Q. t/ X
l4=size(noisy_mix4);
( }. D' \7 s% Q/ Q6 naudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);# }' @$ {; g$ O# W9 t
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
5 X; k( v: h+ Iaudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);) D& k2 [1 `: \$ c
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);& e% n" T8 A, m2 Z
3 w/ ? H8 }: |% k8 J: n) t% ?" }& O2 \! }% x! ?! ?: u
%-----------------------------end-------------------------------------------------------------------------: T' d3 R" z& |" ?0 u# h
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。 ^+ V' k |( l9 {
直接把它们替换成你想要处理的音频文件即可。
& x* T& J, h0 V: q0 g# |% I( o
8 y' C& I4 o5 P8 r: q4 |9 f$ m 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。# M% I9 J+ T Y! J5 g" ^* \
0 s" _' E: x9 R W8 P* x
![]()
/ v: K1 w+ Y) n9 G! g' z
6 ^ ~" _# ^. j" k$ s, P图1 麦克风类型图8 T6 {$ V: E1 Q
![]()
" ?8 N* W4 _2 S图二 房间的坐标系
5 |6 e, W" R# _: C |
2 Z+ W5 P! N! M+ ^ 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
( C+ ^! p7 t2 A4 K. N————————————————# p/ o1 [" C2 L6 [$ N
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
1 C) ~9 T1 W' n7 \) J原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
* W( {( z# j1 c$ W4 h6 o! V* z* M. _0 G# t/ Q
0 u) H2 v- C/ c
|
zan
|