- 在线时间
- 791 小时
- 最后登录
- 2022-11-28
- 注册时间
- 2017-6-12
- 听众数
- 15
- 收听数
- 0
- 能力
- 120 分
- 体力
- 36311 点
- 威望
- 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. 引言
1 P7 h( S1 G& Z- B) F: o$ ~, x& K 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。1 |- L1 _# V m0 C# ^6 P
9 R2 j$ @* P$ T" t$ ^5 Q/ k 然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
5 }1 w: W( P; _3 h
( B$ h% H J$ u2. 代码介绍$ t' v% ]3 A$ v+ b7 l
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:0 Y0 m- ^, W( u' j
function [mcSignals,setup] = multichannelSignalGenerator(setup)7 O9 G y) J+ C8 x0 K, r P$ H& Q8 P9 W
* V5 U" {, @" Z T+ U
% E+ n7 S3 U* a; a8 f
%-----------------------------------------------------------------------
0 n: J+ l2 M- P) @2 ?1 G% Producing the multi_noisy_signals for Mic array Beamforming.# G- b) _" B {7 p* W: g2 C3 ~( h3 B
% + i- m/ m% B7 R3 ~' b4 J' U. G6 G0 w
% Usage: multichannelSignalGenerator(setup)
/ H# G; X2 n. x8 m+ S& y! e% 4 j1 x* q, X3 A v H
% setup.nRirLength : The length of Room Impulse Response Filter
- T* \* q8 Y* v$ u9 |- E% setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default1 M7 U' H- J) n& p9 s1 q1 a! V
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
r6 p( D* C. r& F% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
" ^" B9 }7 L/ H; t5 ~( j) y% $ R" F* M5 Q, ]" ~
% setup.nSensors : The numbers of the Mic
( G- N0 @( A( n8 I% setup.sensorDistance : The distance between the adjacent Mics (m) z+ _& x W* p- s
% setup.reverbTime : The reverberation time of room: t4 l8 l/ b4 c7 _: A8 U' @
% setup.speedOfSound : sound velocity (m/s)
2 S' h" ~+ W" y8 \$ G# R: @%1 H9 d8 b' `3 P! @- U# s" |& N
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
- c* j! H) m. s W# r+ Q5 L% setup.sdnr : The target mixing snr for diffuse noise and clean siganl.9 C8 X- a8 p. r
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
8 h+ w T' e0 u, _%; c: m% b9 L9 H+ p; h
% setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m). a5 z l4 `& |0 ^2 G
% setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
8 O# `; d8 v' T6 K" P) t: Y8 e% setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
8 o& |6 Y' }1 t% P%
, X* f* G4 O4 M) `& e* k( b+ Y% srcHeight : The height of target audio source
" D( k% p' |* }! Z% arrayHeight : The height of mic array
9 `& B- k" ^( ?5 r K%
! s$ A3 @ m! L' R4 I* W$ M% o5 R% arrayCenter : The Center Postion of mic array 2 _) B2 ?, T Z& C4 V
%
' v9 z! W& m) L( |% arrayToSrcDistInt :The distance between the array and audio source on the xy axis2 a T5 ?) ?& W+ e0 U: B
%
9 V5 g; b& @: z+ c! \- M% ) [/ b3 Z- q% x# r: Z4 k
%
7 m% j: g2 L+ V% a. W%8 C& P3 C/ V4 }4 j' m
% ( C$ R& S: L1 x; |. H
%
/ B3 T2 m0 M j- K- g8 _, h& e1 {% How To Use : JUST RUN& i& |8 j3 P ?6 B: k6 N- N) ?" w
%
# J+ e' q9 `8 C! j- E; a8 W! i%
6 ?0 c1 W6 k- R0 h5 t6 X%
; j4 P. v. @7 k% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
/ B0 S9 K2 P" N% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24. F: }1 ~1 R0 |# `
%
& Q" ~8 g1 }# Q" ?2 a: Z4 u% Copyright (C) 1989, 1991 Free Software Foundation, Inc. i6 P& j) k3 R" G; ^
%-------------------------------------------------------------------------' t: Z0 g4 F J1 m
& C+ N4 k; z) F* `# \
/ |6 B( M+ G4 i
; v4 z* C0 i" t' O* J: ?addpath([cd,'\..\rirGen\']);) k) f% Q8 g4 z
% D. i) E: u' K% v( o# |
%-----------------------------------------------initial parameters-----------------------------------
/ }! r5 t5 ]# ^) f) l- ^
8 s; a6 i# r5 K& Vsetup.nRirLength = 2048;' b$ |7 P5 u. U2 F! W/ H2 _! `
setup.hpFilterFlag = 1;
3 M+ T; E9 e; Z. K( Y4 Z3 n/ hsetup.reflectionOrder = -1;+ `# o8 C0 `! T2 _9 x& T4 O" C" e; s
setup.micType = 'omnidirectional';
& i. [# h+ ^, D4 R: s% x6 Qsetup.nSensors = 4;) w5 l$ ^) }& B. [
setup.sensorDistance = 0.05;2 a: M, H" A6 v$ Z
setup.reverbTime = 0.1;
0 |, I" }0 m9 f2 d. qsetup.speedOfSound = 340;$ i M1 N: F& ^0 A
" B7 y6 T$ b' Z$ F! |* Asetup.noiseField = 'spherical';
2 k7 i4 g4 ^, e a# rsetup.sdnr = 20;9 ]7 @$ g# A9 J6 B
setup.ssnr = 25;
0 o! \ q! Z; h& _& m+ J4 h
$ p4 t# S9 Q1 V: M) B# O+ Bsetup.roomDim = [3;4;3];% b. \% u9 a" N/ N# r9 Y
7 p2 g% c5 m1 E+ o: n
srcHeight = 1;# H* K. L4 _1 R
arrayHeight = 1;3 c- r/ F$ H% H8 Z3 K/ Z7 [
9 ^7 p* j6 y X8 Y: E
arrayCenter = [setup.roomDim(1:2)/2;1];
' Y7 S0 H3 @- t9 D3 U1 P: P5 B/ O
$ ~( U! z3 c+ ] Q6 c& XarrayToSrcDistInt = [1,1];
( z8 q4 `: y# Y# V; A6 R. M+ ~& ?' J5 K; e3 d& e
setup.srcPoint = [1.5;1;1];
& P- O3 A0 Q6 { `1 @
* W: Z6 k' [. }% I) _setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
( i# }# r" L/ y$ m
3 w' O, L4 ]0 s9 N8 W0 l- e. B8 Y
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
9 D6 l* N `+ C9 m" C6 ~ ~4 g: d' ?& @$ C4 R# c
%---------------------------------------------------initial end----------------------------------------3 V& w/ g* R) }. W
: Q6 w5 l) Q, C$ i
1 _2 ~7 y' b4 L1 T5 z- D$ n
, k. W/ L* H5 X* l2 s%-------------------------------algorithm processing--------------------------------------------------& l, d+ {5 ^- L b; J2 G# ?
* a1 ~/ ^4 [4 o2 K/ w9 D# x( P; Uif setup.reverbTime == 0,0 x" Z" O/ y5 Y* u0 S e
setup.reverbTime = 0.2;
1 }; Z* M# m" h) c reflectionOrder = 0;
9 m/ d! V2 `. Zelse
# }& Q, z9 g5 B+ e' l! u5 Q reflectionOrder = -1;
7 g4 s* b" _6 P5 _% i, v1 `end8 W. D9 F8 h# Z3 k ^2 l4 b+ f
3 T7 ~0 V% H3 WrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
) p% F; J+ C$ E2 @. X0 o setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);- k9 r% i* P* G# J# R9 E
& a$ [6 \. \$ u$ {for iSens = 1:setup.nSensors,! ^. c4 C$ Y# |( s3 f9 |. R1 H
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);% |: J' J7 D2 K/ R0 D5 i5 w
end
+ d0 ]" W/ s8 {mcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;; @1 H; L! ?5 p2 O# U# q9 X
setup.nSamples = length(mcSignals.clean);
6 P9 t }- ~ |" O3 g7 f& l/ ^
9 D/ S& s# o* K6 QmcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
' _5 ^; C" h+ p) D5 T; {2 S7 i) E9 V) c; X
%-------produce the microphone recieved clean signals---------------------------------------------
. M. D; }' C5 ^6 |1 M5 R' B9 k F% ^) H/ }( t B
mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
9 ?- D0 v9 A; K# z! D6 Jmic_clean2=10*mcSignals.clean(:,2);
5 M$ Q$ I5 h8 x+ W! q0 \; [" cmic_clean3=10*mcSignals.clean(:,3);9 |1 ^: A* {5 t" E# u/ d
mic_clean4=10*mcSignals.clean(:,4);7 q7 z' a+ h$ {5 b7 e. }
audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
" Z9 m u. s& j% |( D* N$ paudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);/ f$ X" x) m4 H1 ^( e( G
audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);/ H8 U5 m, q' u- F0 v
audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);& ~! C q! p6 A) ]+ ^
6 f: p8 _- D% h
%----------------------------------end--------------------------------------------------
4 ]. U% M' b+ U9 u
1 m9 `5 E& v9 U# ^+ haddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
$ x" a" Q, ~. c! b% O+ N, y; Y6 N" w$ R I
cleanSignalPowerMeas = var(mcSignals.clean);
* I" ~2 S# ]9 Z+ \4 i O5 B: \- [0 a; ]( f
3 n, o% W& [ HmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...# D* g& n3 ^ \) y4 n
setup.speedOfSound,setup.noiseField);' G0 O. L/ h" d8 M8 k
diffNoisePowerMeas = var(mcSignals.diffNoise);$ U" v: B, j4 ]) r8 R
diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
5 x# F! T3 W/ OmcSignals.diffNoise = mcSignals.diffNoise*...
$ Y8 ]. k# k9 T$ ~2 T! b/ X diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
% f5 s9 A5 E& n# x4 c4 [2 i/ E2 i9 q+ c
mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
, l0 `3 F% ?% m. ?. N' T9 PsensNoisePowerMeas = var(mcSignals.sensNoise);
! ~8 S% O1 u: A: P# q+ ~! i$ ^sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);3 i5 e! B2 `/ i
mcSignals.sensNoise = mcSignals.sensNoise*... R3 a/ J% v! J1 ~
diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));- p7 s: }' b4 v g0 \. J
) x8 ^: d6 o0 E2 [$ hmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
+ ?- ?4 m" X) }3 X) _# J. N( l3 PmcSignals.observed = mcSignals.clean + mcSignals.noise;
% O. r, f4 X9 _$ K3 O/ l' s2 X T; c, }( U1 A( a: ^
%------------------------------processing end-----------------------------------------------------------+ F+ U% m" @( e* G
3 S# l1 B3 J1 r4 j" z' @' g/ Z
' g8 J3 x6 W; P" e/ F7 o( j1 C% J3 m ?
4 {0 S T4 r$ {; Q4 Q c%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
, U0 ` `/ l/ V& ^7 T/ ~( O! X* `: |# V* w9 W6 ?! x
noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
$ P% d* Q% h5 |% K5 Qnoisy_mix2=10*mcSignals.observed(:,2);% d# T7 g0 C. [; a+ j, v
noisy_mix3=10*mcSignals.observed(:,3);
1 g# a" A( G5 Y2 Y3 v V. o4 V% \noisy_mix4=10*mcSignals.observed(:,4);
0 X4 b; w$ q; P2 Tl1=size(noisy_mix1);
0 Y' {1 B4 L4 V9 j% L+ jl2=size(noisy_mix2);; J0 ~ N5 E5 W. }- z* D
l3=size(noisy_mix3);/ k: F' k) ^$ T1 l( ^% T2 y
l4=size(noisy_mix4);# A6 K8 t! z- D; K! J
audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
8 G0 R$ K$ J- u6 Z& Q$ p+ A: L) ~$ V$ waudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);$ K7 b9 O, ]: c# v7 F- B
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
7 o) @- T% s$ ~1 e& xaudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
- M( g' p3 _0 d- x, u8 v2 [' J( G. r# _2 A8 i r. z
% n. F i3 {* W5 L( ]% W
%-----------------------------end-------------------------------------------------------------------------$ U: b$ A- X7 g& L- x
这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。0 R9 N [9 j1 b6 I2 T' b& t
直接把它们替换成你想要处理的音频文件即可。& L1 z" d; P6 M2 F4 w. B
+ M& a8 A$ l3 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)。
$ O, f' S2 D+ y, `% b% N
2 t3 b/ c( j1 K9 Q/ @+ w7 I% b* s ( ]8 Y' F% @/ _$ h1 x4 C: H L7 O6 t
+ J) C$ Q; i+ \9 S6 k6 E图1 麦克风类型图
$ ]( t7 d( m9 i![]()
- x& m0 {) h' F( Q7 M, T$ u图二 房间的坐标系8 ]% d1 p; _* k/ ?
3 q. q9 N7 E, ^2 r. B/ @! h) I
以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
3 V, O! Q" c$ R1 s4 `————————————————
0 b( ? d% O0 z4 S, f版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# o3 D8 d& S5 D6 x0 m原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
! @1 U$ s" d4 g2 E
5 U7 @3 R6 a6 J# V3 T H, o9 y* \9 ?0 d8 K& ^- \! z; C* @0 e4 L6 g
|
zan
|