QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3389|回复: 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. 引言
    8 j& \) N7 h% r+ M7 {; v  之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
    " C* [% H9 d8 D4 k! Y' h
    7 D1 ?0 d# D. R' D! t  然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。/ M0 _/ D/ ]5 t
    * H8 |/ h6 Q5 U! k
    2. 代码介绍
    ' n# A& k' s& O1 j' |2 }: f  原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:! r6 ?6 G2 Q+ A. J
    function [mcSignals,setup] = multichannelSignalGenerator(setup)9 }6 U- n0 k" x- P

    7 t3 d+ D5 J" N6 o
    0 L4 \+ }2 ?% \%-----------------------------------------------------------------------
    . H" Y6 Y% ]  L1 B" G%  Producing the multi_noisy_signals for Mic array Beamforming.5 q+ G, Z& q4 z! S3 K' `
    %
    ( v1 y5 T8 Y; _6 Y' j/ x%  Usage:  multichannelSignalGenerator(setup)
    5 Y$ X# E) q7 X( T; b& Y%         
    % y" P. d7 v1 G. ?; t%        setup.nRirLength : The length of Room Impulse Response Filter8 J4 L4 o  `% Z; t+ ~: w
    %        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
    , w! a: G' s$ x. U9 `- O' T%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order." z8 U: B2 P' A1 {/ y7 s, x& \4 t) U+ a
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
    , h* V2 A7 q' I- a4 V0 n%           
    # i& M1 [& R0 f- J5 v%        setup.nSensors : The numbers of the Mic# W1 _! N. Y8 b4 x. W! n& ]
    %        setup.sensorDistance : The distance between the adjacent Mics (m)7 W4 n7 r9 \. R6 g4 A7 E
    %        setup.reverbTime : The reverberation time of room
    2 u5 p% [8 b& A7 O3 K1 U%        setup.speedOfSound : sound velocity (m/s)
    # o2 C% F4 y6 @4 R0 i9 t%! _9 v/ M9 z1 _1 [3 }: X6 S* T
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    & Y, Z: l# ~9 t, S%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
    4 p( P9 J  }0 d( d; A%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.$ y3 h2 e$ Z1 K2 X
    %+ `; z: J6 y$ h: W$ j) x
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           0 E0 X. q$ M7 I5 {$ E1 f0 e' d- B" a
    %        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
    # V  ]! l' c5 m# s%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). 4 N" W1 g1 Q5 h2 E8 e/ k
    %+ G" m- K7 J+ j6 C& i5 s4 V1 \
    %        srcHeight : The height of target audio source1 T" B) {6 p4 A8 y( k' v# |5 o) T
    %        arrayHeight : The height of mic array+ Q  B4 `5 H- a
    %
    - @& S/ S" f8 o%        arrayCenter : The Center Postion of mic array
    9 N1 x3 p& X4 m8 z8 |9 v' Y( G1 y%
    ; N8 ~  M5 ^4 B" y%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis1 \+ [8 n# j+ \) \5 I0 D  ~
    %, i) A$ s$ S  a7 v5 [+ W$ j$ G
    %                       
    . D' l: k9 M# D. p2 n4 r7 ^%  u/ B5 ~3 Q7 f3 E3 k
    %
    & j( A0 Z1 |# j' U$ Z* Z; c2 v' \%         - U$ @, u2 N2 l
    %
    ( [6 n; `( K! c" v4 |%  How To Use : JUST RUN4 {& e/ Q7 r# h3 Q7 T
    %2 M; J! g3 ?  V3 r: n$ c- U
    %  
    , u9 {+ Q7 y2 h0 V/ h( Y, y%   
    9 L% y3 }2 _6 n( ~. s4 N# A( ]% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),( n9 @: c8 u: X) S0 l6 Y
    %            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    4 \. k+ h' O" @2 Z6 r9 [5 G! F%) g6 J+ b+ e1 z: ]2 f
    % Copyright (C) 1989, 1991 Free Software Foundation, Inc.+ e' }- Z& _) o  I( g# n% x* F
    %-------------------------------------------------------------------------# f4 B5 `4 v( Y

    % g  u* Z$ O: x) ?
    " A; u2 k$ }7 m8 O* c2 h2 ]
    % R. g% L6 ~9 P( g+ paddpath([cd,'\..\rirGen\']);! O' I% ]" I- X3 ?

    ' c( U. p8 I5 `- v4 s%-----------------------------------------------initial parameters-----------------------------------
    7 n2 R$ I1 ^) V& k+ u' _8 ~8 d" l; ~1 j* ^: K
    setup.nRirLength = 2048;+ M- U1 A- K5 t8 i0 E- |
    setup.hpFilterFlag = 1;
    ( {$ l0 N2 j* {9 @2 Wsetup.reflectionOrder = -1;
    ! P# T) Y5 A- g; t) Psetup.micType = 'omnidirectional';
    - l6 _7 S& N! K0 |setup.nSensors = 4;
    9 @" V8 D" W3 _! H4 ?setup.sensorDistance = 0.05;. x0 }4 [7 J  e( n: D" ]3 s1 A$ n
    setup.reverbTime = 0.1;* Z: P- |2 V% S, P. _5 Q* ^
    setup.speedOfSound = 340;
    " ^" O: u% v  s. `: ]2 E/ u8 _3 g6 d3 S' J) q, G$ v3 {. ~
    setup.noiseField = 'spherical';
    / M+ ^$ u$ B$ u* Csetup.sdnr = 20;
    ' n/ s. t! |  q# g& }setup.ssnr = 25;2 k3 a7 u6 x; z6 Q# o

    5 ]' x7 V9 X+ X0 V2 }7 ~" w" ssetup.roomDim = [3;4;3];
    & k# M1 J8 r; |6 t
    ) t7 ~% V3 `6 w. \4 gsrcHeight = 1;/ H5 q/ P( d+ c' C" Y% V1 @4 l
    arrayHeight = 1;2 P6 O- Y$ Y" O5 e8 l9 G/ H( D

    : L: ~. R0 Y* v6 P9 a. |7 barrayCenter = [setup.roomDim(1:2)/2;1];
    $ |& E" [  n# l
    ' F% X4 ~- Z3 [9 }2 ]arrayToSrcDistInt = [1,1];
    7 ^/ o. B( C8 d" y. J3 i; N
    7 R3 g: V' V  K- T& [6 `. ]; Isetup.srcPoint = [1.5;1;1];
    . c7 [" [: }5 T* [/ c
    3 k6 ?' f7 p, C  e' L  \setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);9 ~# v4 N. z8 J
    ; l' e- D0 [; q
    : Z4 f% U+ o/ x# u$ ~
    [cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    ' N" Z1 d' ]5 B1 m# I
    ' l+ V# O' H( B' L; J%---------------------------------------------------initial end----------------------------------------4 u, g( j) v+ w3 E4 M) v9 K( {
    9 ~  Y; s! M- b

    0 d- H( f! y' {+ t$ r( f$ x8 c
    ! s0 b! F! k" O4 U5 M%-------------------------------algorithm processing--------------------------------------------------
    ! @, V, A9 ~+ [- M) z* ^. f5 U' ]" @' w% N- n
    if setup.reverbTime == 0,3 H# s* c! q' _( m' R
        setup.reverbTime = 0.2;
    & i5 e. i  N; g* f" P    reflectionOrder = 0;; {1 H/ x: ^" D; D
    else2 Y8 T& I& r6 i. ?/ O0 S
        reflectionOrder = -1;
    . N1 Q' u2 Y, W& ?; D% nend2 ]( n$ {  i' Z+ Y

    : B3 M. r/ u5 ]; t: G) \rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
    ) O; w8 Y, ]4 @. r* W; u& H7 K    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);( T) l& V  [7 M1 |% ]6 p. u/ @

    2 d1 n1 I, X# p, z1 P  J  pfor iSens = 1:setup.nSensors,. N) A* S& c! X! b& p! z2 w
        tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);& q/ {& {; j  Q# i4 V8 U4 X# m
    end
    & u5 f$ @0 l' o! N+ qmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    ) D) K/ j5 S; w) X; [setup.nSamples = length(mcSignals.clean);, s' N8 F- O' s

    ; b* O! I7 G0 Y. j( \) g. m5 {mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    ) e, t% i# \  w' {- R6 |+ j
    + o0 k/ `6 \0 `3 A; X5 u/ \%-------produce the microphone recieved clean signals---------------------------------------------
    ( f1 r) I. A5 T- e  Q. C" L/ v& D$ U  R3 r# e  B' K  s
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    8 j% z% Y1 [2 C6 l7 cmic_clean2=10*mcSignals.clean(:,2);" v( [" d1 g: h) u
    mic_clean3=10*mcSignals.clean(:,3);  R2 w) v: l' {2 G" _" b+ F
    mic_clean4=10*mcSignals.clean(:,4);! _" g( [$ A3 i& @" u* M
    audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    9 S1 |+ \) a2 V( L2 {& zaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);3 Y" C3 X) \$ d  ^0 Y+ h
    audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);& A7 ^$ x* v0 ]0 I5 b
    audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
    6 I& G9 j: L/ z! C% R) O1 f, C5 u/ o7 P+ a6 P
    %----------------------------------end--------------------------------------------------
    & D. t3 v% J5 S0 n/ [" c
    ' ]* _, J- y" v% d3 w4 \7 qaddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
      T, X# D* Z1 U' q
    * e4 {$ |" n4 v6 q" q# j) hcleanSignalPowerMeas = var(mcSignals.clean);: Y. O# Q4 M/ u7 ]1 b

    2 ]1 W3 @$ N$ Y! H+ N
    - d/ Y& s0 _7 L. BmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...& q' T; T6 X  b# J  Y' M+ o
        setup.speedOfSound,setup.noiseField);8 s7 Y9 k& Z) U% z: u1 h
    diffNoisePowerMeas = var(mcSignals.diffNoise);
    9 v+ U8 F" C) ^+ a' wdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
    1 I* k( u6 E$ e5 O7 J4 CmcSignals.diffNoise = mcSignals.diffNoise*...( c3 J, o  d& a$ c# N/ Y/ O
        diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
    8 ?7 H2 @4 n" n8 R( v9 N% Q: H. A: m/ e4 `7 N. P* h
    mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);# u* I) D! f5 X# l. B, Q" K
    sensNoisePowerMeas = var(mcSignals.sensNoise);' ?4 E2 W7 r9 t, P$ {
    sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);8 s% A5 W, Y; s% q
    mcSignals.sensNoise = mcSignals.sensNoise*...: i% S! z- A" T8 v" x/ n' {* i
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
    - s  h( i; ^, W2 W$ c" I, C! k
    & m, p% _1 [7 C# J8 G. OmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;% j9 o  S2 D% m% ?- q
    mcSignals.observed = mcSignals.clean + mcSignals.noise;
    # A$ @) D  x$ M& p3 H$ P& ^4 N
    7 o  e1 B1 [0 e$ M2 H5 C3 t' R9 _%------------------------------processing end-----------------------------------------------------------6 H% D) |+ p+ v. H
    ' k8 i0 S2 A! q7 }9 M

    & v! X: H. L9 g& F# a6 K
    % s3 B  a+ F" i/ Z8 V) b* S
      s3 p. R# d/ ^* t+ u+ H%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
    : P2 {; x; v" m& k; t. ?' J6 k9 i* }3 D/ c: D  T/ a
    noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold& Q% q- l  ?8 O8 }
    noisy_mix2=10*mcSignals.observed(:,2);0 }4 p, J% }+ y! s' K7 T
    noisy_mix3=10*mcSignals.observed(:,3);; a3 Y" ^- w9 F( e. k2 r
    noisy_mix4=10*mcSignals.observed(:,4);
    / ~- _' a4 d$ ]( Z: _3 l/ Q1 i( Pl1=size(noisy_mix1);
    2 X% f+ R. j/ S% A% L* Zl2=size(noisy_mix2);( a( z2 J9 t2 Y- t
    l3=size(noisy_mix3);
    ) W3 F  C/ c/ n+ ?* C3 u  w& u2 dl4=size(noisy_mix4);- i; J5 z" d/ J/ J- E
    audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);( F1 O( n. L$ S% l) L& m
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);8 Q! A0 b. \# y, P, r
    audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);* M; a# u! k4 Y; b5 ^9 s" F
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);. g, m1 x  S2 U8 A5 b

    % ~2 d  W3 B$ B
    ) G2 p# B3 `% o" [5 H1 n" ^%-----------------------------end-------------------------------------------------------------------------
    1 B! z' d2 \4 `) B5 B, N  o: d& \这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。5 w+ c( c  \7 {
    直接把它们替换成你想要处理的音频文件即可。. O, I) [' F' z
    * j& M6 a' W) c& Q3 t/ O, s
      除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。9 l8 `" C( p/ N
    * f, M5 U6 c8 v% Y. C
    & Y1 Q  e0 A. g- P0 ^' @6 S

    9 S0 i9 k( ]) J图1 麦克风类型图
    : ?* j+ y2 O; v; C. [2 o9 R2 Y0 h2 p' K5 a! l0 Y
    图二 房间的坐标系7 x! Q" D( E. C, b& {5 F  y+ Q& k

    # ]( k0 w' ~6 T* C8 d" L  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。9 v# {2 {3 w3 G) ?9 }' Q; _
    ————————————————% d( {. r( z# R/ |6 P
    版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 J2 V' q& g* I# l原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749986 ?! R9 ?6 T: e. J

    7 N; X6 \2 a# `3 Z, v1 x9 M0 H. F
    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-9-8 16:38 , Processed in 0.652182 second(s), 50 queries .

    回顶部