QQ登录

只需要一步,快速开始

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

    & T2 s+ t$ K+ Q0 J- L4 B* c2. 代码介绍
    " J+ \$ a) o1 S0 n+ [2 F  原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
    ( j# v- S6 }7 ^, [function [mcSignals,setup] = multichannelSignalGenerator(setup)
    4 A& ?$ K- @' O% k$ h' J, b( Z) Q7 |/ x
    0 x4 @2 ]1 I6 P! F' O
    %-----------------------------------------------------------------------
    1 H5 Y+ q$ \9 F9 T' C6 w- D$ k%  Producing the multi_noisy_signals for Mic array Beamforming.) Z* k: p0 K! S6 V( b2 s" n
    %
    & ]0 [* m# [! Q4 p; B- l4 _. t%  Usage:  multichannelSignalGenerator(setup)- h& f) v; {% o
    %         
    7 `2 \' F' V- C# e$ J% U%        setup.nRirLength : The length of Room Impulse Response Filter5 Z$ M* M/ [* h2 ^! f
    %        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
    . v) [, \; Q( A%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
    - x  _. m4 T7 u" ^5 h4 F* z%        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.7 K9 N8 [1 \2 z, t! ?" T5 a
    %           
    0 A/ {; e) q/ R! B%        setup.nSensors : The numbers of the Mic7 o2 ~  G& ]+ }2 ?  l5 B$ }
    %        setup.sensorDistance : The distance between the adjacent Mics (m)
    ) _+ A" ?& }' |9 q' l' m%        setup.reverbTime : The reverberation time of room
    8 L9 l0 B) _* k% ?%        setup.speedOfSound : sound velocity (m/s)
    2 C+ j3 h% h2 o/ R" W%( y7 I3 B9 m1 q- H
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'% i7 y7 t, E5 Z( n( [5 W- D- `
    %        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.' d' ^, j) P1 }4 W4 |
    %        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
    / E7 N4 m7 ?, O# O3 Z1 ?" ^%
    ! j# T7 o, @0 ^& W& e8 ~! A% z%        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
    8 a0 V, b# y/ }# |8 b; A. p" L2 p%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
    , f$ I9 @( |. Y" X  [%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). 2 {4 S3 z$ ?( e
    %0 F- n; R! b) s7 [
    %        srcHeight : The height of target audio source
    - V1 H4 W2 Y( W/ E%        arrayHeight : The height of mic array
    7 W& e$ N3 a- O%6 k0 h: R; h$ c( M% L; O6 G6 t" ~
    %        arrayCenter : The Center Postion of mic array , e5 G" l% |3 p0 t
    %
    * t( v0 }8 o, ]' p* o6 z%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis
    + @6 F( K8 v1 u; s. [4 a4 [%  Q9 W  r6 |( Z% w0 }! v
    %                        3 V$ W5 u" y3 m- P  j! z/ v* [4 D) n8 Y
    %* h$ v. L0 b$ q/ G( ~' w: T
    %: P0 o9 m7 g( n7 |- r2 a
    %         - j9 {2 a* @# h1 Q
    %
    / }: }6 Y- a2 |6 h3 {%  How To Use : JUST RUN) `, I* n* m" U+ S) \
    %- o% @/ z, K( R+ ?
    %  + d# r4 ~1 v6 j8 z) ~
    %   ' C; S% @: l6 |* z! A2 B
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),3 s6 Z, f8 X5 c, i
    %            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    * J( a" J1 J& ^%
    ( N- @9 q7 f2 H6 U' g( S% Copyright (C) 1989, 1991 Free Software Foundation, Inc.1 ^  n3 W8 C2 K( B% j. V2 i1 q$ \
    %-------------------------------------------------------------------------
    % d9 p1 |9 g2 O6 }( C+ c. C& \# w, q0 I) N& u2 W$ {- h, T7 U0 }

    7 @4 }  C# l! z! k* w# X
    3 A' O# V, c; p5 Z! Laddpath([cd,'\..\rirGen\']);
    1 a, ^0 f% P( p6 M5 {. _' _+ K
    - q6 _3 E+ V$ z- Y/ {%-----------------------------------------------initial parameters-----------------------------------; a- a: w) o6 G+ Q" T2 ]
    ( c9 s$ `+ `+ g9 e/ `
    setup.nRirLength = 2048;
    $ S6 V7 {( f7 B: h$ ?$ M- n/ rsetup.hpFilterFlag = 1;0 Y- Y3 v- w$ C8 M7 O* i2 K
    setup.reflectionOrder = -1;
    7 h9 ?7 ]7 S% w. Ksetup.micType = 'omnidirectional';  K5 o' @2 r! f; `3 k
    setup.nSensors = 4;, R/ _5 }6 B4 a) P9 p
    setup.sensorDistance = 0.05;, C8 c# O. I( I8 W4 a  H: c
    setup.reverbTime = 0.1;
    " O+ ~" z' Z$ P, z4 Gsetup.speedOfSound = 340;
    , B8 p% _9 W+ Q  H0 b2 [9 I; I; U! k/ K/ }
    setup.noiseField = 'spherical';
    * _6 L0 w$ s3 h* o; }0 `) ^setup.sdnr = 20;
    / @& J5 p3 I# `! Ssetup.ssnr = 25;/ K( h. F  h8 Z4 B. ^$ U1 P8 @+ D

    - v% _) j- l5 D: \" Bsetup.roomDim = [3;4;3];$ l# ]0 h% e9 B2 T

    ! d; x, N9 A; b5 K6 e4 h( p9 d& TsrcHeight = 1;
    - h" i" T3 @  h# w! h2 narrayHeight = 1;
    . Q  g. U8 F8 U( Q* i" a* Z
    ! `' o& u1 v, g! f1 \9 t+ BarrayCenter = [setup.roomDim(1:2)/2;1];
    2 l, {3 f% }. A: k! F/ I9 r3 J4 y# A$ c- ]
    arrayToSrcDistInt = [1,1];( a, Y* \5 z9 I0 b+ R
    7 r. V" d$ |' M* k
    setup.srcPoint = [1.5;1;1];
    % O' m: d) n4 D/ l6 ?. d# N1 S1 K8 ~" X& N: e7 O
    setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);6 r) q: ~; o1 o' y& T8 h
    9 |+ [) ^" a3 R$ G

    , q7 s3 n& G+ R* a/ S* l9 ]# P[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    & E( L& g" s, j8 M% Q% ~- h- h7 m, S# t; q
    %---------------------------------------------------initial end----------------------------------------
    . \9 M6 l5 `1 |" s, A7 H2 W
    & |/ {( B' l& t. q
    / r( z6 X8 X0 W, N+ W
    * N" D, D! ~3 d" U6 L# U! {%-------------------------------algorithm processing--------------------------------------------------3 k0 t- P6 E/ X- u* }; C

    * l8 r! G) J' D0 B. Wif setup.reverbTime == 0,' x, y0 j7 @! \% v7 g3 @# }
        setup.reverbTime = 0.2;
    + ]$ P/ V4 @( h    reflectionOrder = 0;+ z6 n) A" v% N
    else
    : D4 w7 y$ Z0 c) C    reflectionOrder = -1;% e$ e9 m% ~" a3 ]8 O! h
    end2 H1 `2 ~9 ?3 ~1 ^" m% w

    , J% X6 Q8 ?+ D; n1 MrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...6 o3 e0 P' f. @! n6 x
        setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);' K$ h& c" H  U# K

    3 u- q0 b4 s2 r1 \& _$ rfor iSens = 1:setup.nSensors,
    0 K. q# G$ \1 z$ X) R    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);
    ' d3 c8 M/ P5 d9 ?) X9 s+ ?end
    8 C6 v. x. U4 @2 I5 l; jmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;. C& t7 X7 ?* s. n+ ?' L
    setup.nSamples = length(mcSignals.clean);. t3 q* J5 U# v; D3 v) ~& v5 k
    ; y% i& I$ [) P! |9 Z
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    / V" @6 z1 O. Z/ e+ z. r, i- S+ O' U) ~, A
    %-------produce the microphone recieved clean signals---------------------------------------------! @1 U8 }7 A% J! m+ F+ t8 N" u
    4 T; H. D5 D: R: K; W+ I7 s
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    + e2 L$ b/ @; `0 Q( Mmic_clean2=10*mcSignals.clean(:,2);+ g: O9 n1 Y% O  ]3 m+ g2 V3 U
    mic_clean3=10*mcSignals.clean(:,3);  \! Y* B# d4 [+ I* Z4 R6 [
    mic_clean4=10*mcSignals.clean(:,4);
    0 [, H& t- p4 P. `audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    " X) {7 b# X6 v$ q+ q1 raudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);; x; K( N6 y- x2 m- o* W
    audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
    + u3 |( `3 }$ j3 l, ~2 k  E$ zaudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);, U: ~+ X1 G- T9 \3 }& ^% j" J
    : }5 K/ b8 Q* @$ M
    %----------------------------------end--------------------------------------------------
    5 J! [4 a- A8 d3 J* J( B( f
    1 J- r. {0 c* u# r+ A4 O# M' xaddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);" D& M/ G0 I% g% \1 D* `3 ~, J

    ) m; h+ P# C* M) d4 P, x7 d% o: `! [cleanSignalPowerMeas = var(mcSignals.clean);0 F8 ]$ `, v( n- z, X

    ) ~$ K$ [, N  g9 b, a
    # u* {% `6 ]0 E! \2 M1 ymcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
    - h  O0 ?  h* I4 k    setup.speedOfSound,setup.noiseField);7 X, n9 |+ H4 h& z9 M
    diffNoisePowerMeas = var(mcSignals.diffNoise);8 U0 I+ E$ D& a4 X$ Q
    diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);8 }* f0 J7 K& x2 B9 E# B6 F
    mcSignals.diffNoise = mcSignals.diffNoise*...
    ; h3 K# u" b' @  r3 F    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
    1 F& d8 x; @4 J3 s1 L/ P
    7 d4 j6 z6 C' W1 B# N& f  \mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    # t" R+ _9 r) v1 o. w+ m$ E6 v' msensNoisePowerMeas = var(mcSignals.sensNoise);5 O4 U1 c! ?& ^- q) S: H6 L" b
    sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);. \( y, a  H5 t4 |! c  A: l  }
    mcSignals.sensNoise = mcSignals.sensNoise*...
    % o2 J" F! a* G% b1 c- H% Q; h  J- m    diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));0 Y1 @0 r" o7 Q* `. N- W* {
    9 A: W4 q) [3 O- w% ~0 h( b2 f* M
    mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
    ; C5 B* U8 _" ]3 G( e1 t  J7 wmcSignals.observed = mcSignals.clean + mcSignals.noise;/ c! e. }! P) V! m; Q
    7 `8 k& L' \! H( z: O
    %------------------------------processing end-----------------------------------------------------------7 M: w" L% Q( O. o" _3 y9 P
    ' r% A5 q8 n: A8 k

    ( L! f# k& Z  C- ]) Y) n$ }$ G$ @5 x
    2 Z0 [( Z/ n8 C5 \8 U7 O9 m3 i, X% _- g; C5 Q7 V# k9 `
    %----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
    % T. g+ l: \, u; |2 A6 t
    $ G9 e1 V8 W% R* qnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
    & l- I! f& G2 h. lnoisy_mix2=10*mcSignals.observed(:,2);+ Z. g' \$ u: @  m/ _- [. P
    noisy_mix3=10*mcSignals.observed(:,3);
    . V4 s' L4 s4 ~/ f) ~" {noisy_mix4=10*mcSignals.observed(:,4);
    # I3 t2 `/ o7 Dl1=size(noisy_mix1);  m, d! J' ]" [" y# H1 e
    l2=size(noisy_mix2);
    0 q5 n" R: ]+ S. ?l3=size(noisy_mix3);
    + q( i! v4 I3 o" C0 O% J6 [5 pl4=size(noisy_mix4);
    0 O* t- L$ f7 u5 b+ l& baudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);# G; l- }, c1 R, Q
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
    5 H! s* v% |/ V0 q" {, x, daudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
    $ c, Y- Q9 C; B, p) B$ ]0 o. b* eaudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
    0 T' l6 a/ k( @/ @# b2 w7 O5 Z$ F6 r0 x5 A' q1 v4 w" ?/ ^  C

    9 o: H5 \4 m5 `' ]# j%-----------------------------end-------------------------------------------------------------------------7 c* C. r7 w5 Q. l* o) a' p
    这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
    2 [) Q( V6 s: U' s+ ?9 z直接把它们替换成你想要处理的音频文件即可。: U5 N; ?9 L0 Z( ?- K/ K
    8 K: R, o# q0 J. @6 Q' `
      除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。; A. x$ b! D/ ?0 O5 C. a' n

    0 N0 n$ x. w/ _4 c- X4 ~, R7 T  d9 E& F' ?7 T2 A

    0 f7 J" u9 h8 P1 w4 s图1 麦克风类型图3 Y6 O( j) S  y' H

    7 E& b( Z. \, |' }. b图二 房间的坐标系$ A8 W' b9 C. R9 ~  X1 b

    % o0 v, a8 I0 F2 [1 n  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
    : o, Z  Y/ f* D8 o————————————————5 W/ c: `9 Y& Z, r7 L
    版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。4 c1 ~' j$ s1 m1 `
    原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998, z9 ?9 }; r: N# q2 d! y$ y4 ?' K

    + `/ i' Z8 D" c9 G: O( o6 F
    ! h: M5 ^7 T  n( E) N  q# ~
    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-14 06:54 , Processed in 0.398993 second(s), 51 queries .

    回顶部