QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3369|回复: 0
打印 上一主题 下一主题

麦克风阵列仿真环境的搭建

[复制链接]
字体大小: 正常 放大
浅夏110 实名认证       

542

主题

15

听众

1万

积分

  • TA的每日心情
    开心
    2020-11-14 17:15
  • 签到天数: 74 天

    [LV.6]常住居民II

    邮箱绑定达人

    群组2019美赛冲刺课程

    群组站长地区赛培训

    群组2019考研数学 桃子老师

    群组2018教师培训(呼伦贝

    群组2019考研数学 站长系列

    跳转到指定楼层
    1#
    发表于 2020-5-15 15:10 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta |邮箱已经成功绑定
    1. 引言5 L. S9 f6 Y# m+ l9 V; g
      之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。) ^2 @, L" `( t8 Z

    * |& A' V- a# H% ^5 U+ N  然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
    $ h1 H4 I" D" L) H. b9 l0 P& S" t. g) T1 g" p
    2. 代码介绍9 Z. }: d4 d! _1 [1 \% d
      原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
      M) Q- K, R7 ~2 r  Rfunction [mcSignals,setup] = multichannelSignalGenerator(setup)
    $ v+ h* c! U- e; l( F% e2 N1 d8 b7 I5 P9 y7 N4 u- x  G3 K+ r, }( p4 y
      B) ?  d3 a: k% ]
    %-----------------------------------------------------------------------
    , Y  g( k" Z* v4 w, {5 Z%  Producing the multi_noisy_signals for Mic array Beamforming.8 O7 N$ G( s  e- c# S( ^. q
    %
    : Y- m  h# I% ~% {% w' i+ u% z" |%  Usage:  multichannelSignalGenerator(setup)
    + H, s* }! k4 r+ I0 V%         
    ) P! \2 F& E  I  d; b9 ~%        setup.nRirLength : The length of Room Impulse Response Filter+ O" v" n6 g9 F/ m- |
    %        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
    9 X1 E' u! {( U6 G%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
    ! u4 n: q6 ]: g%        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
    ( p- U* H, I! W/ q  O* W%           ; `% o6 ~# B! o. I" K
    %        setup.nSensors : The numbers of the Mic/ `' j1 }6 ^1 ?1 d
    %        setup.sensorDistance : The distance between the adjacent Mics (m)- g. @( ~7 N, r! J1 a# @
    %        setup.reverbTime : The reverberation time of room2 n) D; c9 c; T# O9 [
    %        setup.speedOfSound : sound velocity (m/s)" }# r" J( M- ^* j5 J% a
    %8 p3 u+ F! B% }7 ^
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    - c/ V( K4 S+ C  {* D4 {4 a%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.% K/ V4 z+ \' R8 E
    %        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl., I5 ^" p1 \; [% _% y
    %
    1 z8 v9 S# L, z, Y* M%        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
    8 V# e* h0 f2 u8 z% [9 \%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
    # D2 E, \( b2 ~! @- \%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). 3 A+ s6 r/ ~1 g' `
    %
    7 S: n. I" V" R$ C% F%        srcHeight : The height of target audio source) i9 N; t; u$ s+ z$ c) H4 @+ u# Z
    %        arrayHeight : The height of mic array
    2 J2 G0 w0 D6 q# L%
    7 H) Z. l6 A1 Z+ U& a! f7 V%        arrayCenter : The Center Postion of mic array 1 d) d' i% U! W5 `
    %# @  A/ d' q* K1 o4 ]* {' m
    %        arrayToSrcDistInt :The distance between the array and audio source on the xy axis5 }" y2 s' H7 R4 h
    %/ Y* s! R- K0 H) f% S5 v' L
    %                       
    % ~* |# }  h) Y" i, C/ v%* R9 R  B5 u# ~
    %
    , i0 Y# N, F/ ~, @0 n! L/ t1 K! h%         
    0 g5 ]# l$ U3 I%4 H) s: |/ q6 c* k& ~
    %  How To Use : JUST RUN
    - V6 M& R+ g- a( O! f%) W# l" @  M# f! f- i
    %  
    5 w1 X* x4 p9 E: Y- R%   1 `, S) n* ?9 m7 j& i
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),$ H/ @7 z5 g" ^6 @9 C9 I
    %            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24% o. z* X. ]2 u4 e. x+ d9 y% c
    %8 X7 b  f5 c7 g2 e7 t  y
    % Copyright (C) 1989, 1991 Free Software Foundation, Inc.& z. b$ F( }# t0 P
    %-------------------------------------------------------------------------
    - _/ m! c. D8 |) A3 r- J$ n2 q# ^8 t. M% B4 \% K6 }* R; y1 n
    : e! t- _6 j6 K+ }% A/ C3 s; T

    4 X( K+ R0 |6 s- h' Z* n/ baddpath([cd,'\..\rirGen\']);
    9 \6 m1 ?! z$ W! E: w. X% m% X/ Q, A
    , ]+ t8 Z/ N: C- c, Z6 j. ]2 E0 J%-----------------------------------------------initial parameters-----------------------------------$ E& w0 C+ Z0 Q0 v7 V3 @5 ]
    % Y) j* P" T6 u( O2 o2 A
    setup.nRirLength = 2048;$ h/ q+ _+ Q# v$ o3 f7 ]
    setup.hpFilterFlag = 1;  q9 M, b, D( d+ R0 n
    setup.reflectionOrder = -1;$ ]9 ~0 E) _: z: z% d: n9 a& k
    setup.micType = 'omnidirectional';/ |1 J; l) T" x1 g. \' D: \' b
    setup.nSensors = 4;
    4 M6 k, K2 c5 V# Q2 Ysetup.sensorDistance = 0.05;) Q& D7 V+ ^/ C( a3 F# P3 a
    setup.reverbTime = 0.1;- ^( B$ r; d) ]" J& }/ N* z
    setup.speedOfSound = 340;' y. N+ R+ {- ?. V, m5 E+ n
    . d, p0 u7 m- N; I9 s* I
    setup.noiseField = 'spherical';
    4 }7 S% I$ D/ Z; o0 D+ m0 t1 Nsetup.sdnr = 20;4 J+ @' o/ X) `7 X6 [, S# H
    setup.ssnr = 25;
    , j- H0 v5 o5 e' h+ m9 ]$ |5 _, F& E, H3 s$ u$ r" g
    setup.roomDim = [3;4;3];# ]- l7 V9 U& v0 O- B$ q- z8 v

    $ }; m( t8 M, ]0 d% FsrcHeight = 1;
    0 M2 |0 |" P! F  I; X7 JarrayHeight = 1;- o2 Y3 E) V* U! J2 J

    $ Q# t7 X, Z0 G1 y! jarrayCenter = [setup.roomDim(1:2)/2;1];. P* J; ?& r* K0 E
    " y. t% R3 P% I$ Y5 H2 F+ u, w
    arrayToSrcDistInt = [1,1];
    " C6 W* t3 _, S5 o* h* C/ L! a. I* o4 T0 i! P
    setup.srcPoint = [1.5;1;1];% v+ X: U# Y7 x

    ; q: h2 L" G. v' Y9 _, ?setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
    # |' F9 [* j/ q1 s/ V# q& i- [2 g# F# \2 R% z' z( Q# D

    . g; t0 Z( B8 W5 V- l& U[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');- S$ S* Y0 O! x5 x

    ) Z( Z) r: [4 z6 U/ j%---------------------------------------------------initial end----------------------------------------
    0 @5 U8 p1 c7 }1 {7 n) P( x1 k0 T8 R& j0 |' g) N$ a* v

    % H0 H' O: \4 Q: ?$ ]( M
    & G- r( Q* a6 Y0 @%-------------------------------algorithm processing--------------------------------------------------
    ' h3 ?4 Q2 C' ?  ^" N. S; `$ R( K6 I
    if setup.reverbTime == 0,
    # s1 g$ l. I& Y7 Q3 K' o    setup.reverbTime = 0.2;
      j1 K' A% a8 Q' H3 A    reflectionOrder = 0;, J$ _  `% x/ `4 ]6 f3 |5 [
    else
    6 j1 h  @8 b# e- X) P    reflectionOrder = -1;! i4 U; r8 ]% Z
    end9 ?  @, _0 Y4 r9 Q, x' F

    / X" X) |7 S- X9 [7 h' K; S4 E; }' N' YrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
    & m# q; W# O& ~    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
    - H3 V1 l* ]: ]
    6 ]4 z/ v7 I' K/ B1 I1 [! Xfor iSens = 1:setup.nSensors,
    0 @  m! o( w* r; J$ c    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);) d1 {  E$ J! I/ E) Q% }
    end
    2 \& {4 j2 i; Z/ u  e. p1 M) ^) U+ SmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    $ S: _* Q1 n) q/ M" }, I" `& X# nsetup.nSamples = length(mcSignals.clean);  r3 B. }9 m1 ]# K0 c

    , E$ v7 t5 i% N$ ymcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    , q' L2 k9 v5 r* G) p: c
    9 v. y$ e3 j/ L; C9 j' I%-------produce the microphone recieved clean signals---------------------------------------------& x" B6 I! y5 s" z) x1 m* e4 v; g: _

      c4 x, L4 d  u, s& _mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    $ Q& K5 e0 z' b+ I! Q  qmic_clean2=10*mcSignals.clean(:,2);4 N' ~- P  `; Z; V  k
    mic_clean3=10*mcSignals.clean(:,3);" O: C" `' d, D$ h% [6 K5 h3 `
    mic_clean4=10*mcSignals.clean(:,4);7 I6 n5 R2 ^% W9 Q; P$ h! u
    audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    ; e* I* v$ `# L9 g. U( Raudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);0 U6 M, F! O1 A4 q
    audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);- @+ a5 e; T6 f7 i) i- y9 r8 K
    audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);7 _( [3 `$ H1 P$ Y& R( G  @
      e! i1 y/ z5 O  u# w0 T5 d
    %----------------------------------end--------------------------------------------------9 d0 F( F3 z. d' ?7 V4 ^# A0 Q
    , O5 H; i( D) t. c3 J; A
    addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);# b% \% F" H3 o; M  ]) o5 a

    . q# g# l4 h7 z9 P; HcleanSignalPowerMeas = var(mcSignals.clean);' Y  E- }4 x/ C  _# \

    ! B0 }% R+ g3 k
    & Z4 B5 K% q3 ?& X( M: j. {. P. `mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,..." U) t6 l- Q" M' {
        setup.speedOfSound,setup.noiseField);
    . t4 Y. I% C( Z( X3 }  M$ SdiffNoisePowerMeas = var(mcSignals.diffNoise);
    $ f$ {) o) c8 [0 w3 p' y( {0 \5 WdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
    3 f3 b! v: f* i! s) BmcSignals.diffNoise = mcSignals.diffNoise*.../ B* v7 Q2 D- w9 K& ?' \) c
        diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
    6 f3 \1 h  j# C
      W  c0 J' X0 x( T/ ?  |3 w3 A  bmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    " I8 I) w4 Y/ G& |sensNoisePowerMeas = var(mcSignals.sensNoise);
    8 p5 d  u5 [2 {8 B- V2 wsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
    ! P. |* H7 b) V! ~$ L3 @mcSignals.sensNoise = mcSignals.sensNoise*...
    / I6 n* N, Z7 s    diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
      x$ j& _* n& T3 b! H" t
    1 m" `6 H1 x0 j  |mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;& m% N! r$ P/ W, e0 \0 |  D! F
    mcSignals.observed = mcSignals.clean + mcSignals.noise;
    1 t$ A3 w( w9 ?: K& F+ v% ^' A. v. z& K" @0 j4 s- |4 I/ P
    %------------------------------processing end-----------------------------------------------------------! V8 r( c. v; b* C0 A: q

    2 o- ^2 i4 W2 c& L  n4 R/ ?9 ?4 I+ h1 Y; F2 c8 I3 c, s
    , ^: T  j! r. Y% ]6 ?# A

    3 J$ ~: a6 Q. B* Y%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------3 w' P7 U* E# C4 A/ e, n& I$ s

      m* k$ Q. O9 z5 q3 Dnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold7 D- w) y$ t! V8 R
    noisy_mix2=10*mcSignals.observed(:,2);
    2 w0 z$ e6 M8 P' h( Cnoisy_mix3=10*mcSignals.observed(:,3);
    ) M1 u9 Q7 J; O/ K& I7 u1 W4 lnoisy_mix4=10*mcSignals.observed(:,4);
    ) M+ o/ |  z/ Y/ X. E# Fl1=size(noisy_mix1);# Y+ z! q" U' w% h8 f
    l2=size(noisy_mix2);8 F  s( \1 a" J
    l3=size(noisy_mix3);
    , `/ z! ^1 i! \l4=size(noisy_mix4);9 u. q; C6 q- g2 t  N
    audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);) I) n, j- N7 [* o& k
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);7 i  O( r5 m: u4 O8 R
    audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);" a- y. V( e; C# E, q) W
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);& r6 _5 |. g' ]: g
    6 {* A  W5 F  Y. E( a
    - s: h6 i- i3 K* ^
    %-----------------------------end-------------------------------------------------------------------------
    7 d( b* ~6 j6 A( j5 o+ ~这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
    % \6 E6 X* j( @直接把它们替换成你想要处理的音频文件即可。
    5 C# H* v% q5 _, Q' E1 C1 i# M- ]! N9 B% Q) \5 g
      除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
    1 U$ A1 E1 {- q3 A/ V3 v% _8 [+ O- G/ t9 Y

    # ^; k0 A! w- [5 F7 ~
    * r# I- K% m0 h! h/ s! j图1 麦克风类型图
    & b( F, ^$ I, g6 x! K& z7 x7 w7 O5 A# e- t" ^: G" s  v
    图二 房间的坐标系7 C) y3 o+ |, p& ]% D0 g& E

    2 x5 {% ^8 H/ f& A  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
    ) ?5 z; n5 I& _7 _* S1 l0 c————————————————
    ( g  [9 D8 r/ y( d9 A# E版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' W9 [$ ?- T+ T: J0 ?/ @
    原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749984 R, d$ ?; J9 `  L/ h
    ( B) H* P: n' }+ O3 B8 j' p. o5 W/ m: G

    9 b7 Q4 D! G4 N. \: P
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-25 03:41 , Processed in 0.325764 second(s), 51 queries .

    回顶部