QQ登录

只需要一步,快速开始

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

      B8 a4 w2 G3 `9 ^. r%-----------------------------------------------------------------------. t0 S5 V  Q, t# P* o
    %  Producing the multi_noisy_signals for Mic array Beamforming.
    * H* y9 W0 c+ L/ [# g% 3 s" Z5 H2 }* |$ Q$ Q, Y' k
    %  Usage:  multichannelSignalGenerator(setup)
    0 |; E" ?- {7 i! Q# y' r" l6 D% v" l. f%         
    ' o" |5 r8 G1 {1 Q( R( H%        setup.nRirLength : The length of Room Impulse Response Filter
    . o. O% Q" K( i- E%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
    + j, ]! ^# d9 D! M%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.3 L) V; ]5 X0 s$ }& p, [
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
    1 o/ l0 j: p. i' D%           1 h5 W  Q; u. h# F) s! Q9 Q
    %        setup.nSensors : The numbers of the Mic
    7 A; Z! W! [& k) N" P%        setup.sensorDistance : The distance between the adjacent Mics (m)
    2 Y* r; ]7 D+ J  W; l%        setup.reverbTime : The reverberation time of room
    + |3 r2 B1 e$ Z: p& x. J  D. k1 Z1 T/ C%        setup.speedOfSound : sound velocity (m/s)
    / {9 }' m" m: P%6 K- Q0 m1 X7 C2 |/ U$ {* Z
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    6 ~, m1 f: H; y3 l( |5 y%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.4 x* [+ d& y% L. K( o# j
    %        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
    ' \2 V) C# n% n; P& a8 |%/ k4 `" h% V$ f* ~4 u0 ^
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
    ; p8 m9 Y" Q6 b%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). / ]" [! S. U6 s0 q* _3 [1 u
    %        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m).
    . e2 Y7 K" R! C) @%
    / w3 l$ ]  X% T1 ]%        srcHeight : The height of target audio source5 f. K# a8 h( M$ }
    %        arrayHeight : The height of mic array- o9 u7 c- U2 t9 W7 V
    %
    ! L+ I* o, M( ]& T( L! ]* k3 s%        arrayCenter : The Center Postion of mic array
    0 g) e5 j+ F  l$ t( J3 x* D%
    ! v; x7 u7 r4 V' N, W%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis9 L) w7 v" E0 S7 I1 Q. e: e" {# ^
    %& d7 ]6 P4 ~4 U+ [- k$ J; }2 f  m3 Z
    %                        ) U2 i" h3 e7 z( \* o% m4 h
    %
    ! p# i0 z0 X1 ^0 x; s) [%# `' o* ^2 O3 {0 Z) S- E8 \
    %         
    . C& f  o+ D' i4 Q5 t: ^# |%8 v3 y2 Z/ ^+ e$ c6 ?: \
    %  How To Use : JUST RUN
    5 y8 R; y8 V* s: e2 S8 M4 [%
    8 C7 _- X0 E  L7 ^" ~$ ^- F%  
    5 x" [& p: L. U$ O; a* d4 E* Y%   ( C& K* J8 ^$ L  h
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),7 r. E' j9 v  s+ `6 O7 C9 H
    %            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    3 n$ a/ ^, ?0 u; y; `1 m%+ `' ]7 `$ B) u+ b& V9 }+ G) W9 Z
    % Copyright (C) 1989, 1991 Free Software Foundation, Inc.$ d; b. o; B2 G' ], x
    %-------------------------------------------------------------------------; m  \  B: s: H" q2 i
    + _* t- P$ h8 ^6 _; c4 p* O* u

    # o5 Y1 T7 l! y7 Z4 R& n
    $ q6 @3 t* _8 \7 `addpath([cd,'\..\rirGen\']);, k, G- b& V/ l, D

    * T$ S2 _" \/ d" p: H%-----------------------------------------------initial parameters-----------------------------------% w, P( V- W. u4 u/ {% j6 P

    : ?6 _* U0 O2 Lsetup.nRirLength = 2048;
    / X+ I5 ^3 U3 N$ r4 x9 j; T- ?setup.hpFilterFlag = 1;0 u* `) g; l) O2 W4 w  t7 a
    setup.reflectionOrder = -1;  F- k" N; w# H1 v' x: |
    setup.micType = 'omnidirectional';
    % ^6 o! f% X% H2 Usetup.nSensors = 4;6 a& M4 t( @& m3 c' Q
    setup.sensorDistance = 0.05;0 L( @  a! u( s. ^$ A
    setup.reverbTime = 0.1;
    7 }; o% V3 G3 i8 K( Tsetup.speedOfSound = 340;
    ' B0 `/ J% Q1 v2 G5 b% i
    / D1 S  d' R" L+ Lsetup.noiseField = 'spherical';
    + _8 r& y& e* N! l8 ~& ?setup.sdnr = 20;
    % e% R: K1 w) G$ p, W4 Isetup.ssnr = 25;: m; Z' r& ]+ @1 W+ q

    $ b/ |/ l- b7 p0 a0 [8 {5 j3 xsetup.roomDim = [3;4;3];) C* j0 R0 P: T

    $ T; Z, U5 [( N, Q* `srcHeight = 1;4 O8 P) h) y4 D! d1 H/ p- y
    arrayHeight = 1;) N9 Z" p* i* e

    4 d- S! a$ w$ k% B1 U8 Y- ]arrayCenter = [setup.roomDim(1:2)/2;1];  o8 i) g/ l2 N9 u

    ' o% d; j  |- oarrayToSrcDistInt = [1,1];
    ; V) Z7 n! U: N+ v0 Q3 V
    ! V; E+ w7 n/ R/ p& Y8 Hsetup.srcPoint = [1.5;1;1];" X: `' Z0 `' d0 G; s3 {) C4 C* l
      Y4 }$ U7 \, C) J( K0 I1 ~! h8 j
    setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);; `; ?7 @3 h& r/ l  s, U! k% g

    ! O9 J  z3 F; l; r& ]% [5 v! ^! d2 X( i& h% S7 w4 B# [
    [cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    0 w+ G& q: a4 Q" R) Z
    - s( `5 S$ Z- j, C) |' W( z%---------------------------------------------------initial end----------------------------------------  O7 z6 l& ]) N8 ~

    + h; V1 A) }" Y9 q  W% O( r) O
    # @7 d. U& Q% c- Q  C. }
    : e0 _5 M) A, `8 W& S+ Y" \%-------------------------------algorithm processing--------------------------------------------------) u: j' b- P- x$ T  f' b. B) S

    7 z% q& R9 c- ]8 ^. Z# B+ P5 X, tif setup.reverbTime == 0,; X7 E0 i2 Q( S5 }! T
        setup.reverbTime = 0.2;
    ! D* w3 w' k6 r  c- A! a    reflectionOrder = 0;
    + E1 Z% J6 K% {2 {* B0 }  b! \else
    * l. w, g3 \- c6 e+ J, \' Z+ i$ _    reflectionOrder = -1;
    5 r- v" G, ]1 @8 C4 D/ a- b$ Rend
    # C7 [- G! j0 j/ |7 j3 r, _6 k) @
    8 \& S" q$ Y4 i" u* M8 K8 HrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
    2 c; B2 L2 v$ p0 W' y) ?. i& D    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
    % o  j( I; u4 ^, x% O$ A9 ?) z/ m* q7 Z9 v+ ?
    for iSens = 1:setup.nSensors,
    8 j' @, Q7 K6 M7 M6 [' ~    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);
    % U' d. D" V) @0 U! ^. xend
    2 O: U1 F( Q. c' D4 nmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    0 r" t# _" o  Y" f/ R1 s0 q# csetup.nSamples = length(mcSignals.clean);
    % j: j2 g* h. _) v, d3 h4 q: w% R2 U/ M
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);0 B2 a, X* m. A

      u$ A. U# Y, F8 j9 K%-------produce the microphone recieved clean signals---------------------------------------------
    + D" l* |9 _% N6 ]) g, W9 u! G5 @# X7 o8 t% Q# A8 `! a5 K* }2 u
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    0 y  C+ K$ o2 D( Dmic_clean2=10*mcSignals.clean(:,2);
    ; I2 i  l% r0 R$ Q& Q' v1 imic_clean3=10*mcSignals.clean(:,3);! ?3 t; {: M9 p
    mic_clean4=10*mcSignals.clean(:,4);: K5 }! o9 M9 [7 i' w
    audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    ; Y6 C" y: _, iaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);! @2 O/ X6 s; `  R! w  N
    audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
    0 ^# ^8 O' J0 Z+ ?7 s9 E. aaudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);$ U8 j, h7 W. Z% S* w, x5 @9 `

    9 W: P3 ]& B/ d/ P%----------------------------------end--------------------------------------------------
    * x, U% [! J( Q" q4 \% n1 ]2 v* N- C/ _5 w/ H
    addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);2 s! T% L; r& E+ r
    7 ?: ^5 s3 x% \; N$ Y! G
    cleanSignalPowerMeas = var(mcSignals.clean);
    , N8 U6 E& V' A) d) r. x  p5 H7 z& Y
    + x( t  K. W( r' P7 [
    $ Q' e7 v, m2 o: ?5 HmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
    # ^: v6 O; E% ~8 |$ v- u. \    setup.speedOfSound,setup.noiseField);
    - m, b7 ?$ c5 n; g" C7 i5 tdiffNoisePowerMeas = var(mcSignals.diffNoise);& H3 n1 [# F4 ?( C" U8 h( B
    diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);& k, e! O8 P! c; M) T; U% X% d
    mcSignals.diffNoise = mcSignals.diffNoise*..." ~9 K7 [  R5 B
        diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
    " v& w- N2 @% b) U# m# g, A& J! q7 g$ K+ j  p# c
    mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);  G  n( r2 {. `; Z, G
    sensNoisePowerMeas = var(mcSignals.sensNoise);9 q" N% Y( ?3 {+ [
    sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
    . Y5 y( I$ J# \! B9 `5 ~mcSignals.sensNoise = mcSignals.sensNoise*...3 D! @9 X4 d9 D& B
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
    8 }8 i" |, D/ [( g2 g1 J" c. Y8 H& Y  g/ Q& h: h, l
    mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
    * D/ i; r/ H$ z) l: G; U  @mcSignals.observed = mcSignals.clean + mcSignals.noise;: ^, K# D2 {# S# |# B+ \

    2 S! v+ _) Y- Q8 M0 Z1 s%------------------------------processing end-----------------------------------------------------------" ^& l/ P5 |6 l) |* o" {

    0 W/ L5 p2 F) A3 E4 [& l1 y) R) T& \' ~7 d

    0 ^7 }! C) i' [
    ; O# I& w! ]$ D( C) a( u, P0 T, u%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------( X7 L+ c; x1 S0 i7 `' T
    4 Z( ]) o1 R0 J6 j
    noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
    5 J' ~! R. m0 r# M3 K% H' r" V% T- Tnoisy_mix2=10*mcSignals.observed(:,2);
    # K0 I8 j9 h' H+ M0 Anoisy_mix3=10*mcSignals.observed(:,3);
    5 p+ [5 e  e: t3 l! ?- Inoisy_mix4=10*mcSignals.observed(:,4);: A) Z9 R7 M9 P5 s/ N
    l1=size(noisy_mix1);
    ' J/ h$ r/ T9 M2 z7 `8 Ql2=size(noisy_mix2);
    % N: S* G, m7 {( O0 u5 wl3=size(noisy_mix3);
    ; G* C: A: ?: @) ml4=size(noisy_mix4);$ v* b* D5 A* R5 V8 c9 v% L1 z) g7 T
    audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
    1 n. m! ?9 i4 P; v6 c! k" Naudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
    + k; y0 J0 d, `audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);0 A6 {9 p$ p* \% c. M3 O" S4 d
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
    . ~( J# o/ t: d
    1 N  H( w& G3 q) c& L( k$ h) L; u; r7 N2 r
    %-----------------------------end-------------------------------------------------------------------------
      G# u2 k2 B) x) }这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
    $ v4 ~5 o# L7 O  Q( g! N, A直接把它们替换成你想要处理的音频文件即可。
    $ n, E7 N5 H% X) c: \  x. o  l2 s% 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)。0 k* m+ j  V* `; S

      r' X7 j: X; m5 v; Q- v; ^  G5 D3 [/ U+ F( L8 @

    8 ]- S$ w( U/ N, D图1 麦克风类型图- q6 i; b* m3 b+ S1 S7 I3 ?
    $ `/ h& V5 X+ Q7 O$ b" q$ y& f
    图二 房间的坐标系' E; J. P+ @& K: R+ Q
    ( U* ]7 }+ b$ ]$ @& L6 w) z
      以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
      @! X5 Y$ B0 U+ j" }& u: h————————————————( l, W) W. o2 a; u+ M8 ]  j% U6 @
    版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。4 q6 P# m/ `& D3 U& |8 b
    原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
    1 V) {/ q# d9 U* B# w- ?7 q2 ]* S. H
    : G9 X8 k4 Z  O- \# s
    ; |) X- r: s0 W1 P6 T4 q& R. G
    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, 2024-4-27 08:36 , Processed in 0.405016 second(s), 50 queries .

    回顶部