- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36312 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13854
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言( ^ d1 C }8 l* W# y2 z
之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。1 D! t% N1 L8 W) I
* x4 F5 ]0 H9 |7 ^ 然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。3 M( v" E d! W/ p- C3 }
) E0 |- H7 r& M) |1 H2. 代码介绍
$ s1 E: R/ [3 Q* L 原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:7 F, a1 \. S( z
function [mcSignals,setup] = multichannelSignalGenerator(setup)
7 \. P+ Q/ m! d- X* ~ L
' y3 \$ q, U K7 U0 t7 Q: E/ j( d' j; j" D5 ?+ {
%-----------------------------------------------------------------------# g0 z% j5 k) t
% Producing the multi_noisy_signals for Mic array Beamforming.
/ x( a" ]/ j, E( \+ `6 C3 z3 K# ^%
6 h- f( B: Y) O% [% U! D* p/ H% Usage: multichannelSignalGenerator(setup)
3 } z E! Q2 m8 o2 O0 h$ Z% H8 H* x, o/ V* ?" e9 H% J, W4 {
% setup.nRirLength : The length of Room Impulse Response Filter
! d1 Z$ o+ c! ?) x4 P% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
4 u" j# J {5 E2 v& _0 [+ [% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.# A A5 X! J2 @6 q" t
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.* k& x. \- E* H J
% $ t% _6 D( l) C4 b' u( T
% setup.nSensors : The numbers of the Mic
: E9 o- R$ \: ^" f! M. c1 m% setup.sensorDistance : The distance between the adjacent Mics (m)
$ ]8 a7 t. s& v) Y& f7 ^% setup.reverbTime : The reverberation time of room# N% P* `! ]3 R9 M! P
% setup.speedOfSound : sound velocity (m/s)
( T. C( B+ o3 |. K%3 H* _6 k* t. D2 T6 I- @
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'1 \1 `* m( L, x4 `5 Q
% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.4 q- i. e( N, I. A
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
4 j, X9 n! [4 ^7 M; k7 ^; H%: x% i4 a# a7 E/ Z6 K* l
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). 2 Y" @& d6 Y. V0 D6 P8 [
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). 2 s$ y4 H' K; X0 A6 o
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
$ Q/ c4 H0 V' m+ W+ p; x%4 G& F; F8 k/ C. b& _
% srcHeight : The height of target audio source
0 U& v/ z1 l3 I4 V% arrayHeight : The height of mic array
7 H% N' Q" q1 F6 U, i- E2 t6 ]%9 l) T) S1 q3 D9 ~# n, I
% arrayCenter : The Center Postion of mic array
/ D# V% [0 A& t4 ?, \. U/ r%1 N5 q. P* H& F o* n
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis7 E7 n) f; Z) a
%9 h# y3 _$ y+ E7 F$ B! V+ j. Q3 @1 x
% 1 H! y7 ^! a% Y# [5 n- e
%
0 R- e8 s0 v: Z" P5 ^%
6 n" t" _7 o, W! ]% 9 Z0 I- ^4 n/ _5 X f. }7 Z
%
. g) R; d$ b1 E2 W% How To Use : JUST RUN& c+ t2 O: Q% Z& C0 q
%
' ^6 Y) t( n9 n5 k g%
* q1 F% Z5 n9 M2 _%
) a! B: u$ \9 Z' @! J% e% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
% a6 e; k$ f# h4 o% a, S% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24; Q! ~+ X" _' S+ {% B" `3 I
%
; x- g" h4 O" A$ g# Z- \6 U% Copyright (C) 1989, 1991 Free Software Foundation, Inc.2 P9 E1 d Y0 z3 u( R! A
%-------------------------------------------------------------------------! P5 o+ r5 T! V, p' C- P
" m) p1 ]& q. q; N5 X% ^. E0 h
- n' P3 _: ?! Q4 K* u' ]+ I8 L
0 X$ v1 ]2 v J1 Caddpath([cd,'\..\rirGen\']);5 R( L6 g8 L: s3 B
& t Q; E: n* O: ~5 o%-----------------------------------------------initial parameters-----------------------------------
! J5 D4 z% d7 Y8 M6 J# B
0 r+ J9 P( _7 ]' X& m- \3 tsetup.nRirLength = 2048;% _, }' u2 V; V$ t9 w' h2 ]: O
setup.hpFilterFlag = 1;& G }* _0 P2 x. Z, |* a+ \2 I
setup.reflectionOrder = -1;
4 s2 W z& l1 I( Z) u! i# Zsetup.micType = 'omnidirectional';5 a- y! d6 ?0 n: L& M- p
setup.nSensors = 4;
) ?( n N# O5 C& E- vsetup.sensorDistance = 0.05;
. `$ \. l1 r, S5 _. ~setup.reverbTime = 0.1;! a q, q; x. ~2 \6 s
setup.speedOfSound = 340;
& v( U4 M D# s* |
& o7 O/ ^2 p! ^' h9 {setup.noiseField = 'spherical';* L7 R0 Z9 N4 S5 N2 l8 j
setup.sdnr = 20;& ^# i% _$ A3 q8 f# S, d2 I
setup.ssnr = 25;) H% g" e8 {3 w- R+ ~1 s
' d4 _: u }; E0 ]setup.roomDim = [3;4;3];' ?. o7 k( L3 [8 p3 `% N: V
" m0 |. H6 ] D$ E
srcHeight = 1;6 X d# B+ s- r) {& D! k; q
arrayHeight = 1;9 H2 M3 @3 Z$ g. t" j2 |
( F8 ~, u* n7 }0 K$ k
arrayCenter = [setup.roomDim(1:2)/2;1];0 v7 x4 S$ Q( K' n* x$ ^# W
/ w* v% ~3 o% U$ S7 {* D- @( j) D1 t5 f2 ]arrayToSrcDistInt = [1,1];
6 M6 m! J0 |3 ^) a2 G, h# J( }0 J/ t
setup.srcPoint = [1.5;1;1];
0 l# e& _9 V; K/ y9 t6 m* T: P$ @9 U: L: v
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
( [& l @, K- k% t1 S0 }! w+ |0 {5 Y! c& o9 c: }. Q
8 m( o/ @$ B4 a+ b% J
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');" c4 n# Z1 K0 Z5 P1 _
R) m. S5 ^1 L$ v% p" C%---------------------------------------------------initial end----------------------------------------
5 {6 ?2 b2 K5 G H7 X0 \( j
0 m5 I+ @- m& s4 a, u: y1 P
W$ @2 s# t' L; p/ V, Q4 H1 s5 k& X( h3 z/ [! R9 Q
%-------------------------------algorithm processing--------------------------------------------------/ O% k. b% E, Q3 z6 x9 o
6 W7 B- F/ P8 ]if setup.reverbTime == 0,$ l, C) @2 o* o# ~4 W: U
setup.reverbTime = 0.2;
. I# v4 q8 S. _0 t0 a# {- v% @4 L" _0 n0 J reflectionOrder = 0;$ T2 x5 [3 W3 C/ _' x% R" @1 A
else
8 i3 Q5 U6 ~( f& j! o) v. B7 ?( _ reflectionOrder = -1;9 ]- t3 A% X: T2 k( U- p& o) L
end
3 ^( H) Z2 I# c8 b. p# J; y' b- }' M$ F6 Y, s) d
rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
( k: B) f' J: ]5 s* S9 |$ e5 q2 A/ r setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);6 F. h/ F, E5 o9 }& t. p
- U# A! Y8 l" a0 u7 E+ }7 t+ tfor iSens = 1:setup.nSensors,+ \, a( a3 Y( E E6 u) ~
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);: P% B4 N8 E- Q( l1 ^1 h- J
end
- T# Q- Q2 s- G6 MmcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;. i( y @7 s, H( t
setup.nSamples = length(mcSignals.clean);6 |8 t( b) }+ o e+ Q$ D
0 t$ e2 K, X& K% ^& U! {, }
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
) X5 Z/ H/ ^2 D, U$ {: X5 J" q0 a8 i2 P6 S. l% V
%-------produce the microphone recieved clean signals---------------------------------------------
( E2 V% ~2 H9 K2 K6 d- P" O
9 S0 n$ w; O( ^% G' ~+ Qmic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold }8 c0 s9 E( N2 `
mic_clean2=10*mcSignals.clean(:,2);
4 {8 a* }/ Z: b) {4 e0 Q7 s( A, xmic_clean3=10*mcSignals.clean(:,3);7 f" d! P- f+ X5 R, P
mic_clean4=10*mcSignals.clean(:,4);9 l' @# w% R' s, w
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
' ], s7 d1 q6 F% Z3 qaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
' k( D6 k! q" x! b" \audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);; ~1 \0 V/ b- c6 @5 p
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
( w7 b! Y" p" _4 Z4 _/ B- P$ x; I" s
%----------------------------------end--------------------------------------------------( O3 o Z, w5 j7 ], k
: G* ~, h3 z) j% y1 Yaddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
+ y$ w- E( c4 n4 u H; S# {3 I$ ^/ Q* h
1 z5 R m1 ` X, d5 KcleanSignalPowerMeas = var(mcSignals.clean);$ P& T0 u0 d- T) @- W4 t
' f( z) ?/ E) b% Y3 s. P3 }. [8 o" J- W
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
& W( J! y: c) w* `/ y" K setup.speedOfSound,setup.noiseField);
8 v( |6 i f; s5 C5 c" kdiffNoisePowerMeas = var(mcSignals.diffNoise);* E4 T; n. W& R, ]
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);: i, W4 c" F) E2 X8 A
mcSignals.diffNoise = mcSignals.diffNoise*...
2 J3 ^. @% G' E3 c/ r2 L5 @ diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
A+ o/ _- N S$ f
* F& E* m J9 ~( Q7 p. w8 f% C8 jmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);5 @) ^! A8 I M; z( B$ {4 ]1 ^ G
sensNoisePowerMeas = var(mcSignals.sensNoise);
* ]9 a9 N0 `' M7 BsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
D$ E# m$ m9 i( pmcSignals.sensNoise = mcSignals.sensNoise*...$ d* k+ k" a6 o: F' a
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));! z' Y8 W1 k# h$ t5 k9 Q+ I) u
/ w) q0 s, P2 a# e6 Z: H' s$ \, o
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;1 D3 y& X: {0 t& b3 [" ]
mcSignals.observed = mcSignals.clean + mcSignals.noise;$ k% x! n6 ?- F6 r
C7 \+ B. U+ _7 f%------------------------------processing end-----------------------------------------------------------9 F; |" Y; E. x, R0 L* [
! l; v9 A8 S) ~ E3 Z& n4 d& Y7 f# |
6 F5 l6 M. p$ M: n% L& Q$ S' O$ o9 @. y: [3 ~$ q
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
7 H. f1 g, M: E) `* L: v' F4 M1 t3 D4 H
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold V+ t! W4 s& [6 `+ q
noisy_mix2=10*mcSignals.observed(:,2);
- c& i8 O- L/ onoisy_mix3=10*mcSignals.observed(:,3);$ z* n1 {9 |. K& \
noisy_mix4=10*mcSignals.observed(:,4);( [! ~$ O+ B( n2 N! @. `7 N% Q% H
l1=size(noisy_mix1);/ l$ l! c% V- m2 m$ p6 [9 V+ R
l2=size(noisy_mix2);2 [4 e U) H. k& @- H5 m1 p
l3=size(noisy_mix3);' \7 L# p; }& t2 Z
l4=size(noisy_mix4);% }6 K7 b% C# N6 L; L
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);1 ~# e8 d' c# ^' ~
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
0 ]$ |7 b8 K# yaudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
$ }0 D; r2 v5 q6 Haudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);) h/ S o( W0 K# t7 H
8 V2 _+ [! U/ F+ l, H1 Y" U
- E5 n% C( U) i; s$ m" u%-----------------------------end-------------------------------------------------------------------------
5 X0 W$ X' V+ @1 ?! o' }" A* e这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
% b! v" W! L, h& y) X直接把它们替换成你想要处理的音频文件即可。: g- D, J" f" R. J( G: A" G; ]
' z) h4 \: b, p, F* { 除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。7 X7 Z" ^3 @; K4 Z
: U$ @ A: h @1 \, T![]()
- h, a$ \+ \3 E& S" {" m2 {% ~: s5 O4 n M- S& O, Q' r9 Q3 h( g8 n
图1 麦克风类型图7 n) r: z" U8 G6 C7 {
![]()
U1 u1 p+ O+ H4 g4 d$ R3 f图二 房间的坐标系
N5 e" M, E" e( w# P f$ h+ C! U; I$ y& E0 [. T Q
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
% g1 b. R) S1 `% j( I$ @! t, t2 t————————————————; h; \ u5 Q+ O; v2 v
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' V Y2 v" o) H4 w
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
+ a0 U- d" z$ z! o% P. Y4 f3 {
3 L8 F% E4 J& u) `: j
" q: f2 b8 X4 b |
zan
|