QQ登录

只需要一步,快速开始

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

    ! y! t; ^7 `- ^& F7 F( W%-----------------------------------------------------------------------4 {, B9 I/ Z- z6 g- j( j
    %  Producing the multi_noisy_signals for Mic array Beamforming., i9 \; h% w# P  G3 ~
    %
    / P9 \5 g+ ~! a3 E, Q3 U%  Usage:  multichannelSignalGenerator(setup)
    6 ~$ g0 N* @, L: q$ l- m%         
    9 \3 D) i, ]5 B) m1 v3 `%        setup.nRirLength : The length of Room Impulse Response Filter( W  k& z. ~  ^/ n" y
    %        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
    ( _5 Q/ n' L( H- N%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.  X9 n! H; T( }* L* x
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional., B) o% w8 ^7 @+ K/ K
    %           8 g* r" p  J' l5 a
    %        setup.nSensors : The numbers of the Mic
    - D2 `2 b3 K+ J9 N! Z%        setup.sensorDistance : The distance between the adjacent Mics (m)6 f8 P! x& z( A
    %        setup.reverbTime : The reverberation time of room
    * ~+ W% A" p2 u; n; r( A3 C3 r  C%        setup.speedOfSound : sound velocity (m/s)
    6 m" q1 y; m8 a3 [# ]%8 Q5 z0 J5 a1 I+ ~5 g
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical') ~3 h4 ^! i1 h7 b: H& s( H
    %        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.3 q' v! `. ?* V
    %        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.  E+ P' N1 Z8 o0 ~) f
    %# y4 v7 [2 |. j+ ?8 b2 V
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
    7 s1 J3 n  U/ }3 u1 Z. U6 q%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). / n' _8 W% H+ {! p- Z
    %        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m).
    0 w  `3 Y3 n# F%, A% C) C0 ~2 f9 o  z
    %        srcHeight : The height of target audio source: E) X0 Z6 I- ^: w) w: V
    %        arrayHeight : The height of mic array
    % n% i2 s4 O, f5 L& ^6 w5 Q: Z%, }, e5 M' D  L# N
    %        arrayCenter : The Center Postion of mic array
    + z) p1 v$ x( |5 g# ?" U) b& m%; r) h- G2 N) G/ Y( Y' }: v
    %        arrayToSrcDistInt :The distance between the array and audio source on the xy axis
    / d4 Q( O+ Y2 O. H# _%
    ' ]% E& x8 T3 o* K! O' ^%                       
    : Q& W2 p6 ~7 s$ @%
    # \, R1 O/ }: j1 E8 |+ Z, p%7 J# c9 n/ o; T0 H
    %         
    : z7 ~9 L( c. f% \# ^%- u- V' m( w0 w9 a& y2 p
    %  How To Use : JUST RUN+ Y' j& q# r# J+ o/ ^$ C- Q$ m  b
    %1 j* d  r& H! U' l0 h; y
    %  6 `: A, K! s$ _* P3 m) i% T. h
    %   
    / }7 b# u2 r! G0 d4 t) V% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
    1 p. p0 o# P! C& }- h" ]" Z%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.240 ~+ _" {6 Z& H7 R) W
    %
    / y4 v. Z' K4 y4 A8 V% Copyright (C) 1989, 1991 Free Software Foundation, Inc.. L* S* j- ], W+ M" K: X8 a7 U
    %-------------------------------------------------------------------------
    $ K/ F" i& Y5 @* g5 F2 ]5 p: O) k; F* Y3 q; n$ c
    6 ?7 X  |" D2 g/ N- f4 X; _( S
    " {( R! k# Y& e- b0 z" B# T
    addpath([cd,'\..\rirGen\']);
    6 u  {6 G1 U6 Y' }" m
    2 J. N7 H' E8 ~, Q( m) U%-----------------------------------------------initial parameters-----------------------------------
    5 i; x" q% s+ t" ?
    4 ~4 h" J2 K% l) hsetup.nRirLength = 2048;
    ; L3 Z3 S7 a0 K! G% e  r0 \setup.hpFilterFlag = 1;/ y- B: |" x/ e" E* ~
    setup.reflectionOrder = -1;
    4 f5 p9 B2 g* ~. dsetup.micType = 'omnidirectional';! A, M. {  P5 s$ s
    setup.nSensors = 4;
    * q( D/ Q) b# @setup.sensorDistance = 0.05;
    + b2 d* G+ o) S6 B, V: w; msetup.reverbTime = 0.1;2 j1 w/ ?8 S, q# Y# N
    setup.speedOfSound = 340;0 `% e. {( |* H0 I6 c7 K
    * g, w! y: ]" x- f3 O  V" V
    setup.noiseField = 'spherical';
    & t# h  O) V+ K9 y$ \+ Usetup.sdnr = 20;5 E8 c$ K2 z# c% {( F7 S3 }- H- t! i
    setup.ssnr = 25;
    : ^5 }! n" c5 ]( Y7 b! X, i5 z9 |: ^2 }" V) S
    setup.roomDim = [3;4;3];
    3 |/ Y7 F, y( v$ q) K  Z8 ]: S5 P9 M2 ?; V6 l/ J$ z' V3 U
    srcHeight = 1;* z8 O# Y5 F, w
    arrayHeight = 1;
    * |% p; L  Z' v+ Y1 f8 C8 G
    4 z: e- E! m3 j, t, C# D$ barrayCenter = [setup.roomDim(1:2)/2;1];
    - C1 M. U  Y; s! F3 @- g
    , A# Y+ J* k4 m2 i3 y8 @. NarrayToSrcDistInt = [1,1];
    + h3 |( D& o/ v: r' l
    2 x7 S$ R8 K! B4 I) J7 u: ?& fsetup.srcPoint = [1.5;1;1];
    8 c2 w5 U1 \( l
    1 z- |, h3 I3 K+ c, ]$ Msetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);" \4 k9 m$ M- U8 @* v# z. R' f

    + ]; I# p& |( f
    * f7 m5 x) f1 W0 D[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');! E& O, F$ i+ C9 S

    : V" J- E' U. @/ j+ u) f) S%---------------------------------------------------initial end----------------------------------------
    3 k: ]: v. d2 D& H# D
    % }; k) C7 a; r9 l' i5 @; m3 c: M, g) e* b" ^5 t( m
    / m6 q" V, t! K* b
    %-------------------------------algorithm processing--------------------------------------------------1 X- }7 P9 O7 d3 N3 [2 G( E, G. [
    2 U3 t6 w  L! Z) ^- z: ~/ E( Y) m, a9 m
    if setup.reverbTime == 0,
    6 M6 L( t9 V8 y4 g* p    setup.reverbTime = 0.2;) Q; ~0 d6 r( O
        reflectionOrder = 0;% V& U. N* i: s' M6 U- J
    else5 i( U, i9 T2 |6 l1 K# u0 Y  C8 _2 W
        reflectionOrder = -1;
    ! f, ?: F9 \% z, ~+ }! bend5 |0 [" A, O+ S9 ~/ J) t/ l

    6 X7 R) W- f  W8 I: s' y0 YrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
      j  q9 E" x7 z- v0 l7 ?& `    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);+ V0 B! z/ i* Z  W
    0 p7 ~. p! P4 U" U; G
    for iSens = 1:setup.nSensors,' X. @. C  ~6 }/ G3 r6 R) c+ A
        tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);4 d& x2 U5 M; t# |& X
    end
    - e; L8 L$ H  q3 emcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    7 A" B+ z' K  s) {9 U4 k& s& B& t3 Asetup.nSamples = length(mcSignals.clean);; H) k3 B) x' b) f) v
    / S# X$ d! ?: A7 d/ k
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    7 @# c- s, Q  q) [
    . [) q( A) z) ?  s. G) k: \%-------produce the microphone recieved clean signals---------------------------------------------
    7 p0 l6 b1 b7 o& V% _2 j% \/ ?! [
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold. M; _0 g# T6 M6 q- A8 l  K
    mic_clean2=10*mcSignals.clean(:,2);" C9 _$ d! x  ?$ h$ X9 Y( y3 U
    mic_clean3=10*mcSignals.clean(:,3);# C4 I* H9 c: u, Y0 c) Q% k0 j
    mic_clean4=10*mcSignals.clean(:,4);
    6 L/ Z4 `6 m' }1 [audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    - j2 m% B* E$ }2 [: N- Maudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
    " b$ f, ]4 z: v3 l& C; O  ?; faudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
    ( A, z9 _7 f. D, ~3 Kaudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
    2 V0 x; k, J) J( q% y4 W3 r" F
    8 N7 @2 J6 w' }6 H# M; g%----------------------------------end--------------------------------------------------$ ~: K- D# P$ M3 v5 ?

    4 i! n1 f. J" Jaddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
    - \) t8 X7 ]8 @2 I0 }' U
    : u! d1 Z" O1 V1 d9 I% t, _8 W" RcleanSignalPowerMeas = var(mcSignals.clean);
    8 C  o  H# s3 W6 A; w  i4 \, S& t) ], Z: ]/ E. s

    , q2 _( V) U3 W0 Q6 }6 kmcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...+ Z! z+ z3 m+ q7 L8 _
        setup.speedOfSound,setup.noiseField);" M7 p/ {: j1 ^2 C
    diffNoisePowerMeas = var(mcSignals.diffNoise);$ a% \; Y4 a% z9 f- @+ n- n7 J
    diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);& ^; P" |) \; R/ l7 s! ]
    mcSignals.diffNoise = mcSignals.diffNoise*...
    8 i) Y" b$ B. N" ^0 a' G    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));4 w" N! Y6 S. I- u* {( V# C7 A
    7 o, \4 g) Y  W
    mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    8 W) Q" C( L2 W3 c- H1 rsensNoisePowerMeas = var(mcSignals.sensNoise);& L) z( p! L  Y
    sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);: v1 Y: y- E- T2 y
    mcSignals.sensNoise = mcSignals.sensNoise*...$ H8 H. t: [- p! O% x; m2 |& D. A
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
    9 s1 c. w1 @. K+ q
    " l" y# T. t. ^7 d# UmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;2 _# r' n# u9 O" ~
    mcSignals.observed = mcSignals.clean + mcSignals.noise;
    + A( J% l' ?5 E6 B& U, H4 w6 V1 Q! S; [- Z  K; p4 x- g
    %------------------------------processing end-----------------------------------------------------------
    7 A. a, q8 W: `) M& M% @+ ?2 ?# A# N5 f; ]
    8 N7 q6 V) z5 b( B2 h

    . d0 C2 B$ F3 K1 z$ g
    4 g+ J- O9 V+ s, S%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
    ! a0 U- C- M2 ]: I" Q( k: x
    4 N3 ], t3 |9 I( }$ A& s* l3 L9 Dnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold
    3 B2 W4 P, V% c0 Lnoisy_mix2=10*mcSignals.observed(:,2);. a4 i- k1 D- _0 A, `
    noisy_mix3=10*mcSignals.observed(:,3);
    1 H: ]  D: }& ^" l9 e( S! Z7 v4 b" Gnoisy_mix4=10*mcSignals.observed(:,4);7 f9 A1 N- `3 r- Q
    l1=size(noisy_mix1);+ D; _) X& [6 P
    l2=size(noisy_mix2);. G9 }7 A" g' B
    l3=size(noisy_mix3);0 o3 G2 O$ \. N% C+ V/ F3 O
    l4=size(noisy_mix4);& w, [# [6 d% G0 J( O- V+ ^1 N
    audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);+ i) Z5 k3 i% g
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);: e7 @  l* W4 G, i
    audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);3 U3 n* j2 @* \
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);
    * w9 ?. Y# X' U# E" R7 Q" ]- S- y; X8 D6 J- T% e
    5 j+ T* l6 B& S4 K: Y4 y/ L
    %-----------------------------end-------------------------------------------------------------------------
    - ^' k% h4 i( w& p& {) D1 V这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
    0 q' E) Q( i+ J4 d6 q! ~4 f( @直接把它们替换成你想要处理的音频文件即可。. [) A( t- K; Z3 T- s( T
    5 n( K* z" c  }4 x
      除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
    # z1 H1 G7 X8 m6 m
    ; y5 p: q7 u+ V9 H. U2 L0 O
    4 ]  a( z7 t0 R2 P7 {, ?! [2 `7 M' Z) a9 T8 s! h9 Z
    图1 麦克风类型图
    7 Y* q% k6 ]$ s5 h, A! `9 B1 W! r  r: P0 [. T
    图二 房间的坐标系
    2 t. f; l( C; M
    , f; Y% q  L) a2 |  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。6 Y1 q& W; I8 P& B8 z# b& T
    ————————————————
    ; e7 o. n$ w: X7 v% r版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。0 d' j: a) H5 X# P2 U9 y& z3 d
    原文链接:https://blog.csdn.net/zhanglu_wind/article/details/796749980 O8 t- N. d5 a6 z* z
    8 ?6 s- z6 p" S& s% m
      }8 @  _- X- K0 w3 t! 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-10 06:32 , Processed in 0.426249 second(s), 51 queries .

    回顶部