- 在线时间
- 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. 引言- b/ d1 ]" o3 U. v3 J! |. i
之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。/ \9 j, k+ n% W/ s4 W- C
8 @ a+ q8 h. u9 {: |% @
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
! d; l. h/ O% L7 z9 q8 y S. Y2 K S4 B& P6 u6 P9 }# b D4 v
2. 代码介绍" x% ?' L; r6 `' G1 ]" o2 B* J; d
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
+ P. q7 p2 P* Ofunction [mcSignals,setup] = multichannelSignalGenerator(setup)
: r' C* c0 _$ C# s: t
0 U% G, C( x* j5 b" N6 I3 y* Z
%-----------------------------------------------------------------------( O8 J, k8 O7 l$ U+ }3 i
% Producing the multi_noisy_signals for Mic array Beamforming.% R$ T9 q: ?. s/ D+ c0 _2 T# |
% ' ]' c; Q8 U4 b" { P4 j, o/ i
% Usage: multichannelSignalGenerator(setup)
# j F0 r- i% ~4 ]8 Q, `& S%
7 k5 E. W+ |, E9 ]3 d' `" z8 O% setup.nRirLength : The length of Room Impulse Response Filter1 r- a1 B5 \ B% C4 K
% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default" M1 y" O1 d' ~9 e+ d2 g
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order., r& Q. J; I3 V! S! [
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.2 z$ e W. a G! b% ~
% . \/ O& j6 I, N
% setup.nSensors : The numbers of the Mic
7 Y/ c' ^$ [+ Z! Y( b/ x6 `% setup.sensorDistance : The distance between the adjacent Mics (m)4 S! {6 c8 x* W; ^( l
% setup.reverbTime : The reverberation time of room, z; ~/ K+ W) ]+ n" f) t
% setup.speedOfSound : sound velocity (m/s)2 w9 C/ m6 S% B$ |7 }( U2 q
%
3 j, m# }3 ~& j2 x& e* d% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
! L$ ~8 [. k$ ^, O8 @% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.) x* w# H/ r9 C
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.; E' V! w/ [5 Q, o( G7 _' ]
%
' o( p; r5 e, M* W3 R8 Q" f% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). 5 A/ Q4 ?) ^/ q7 a
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). / `) y% D" r& r
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
7 a& ^6 \. w3 t' o%
: @8 k8 e* Q8 l5 V: }( \$ L; O% srcHeight : The height of target audio source8 l* K6 E+ b6 V5 s0 w
% arrayHeight : The height of mic array
) |. ]8 c7 Y% a8 O%4 x1 P8 [' G9 ^- z
% arrayCenter : The Center Postion of mic array
* c1 y4 L% v+ G2 ~2 J; k: N%
: ^2 h. x0 x/ D5 ^$ [3 ?, s% arrayToSrcDistInt :The distance between the array and audio source on the xy axis
* p: z( ?+ b3 p! }" I y%
/ A0 o9 O+ }: F; w4 u9 E+ u# ~% 7 J) R7 g# f! s9 T+ }, ?) `
%! @ E' R5 _5 B4 S( H7 y8 w( [
%
- S) ^5 n" S! [8 p& X% 2 {4 O) ^ @- n: `# f
%! {% t0 S9 u# e) B1 F
% How To Use : JUST RUN! Y) j' e- f! N! L6 ^9 D
%
6 {% z1 h( f, ^' X, b1 n% * N- r9 c% H7 u, M4 J8 |: W
% 0 F- c3 v: k' P+ P; l7 b
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),- n* A/ ~& v+ m8 ^: X' P3 H
% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
E" D$ m! z; C; W; q6 ~4 y%; b- W4 p' E( m9 Z
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- I' j( d. U* l M%-------------------------------------------------------------------------/ {; ?+ o( O& A8 x# C
# o$ s+ p- Q; o" J! j9 y( [
$ h; ]/ L* L4 p" g0 \- Q
% L% w7 ]; o" caddpath([cd,'\..\rirGen\']);
1 K: t0 k7 E: P$ A; x% | S' f% R3 v# v- H( F0 R" u) L- a/ R- {3 w
%-----------------------------------------------initial parameters-----------------------------------1 U, S6 M j( H/ G/ K6 z8 v3 T
0 |+ m0 \8 A4 x; H0 t0 b% A1 O9 D
setup.nRirLength = 2048;3 o) s2 F. \/ d7 F, q
setup.hpFilterFlag = 1;
% Y* u& I- A& Q! ~$ V7 q2 P; R( t. w$ isetup.reflectionOrder = -1;
- v. d8 ~# D4 y' |# K7 Ssetup.micType = 'omnidirectional';) S$ L9 E7 m4 o3 B
setup.nSensors = 4;
* h, \0 m2 _: X- N! Asetup.sensorDistance = 0.05;
! G2 K" e: [7 M! B& Isetup.reverbTime = 0.1;
+ x4 z+ z. K% Dsetup.speedOfSound = 340;5 J3 h% F9 [* o! E1 \9 h; E x1 d" C
5 \- ^6 w5 _3 U7 t- W5 K7 Jsetup.noiseField = 'spherical';9 R5 m3 ~! e5 m' r
setup.sdnr = 20;
& D: i* h9 g: |3 hsetup.ssnr = 25;* |$ s1 \% v* K+ I) q2 F) V( P: |
* l t5 v8 O' E
setup.roomDim = [3;4;3];- ?# y, L+ H- A0 Y
! S, b0 O1 i* j8 _! p+ }8 _0 U+ N9 q
srcHeight = 1;6 Q% L1 \& ^9 G6 ^1 ~( C/ |
arrayHeight = 1;7 \" L! S, r+ I- P+ S0 i
. p6 j" `0 _# V5 u/ i! [3 oarrayCenter = [setup.roomDim(1:2)/2;1];
# w9 n6 ?. o2 ~( J3 S6 ]
O4 a6 k9 J6 v6 L' harrayToSrcDistInt = [1,1];0 e. n; v& V* Z' g4 @% r3 v- m
) p1 `) i( n% z! n
setup.srcPoint = [1.5;1;1];
' o! Y# ^: T) G' W9 }9 C% E
$ i C, E( E4 T) D# l2 F6 H9 S. ssetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);+ }! J8 D1 | x4 A: t$ T
' h4 e9 H; g5 d
+ } |, q2 H6 n" J[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');! O/ \6 B& s7 h
1 G0 w$ Q. ^) I6 x) d0 F$ a
%---------------------------------------------------initial end----------------------------------------
; o4 @. G" h3 z7 }4 x5 p& M. a( T% c: P+ N4 ^
1 L5 |6 [* x: o; r5 u/ D9 B+ Z& {
, M3 ^1 v _3 s5 R( d%-------------------------------algorithm processing--------------------------------------------------8 G7 A- Q7 B: J( y! I* v
1 y7 D- C+ J' |. Q: ]% S
if setup.reverbTime == 0,: ^6 |1 b# t0 r, X% U0 r( e$ r# v
setup.reverbTime = 0.2;
- ^. p1 M Y& r) z reflectionOrder = 0;& r! I9 z7 {5 }
else' g7 e: D; I. r, F r
reflectionOrder = -1;/ H- [* ^9 J: Q
end
8 Y9 |# q( L" a" \5 q: P, j% r/ `, _* u2 A$ }4 A! V2 f' X
rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...1 {: @' q" S, Y1 n p; W' ]
setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
7 N, Q R; \, I" ~: `; ~& f0 p
; L" v1 I9 ~6 S/ R' t1 |3 q0 bfor iSens = 1:setup.nSensors,( R7 K& d/ ]3 ]$ J% ~+ k
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);2 _* j# k8 g( ]1 g
end& ]: n- d& N. h- k7 I* W
mcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;
$ ~* l1 k6 p/ N' p6 ` D; Jsetup.nSamples = length(mcSignals.clean);
q3 q$ c1 T. Y( ` v9 ?' ~. U& L$ W) A
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
% R3 {; E7 F# p1 f" M2 Z. Y6 {/ `; G/ D. E% y3 H; H& ^
%-------produce the microphone recieved clean signals---------------------------------------------- z: h" `( r3 t% D0 z
$ P& r* x8 P1 A$ K( b# b& c8 k$ W
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold, k% S1 N7 z; f! O
mic_clean2=10*mcSignals.clean(:,2);( P# S8 d* C8 }. E
mic_clean3=10*mcSignals.clean(:,3);
2 u& O' Y I: O$ s1 R: f# Dmic_clean4=10*mcSignals.clean(:,4);
7 r4 B7 ~, B+ d5 d- ]; ^audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
! l, H3 d! j# f- A0 F% I5 Gaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);1 ?5 V& v4 Q6 N* T& i! `- L3 _! B
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);* ? g; e9 N. Y
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);7 c) Q- r5 d* l2 X! Y+ i' L
4 ]6 S$ [$ \3 b: w$ K
%----------------------------------end--------------------------------------------------
q G/ P; [3 o! Z' @& U0 D$ e* g& e% C* E
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
; q; q. F! {& |2 R- h
- g5 o( x% h P0 G7 }4 f H2 gcleanSignalPowerMeas = var(mcSignals.clean);2 J% x% D x' ~) P
2 ?* o4 u2 ]2 F: G" ?3 q, S
' A& Z, @, t$ w. s% [7 S! O8 N
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
- E9 Z8 q+ X$ i7 i& D setup.speedOfSound,setup.noiseField);* H; u- ^$ ~ K& ?9 G4 b ~
diffNoisePowerMeas = var(mcSignals.diffNoise);
0 Y9 b- Q/ V5 H2 \9 X2 LdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);. b% [7 w* z; `$ D$ h7 H
mcSignals.diffNoise = mcSignals.diffNoise*...
: t1 G' z/ M: k8 B- B' ^ diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));/ I; W6 Q, {: u' [
$ B8 D" g8 `4 F' t! s/ N( P; J
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
8 L* r" ~0 z* j; K) qsensNoisePowerMeas = var(mcSignals.sensNoise);
# b, c+ U& ?8 n- S, BsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);) h+ q1 {/ M4 s) U3 g& B
mcSignals.sensNoise = mcSignals.sensNoise*...0 G3 ~) {3 ^! E( F% h% _/ W
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
- ?5 ]5 }8 |- f% M; R& W
) A2 L* D2 @3 |! ~( SmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
5 D6 _9 r; ^3 x% u# x- t0 l, K) {mcSignals.observed = mcSignals.clean + mcSignals.noise;
8 ]* H0 q V. A- g( }* w, A& `$ V* |: J( }9 H+ P% G+ K, T) V( P9 V
%------------------------------processing end-----------------------------------------------------------7 I) g9 U1 V' x! L) L: [3 i
Q, ~; w. |& q# t8 O% F5 J4 _( p
5 e; S0 T* i2 C# K- O5 k! M4 u. L' @1 |
0 q$ n( |+ T b* y
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
* Q' t* L2 [+ I! U: a4 j! K+ l" B9 T' b6 s
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold$ p8 c6 d8 }! n! p( u& \5 R: j
noisy_mix2=10*mcSignals.observed(:,2);3 I' k/ Y+ n% f6 c
noisy_mix3=10*mcSignals.observed(:,3);. }4 b& i0 P2 P7 y
noisy_mix4=10*mcSignals.observed(:,4);
8 h: W4 e/ v# _# C2 x% _, F1 S$ ul1=size(noisy_mix1);( f' p, R$ ]6 H% [
l2=size(noisy_mix2);
* x) H8 A' t) @ L7 w9 O$ c# i; D7 jl3=size(noisy_mix3);; P' Q8 @& w2 I# @7 i/ \- V4 [
l4=size(noisy_mix4);
8 h6 @9 `; D/ h- M3 B% paudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);4 H% _0 d2 U% a
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
# o: J3 P' R! T; u, o" taudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);; V8 }5 m# p5 w, Z
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);4 N& l. ^' C5 q: a) F
/ U& u, U _$ Z4 J6 T/ X6 k8 N% u; u- a' N! P; X1 i. j
%-----------------------------end-------------------------------------------------------------------------
/ f" ] U5 @9 {$ {7 @5 _这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
x2 c) I) s# p* ?, ^- O直接把它们替换成你想要处理的音频文件即可。
9 ~' p$ V2 k7 \8 i- t4 H& ]4 B
e! r( T# |; f" h3 ~5 P 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。9 q4 c- [! ^3 B H# q
* ]6 O/ R5 o. k$ m; z8 l![]()
2 O7 g5 @8 W4 J' ]
" ^9 k3 k1 r# v7 a/ V, j* \图1 麦克风类型图* i0 O$ u; G- x" Q
![]()
6 ?4 U( S3 ^2 A! S图二 房间的坐标系
+ K, ]. l' B$ y1 l
! A; U" w9 [; o$ q 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
5 N- p7 ~8 U# o+ Y: e- M8 C- x————————————————
) ~0 L7 |% t9 N* a+ C( H版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。7 _. z9 @( p" q x" P( M" i) o% }
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998# X# T+ T% {8 ^2 F
9 v/ a% F/ ?" t% l; z9 R4 j5 M
. F' v+ ~1 {4 w. ]: t0 F9 I2 k |
zan
|