在线时间 791 小时 最后登录 2022-11-28 注册时间 2017-6-12 听众数 15 收听数 0 能力 120 分 体力 35386 点 威望 11 点 阅读权限 255 积分 13559 相册 0 日志 0 记录 1 帖子 621 主题 542 精华 10 分享 0 好友 225
TA的每日心情 开心 2020-11-14 17:15
签到天数: 74 天
[LV.6]常住居民II
群组 : 2019美赛冲刺课程
群组 : 站长地区赛培训
群组 : 2019考研数学 桃子老师
群组 : 2018教师培训(呼伦贝
群组 : 2019考研数学 站长系列
1. 引言 u+ w- u0 b+ |" c% U# T: [
之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
- t- T6 ^+ \ D + R, j2 |9 ] n3 B2 y
然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
o: u8 |' l8 X, q# ` ( ?! X4 j2 s. O6 ~
2. 代码介绍: H4 }( a+ @5 E* V( t! r |
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:8 K. X! p: j# M6 `/ l# u5 X
function [mcSignals,setup] = multichannelSignalGenerator(setup)
9 y- U4 u% g2 B5 x/ p$ T : Y9 N" h0 @( I3 U
B8 a4 w2 G3 `9 ^. r %-----------------------------------------------------------------------. t0 S5 V Q, t# P* o
% Producing the multi_noisy_signals for Mic array Beamforming.
* H* y9 W0 c+ L/ [# g % 3 s" Z5 H2 }* |$ Q$ Q, Y' k
% Usage: multichannelSignalGenerator(setup)
0 |; E" ?- {7 i! Q# y' r" l6 D% v" l. f %
' o" |5 r8 G1 {1 Q( R( H % setup.nRirLength : The length of Room Impulse Response Filter
. o. O% Q" K( i- E % setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
+ j, ]! ^# d9 D! M % setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.3 L) V; ]5 X0 s$ }& p, [
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
1 o/ l0 j: p. i' D % 1 h5 W Q; u. h# F) s! Q9 Q
% setup.nSensors : The numbers of the Mic
7 A; Z! W! [& k) N" P % setup.sensorDistance : The distance between the adjacent Mics (m)
2 Y* r; ]7 D+ J W; l % setup.reverbTime : The reverberation time of room
+ |3 r2 B1 e$ Z: p& x. J D. k1 Z1 T/ C % setup.speedOfSound : sound velocity (m/s)
/ {9 }' m" m: P %6 K- Q0 m1 X7 C2 |/ U$ {* Z
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
6 ~, m1 f: H; y3 l( |5 y % setup.sdnr : The target mixing snr for diffuse noise and clean siganl.4 x* [+ d& y% L. K( o# j
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
' \2 V) C# n% n; P& a8 | %/ k4 `" h% V$ f* ~4 u0 ^
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
; p8 m9 Y" Q6 b % setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). / ]" [! S. U6 s0 q* _3 [1 u
% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
. e2 Y7 K" R! C) @ %
/ w3 l$ ] X% T1 ] % srcHeight : The height of target audio source5 f. K# a8 h( M$ }
% arrayHeight : The height of mic array- o9 u7 c- U2 t9 W7 V
%
! L+ I* o, M( ]& T( L! ]* k3 s % arrayCenter : The Center Postion of mic array
0 g) e5 j+ F l$ t( J3 x* D %
! v; x7 u7 r4 V' N, W % arrayToSrcDistInt :The distance between the array and audio source on the xy axis9 L) w7 v" E0 S7 I1 Q. e: e" {# ^
%& d7 ]6 P4 ~4 U+ [- k$ J; }2 f m3 Z
% ) U2 i" h3 e7 z( \* o% m4 h
%
! p# i0 z0 X1 ^0 x; s) [ %# `' o* ^2 O3 {0 Z) S- E8 \
%
. C& f o+ D' i4 Q5 t: ^# | %8 v3 y2 Z/ ^+ e$ c6 ?: \
% How To Use : JUST RUN
5 y8 R; y8 V* s: e2 S8 M4 [ %
8 C7 _- X0 E L7 ^" ~$ ^- F %
5 x" [& p: L. U$ O; a* d4 E* Y % ( C& K* J8 ^$ L h
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),7 r. E' j9 v s+ `6 O7 C9 H
% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
3 n$ a/ ^, ?0 u; y; `1 m %+ `' ]7 `$ B) u+ b& V9 }+ G) W9 Z
% Copyright (C) 1989, 1991 Free Software Foundation, Inc.$ d; b. o; B2 G' ], x
%-------------------------------------------------------------------------; m \ B: s: H" q2 i
+ _* t- P$ h8 ^6 _; c4 p* O* u
# o5 Y1 T7 l! y7 Z4 R& n
$ q6 @3 t* _8 \7 ` addpath([cd,'\..\rirGen\']);, k, G- b& V/ l, D
* T$ S2 _" \/ d" p: H %-----------------------------------------------initial parameters-----------------------------------% w, P( V- W. u4 u/ {% j6 P
: ?6 _* U0 O2 L setup.nRirLength = 2048;
/ X+ I5 ^3 U3 N$ r4 x9 j; T- ? setup.hpFilterFlag = 1;0 u* `) g; l) O2 W4 w t7 a
setup.reflectionOrder = -1; F- k" N; w# H1 v' x: |
setup.micType = 'omnidirectional';
% ^6 o! f% X% H2 U setup.nSensors = 4;6 a& M4 t( @& m3 c' Q
setup.sensorDistance = 0.05;0 L( @ a! u( s. ^$ A
setup.reverbTime = 0.1;
7 }; o% V3 G3 i8 K( T setup.speedOfSound = 340;
' B0 `/ J% Q1 v2 G5 b% i
/ D1 S d' R" L+ L setup.noiseField = 'spherical';
+ _8 r& y& e* N! l8 ~& ? setup.sdnr = 20;
% e% R: K1 w) G$ p, W4 I setup.ssnr = 25;: m; Z' r& ]+ @1 W+ q
$ b/ |/ l- b7 p0 a0 [8 {5 j3 x setup.roomDim = [3;4;3];) C* j0 R0 P: T
$ T; Z, U5 [( N, Q* ` srcHeight = 1;4 O8 P) h) y4 D! d1 H/ p- y
arrayHeight = 1;) N9 Z" p* i* e
4 d- S! a$ w$ k% B1 U8 Y- ] arrayCenter = [setup.roomDim(1:2)/2;1]; o8 i) g/ l2 N9 u
' o% d; j |- o arrayToSrcDistInt = [1,1];
; V) Z7 n! U: N+ v0 Q3 V
! V; E+ w7 n/ R/ p& Y8 H setup.srcPoint = [1.5;1;1];" X: `' Z0 `' d0 G; s3 {) C4 C* l
Y4 }$ U7 \, C) J( K0 I1 ~! h8 j
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);; `; ?7 @3 h& r/ l s, U! k% g
! O9 J z3 F; l; r& ]% [5 v ! ^! d2 X( i& h% S7 w4 B# [
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
0 w+ G& q: a4 Q" R) Z
- s( `5 S$ Z- j, C) |' W( z %---------------------------------------------------initial end---------------------------------------- O7 z6 l& ]) N8 ~
+ h; V1 A) }" Y9 q W% O( r) O
# @7 d. U& Q% c- Q C. }
: e0 _5 M) A, `8 W& S+ Y" \ %-------------------------------algorithm processing--------------------------------------------------) u: j' b- P- x$ T f' b. B) S
7 z% q& R9 c- ]8 ^. Z# B+ P5 X, t if setup.reverbTime == 0,; X7 E0 i2 Q( S5 }! T
setup.reverbTime = 0.2;
! D* w3 w' k6 r c- A! a reflectionOrder = 0;
+ E1 Z% J6 K% {2 {* B0 } b! \ else
* l. w, g3 \- c6 e+ J, \' Z+ i$ _ reflectionOrder = -1;
5 r- v" G, ]1 @8 C4 D/ a- b$ R end
# C7 [- G! j0 j/ |7 j3 r, _6 k) @
8 \& S" q$ Y4 i" u* M8 K8 H rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
2 c; B2 L2 v$ p0 W' y) ?. i& D setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
% o j( I; u4 ^, x% O$ A9 ? ) z/ m* q7 Z9 v+ ?
for iSens = 1:setup.nSensors,
8 j' @, Q7 K6 M7 M6 [' ~ tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);
% U' d. D" V) @0 U! ^. x end
2 O: U1 F( Q. c' D4 n mcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;
0 r" t# _" o Y" f/ R1 s0 q# c setup.nSamples = length(mcSignals.clean);
% j: j2 g* h. _) v , d3 h4 q: w% R2 U/ M
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);0 B2 a, X* m. A
u$ A. U# Y, F8 j9 K %-------produce the microphone recieved clean signals---------------------------------------------
+ D" l* |9 _% N6 ]) g, W9 u! G 5 @# X7 o8 t% Q# A8 `! a5 K* }2 u
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
0 y C+ K$ o2 D( D mic_clean2=10*mcSignals.clean(:,2);
; I2 i l% r0 R$ Q& Q' v1 i mic_clean3=10*mcSignals.clean(:,3);! ?3 t; {: M9 p
mic_clean4=10*mcSignals.clean(:,4);: K5 }! o9 M9 [7 i' w
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
; Y6 C" y: _, i audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);! @2 O/ X6 s; ` R! w N
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
0 ^# ^8 O' J0 Z+ ?7 s9 E. a audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);$ U8 j, h7 W. Z% S* w, x5 @9 `
9 W: P3 ]& B/ d/ P %----------------------------------end--------------------------------------------------
* x, U% [! J( Q " q4 \% n1 ]2 v* N- C/ _5 w/ H
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);2 s! T% L; r& E+ r
7 ?: ^5 s3 x% \; N$ Y! G
cleanSignalPowerMeas = var(mcSignals.clean);
, N8 U6 E& V' A) d) r. x p5 H7 z& Y
+ x( t K. W( r' P7 [
$ Q' e7 v, m2 o: ?5 H mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
# ^: v6 O; E% ~8 |$ v- u. \ setup.speedOfSound,setup.noiseField);
- m, b7 ?$ c5 n; g" C7 i5 t diffNoisePowerMeas = var(mcSignals.diffNoise);& H3 n1 [# F4 ?( C" U8 h( B
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);& k, e! O8 P! c; M) T; U% X% d
mcSignals.diffNoise = mcSignals.diffNoise*..." ~9 K7 [ R5 B
diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
" v& w- N2 @% b) U # m# g, A& J! q7 g$ K+ j p# c
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors); G n( r2 {. `; Z, G
sensNoisePowerMeas = var(mcSignals.sensNoise);9 q" N% Y( ?3 {+ [
sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
. Y5 y( I$ J# \! B9 `5 ~ mcSignals.sensNoise = mcSignals.sensNoise*...3 D! @9 X4 d9 D& B
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
8 }8 i" |, D/ [( g2 g1 J" c. Y 8 H& Y g/ Q& h: h, l
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
* D/ i; r/ H$ z) l: G; U @ mcSignals.observed = mcSignals.clean + mcSignals.noise;: ^, K# D2 {# S# |# B+ \
2 S! v+ _) Y- Q8 M0 Z1 s %------------------------------processing end-----------------------------------------------------------" ^& l/ P5 |6 l) |* o" {
0 W/ L5 p2 F) A 3 E4 [& l1 y) R) T& \' ~7 d
0 ^7 }! C) i' [
; O# I& w! ]$ D( C) a( u, P0 T, u %----------------produce the noisy speech of MIc in the specific ervironment sets------------------------( X7 L+ c; x1 S0 i7 `' T
4 Z( ]) o1 R0 J6 j
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
5 J' ~! R. m0 r# M3 K% H' r" V% T- T noisy_mix2=10*mcSignals.observed(:,2);
# K0 I8 j9 h' H+ M0 A noisy_mix3=10*mcSignals.observed(:,3);
5 p+ [5 e e: t3 l! ?- I noisy_mix4=10*mcSignals.observed(:,4);: A) Z9 R7 M9 P5 s/ N
l1=size(noisy_mix1);
' J/ h$ r/ T9 M2 z7 `8 Q l2=size(noisy_mix2);
% N: S* G, m7 {( O0 u5 w l3=size(noisy_mix3);
; G* C: A: ?: @) m l4=size(noisy_mix4);$ v* b* D5 A* R5 V8 c9 v% L1 z) g7 T
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
1 n. m! ?9 i4 P; v6 c! k" N audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
+ k; y0 J0 d, ` audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);0 A6 {9 p$ p* \% c. M3 O" S4 d
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
. ~( J# o/ t: d
1 N H( w& G3 q) c& L ( k$ h) L; u; r7 N2 r
%-----------------------------end-------------------------------------------------------------------------
G# u2 k2 B) x) } 这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
$ v4 ~5 o# L7 O Q( g! N, A 直接把它们替换成你想要处理的音频文件即可。
$ n, E7 N5 H% X ) c: \ x. o l2 s% 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)。0 k* m+ j V* `; S
r' X7 j: X; m 5 v; Q- v; ^ G5 D3 [/ U+ F( L8 @
8 ]- S$ w( U/ N, D 图1 麦克风类型图 - q6 i; b* m3 b+ S1 S7 I3 ?
$ `/ h& V5 X+ Q7 O$ b" q$ y& f
图二 房间的坐标系' E; J. P+ @& K: R+ Q
( U* ]7 }+ b$ ]$ @& L6 w) z
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
@! X5 Y$ B0 U+ j" }& u: h ————————————————( l, W) W. o2 a; u+ M8 ] j% U6 @
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。4 q6 P# m/ `& D3 U& |8 b
原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
1 V) {/ q# d9 U* B# w- ?7 q2 ]* S. H
: G9 X8 k4 Z O- \# s
; |) X- r: s0 W1 P6 T4 q& R. G
zan