- 在线时间
- 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. 引言 H7 ?' O( B' _/ O4 J
之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。: u2 U4 z# T: L% g$ h
3 R |: X" X& z* {" U
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
, O; d- Q% ~* ~2 m* x* J+ R, h
! Y5 d8 I% e& J, E2. 代码介绍
, `/ o6 M2 ^8 S 原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:2 t* |- A1 u: x2 J6 a4 F9 [
function [mcSignals,setup] = multichannelSignalGenerator(setup)# `/ E/ d4 y& u
. F8 L/ G1 I6 }: P7 @
5 y6 g T q- X+ \3 C6 c' f( N; M
%-----------------------------------------------------------------------
# Y- S+ u2 H( Y% P9 c: E; s% w* K% Producing the multi_noisy_signals for Mic array Beamforming. A/ m d6 s; p& ?! {
%
, k8 C$ a+ c* t' o1 q% Usage: multichannelSignalGenerator(setup)" z+ x0 O5 A- x$ X
%
" H. L" \0 d5 q2 v5 n% setup.nRirLength : The length of Room Impulse Response Filter
' Q0 g" u- I8 o8 \: z$ r5 c% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
; q3 ~, V& V+ A9 g6 K3 V% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
h$ K8 I1 x& I% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
6 D" W" i+ V6 ^" B: D4 c% * i/ b% T/ [/ j
% setup.nSensors : The numbers of the Mic; G" R) N& r2 o
% setup.sensorDistance : The distance between the adjacent Mics (m)
* w# V! D9 p7 k, V7 }. n9 B. m( {% setup.reverbTime : The reverberation time of room
, f5 J8 `3 X; M5 {+ {% setup.speedOfSound : sound velocity (m/s)' a. O5 o1 k; H/ P
%
! q3 s' P- A' ], {+ H$ j1 d% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
' ?( b! q q3 R, }+ B% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.' C" _/ h* T8 `+ P2 D
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
' f3 y# K, s- x( @. O$ R2 B. w9 @%
3 p5 z. V2 w5 m; C; d) W% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). 3 G" R' b. B2 S2 Y2 e( d5 u
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
. e2 }3 o; x# p$ I, m" a* Q& O# I% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m). $ O7 [8 M5 ? d+ G! }
%' L( G" \- k; _' _* H
% srcHeight : The height of target audio source
" Q1 ^/ W8 v% F g) J$ N% arrayHeight : The height of mic array4 |! F) ^ R0 H
%
" ] J0 F$ V2 p3 N( X' f% arrayCenter : The Center Postion of mic array 4 ^% L, N( _3 {+ j. Q$ B
%
/ y7 u3 s( a: |5 T( S% arrayToSrcDistInt :The distance between the array and audio source on the xy axis9 ^' Z2 H" O: N/ \7 K
%
( o0 H, p- g8 A: R4 y1 h# Y%
: X. w/ N* S) x( j5 p9 v9 l- ^ v6 \* j%
! h* X3 P. c# d. Q6 E) j%5 Q1 [. p: L; x, z1 w# w. p& x
%
: v) y( {$ B% I) D% `%
- m9 l# W( P/ O+ z9 X1 R& M( h% How To Use : JUST RUN" h+ S# j' s* ?) n3 Y1 _
%# O @& _7 ~0 O& P6 d( \
% ) W3 [9 j j+ {; s: e
% " O" J- U: @( B) J
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
8 M, B% M7 J& s5 _* L; R! ^% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
" U! A% {& J1 R%8 F! n8 E+ s4 H$ Z2 ^5 W
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 D3 i7 T& A* m# w. |4 i' e%-------------------------------------------------------------------------: u5 F0 i3 E }: m1 |$ U% C6 U; z" s2 f
% N/ i1 c9 ]; i1 Q
! o2 W6 D( i" k
; N+ \2 _/ Y1 Z; I2 Daddpath([cd,'\..\rirGen\']);
. H6 l! F8 X' s% Z: k b
c, \( g Q+ ?%-----------------------------------------------initial parameters-----------------------------------
1 b9 M: i: P! Z h. |# e5 R ~/ y) Y: ~
) Q8 y7 v& A w _9 _7 T( esetup.nRirLength = 2048;
& Z; \- b: L$ Lsetup.hpFilterFlag = 1;' N6 `. ?$ x. M9 ]8 T% V
setup.reflectionOrder = -1;
3 }! R) h- s3 @3 j! Psetup.micType = 'omnidirectional';
/ b+ O% N6 M% ?" d, C. S: esetup.nSensors = 4;) c8 R: n" Q+ v4 Q2 m' J/ E
setup.sensorDistance = 0.05;& \, N# n, }* P5 E1 P8 P. s' r
setup.reverbTime = 0.1;
. m0 d; [9 b" C+ y& gsetup.speedOfSound = 340;
3 ]* a2 p4 Z) K: |" ]; {4 c* L s
8 `- E/ Z" f4 K! U3 osetup.noiseField = 'spherical';
" A$ |# q/ Y' s3 Wsetup.sdnr = 20;
; ^# z, J5 g" q7 G# \setup.ssnr = 25;4 F% u! A0 m, l0 ~
/ e* K! {5 ]: V" c
setup.roomDim = [3;4;3];2 m) _% ^9 ?" r- L. @4 C
2 ?! R; Q2 C# v/ d6 D7 O# p
srcHeight = 1;% w3 m0 S& ` ?: L7 z$ j
arrayHeight = 1;
9 Z7 B* g' Y) b9 [& G: ~4 x
, V" t7 a' z& m: i& varrayCenter = [setup.roomDim(1:2)/2;1];( }& y) w, Z- n# K/ P5 Q
9 @4 o3 L8 R: g. ?
arrayToSrcDistInt = [1,1];. ]! G* O i9 R/ I. p
3 F2 t) v' G7 n: {3 J9 K* c; Jsetup.srcPoint = [1.5;1;1];# R7 F* @& M0 O! k6 @
9 a* p# k4 i/ b5 y) w9 W4 _& b: Ysetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);# U7 d5 H' w1 {' e4 |- U
B* p, c/ C* x/ n" S0 d6 E6 Q8 \
6 i6 v& H& q+ r4 y7 X, R[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
3 v. J) s% A! B* E" Y' P$ i, T# p/ S$ Y( I. M" V1 j
%---------------------------------------------------initial end----------------------------------------5 {6 V0 Z6 o( E; W. W
6 E, ?0 T- _0 P9 { U9 |' g8 C
* t) }8 E; x* c
5 T4 x7 [8 r. Q# F%-------------------------------algorithm processing--------------------------------------------------
; M: A& x% W+ \6 V/ M+ Q
% w- @% _8 D# ~( J+ D/ b3 Uif setup.reverbTime == 0,% a1 a$ J* p* l8 ~4 X% S( m- y# T
setup.reverbTime = 0.2;7 G2 c1 j! K0 f6 ^ T
reflectionOrder = 0;
8 i$ U4 x1 t+ x0 @0 B- F! E: ?else
6 D0 }0 r$ z3 l3 R- j reflectionOrder = -1;
- M5 v' ?# o# B) Iend
9 V0 U9 V3 M! o p/ o$ u5 b, X
( X! }) Z+ j. _ S) S# y9 VrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
! j; Q3 E5 w# L setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
, q6 X8 f/ e% G/ O. j
- U5 q: D+ o5 O8 O/ }9 `8 dfor iSens = 1:setup.nSensors,
4 _( K: F" g" B tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);" E; ^/ l0 g6 g; t2 ^4 p4 e
end
0 f* Z( ]* }: GmcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;8 T* [# F9 Q6 P! r0 Q# n. r( h
setup.nSamples = length(mcSignals.clean);# f8 c+ K0 w7 @5 @
) q$ [) R, B6 R
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
, r2 w) H" i; J' G! [9 v% ?2 x! J: W& ] G9 D
%-------produce the microphone recieved clean signals---------------------------------------------
+ M, E; k. `% d
4 Z9 c, C6 b7 m" Y) kmic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold# w- B: [+ @3 v& d1 H
mic_clean2=10*mcSignals.clean(:,2);& @* W* t: R5 h6 Y
mic_clean3=10*mcSignals.clean(:,3);
9 N: V( W5 D- Cmic_clean4=10*mcSignals.clean(:,4);
) a- T3 w% M# c% r/ M, p: saudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
) \; B4 z* G" Y: s6 o, }& Haudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);& R6 d( I, }8 @$ Q
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);' o8 k6 M8 n3 X' v
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);( ^1 {4 s# ]: ^6 p1 |: u4 y
2 g; }5 j } c
%----------------------------------end--------------------------------------------------" Z: _* p |" B s$ Z" I2 a. Y
+ W# w x& e! u/ \4 y9 h
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
( ^- q/ I/ l* j ^$ t: n& b9 V
! U ?4 G% S2 T4 t, C: B9 NcleanSignalPowerMeas = var(mcSignals.clean);
6 o& @: Z2 q/ _& s+ Y
" H- |; f& E! e. V) v, U! P2 i9 A* A- Q: d8 O
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
4 L/ Z- u$ U0 ~) V, t1 p setup.speedOfSound,setup.noiseField);
; ?( G' g# A$ _! o1 {diffNoisePowerMeas = var(mcSignals.diffNoise);
8 o2 y8 G% r! I% w/ DdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
) x( \$ P; d! RmcSignals.diffNoise = mcSignals.diffNoise*...
; D. h' P* K4 k ^+ e diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
. F9 d6 K) k9 c. a6 @
9 X- b( R* B+ q2 U, m4 c( @mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
. U/ Q- N2 G# [4 PsensNoisePowerMeas = var(mcSignals.sensNoise);, W/ d$ \% t* z: R$ ~2 n$ z8 z) x
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
! T' ]. L) e+ j' B5 @) A, x x) KmcSignals.sensNoise = mcSignals.sensNoise*...% h: D/ h- d. A a9 ^: A
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));; p; Z& r8 ?3 i( u9 A- V; f
, p) G) D2 z9 I! ]* C8 ], \
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
0 m5 c- s N1 ImcSignals.observed = mcSignals.clean + mcSignals.noise;, K, p+ b1 r, g: L/ |! w0 \
* ~. C( t- F* L- t$ F
%------------------------------processing end-----------------------------------------------------------6 b5 E( r2 _2 w4 s) `9 x
& R" h& a- P: y
. ~8 U, c7 G. P( \ e9 ?5 e( V7 m' ]) G- Y1 A
# N: }( M& c7 M+ ~/ b5 a# A( |- d%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
5 o/ x4 h$ s( h! v @6 O' V6 G q
& F, T( P0 Y( k+ Cnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold n" b( k; ^$ Y! f" v9 W
noisy_mix2=10*mcSignals.observed(:,2);
+ Q7 M4 U d8 |5 s- a, Qnoisy_mix3=10*mcSignals.observed(:,3);" x) G$ _0 ^ P3 P1 i
noisy_mix4=10*mcSignals.observed(:,4);
" h" R( U8 k8 I: w5 _; }l1=size(noisy_mix1);
- j5 F3 ]6 ~% k. Y! ^' t H( C7 ?l2=size(noisy_mix2);1 H% S+ |4 {( {3 A% f/ W- z7 K: N
l3=size(noisy_mix3);# \! d% P9 z ^7 K
l4=size(noisy_mix4);
5 Y/ ]3 x2 d+ G8 x u0 Paudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);7 ^; k; d3 \0 ?7 n* @4 `
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
7 p8 p- x2 n6 Waudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
Y) o5 { g2 k+ `0 B& oaudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);1 R5 K- G& w8 W7 L
: u* Z9 j0 h3 H% {% s
0 h9 N% v1 X; N& g f% M' |8 k- Q
%-----------------------------end-------------------------------------------------------------------------( j+ c' }. p0 u4 t
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
( J' Q. l* P& ?& h8 g# L, ^7 s6 c, ^* Q直接把它们替换成你想要处理的音频文件即可。9 s, ]4 ?- K1 f* T) I7 \: x
" N; }1 n- T# g/ i5 T( ]7 } 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。, _" A/ A- \2 C
2 K x" a6 p5 R3 Q* O
2 j* c$ n6 V, w, z- \7 ?
2 S% G' w% d. }3 D; ~4 v; ^图1 麦克风类型图
* I3 Z; t0 e8 A' Q + z0 i( N& e0 v. l$ A$ T9 z1 X
图二 房间的坐标系
- N0 b) [& l; T M4 Y2 O
3 y& n4 ]8 E( O: i) @& m0 m 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
2 i% f# q' d* U4 F; D; B5 s————————————————
; f) w% G; X% N* K' g版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
. K" m# b' p: b0 X/ z$ p' U原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749989 O, s. ?, x, J7 L% W
- Y' n; U- M& X
' m, c8 B+ T1 H, `2 z |
zan
|