在线时间 791 小时 最后登录 2022-11-28 注册时间 2017-6-12 听众数 15 收听数 0 能力 120 分 体力 36446 点 威望 11 点 阅读权限 255 积分 13894 相册 0 日志 0 记录 1 帖子 616 主题 542 精华 12 分享 0 好友 225
TA的每日心情 开心 2020-11-14 17:15
签到天数: 74 天
[LV.6]常住居民II
群组 : 2019美赛冲刺课程
群组 : 站长地区赛培训
群组 : 2019考研数学 桃子老师
群组 : 2018教师培训(呼伦贝
群组 : 2019考研数学 站长系列
1. 引言
% C1 T6 X/ j6 D) W: J 之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
- J8 v2 X( J. n; h9 r
8 O' ]7 P$ m) P9 I. b 然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。 u8 h# a+ G9 I0 j9 r: y2 v% V
! [' w1 b |6 J# N* O! p! n 2. 代码介绍) Z( [0 w, Y* |7 X
原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:* P; F' U% _2 v6 [3 Y* U
function [mcSignals,setup] = multichannelSignalGenerator(setup)* B( C" j. S* X# W; X
. |) c; h8 w2 g) c* `* G 7 z# O: F( D, W
%-----------------------------------------------------------------------
' ~% g1 g, |6 s2 J# w8 K % Producing the multi_noisy_signals for Mic array Beamforming.
8 W9 S8 Y3 N' E$ K %
`0 e. U/ m5 @* n- Y# }( z % Usage: multichannelSignalGenerator(setup); J% {' w3 [3 o$ X4 i+ }' \
% . m" d/ W% C0 M Q. `- U
% setup.nRirLength : The length of Room Impulse Response Filter
5 K) m2 c6 x; q* s % setup.hpFilterFlag : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default+ H: a! x, o' ?. ^
% setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.8 L: M8 I. C4 n% X& p$ z
% setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.5 Y) I9 h/ C+ V+ J% j% U
% 2 c8 O( d% s( M7 f( q/ [
% setup.nSensors : The numbers of the Mic
; Y+ N0 y0 Q' S* e$ x& W# |; X: t % setup.sensorDistance : The distance between the adjacent Mics (m)" K M; k2 N0 V1 D( L7 M: b7 r
% setup.reverbTime : The reverberation time of room& w1 E0 N& _- l9 W, a F1 m
% setup.speedOfSound : sound velocity (m/s)* I/ h0 k3 V! X( `0 a o3 i5 }
%1 N1 i7 q- t0 \3 z+ U9 H; s5 g
% setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
) f6 x+ F1 v/ e. d5 p& Q % setup.sdnr : The target mixing snr for diffuse noise and clean siganl.( Q# U3 U# e: J; P6 I6 v
% setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.9 P% M/ ]/ H9 w* C7 u7 J
%
( e7 l' F( a/ c9 q B7 k % setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).
1 G6 I6 |. o, W# ]( Y0 | % setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
# N- U, D/ d: O- q$ m % setup.srcPoint : 3 x M array, the rows specifying the (x,y,z) coordinates of the audio source postion (m).
' H/ V+ r% g9 j- _3 W %
5 i0 `% K' m4 g2 P" c % srcHeight : The height of target audio source. Z" I2 C7 O/ u+ p
% arrayHeight : The height of mic array
0 A1 Z, V2 u1 a7 E %' Z# e% V8 f( F `6 D
% arrayCenter : The Center Postion of mic array
* k) D0 ~% b( p3 E. [& @ e %
. h2 i, I- @7 N b! g % arrayToSrcDistInt :The distance between the array and audio source on the xy axis
' x( ?: c+ t& f+ F- ~ %/ G; l+ d- o* J. U2 t
% , Z% w" X0 |9 F9 d
%' Q7 w1 I1 I: F0 k3 F
%
$ k; [9 L+ L6 h' j6 p* M% C %
n# _- o1 J/ U: K5 e5 T %0 u* t) u% Z! v) `5 V$ P' `
% How To Use : JUST RUN
M( M5 H. p, c4 f0 E %# d3 F+ |0 k. @# f
% - c) R* {4 y0 ?: v, m/ g0 A& w8 T" n
% 6 E. u' b" S, }! ?( t% k' x4 `2 G, g
% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),' @) V9 z D" B6 x
% slightly modified by Wind at Harbin Institute of Technology, Shenzhen, in 2018.3.24
) C) c; A! L2 t/ w {1 S( L% F* ~ %
3 W. v+ m, z T % Copyright (C) 1989, 1991 Free Software Foundation, Inc.
& v* o3 U" l# h0 l: @) e %-------------------------------------------------------------------------
2 g6 i- N }5 d1 p
6 |3 z3 S) z! m' @' n
`' O0 n/ @. ?% h$ p ) p. J" o( ] `/ i
addpath([cd,'\..\rirGen\']);9 h' y4 [0 A4 G" e! u) |
& u2 q( V6 E: h# k6 N& p
%-----------------------------------------------initial parameters-----------------------------------
8 K( F8 C$ B7 F3 _' Q; D! i 7 W" n3 ?. Y$ o3 E* Y2 J W
setup.nRirLength = 2048;+ g9 Y. y( }% S% |
setup.hpFilterFlag = 1;6 x3 m- @! @ O9 d, s q( f' O% X
setup.reflectionOrder = -1;
' _4 |; d5 P4 t9 d) a6 Q setup.micType = 'omnidirectional';; N- Y2 ~' e5 Q& U( M
setup.nSensors = 4;
* ^& y6 Y" s+ T1 |* S" i: ? setup.sensorDistance = 0.05;7 E% v6 S9 n8 H+ J' B* H
setup.reverbTime = 0.1;7 U, K# z z* w s/ m5 B& Y
setup.speedOfSound = 340;, h& p F9 x( f8 u2 r
2 z- ]' @2 W4 ^# b& g, y setup.noiseField = 'spherical';) w4 v' ^2 D+ X8 M
setup.sdnr = 20;8 Q+ m- I1 Z# v/ M/ @
setup.ssnr = 25;( u9 a) w7 I+ r7 H
9 j/ Q- \" o) M) a
setup.roomDim = [3;4;3];4 B" r0 p( F) ^8 J8 D8 N
: b0 o" N! U7 ~4 e1 @# o1 @5 z srcHeight = 1;
* o$ U3 B- h y3 v arrayHeight = 1;, a0 ~6 U _( ?0 R, J7 a
3 u% _& R8 V) g" h, [2 t arrayCenter = [setup.roomDim(1:2)/2;1];7 W2 u; i# t" Y. S
& Z! p# l3 ? ]; R arrayToSrcDistInt = [1,1];
- V; i( m' {0 P4 @- z
# X6 V1 c0 u1 d- G setup.srcPoint = [1.5;1;1];4 h. N3 [5 I* w7 q' l) Z! `
! g" u) K9 V' D- w3 X
setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
0 F# R+ w2 \7 |! P3 z 1 ]2 A, ^& Z. x
- ]8 F3 N& ]- V
[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');3 S. ^3 i* A* \7 {0 Q; L
+ j: y. a: q4 Z %---------------------------------------------------initial end----------------------------------------/ [, Q3 P* t' S7 R: m, Z
9 r( ~4 z2 r% b0 |1 }: E
9 L* U# P' D: i4 {1 ^ r4 x1 N8 i( W
%-------------------------------algorithm processing--------------------------------------------------
6 q! I3 L5 X: e7 q% W+ Q
$ ^' y0 ~ M! G" y( B if setup.reverbTime == 0,
% X0 L" N& U0 p" A setup.reverbTime = 0.2;! Q8 R* W' d9 z4 x8 Y2 }4 ]$ R+ d' t
reflectionOrder = 0;
' N5 r9 M! w3 |, I else
# Q5 J1 ^, ?; a6 p. }6 q* ? reflectionOrder = -1;
& Y8 ]6 |6 T- E0 n7 J0 O end
5 l/ ], B/ ?! w4 |
) J" k8 h! P2 L0 e- l rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
% Q: h' h/ n1 `) n( }4 L setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);( `, W# F a, W, c# k' _2 R
, S" _5 x, Y1 Z, m9 y6 i for iSens = 1:setup.nSensors,2 P, X |/ ?' p& Z: |7 s5 D
tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens, ',cleanSignal);1 X' f5 j; F7 r5 a! ]. e: w& L
end
+ z' C: R( |: t f: e, n# E mcSignals.clean = tmpCleanSignal(setup.nRirLength:end, ;! r. V o- d1 l2 V
setup.nSamples = length(mcSignals.clean);- X/ E, J! ^% U( G9 N3 ^
P) S! K& |; u- L/ u
mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);4 d N2 L! E. n7 r) S2 B
( w5 }2 p& C+ ?3 U( C %-------produce the microphone recieved clean signals---------------------------------------------1 P$ w7 ]- _+ R( N, i/ x3 O
4 @1 i% }8 u' U- | mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
! `- B2 W6 T5 \* {$ k( u( U6 g mic_clean2=10*mcSignals.clean(:,2);
; y" H5 i' y; y% E1 A. }, f mic_clean3=10*mcSignals.clean(:,3);
4 k2 y! h4 h& E& X8 x mic_clean4=10*mcSignals.clean(:,4);
C4 k8 U* j. c; i( ? audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
0 S7 ] l4 S$ Q/ {9 c audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
6 n4 G* \; T# ^# @7 X audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
9 p' H, g. B$ r' P# G3 ]* z. \) h audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
: D/ q- f. ?/ L; w . g5 ?2 G Z! o7 k6 U2 J; w
%----------------------------------end--------------------------------------------------) @) S- X% G! ?1 A# s" W1 e) n8 U
( T% P" @8 J* A/ m0 a" Y
addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
9 g* i2 m; c: S" I/ \8 X
! e9 X; a' Y1 S5 C cleanSignalPowerMeas = var(mcSignals.clean);
1 t( c0 y! C5 y6 c8 c5 l' H
3 V: a8 X( G- }( U* B( s% t* v 1 V* H' H1 n. @5 e1 _
mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...+ f0 d. V- h& [- P5 H2 a! O
setup.speedOfSound,setup.noiseField);
! X5 B; R* O% Z diffNoisePowerMeas = var(mcSignals.diffNoise);
* U# ?8 R- s0 R \' f6 m3 x+ i diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
2 ~5 H7 w+ d5 U" L' n8 l; X mcSignals.diffNoise = mcSignals.diffNoise*...
. v" l4 q/ W3 P diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));# P' V/ L5 W( F4 ~4 N, c. y
4 r1 {0 h6 v& |# t# P mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);1 D4 R. W9 R& E- a, |
sensNoisePowerMeas = var(mcSignals.sensNoise);
8 f- h+ f6 z2 Q/ w* B sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);7 v$ W3 L k: a% p% M Y5 H
mcSignals.sensNoise = mcSignals.sensNoise*...
0 t A( S; o, k; }8 F& h diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
/ |0 l" Z; p1 R+ V7 |& d 5 p1 k! H0 p. q @% o2 Q/ g' {
mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;* R$ R( A: `& i0 c; u" |" I2 b
mcSignals.observed = mcSignals.clean + mcSignals.noise;* M/ D4 v/ g7 r( j, c# Y
, q( t& K/ a4 S2 o5 {5 s0 q( \$ {& \) J %------------------------------processing end-----------------------------------------------------------$ R5 P* t- K8 W
7 O/ L6 S# |. l
: s5 g* _. s! s; J' K# l% P , r- e9 g6 i' L2 P
" u) A4 I" {# n9 \6 ]4 ?
%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------0 u. `. C5 |" X" c/ u# J& p
- Q6 Y/ t1 [8 r; T4 B1 w6 b noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold! X- _! e6 q; i& \) L: F, P& M
noisy_mix2=10*mcSignals.observed(:,2);
$ J4 A0 b7 |/ ?2 E5 O noisy_mix3=10*mcSignals.observed(:,3);
) S5 J2 O! ~, C% I noisy_mix4=10*mcSignals.observed(:,4);( U8 Z' K% L& `6 Z4 r
l1=size(noisy_mix1);9 F/ n+ \& |! m
l2=size(noisy_mix2);+ v! ?8 n* W& P; X7 ^3 W
l3=size(noisy_mix3);! R6 p7 Y% n8 i( x. Q
l4=size(noisy_mix4);
8 B9 j3 A8 V6 A" \ audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);% Z3 P( {2 p4 ?. c* C# u3 G
audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);" ]7 F F; M5 d4 n$ q
audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);! X$ h! T+ }1 _5 Q: ~0 M+ V K* g
audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq); M" T) y/ v& A) A) V
* K2 i/ C, \2 n$ c2 W9 x1 o% T$ p
4 `/ o3 E9 l# g0 b) t
%-----------------------------end-------------------------------------------------------------------------
9 x m' b$ x2 O# B, Z! o! C 这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
3 G$ s% G9 b2 v+ E 直接把它们替换成你想要处理的音频文件即可。
8 Y. A) m5 K2 |1 j* |6 T5 w " e W) _" |) E
除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。" V9 M9 [, E# | }1 N) O
5 M- ?3 r. C+ ~/ V/ d
. Q% }- H- o; T7 x3 g9 ^ , p2 O r% j. ~: {! _/ w6 {1 d
图1 麦克风类型图
" n& J/ n: Q( N l( ?0 L3 x
- g+ `( ?" z8 m" O* s7 @ 图二 房间的坐标系
, E5 P' ~: R2 E/ ~, ~$ h& k- b
& Z. ^# S+ C/ T/ ~+ {) w 以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。8 F/ S, y8 O# f5 y+ M1 Z* c# m
————————————————+ A2 y7 i+ }, T5 _8 x" @1 O( }
版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
- w' o8 E" i# W: T5 H. j 原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
8 l: k, j$ A- C2 N% [ $ c( r1 S# Q- A0 y. w
# U+ W" D& p. C6 n2 _+ r
zan