QQ登录

只需要一步,快速开始

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

    / W7 w1 m6 g5 C* d: y! m%-----------------------------------------------------------------------7 D; C4 K+ e3 l, G
    %  Producing the multi_noisy_signals for Mic array Beamforming.7 L* f. |% V0 j( `6 \: I. U1 p
    % ! O" H5 u; l9 j
    %  Usage:  multichannelSignalGenerator(setup)1 H% V. W2 }+ Y5 @1 V9 i
    %         - g% K  Y* D' C1 J- Q* ~* h
    %        setup.nRirLength : The length of Room Impulse Response Filter
    , v4 \5 P4 g  P+ r%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default& V& `+ L7 }$ m4 p( S/ J( k; I
    %        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.! }( v) J) }# C& [
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.0 Z: U0 M+ V2 S) J, q+ `# p; E
    %             t9 |7 F# h( {  e& J) ]# B5 S
    %        setup.nSensors : The numbers of the Mic
    / P7 w; {. o" [1 O7 t' T; B/ L%        setup.sensorDistance : The distance between the adjacent Mics (m)
    " }: f, y7 X/ ~/ \! ]. d%        setup.reverbTime : The reverberation time of room
    / [* C4 q, F; C2 H; v4 r%        setup.speedOfSound : sound velocity (m/s)
    . z/ S8 k" T! l& l  [) W) X%
    - m6 ?8 m' t$ z%        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    ! v# Q. B! K% a0 E3 |) G* m& C0 g%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
    , i' n) d' D7 c0 N" Z$ `' u! l: l%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.& H  N; p/ f! L# T9 V: u
    %+ J2 Q3 p+ M5 `2 B1 r4 @9 H
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           0 e7 Y) R4 t8 x! m5 H/ c" Z4 I
    %        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
    $ O8 J5 P1 l* q; k6 [1 ~%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). 1 ]3 @0 h& t' Q  }  K6 A- ]# L4 b  M
    %0 o1 I, |$ ?, k
    %        srcHeight : The height of target audio source" C7 O5 ~, F6 Y
    %        arrayHeight : The height of mic array
    / }0 J4 G! b4 H1 `%5 `; A$ M" C/ u# O
    %        arrayCenter : The Center Postion of mic array & C2 M9 \* O: R! W
    %* X5 T  x+ Y2 p! }0 }
    %        arrayToSrcDistInt :The distance between the array and audio source on the xy axis% m3 q5 Y4 J4 a
    %
    3 |1 {# [2 A# R& e%                       
    . H/ s) V6 `: q- b+ Z4 T%8 C. d  }+ T. D7 i; Y/ r
    %
    1 {! w% H, _0 o' I" ?2 l%         
    ! T  t' |) U  _% I# L' _: G; n; R$ ?%5 @# s2 V' a# z, ]* _* G- R) a; u! ?
    %  How To Use : JUST RUN. e2 k) \% E5 w. M- @6 o
    %
    ' H& A8 |4 j) f" e( R) y%  4 m- ^! h* S* \% L) r$ Y1 Z
    %   
    9 m/ |5 n1 u3 T7 f6 i. H% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),! L+ a7 h2 U# K: M
    %            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24- G  M2 t% M; ~0 {& D5 x+ d
    %2 u7 B; A0 Z& I2 R  S9 {0 }# O0 s
    % Copyright (C) 1989, 1991 Free Software Foundation, Inc.
    4 k8 V4 X8 c% g% D/ B; f& q. C%-------------------------------------------------------------------------
    ) y0 G: {% ^* Q% J- _0 Y! ]( Q0 v% p( f7 r9 x# R

    , |) B. Q5 A; m( a* O9 M9 q/ K& H' P$ _0 j8 N0 e
    addpath([cd,'\..\rirGen\']);: W) ?( h9 {- }0 g# a) C& J

    ; f0 A# [) e! _% l, F$ E%-----------------------------------------------initial parameters-----------------------------------
    3 Z- P3 q$ V* ?( d7 N% N( M7 C6 j
    setup.nRirLength = 2048;
    . N+ q: J3 R6 Y5 Z& N7 E* Rsetup.hpFilterFlag = 1;/ q9 g1 Y% i8 g
    setup.reflectionOrder = -1;
    # ~6 y7 l- H) g0 `. b7 k+ nsetup.micType = 'omnidirectional';
    & ]' h0 y" |; }3 Zsetup.nSensors = 4;) g7 Z5 p9 w. E) r- Y; c+ O
    setup.sensorDistance = 0.05;
    1 g8 D1 z" s1 y  g8 Q3 K  a% tsetup.reverbTime = 0.1;' \; I4 \+ U; T9 r; n. A$ m5 h
    setup.speedOfSound = 340;
    # S$ R. ?& i/ C
    + ]7 l/ S& C  h. [setup.noiseField = 'spherical';/ _8 [& M$ b7 k+ G& Q" e
    setup.sdnr = 20;
    5 m/ H4 g9 |) Zsetup.ssnr = 25;
    8 b* B0 y$ h; j
    2 r! H7 G+ e- d0 l' Gsetup.roomDim = [3;4;3];
    : ^" L# R. P$ f( T" r
    . f$ T8 A) f& |, B; O! lsrcHeight = 1;
    ! |, r6 ~( [3 B% `) ?% ]arrayHeight = 1;: o! Y4 T! }" P: Y: ^

    ; ^. A4 h" W, |$ `! O' ^: o7 H. aarrayCenter = [setup.roomDim(1:2)/2;1];. Y3 W; d7 H# E! [

    6 a& j5 t5 v* X& o# b0 B( I) sarrayToSrcDistInt = [1,1];
    3 z9 U/ e# z/ E' T: C
    4 O- b$ |9 ]3 a0 Q# \# u8 N- D! ysetup.srcPoint = [1.5;1;1];" K/ l- U  u% ?" T) ?3 Z+ D4 a

    ) w7 H/ Q' L) }1 y0 H: Gsetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);7 q+ P' X) u" k( k8 |4 l
    ( j! t, U/ j. i9 x- Q4 k
    7 r7 A/ k0 K+ X6 l: j4 }' w! {
    [cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    ) R) W6 w+ S6 ]+ v/ B
    . A5 Q/ H) n  P7 {9 e%---------------------------------------------------initial end----------------------------------------5 Z; m0 {0 }' l. A) I

    6 v/ D5 E7 l# z+ F; e& \% N4 A" g5 S# x* L* [' K' s
    + [9 T( ?2 u1 u2 {) J$ P. @
    %-------------------------------algorithm processing--------------------------------------------------
    7 C! M  y7 n$ Y
    : {" D4 s$ O8 i8 c4 gif setup.reverbTime == 0,
    2 _6 t5 t1 @  ?1 o% |* M9 l2 v    setup.reverbTime = 0.2;" V( L/ ?9 J( f! X  ?4 G
        reflectionOrder = 0;
    % |% Q) X- M5 f5 e. E, O* a4 I. G( telse
    8 L! |% w1 L. \  s. E7 D" e) ^+ Y3 W    reflectionOrder = -1;
    5 H; O" R% t6 J8 l5 K/ l1 T4 @end
    : Q0 |6 c- ^" z) |8 o. P2 }2 o( Y
    rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
    % [6 F. V/ K& J$ u9 a+ ~+ f( {6 O    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);7 O, h7 Z2 J. K3 M/ a  m

    5 j$ ^1 a4 s& ufor iSens = 1:setup.nSensors,
    * w/ R/ w! y8 h1 Z$ ~0 }7 z    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);
    ; d' r: r3 d0 M# w% h, c' o# Jend* A5 n5 L0 e3 A3 F  b
    mcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    . d/ j$ E. n+ ?+ W7 msetup.nSamples = length(mcSignals.clean);9 ^% r6 D) N9 s2 ~/ N
    2 z1 [  B( i& _4 w4 G3 u6 b1 A
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    ( N0 g9 I; j3 w+ A( E( ~
    3 V6 d$ j3 I+ m$ F/ h4 g# l' ?%-------produce the microphone recieved clean signals---------------------------------------------
    " I" i4 d# {+ z* P, H* j1 r4 m/ `: D7 F( \* ?+ W4 m/ e4 ]- G
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    1 g" L1 u1 x( T1 x2 }8 Amic_clean2=10*mcSignals.clean(:,2);! S5 W: G! x1 e( R6 J' }' |0 p
    mic_clean3=10*mcSignals.clean(:,3);
    8 D6 f5 D" q6 K  k7 E6 f& Gmic_clean4=10*mcSignals.clean(:,4);' l0 C% b! s- w6 l% j# M5 U7 h
    audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    " P* w# d, E, L$ e/ R! P" oaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
    1 r- O1 [2 ?; d3 D+ C  r6 H5 iaudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);4 }7 W! ^( w! o( \" Z
    audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);: W. u  f+ `& [. C6 f

    & e$ e. c6 y- s  h%----------------------------------end--------------------------------------------------
    & T6 C, F& Y- g6 s4 g  l4 Q3 U5 _" b3 O
    addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
    % T2 ]" O7 C& ^# }! s& O$ i, ^0 w  V6 u$ ]: E6 Z1 w! u
    cleanSignalPowerMeas = var(mcSignals.clean);
    2 _- s% }2 R7 T* T1 d7 \; e  ^5 H& `4 r) g! F" b+ k- _3 |: C( G
      w/ c3 N7 l0 h# @4 j" e
    mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
    , f, D" h5 H* \$ w, g( {: }! F$ V    setup.speedOfSound,setup.noiseField);0 c8 O4 H1 e' t# i" F) @
    diffNoisePowerMeas = var(mcSignals.diffNoise);
    - o7 E; b  r" MdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);2 z9 S# s. R! ], c
    mcSignals.diffNoise = mcSignals.diffNoise*...
    0 x7 H8 o# l6 a" h5 N5 n4 f    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));  }$ ?3 O5 h# A0 P. P  k

    ( j: z" }. ^6 d; X% a/ ?mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    ! P) v& q  {5 l" j; A' X8 E7 S/ JsensNoisePowerMeas = var(mcSignals.sensNoise);
    ' o  Z% Z6 Q+ N. |" C( \sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
    . Y/ d1 t5 i, Q! r) @$ G. dmcSignals.sensNoise = mcSignals.sensNoise*...  V! A6 u8 ]6 Z5 W
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
    " |3 |8 }. e/ F5 A
    6 ~/ }& c( r) ~: EmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;, y$ S* v9 {) ^: s. d
    mcSignals.observed = mcSignals.clean + mcSignals.noise;
    0 I8 c" [0 {3 t4 _) n( W3 s0 e, A4 G: Q
    %------------------------------processing end-----------------------------------------------------------
    ( \" q* P& h& g1 ?% P  i% f/ E. e+ d7 L

    $ F# X( F, b$ }3 \* g# w( g6 }" j1 g- n+ ~8 L
    4 B( c/ D% H# T& Y, Q
    %----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
    & V( v- C3 P; s+ ^' [& C  y" w
    + A$ ]2 W8 Y# gnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
    ; c$ a% t% M7 R- h* ^. L7 Wnoisy_mix2=10*mcSignals.observed(:,2);
    ; M' w7 h) C7 @7 B# E. wnoisy_mix3=10*mcSignals.observed(:,3);
    ; N7 E. F0 q4 [$ `& G& R% Hnoisy_mix4=10*mcSignals.observed(:,4);
    - S( y* x$ h5 Q  F3 w/ yl1=size(noisy_mix1);" T2 j" c3 e4 Y
    l2=size(noisy_mix2);( r' ~9 J; O9 @/ t
    l3=size(noisy_mix3);$ z/ M' S/ x7 d& M8 J9 ]2 j
    l4=size(noisy_mix4);
    ! l7 r  F2 @( e/ c' r1 o) @$ N1 xaudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);9 y# R7 ?& X4 N
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);3 u# J$ V4 v3 q* D2 b1 N
    audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);" k4 @4 w' ^# U" _. e
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);0 T7 K- t# ?7 K7 D8 a

    ; x7 P% ]+ V. c! G
    1 @9 Y6 l" z& G  n8 b) n%-----------------------------end-------------------------------------------------------------------------
    ) c* U5 R8 X; c" S' R9 k2 m7 e3 X这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
    & y9 S) F7 h& K+ o/ l; I直接把它们替换成你想要处理的音频文件即可。* e  N; E9 g' i& r- o. }+ L
    9 W) t% x6 m9 ]' c
      除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
    # {2 o* t$ m& G1 [4 y; H2 X
    ! B% X9 w1 V7 C% c; P
    * C# e4 ~7 O+ a" u5 ?8 O2 w+ y/ J  @) E# W
    图1 麦克风类型图! ^/ T2 O! D7 p& B! P4 Y

    4 ~9 e! ?" C' k8 p; O) i8 V图二 房间的坐标系
    % y( D+ K! L, o1 d0 R
    ) n  E6 i; b) R  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
    1 a) D1 {( X; E————————————————9 `# f- o  I' K- \. }! t1 E. W
    版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 m; h( i7 ]) r. L4 [( K原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749985 }4 E8 e7 X. j  v& B
    . l- K0 N, ]3 i4 R
    1 {9 G$ z9 t! E' D* {; J8 K; H1 U, k
    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-10 07:48 , Processed in 1.508895 second(s), 51 queries .

    回顶部