QQ登录

只需要一步,快速开始

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

    " G4 h8 q& `; ]%-----------------------------------------------------------------------
    6 `, d, T( N4 ^! ~' s2 ?%  Producing the multi_noisy_signals for Mic array Beamforming.
    2 r9 I) i5 l( A' s% / x" ~/ t( K  Q) x0 Y$ I% ]: ~4 n: X
    %  Usage:  multichannelSignalGenerator(setup)
    ' o8 e" W! I. }0 g' w%         
    + t1 p0 g3 T1 h- \9 @  p' ?%        setup.nRirLength : The length of Room Impulse Response Filter* [. U! W& C- Q8 e
    %        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default! c& k2 i# E" `; O$ [1 D, D
    %        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
    $ ]; j0 U( o  l0 t0 f8 E* d( H%        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
    6 g8 v. q9 i6 }3 P' P' L, j: W. d%           
    : x, h3 w) r5 ]%        setup.nSensors : The numbers of the Mic$ i2 z2 Q5 g5 ]% x/ Z
    %        setup.sensorDistance : The distance between the adjacent Mics (m)( c9 d$ ]! A: ]# j
    %        setup.reverbTime : The reverberation time of room: E4 N7 L- ]& C: E4 v& m
    %        setup.speedOfSound : sound velocity (m/s)5 o! h7 K7 T5 q/ h- |+ q3 H7 ?
    %, V" d, {3 r' y0 m% C
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    2 J* A$ y9 ^9 x) q, ]; Q2 M%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
    ( H% r% X. q, b. _, z%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.( u9 T( p9 m% r  E" ^
    %# @6 b" v1 E$ W: W  o
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           # Z5 E8 Z( Y! E9 }. r. z$ K
    %        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
    . `, v- X4 L4 s6 K%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). , |1 d1 |, Q' U1 F3 F
    %
    2 }  V. W+ e; Y4 H%        srcHeight : The height of target audio source+ U2 H  V  ]1 k6 ^! u1 m
    %        arrayHeight : The height of mic array
    8 o4 }% C- a: u( J%* I  h0 e6 _; X1 v' f; I
    %        arrayCenter : The Center Postion of mic array , U! |8 i# H4 g( L- Q& h9 b9 r* Q8 K
    %+ G5 F3 @6 I& e* x7 x
    %        arrayToSrcDistInt :The distance between the array and audio source on the xy axis4 F" M9 A, Z1 M- ]" |- h
    %# g/ m" Q  i- [% ]
    %                        ! E- g& c" L7 a
    %
    - X# x: D- s  B7 l%: {+ l  {5 C8 L5 \. Q
    %         ( ]2 J, V! r# G; B
    %" }: {* O9 A* r% v* j, v
    %  How To Use : JUST RUN6 P& j2 Y" z( K$ t) H; V5 g
    %- |2 {& g6 x. ]2 I) E
    %  7 B' \1 @! W- z5 l2 A* ^1 K
    %   1 w7 C8 G7 U' j+ S! }9 G: V! G
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
    1 Y/ x3 X' r' d1 G%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    , _" ]* H9 ^9 g! w( @, ~0 K%9 }/ ?0 Z  s  c. V+ B+ \; w# q
    % Copyright (C) 1989, 1991 Free Software Foundation, Inc.2 [9 v/ @6 F2 ~$ C, T
    %-------------------------------------------------------------------------
    " S4 v/ M) @  r( f7 ^1 f, c
    6 j8 n/ O% y* `  ~" P
    & b2 I; Q4 ^# g9 |' o7 U2 u; U7 Y% t+ j* P$ ?
    addpath([cd,'\..\rirGen\']);
    - U+ K8 s/ f. T6 L% V% O8 R4 v1 k" ^: I- A% ^
    %-----------------------------------------------initial parameters-----------------------------------3 o, f6 ?$ a2 ]. l, P

    8 K, e! i# o# i  Q: S/ `setup.nRirLength = 2048;. D' i3 r- C4 ?, a# V2 M1 ]
    setup.hpFilterFlag = 1;- O2 E3 ^% {: a$ I0 s1 a' n
    setup.reflectionOrder = -1;
    $ O0 c' u3 l# J/ w! Y1 N4 }setup.micType = 'omnidirectional';
    % J& K. p# c: |* y! h7 ~setup.nSensors = 4;
    * j: B( L" M% R/ s! W/ V, n* K4 Wsetup.sensorDistance = 0.05;' m4 g2 G9 p( j  e9 g0 u
    setup.reverbTime = 0.1;
    / a/ T0 c1 [& j# R" t+ h6 Ksetup.speedOfSound = 340;/ p2 y, [, v2 j# C) f% \
    9 k# x# f. e/ u4 [  }" f# [+ ~
    setup.noiseField = 'spherical';
    ' u: r3 L6 f7 t6 osetup.sdnr = 20;  J7 q1 C+ I" c2 G: ?
    setup.ssnr = 25;
      @2 V3 V: U: A- ^' C% v
    9 ~1 p! ?. X" }$ f0 _, A7 ^6 }2 @setup.roomDim = [3;4;3];
    / }5 e$ f( e/ p/ q$ L5 {; W0 n. U5 W$ G
    : C  q; r! Q/ c! T+ OsrcHeight = 1;
    % w: V7 y" Z  `& \9 ^& a/ tarrayHeight = 1;
    5 T0 U# q' S1 f% }7 V2 i+ S% Y) A. h+ c
    arrayCenter = [setup.roomDim(1:2)/2;1];  w- l( x' I; T& j6 Z

    ( {) k/ D( {- b0 v# ^. OarrayToSrcDistInt = [1,1];" l3 }) V" w8 R# X5 A1 [) W' u* v, s

    7 o& C& I) A6 Lsetup.srcPoint = [1.5;1;1];1 f9 M2 T! U5 z" `- B/ c& ]2 Q& ~

    8 R4 S0 K, g* Q- `7 esetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
    ) ]! _+ V- l  d8 ~
    4 T9 X" F) W* h1 J$ Q) s
    & C( o' c) R- a! M/ G* k5 p: M3 w[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    5 t( X: I- q- \) h8 Z, ^) c! h3 x  X) C) A
    %---------------------------------------------------initial end----------------------------------------
    8 t$ c% m3 K9 J- f: {% X, V% T$ m; o9 G# ]' P2 R: o* {8 k' J
    : j( u' `; z5 h$ q; D
    0 L  ?; e( l3 p, ]
    %-------------------------------algorithm processing--------------------------------------------------
    ' S% }6 Y% ~2 b) L9 P4 a; r' M3 r& _8 _' r; \8 X7 x
    if setup.reverbTime == 0,: X; t7 z+ c7 B$ i' O
        setup.reverbTime = 0.2;
    $ G, w  ~  p1 }* J. w+ r2 g    reflectionOrder = 0;1 |$ ~# s$ }, v! K4 H
    else
    4 [9 |8 C  d# d+ a" ~( X    reflectionOrder = -1;
    9 w; ?9 D& M3 H- @8 {end- Y/ _: z. G" b8 f. }$ E
      ~; P+ k0 l" u; ?0 k! Y2 q
    rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
    0 B5 ^# I% u0 a    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
    ' {/ V$ i: K/ a
    3 z$ O. R  W2 s# i, ?( _for iSens = 1:setup.nSensors,- E9 h. I2 P4 q) M; d* T
        tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);" n" F* ~3 [; l* t$ ^3 w
    end3 D+ X$ S5 F( y! r; L- N
    mcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    $ Q, q4 T) \/ f7 C7 i" P, N$ Nsetup.nSamples = length(mcSignals.clean);6 Z' P! J# U3 G3 K+ ~  ~
    0 ?( E+ a: Y/ z6 {5 q8 b( l; _
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    * |% Y4 [8 ?: M  r) v4 `: D
    ! d9 L; E. I  P+ o# Q0 C  s%-------produce the microphone recieved clean signals---------------------------------------------
    / b) z2 P- v7 z3 q( P: \  Y- V* k& @4 C5 u
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold3 v7 I, o- ~5 c, r6 f
    mic_clean2=10*mcSignals.clean(:,2);
    ! D) x# C9 W# e! dmic_clean3=10*mcSignals.clean(:,3);
    # p6 g& z& ^) v5 Z0 t2 j/ ?mic_clean4=10*mcSignals.clean(:,4);
    7 D. q+ ^6 e4 |" Z5 T4 @6 p/ C8 yaudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    ! h: }- z' L$ N( y8 Q9 G8 laudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
    & M( t+ o0 ]8 h0 E/ ^) b4 S0 |; o! Baudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);6 @. p  k9 }. w0 _" g( U
    audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);0 u; e; A5 Z* {

    5 F9 K, M- M3 t1 A- Q) R%----------------------------------end--------------------------------------------------
    6 d1 @4 j, C9 e  Q" g/ a
    1 R2 @# R9 t- ]4 v' P* v1 Laddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);! W5 l! C: ]3 S: P+ w
    2 L1 I' e, D# T% y
    cleanSignalPowerMeas = var(mcSignals.clean);
    7 `2 {9 a; H" h' R! B8 L9 h
    * v6 d6 c. E+ M3 }
    , e7 [) l. N4 O) R3 O! VmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...2 n5 ?2 `  V* e" k) t
        setup.speedOfSound,setup.noiseField);$ W! g; S$ Z; J
    diffNoisePowerMeas = var(mcSignals.diffNoise);* D$ t6 Z' a8 U
    diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);; N% d/ D4 A; r
    mcSignals.diffNoise = mcSignals.diffNoise*...4 w  ]6 ~7 b& p3 g, f: b
        diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
    + n9 ]9 k! h5 _; _# I# W$ B
    / Q& p* G4 C, C* y* z3 q# W4 z5 B. pmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);$ ~7 p3 U# T* V0 \3 Z
    sensNoisePowerMeas = var(mcSignals.sensNoise);6 X7 b5 f4 @+ p- @& k
    sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
    8 F# c5 d* w# A1 P6 A( |mcSignals.sensNoise = mcSignals.sensNoise*...7 a  H5 A& n# Q* s7 ]" ^
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));# V# q  M+ c% U+ J

    / s# @; n, S6 k6 |; w+ }mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
    & b2 l# W8 V* a2 [) ]! P( fmcSignals.observed = mcSignals.clean + mcSignals.noise;
    ) Y- D, }) b, w; t1 |
    4 M! I3 J! A5 |" ^! }% g%------------------------------processing end-----------------------------------------------------------
    - a8 n, w0 d: ?3 `
    . J8 C3 c1 M7 P2 v9 Z" W' T4 \9 Y

    6 H3 a5 L1 b, G9 V" H" T. b) F+ W# S$ l; j: i' b' X/ j& ]: V
    %----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
    : r& \/ I( a# d6 n- I* O
    ' H0 U) ^& Q' M3 S# znoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
    0 o+ j9 J0 S; R' F' B# I& e% X/ ]noisy_mix2=10*mcSignals.observed(:,2);8 p7 B, @$ ~9 w1 F2 `& D
    noisy_mix3=10*mcSignals.observed(:,3);3 O- e4 M6 H/ M$ {2 i
    noisy_mix4=10*mcSignals.observed(:,4);
    * L  C' n$ ?, x9 `3 k' yl1=size(noisy_mix1);
    - R4 E) A& _9 t. @2 k/ ql2=size(noisy_mix2);- `8 p0 t1 Y8 R' u5 }( q0 i. m( ?7 Y
    l3=size(noisy_mix3);$ e0 I; a* Q. t/ X
    l4=size(noisy_mix4);
    ( }. D' \7 s% Q/ Q6 naudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);# }' @$ {; g$ O# W9 t
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
    5 X; k( v: h+ Iaudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);) D& k2 [1 `: \$ c
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);& e% n" T8 A, m2 Z

    3 w/ ?  H8 }: |% k8 J: n) t% ?" }& O2 \! }% x! ?! ?: u
    %-----------------------------end-------------------------------------------------------------------------: T' d3 R" z& |" ?0 u# h
    这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。  ^+ V' k  |( l9 {
    直接把它们替换成你想要处理的音频文件即可。
    & x* T& J, h0 V: q0 g# |% I( o
    8 y' C& I4 o5 P8 r: q4 |9 f$ 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)。# M% I9 J+ T  Y! J5 g" ^* \
    0 s" _' E: x9 R  W8 P* x

    / v: K1 w+ Y) n9 G! g' z
    6 ^  ~" _# ^. j" k$ s, P图1 麦克风类型图8 T6 {$ V: E1 Q

    " ?8 N* W4 _2 S图二 房间的坐标系
    5 |6 e, W" R# _: C  |
    2 Z+ W5 P! N! M+ ^  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
    ( C+ ^! p7 t2 A4 K. N————————————————# p/ o1 [" C2 L6 [$ N
    版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 C) ~9 T1 W' n7 \) J原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
    * W( {( z# j1 c$ W4 h6 o! V* z* M. _0 G# t/ Q
    0 u) H2 v- C/ c
    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-6-15 03:44 , Processed in 0.567962 second(s), 51 queries .

    回顶部