- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36352 点
- 威望
- 11 点
- 阅读权限
- 255
- 积分
- 13866
- 相册
- 0
- 日志
- 0
- 记录
- 1
- 帖子
- 616
- 主题
- 542
- 精华
- 12
- 分享
- 0
- 好友
- 225
TA的每日心情 | 开心 2020-11-14 17:15 |
|---|
签到天数: 74 天 [LV.6]常住居民II
 群组: 2019美赛冲刺课程 群组: 站长地区赛培训 群组: 2019考研数学 桃子老师 群组: 2018教师培训(呼伦贝 群组: 2019考研数学 站长系列 |
1. 引言
7 Q4 _/ m( e2 u3 m8 k- z9 } 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
+ i6 r! v, F5 W% k+ L# T2 u# J; N u l: j
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
! f2 }! Y* K" _; L
; G. G }! x+ b, l2. 代码介绍
; \6 `* c+ O! ^- R4 K, \8 H, L 原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
$ G% N. H' G2 T2 `% Ufunction [mcSignals,setup] = multichannelSignalGenerator(setup)6 w# w% ^7 \2 d/ J5 K1 L
# ~+ G. f9 E5 d( Q$ ?* @8 ]
! y! t; ^7 `- ^& F7 F( W%-----------------------------------------------------------------------4 {, B9 I/ Z- z6 g- j( j
% Producing the multi_noisy_signals for Mic array Beamforming., i9 \; h% w# P G3 ~
%
/ P9 \5 g+ ~! a3 E, Q3 U% Usage: multichannelSignalGenerator(setup)
6 ~$ g0 N* @, L: q$ l- m%
9 \3 D) i, ]5 B) m1 v3 `% setup.nRirLength : The length of Room Impulse Response Filter( W k& z. ~ ^/ n" y
% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
( _5 Q/ n' L( H- N% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order. X9 n! H; T( }* L* x
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional., B) o% w8 ^7 @+ K/ K
% 8 g* r" p J' l5 a
% setup.nSensors : The numbers of the Mic
- D2 `2 b3 K+ J9 N! Z% setup.sensorDistance : The distance between the adjacent Mics (m)6 f8 P! x& z( A
% setup.reverbTime : The reverberation time of room
* ~+ W% A" p2 u; n; r( A3 C3 r C% setup.speedOfSound : sound velocity (m/s)
6 m" q1 y; m8 a3 [# ]%8 Q5 z0 J5 a1 I+ ~5 g
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical') ~3 h4 ^! i1 h7 b: H& s( H
% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.3 q' v! `. ?* V
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl. E+ P' N1 Z8 o0 ~) f
%# y4 v7 [2 |. j+ ?8 b2 V
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
7 s1 J3 n U/ }3 u1 Z. U6 q% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). / n' _8 W% H+ {! p- Z
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
0 w `3 Y3 n# F%, A% C) C0 ~2 f9 o z
% srcHeight : The height of target audio source: E) X0 Z6 I- ^: w) w: V
% arrayHeight : The height of mic array
% n% i2 s4 O, f5 L& ^6 w5 Q: Z%, }, e5 M' D L# N
% arrayCenter : The Center Postion of mic array
+ z) p1 v$ x( |5 g# ?" U) b& m%; r) h- G2 N) G/ Y( Y' }: v
% arrayToSrcDistInt :The distance between the array and audio source on the xy axis
/ d4 Q( O+ Y2 O. H# _%
' ]% E& x8 T3 o* K! O' ^%
: Q& W2 p6 ~7 s$ @%
# \, R1 O/ }: j1 E8 |+ Z, p%7 J# c9 n/ o; T0 H
%
: z7 ~9 L( c. f% \# ^%- u- V' m( w0 w9 a& y2 p
% How To Use : JUST RUN+ Y' j& q# r# J+ o/ ^$ C- Q$ m b
%1 j* d r& H! U' l0 h; y
% 6 `: A, K! s$ _* P3 m) i% T. h
%
/ }7 b# u2 r! G0 d4 t) V% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
1 p. p0 o# P! C& }- h" ]" Z% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.240 ~+ _" {6 Z& H7 R) W
%
/ y4 v. Z' K4 y4 A8 V% Copyright (C) 1989, 1991 Free Software Foundation, Inc.. L* S* j- ], W+ M" K: X8 a7 U
%-------------------------------------------------------------------------
$ K/ F" i& Y5 @* g5 F2 ]5 p: O) k; F* Y3 q; n$ c
6 ?7 X |" D2 g/ N- f4 X; _( S
" {( R! k# Y& e- b0 z" B# T
addpath([cd,'\..\rirGen\']);
6 u {6 G1 U6 Y' }" m
2 J. N7 H' E8 ~, Q( m) U%-----------------------------------------------initial parameters-----------------------------------
5 i; x" q% s+ t" ?
4 ~4 h" J2 K% l) hsetup.nRirLength = 2048;
; L3 Z3 S7 a0 K! G% e r0 \setup.hpFilterFlag = 1;/ y- B: |" x/ e" E* ~
setup.reflectionOrder = -1;
4 f5 p9 B2 g* ~. dsetup.micType = 'omnidirectional';! A, M. { P5 s$ s
setup.nSensors = 4;
* q( D/ Q) b# @setup.sensorDistance = 0.05;
+ b2 d* G+ o) S6 B, V: w; msetup.reverbTime = 0.1;2 j1 w/ ?8 S, q# Y# N
setup.speedOfSound = 340;0 `% e. {( |* H0 I6 c7 K
* g, w! y: ]" x- f3 O V" V
setup.noiseField = 'spherical';
& t# h O) V+ K9 y$ \+ Usetup.sdnr = 20;5 E8 c$ K2 z# c% {( F7 S3 }- H- t! i
setup.ssnr = 25;
: ^5 }! n" c5 ]( Y7 b! X, i5 z9 |: ^2 }" V) S
setup.roomDim = [3;4;3];
3 |/ Y7 F, y( v$ q) K Z8 ]: S5 P9 M2 ?; V6 l/ J$ z' V3 U
srcHeight = 1;* z8 O# Y5 F, w
arrayHeight = 1;
* |% p; L Z' v+ Y1 f8 C8 G
4 z: e- E! m3 j, t, C# D$ barrayCenter = [setup.roomDim(1:2)/2;1];
- C1 M. U Y; s! F3 @- g
, A# Y+ J* k4 m2 i3 y8 @. NarrayToSrcDistInt = [1,1];
+ h3 |( D& o/ v: r' l
2 x7 S$ R8 K! B4 I) J7 u: ?& fsetup.srcPoint = [1.5;1;1];
8 c2 w5 U1 \( l
1 z- |, h3 I3 K+ c, ]$ Msetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);" \4 k9 m$ M- U8 @* v# z. R' f
+ ]; I# p& |( f
* f7 m5 x) f1 W0 D[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');! E& O, F$ i+ C9 S
: V" J- E' U. @/ j+ u) f) S%---------------------------------------------------initial end----------------------------------------
3 k: ]: v. d2 D& H# D
% }; k) C7 a; r9 l' i5 @; m3 c: M, g) e* b" ^5 t( m
/ m6 q" V, t! K* b
%-------------------------------algorithm processing--------------------------------------------------1 X- }7 P9 O7 d3 N3 [2 G( E, G. [
2 U3 t6 w L! Z) ^- z: ~/ E( Y) m, a9 m
if setup.reverbTime == 0,
6 M6 L( t9 V8 y4 g* p setup.reverbTime = 0.2;) Q; ~0 d6 r( O
reflectionOrder = 0;% V& U. N* i: s' M6 U- J
else5 i( U, i9 T2 |6 l1 K# u0 Y C8 _2 W
reflectionOrder = -1;
! f, ?: F9 \% z, ~+ }! bend5 |0 [" A, O+ S9 ~/ J) t/ l
6 X7 R) W- f W8 I: s' y0 YrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
j q9 E" x7 z- v0 l7 ?& ` setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);+ V0 B! z/ i* Z W
0 p7 ~. p! P4 U" U; G
for iSens = 1:setup.nSensors,' X. @. C ~6 }/ G3 r6 R) c+ A
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);4 d& x2 U5 M; t# |& X
end
- e; L8 L$ H q3 emcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;
7 A" B+ z' K s) {9 U4 k& s& B& t3 Asetup.nSamples = length(mcSignals.clean);; H) k3 B) x' b) f) v
/ S# X$ d! ?: A7 d/ k
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
7 @# c- s, Q q) [
. [) q( A) z) ? s. G) k: \%-------produce the microphone recieved clean signals---------------------------------------------
7 p0 l6 b1 b7 o& V% _2 j% \/ ?! [
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold. M; _0 g# T6 M6 q- A8 l K
mic_clean2=10*mcSignals.clean(:,2);" C9 _$ d! x ?$ h$ X9 Y( y3 U
mic_clean3=10*mcSignals.clean(:,3);# C4 I* H9 c: u, Y0 c) Q% k0 j
mic_clean4=10*mcSignals.clean(:,4);
6 L/ Z4 `6 m' }1 [audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
- j2 m% B* E$ }2 [: N- Maudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
" b$ f, ]4 z: v3 l& C; O ?; faudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
( A, z9 _7 f. D, ~3 Kaudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
2 V0 x; k, J) J( q% y4 W3 r" F
8 N7 @2 J6 w' }6 H# M; g%----------------------------------end--------------------------------------------------$ ~: K- D# P$ M3 v5 ?
4 i! n1 f. J" Jaddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
- \) t8 X7 ]8 @2 I0 }' U
: u! d1 Z" O1 V1 d9 I% t, _8 W" RcleanSignalPowerMeas = var(mcSignals.clean);
8 C o H# s3 W6 A; w i4 \, S& t) ], Z: ]/ E. s
, q2 _( V) U3 W0 Q6 }6 kmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...+ Z! z+ z3 m+ q7 L8 _
setup.speedOfSound,setup.noiseField);" M7 p/ {: j1 ^2 C
diffNoisePowerMeas = var(mcSignals.diffNoise);$ a% \; Y4 a% z9 f- @+ n- n7 J
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);& ^; P" |) \; R/ l7 s! ]
mcSignals.diffNoise = mcSignals.diffNoise*...
8 i) Y" b$ B. N" ^0 a' G diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));4 w" N! Y6 S. I- u* {( V# C7 A
7 o, \4 g) Y W
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
8 W) Q" C( L2 W3 c- H1 rsensNoisePowerMeas = var(mcSignals.sensNoise);& L) z( p! L Y
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);: v1 Y: y- E- T2 y
mcSignals.sensNoise = mcSignals.sensNoise*...$ H8 H. t: [- p! O% x; m2 |& D. A
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
9 s1 c. w1 @. K+ q
" l" y# T. t. ^7 d# UmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;2 _# r' n# u9 O" ~
mcSignals.observed = mcSignals.clean + mcSignals.noise;
+ A( J% l' ?5 E6 B& U, H4 w6 V1 Q! S; [- Z K; p4 x- g
%------------------------------processing end-----------------------------------------------------------
7 A. a, q8 W: `) M& M% @+ ?2 ?# A# N5 f; ]
8 N7 q6 V) z5 b( B2 h
. d0 C2 B$ F3 K1 z$ g
4 g+ J- O9 V+ s, S%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
! a0 U- C- M2 ]: I" Q( k: x
4 N3 ], t3 |9 I( }$ A& s* l3 L9 Dnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
3 B2 W4 P, V% c0 Lnoisy_mix2=10*mcSignals.observed(:,2);. a4 i- k1 D- _0 A, `
noisy_mix3=10*mcSignals.observed(:,3);
1 H: ] D: }& ^" l9 e( S! Z7 v4 b" Gnoisy_mix4=10*mcSignals.observed(:,4);7 f9 A1 N- `3 r- Q
l1=size(noisy_mix1);+ D; _) X& [6 P
l2=size(noisy_mix2);. G9 }7 A" g' B
l3=size(noisy_mix3);0 o3 G2 O$ \. N% C+ V/ F3 O
l4=size(noisy_mix4);& w, [# [6 d% G0 J( O- V+ ^1 N
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);+ i) Z5 k3 i% g
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);: e7 @ l* W4 G, i
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);3 U3 n* j2 @* \
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
* w9 ?. Y# X' U# E" R7 Q" ]- S- y; X8 D6 J- T% e
5 j+ T* l6 B& S4 K: Y4 y/ L
%-----------------------------end-------------------------------------------------------------------------
- ^' k% h4 i( w& p& {) D1 V这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
0 q' E) Q( i+ J4 d6 q! ~4 f( @直接把它们替换成你想要处理的音频文件即可。. [) A( t- K; Z3 T- s( T
5 n( K* z" c }4 x
除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
# z1 H1 G7 X8 m6 m
; y5 p: q7 u+ V9 H. U2 L0 O![]()
4 ] a( z7 t0 R2 P7 {, ?! [2 `7 M' Z) a9 T8 s! h9 Z
图1 麦克风类型图
7 Y* q% k6 ]$ s5 h , A! `9 B1 W! r r: P0 [. T
图二 房间的坐标系
2 t. f; l( C; M
, f; Y% q L) a2 | 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。6 Y1 q& W; I8 P& B8 z# b& T
————————————————
; e7 o. n$ w: X7 v% r版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。0 d' j: a) H5 X# P2 U9 y& z3 d
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749980 O8 t- N. d5 a6 z* z
8 ?6 s- z6 p" S& s% m
}8 @ _- X- K0 w3 t! c
|
zan
|