QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3395|回复: 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. 引言
    ( e' X% P$ n+ t  之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
    6 l8 h- N3 g7 C# v0 v0 `, e+ C9 L/ s7 F
      然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。2 R# S# d$ A0 b7 l0 O

    / E4 Z$ ~4 o" [. @/ ]7 c2. 代码介绍/ n- ?0 h; S) e/ w! {
      原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
    , |! e$ X+ U* n3 J: A# R7 Nfunction [mcSignals,setup] = multichannelSignalGenerator(setup)
    & K+ L7 x- g* |! k1 b3 x9 b5 g. @. I( `5 z9 h) A* C/ x% Y

    7 |- }& c, \- i/ d% a+ u# t%-----------------------------------------------------------------------1 y5 T( V7 b- f# g
    %  Producing the multi_noisy_signals for Mic array Beamforming.
    1 G0 N- N7 E% K$ {5 }2 g2 m% : X% w) T1 R) s! ^+ H; G
    %  Usage:  multichannelSignalGenerator(setup)
    : b8 v/ l0 ?3 g%         
    8 q; j6 }. Y7 \2 N$ x, H% \. ~%        setup.nRirLength : The length of Room Impulse Response Filter" m/ L- c( X! b) D$ r
    %        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default) o$ B- R$ `2 M) b
    %        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.5 y) @9 _# ?. j% \- K- ?8 b$ Z) v7 }
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.% k6 m/ N2 }6 `! r5 ]) I
    %           
    . P( e4 ~+ b! x1 b%        setup.nSensors : The numbers of the Mic" w0 m( r' v2 g
    %        setup.sensorDistance : The distance between the adjacent Mics (m)! x7 V9 k. l3 u% c- ?$ d
    %        setup.reverbTime : The reverberation time of room
    ; }% q) O9 p. F5 N4 @  a$ g1 u%        setup.speedOfSound : sound velocity (m/s)! [0 o: ], E5 i- P6 d/ S
    %
    $ e: {1 X( z: G) w# N; u$ O4 e3 C%        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'1 T; g6 R7 P/ e% \/ }% J# F* U
    %        setup.sdnr : The target mixing snr for diffuse noise and clean siganl." S6 N4 N: J* p8 x- S5 l: {6 h( A
    %        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.: @5 O6 I- N, G% f, s4 k# ]& b. {/ Y
    %$ F7 x; ?7 c* w. a! {
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
    ) F/ S! B/ [  Y  R; ]%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). - h5 W2 P( r# e! `
    %        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m).
    + l1 b, G$ Q( I- l%7 p) z' Z$ R4 M0 N7 X1 w/ W
    %        srcHeight : The height of target audio source
    * I  ~4 k0 Q, c+ d4 C%        arrayHeight : The height of mic array9 R& [! v, b5 ^0 b" N
    %, E- g0 }, O# h$ A& a1 u( L* q
    %        arrayCenter : The Center Postion of mic array
    0 x# {2 c) v  j2 B" Z  E%
    1 U2 p( {  c- |3 Y% g. Z%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis! ~4 y+ }6 v: @  E( H# z
    %
    $ v) y: C6 L# `% c%                        5 \  C' w$ R( g! L! z1 u+ j- ~; M: n3 f
    %$ z2 y1 \% H# b3 _
    %
    ( A9 B2 \& @( R% s* x9 p3 _8 R%         % V: m3 D/ n, j7 y
    %$ T: [' i9 S$ x
    %  How To Use : JUST RUN: w3 g; \1 `7 H8 @+ N
    %7 a* b/ u5 V0 b3 _9 X8 l2 T
    %  ) g2 ^% O1 ^, m# i% w
    %   ; f( d! }- b( a: V( {
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
    & g4 X: k9 |. l# B3 \% K8 k5 q%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    - L9 z- L3 U4 r# h( X; @+ K5 z%
    $ {& @0 d+ b0 g% Copyright (C) 1989, 1991 Free Software Foundation, Inc.3 h& r4 `7 U( j( k, S5 v; k
    %-------------------------------------------------------------------------
    - L3 w3 H" ?' V) x% s8 [2 m* m0 t1 e. @! S

    ' f8 y$ A& o7 `: R! C5 q" y- O* w8 H9 D2 q9 X) U& K4 {+ s
    addpath([cd,'\..\rirGen\']);+ M! P# F5 f! P# u4 u0 j

    ' o% V7 V: y' R# P' {  W# R9 t) C9 E%-----------------------------------------------initial parameters-----------------------------------
    # G+ N6 Z) U' A# W  j: o6 ]
    9 [) v8 ^4 p: d) u! b; isetup.nRirLength = 2048;
    " F; L9 W) w$ p- t9 \# Z: wsetup.hpFilterFlag = 1;+ b% N5 F! ?; N: ]# S
    setup.reflectionOrder = -1;2 {$ j# h6 S8 s# D( c) A4 k
    setup.micType = 'omnidirectional';9 ~1 C& \6 f, d2 P- W
    setup.nSensors = 4;$ E2 V) b% I9 z! D0 ^, g  J% ]  |
    setup.sensorDistance = 0.05;
    9 m+ a; G( A7 tsetup.reverbTime = 0.1;  a$ J; d, |. e2 \  k2 R% W: h
    setup.speedOfSound = 340;; _7 h9 x1 T. Y1 [( ~4 q6 w

    ) V$ B& k3 ^) a$ q" P( ^0 M+ C6 Osetup.noiseField = 'spherical';7 ?4 o( Y* f' G: I, P+ k$ q9 S
    setup.sdnr = 20;' o- c9 q5 z3 f8 b( B+ {  ]  Z
    setup.ssnr = 25;* @5 D: s, `- n/ E

    . U' h' P- V. z7 J! d# s7 V* @setup.roomDim = [3;4;3];$ P" v/ S, v6 s& G8 @  ~( W" q- M

    - w. X% E1 A3 h' ?4 j, v0 i$ o) v+ z( SsrcHeight = 1;
    . H" ~( y& z; `% `, ^% parrayHeight = 1;
      o( x9 k4 F6 F6 V( z% c* I
    1 s+ ~: @  ~3 p/ G+ n! r( U( l' D* tarrayCenter = [setup.roomDim(1:2)/2;1];1 v8 q; ^5 [: t3 k
    % j3 t$ c1 v0 K/ m/ A; j
    arrayToSrcDistInt = [1,1];
    % k, y: j( h- D8 K. j% H$ |$ r# d8 c3 Y; O: B
    setup.srcPoint = [1.5;1;1];
    - o0 i0 k$ ]( H
    , Z) q: ~: P- u% U+ p% k, o2 Esetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
    9 S( q: z( i4 Z4 C3 d. m+ W
    4 X9 M0 D0 w, y; m
    * }* L; I6 }) b1 q[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    / `3 w5 s& ~& `% H6 o) p* V& u; I& A8 ^
    ; P2 o5 y$ v8 Y5 x$ H%---------------------------------------------------initial end----------------------------------------1 q$ {$ P! c8 a% f$ h
    * e5 \" @( I& K8 l* u: y: X
    ( N- A& }4 @: p; S& p
    0 J  n- ]( [; Y- [- r5 F& x+ h% c
    %-------------------------------algorithm processing--------------------------------------------------
    1 R9 z, `7 r: {' o( B: v
    ' Q- Q) y; }2 C, d. c6 i7 tif setup.reverbTime == 0,6 J8 W7 l: v- s  {# V; k
        setup.reverbTime = 0.2;) W: ]% t  D) s2 E; M
        reflectionOrder = 0;4 K: m- {% [; i; H: E
    else6 h( s% S. S' g1 ?
        reflectionOrder = -1;# h4 g$ ]. ~" O, I
    end$ R4 l3 @3 u" V- \

    1 R* S0 ]# W% D* UrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...) y: W: q; W# Q8 X) v7 H
        setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
    2 M9 _9 I( j2 k6 G" i3 {
    + e# g) z( D2 |& a1 ?, M* H; Afor iSens = 1:setup.nSensors,
    . H: n" J9 V# t: d" Q* Q/ N    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);
    & k; t9 u) O5 p' w8 H6 T! Kend
    2 _, s& R8 U' C: g' vmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    2 I6 R; z2 Q0 [2 d/ {, ~setup.nSamples = length(mcSignals.clean);
    * X8 ^+ _' w% {: s# R4 H2 ]% [* ?7 b, _( w# J, J/ ?
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    / R2 z2 L' m& F. E6 ]7 f7 C% ^! |+ ?7 M7 b5 j8 j% U$ I
    %-------produce the microphone recieved clean signals---------------------------------------------: Z0 f( Y0 H) r& a3 N
    , r9 Q  s& R& \3 {/ i4 X
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    4 I. T4 L: o! r7 S/ |mic_clean2=10*mcSignals.clean(:,2);
    ' _2 }  H& C* r& d/ f1 Hmic_clean3=10*mcSignals.clean(:,3);
      G+ ?& c' X- n$ Umic_clean4=10*mcSignals.clean(:,4);5 H7 k% N& j  C, j4 ?' B
    audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);% h1 ^: _! p5 t
    audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);; V' \0 F9 C* s% x  H- G$ Q5 m) P* F
    audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
    , f; b4 k. q9 p. j5 z  I4 zaudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
    ; \2 k8 }" h! ?. i' O- _" I
    , }3 x! O. P2 b' u3 z%----------------------------------end--------------------------------------------------
    4 B; x5 ?$ B' X4 c" k; D9 q& x+ N! l& e8 l6 f4 I4 I
    addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);7 ^" ~$ S6 k8 p& j2 [3 J
    , N8 j3 ?. o5 U4 g3 ~! ^7 B- Q7 C
    cleanSignalPowerMeas = var(mcSignals.clean);7 v/ x& _8 n' T: v- b5 ]( c
    ' |0 w7 A+ s4 }! @4 a
    ; Y. C( U3 h% Y. ]! G, f9 K! w3 f
    mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...0 ]. d$ A* s7 A1 }/ Y- D
        setup.speedOfSound,setup.noiseField);7 P2 I2 ~* B# c. L
    diffNoisePowerMeas = var(mcSignals.diffNoise);
    " Z) ~" u8 n/ n0 m0 CdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
    1 G. {, [, @1 b+ F  e- p; L% H0 CmcSignals.diffNoise = mcSignals.diffNoise*...
    / f4 I! Z+ [* b4 [    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));9 F4 ?- d5 s/ T# k: Y$ m4 S: T4 b0 P

    / Q# d$ Q# z3 v+ k2 Q" `mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    ) {- L( ~1 K$ n5 {7 t2 X5 Z+ psensNoisePowerMeas = var(mcSignals.sensNoise);
    $ _: O: P  Q& f4 z( JsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);  _5 t3 X1 w1 p
    mcSignals.sensNoise = mcSignals.sensNoise*...; I5 s# Y4 ~+ [: r
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));  |, t1 A6 G' `& ~- }
    % S5 y3 M- f  ?# W& ]
    mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;; y% g% M# @  y6 q" a
    mcSignals.observed = mcSignals.clean + mcSignals.noise;6 O3 Q1 t9 l, _- G) V

    5 y& c) y. T2 `%------------------------------processing end-----------------------------------------------------------" B) I( G8 `) i$ V; A
    2 X% j% Z# M4 p# q4 O! p0 }% D) S- ]

    3 p( T4 i9 B# y0 k) V" m/ V# p* c- E4 n, x& h' G9 x2 P+ H

      T' s1 _& ]2 x0 v# Q6 p%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------' H" c% M. W% X

    : e1 Z& H+ h& }2 _4 p4 j2 l/ snoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
    ! k9 Y* x3 Y. }7 U, ~! Qnoisy_mix2=10*mcSignals.observed(:,2);
    . j5 c. u; W8 G# J3 A' n( @6 D) f5 b3 Ynoisy_mix3=10*mcSignals.observed(:,3);
      M4 z2 {& L5 E- {1 Gnoisy_mix4=10*mcSignals.observed(:,4);: S' q# J/ H7 H2 z' P! D2 n4 q) ^
    l1=size(noisy_mix1);
    " j) Z6 J" Q& g( Sl2=size(noisy_mix2);( ^+ `. D! }6 }1 J
    l3=size(noisy_mix3);7 e+ a) v* c; `* U# ^
    l4=size(noisy_mix4);7 `) u$ s3 \2 H1 _. [
    audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
    ! \5 q! U" X% u5 x8 p. {$ N) ?audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
    9 o0 A% n. S* O7 c, l- |  w& B, Q& Vaudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);4 D+ {0 j' i7 b1 |& t! p' d* [9 H
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
    , ^2 \; R2 V+ L
    " A$ u0 H7 [6 l2 O0 L) F) y  A$ R  \7 |
    %-----------------------------end-------------------------------------------------------------------------
    ; ?1 B- ]2 t& J/ ?& \- m这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。; Q2 K0 s1 k1 ^
    直接把它们替换成你想要处理的音频文件即可。% z! f1 b6 `7 m
    0 @# @) G4 `! N
      除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。6 \. ^' |2 ~  I, c( o

    2 z4 K/ a, [& m# G  m2 w2 t- J4 s$ ~8 _  B) L1 q: q
    8 i' K' ?0 }' N" \  o1 W* W
    图1 麦克风类型图
    4 m6 V- N% A/ ]; A( E, Y7 Z* I; k" Y( T
    图二 房间的坐标系4 ]3 I/ Z& {) ~" B7 b5 o

    8 Y  g; v" d3 Z  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
    & C8 h* u, y* V/ B7 ~. X————————————————
    , p' I' b. G& ?0 A3 h& c版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 D+ {7 w5 j7 [
    原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
    , {1 P; c5 j1 B; m+ U
    $ v% l; p  N* ^9 l* |; N7 K) O4 x8 V
    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-9 13:28 , Processed in 0.375740 second(s), 51 queries .

    回顶部