QQ登录

只需要一步,快速开始

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

    9 z, o! Y3 O( E% y. N2. 代码介绍, y: I+ I+ t3 n2 d! P
      原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:9 V- K8 l" V8 R* l/ P; {
    function [mcSignals,setup] = multichannelSignalGenerator(setup)3 p4 p8 G7 K8 m' P, R7 s; w' M

    8 u3 D" a, w! x) v% N+ @  C2 x8 a. o
    ' W9 h" w5 T; k) ~# ]8 Y3 T6 a. Y( u%-----------------------------------------------------------------------* x4 W1 r' c0 k! f2 Z) w9 C2 z3 P
    %  Producing the multi_noisy_signals for Mic array Beamforming.
    6 q* V1 M/ _  H  [0 V% # }) F3 G/ [0 W' J4 m4 [
    %  Usage:  multichannelSignalGenerator(setup)  f* D8 r6 M. H( s% y% J
    %         
    , W" ^- v$ C, n3 h; G%        setup.nRirLength : The length of Room Impulse Response Filter
    2 t$ g; S) U( ]2 p% \%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default- b$ V1 q3 m2 f- f: }, `
    %        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order./ ~5 h; O& E4 L/ G% ~0 l
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.
    3 }; z2 y5 n" t%           
    5 w1 H' D; L4 a; q" r: Z$ `%        setup.nSensors : The numbers of the Mic
    0 s3 ^- t8 {! \+ }2 X. t, b) O%        setup.sensorDistance : The distance between the adjacent Mics (m)
    & g1 R. s% {9 ]$ I" l%        setup.reverbTime : The reverberation time of room
    4 [9 ^: I1 R0 V: D  n) W9 `7 T%        setup.speedOfSound : sound velocity (m/s)
    0 l/ j; G5 S, v; Z3 z* x2 x$ g) x%# n$ I2 i: ~0 i8 N' E' e. |
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    0 c7 B3 L) W! W/ C8 U* ~%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
    ( j5 I) s3 X+ C  n8 B3 w%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.8 A5 m% [4 y0 O0 r; |
    %( |. E- L8 B' h0 J
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
      j8 [" t2 N2 ~) l%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
    7 r3 u# V' F( k) F( Y# I%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). 3 g+ B2 S- b/ `- E
    %
    8 Z) U$ H# ^" D$ h8 ^5 t3 Y%        srcHeight : The height of target audio source
    " _* V5 |" {* M/ g* g6 G%        arrayHeight : The height of mic array+ C, J$ _5 n% C. r1 i: @, k
    %
    : V; c! _! e# M! e% r$ d: N%        arrayCenter : The Center Postion of mic array # J+ \0 `6 `: [" D" q
    %/ ]4 h, Z  {6 f! s* U6 m4 v& D
    %        arrayToSrcDistInt :The distance between the array and audio source on the xy axis
    : M( u( o4 L. {, L( {! f%
    " Y8 `4 }# y8 h+ ?5 H%                       
    ! ?/ ?" v) {$ F8 m  h%
    7 K9 _' g  J% {( v3 X6 p- W%6 }0 F; y5 b/ y. {# f- N& ?5 S
    %         
    $ a7 x* \, I# M+ z$ A* H, u2 ]%. r+ ~5 Z/ o" R) X3 ^  Q7 j0 K4 Y
    %  How To Use : JUST RUN
    % o: k, `" N2 L4 i2 e  B%
    , W5 L2 D+ C: |" G5 d%  
    % v# o" H1 S3 w%   : a, I& {+ D( U. \  `
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
    ) |1 t6 g: i. F0 i6 |%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    ' [# Q' c5 P0 @* t) F' u: P%) I' r: U# w7 A- v: c
    % Copyright (C) 1989, 1991 Free Software Foundation, Inc.
    ) W) v) {& w3 Q$ `" K7 n%-------------------------------------------------------------------------
    ' I. d  `# b" s# U: e$ R* ^2 b, k8 z2 C' ]

    6 J9 p  V  G  ]. x
    $ w$ g/ z: `+ v7 G1 u* Daddpath([cd,'\..\rirGen\']);
    * ~4 T6 F- a$ z; P' v$ L5 ^: ^* I! V& L- S
    %-----------------------------------------------initial parameters-----------------------------------4 Y( t* E9 z# u0 m6 n8 j& e) t

    " Y& y$ S$ A& @6 v$ fsetup.nRirLength = 2048;
    7 O  R1 r$ ?" U1 X4 {setup.hpFilterFlag = 1;
    " E4 [6 ]8 X( T6 `9 }/ Fsetup.reflectionOrder = -1;
    0 g; t4 M! r' w# z. C! U! s2 n: hsetup.micType = 'omnidirectional';% w3 y  {8 k/ ]7 J8 s; @4 A
    setup.nSensors = 4;+ a# O9 b. `7 |
    setup.sensorDistance = 0.05;
    : k9 d9 E4 u9 x$ ?0 [setup.reverbTime = 0.1;5 H# {3 _8 L* p" S& w
    setup.speedOfSound = 340;
    * L! D- I/ R$ y- B5 z1 ^
    7 G& o  Y5 o# y, r3 ~setup.noiseField = 'spherical';% [: E: K& L2 _  {* K; E  g0 Z
    setup.sdnr = 20;/ l4 @  s5 J5 H- [6 f- d
    setup.ssnr = 25;7 q: O- L% p5 L% f% F- M! S2 g0 s
    ! N" e+ {$ i& w' S
    setup.roomDim = [3;4;3];
    6 V; n. ~  H$ z$ `, k" Z$ l. J2 M/ R& d7 Y: g
    srcHeight = 1;+ T" t  \/ ~. s2 R( C
    arrayHeight = 1;
    ' d* \7 U+ [9 L. `. i$ _
    $ Z) I8 |( f& X7 TarrayCenter = [setup.roomDim(1:2)/2;1];+ }/ }. ^( b2 ^) o) G( [. _4 J

    - ^. N  x0 F: r9 K$ z9 c. ~. S" harrayToSrcDistInt = [1,1];
    6 {. G, z& b, c5 V9 f9 e9 S1 r1 V& T' p! y# ~" `& ~4 P* v
    setup.srcPoint = [1.5;1;1];: w- U9 ?9 Q5 f. r) b( v8 _/ k
    4 W2 ]/ L6 }8 {% u4 _4 K
    setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
    5 W2 z2 ]( `# C. X: A8 y5 ]/ O
      f& n0 H, d8 X/ }# ~& Z* G. I9 j9 M0 @" `5 e& |. }" ]
    [cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    2 e: a& R* K  F; o6 P# `0 P7 j
    3 b8 M8 A' r, Y( S0 M%---------------------------------------------------initial end----------------------------------------
    + F- Y" n6 E! b6 B9 ]5 I* f. ~0 ?( p% ]6 ]* d+ R* I

    5 z# D6 T( x2 F  c: m/ n6 ]6 }' h9 Y7 H) x8 n. d) f
    %-------------------------------algorithm processing--------------------------------------------------8 l. C! x- m: M0 q

    3 p) C4 b* R$ [3 `+ rif setup.reverbTime == 0,
    ' P7 N$ ]0 S  u! p' }  s1 r    setup.reverbTime = 0.2;
    % `/ ?" _2 t' N" R    reflectionOrder = 0;2 J# ]1 W6 C3 N* b2 N
    else
    : S2 e% W# o( R' s# M* Z    reflectionOrder = -1;. j5 {- n, J& l
    end* @: T. X$ X1 @9 f
    * v3 v1 K4 |9 h$ }  ^$ r5 b
    rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
    7 o! o! G- D  z5 X( D) X! ]7 o3 b    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);/ ~! Q9 M* L+ o3 a+ R& Q- e
    # \% S- U: R3 o4 Z$ N+ \
    for iSens = 1:setup.nSensors,
    0 i' ]9 E; X% ]    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);
    0 x: H$ Y) l# @4 Nend. ]4 P7 P9 h% N+ K/ Y3 C# O
    mcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;* r3 X6 W, F1 c/ y2 \) M
    setup.nSamples = length(mcSignals.clean);' s' J0 C: Q! g$ F7 X( E4 L
    9 }# S8 R8 x1 q7 h/ c* @6 M7 h
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);3 ]) S! q; Z% t( S
    ; D6 o. Q- {0 T1 c' l
    %-------produce the microphone recieved clean signals---------------------------------------------' g; Q0 X* U4 z& Q6 [8 a7 A/ [5 L) i1 r

    ( V% h: J( N9 |. q9 [4 G, m5 Cmic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    1 K) e$ V. k* V5 k# @" r+ |mic_clean2=10*mcSignals.clean(:,2);2 d) v6 H  X5 B, ~7 o& Y" ~$ F
    mic_clean3=10*mcSignals.clean(:,3);
    & X' O5 Q& P7 t5 H  z6 ?9 F7 ~mic_clean4=10*mcSignals.clean(:,4);
    : q  @( C9 Q3 L7 D0 h( uaudiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);, P8 W" \. X$ d+ w
    audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);6 A% E- h; P3 d8 t
    audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
    : f7 @& {0 o. h  [5 haudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);9 Y$ A6 a$ b9 F. O/ h4 e

    0 J% G) ], X8 w0 ]9 ^7 i$ L; q%----------------------------------end--------------------------------------------------
    - V4 x9 V; z# G, w7 G+ R- f- q( c" w
    addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);9 W% S0 \+ a# O* D! w0 d

    - G0 @+ _$ |* M. V3 ScleanSignalPowerMeas = var(mcSignals.clean);( J  R# m( ]" V" X/ [8 _
    4 @5 ?9 c8 I! l
    5 L: H5 L  Y  E1 a, N# Q/ l' ^$ X
    mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,.... K9 P! J6 e0 ~$ m1 ?$ T5 L$ n6 s
        setup.speedOfSound,setup.noiseField);
    ' g5 ^9 c5 v+ c& x( }" k2 j3 rdiffNoisePowerMeas = var(mcSignals.diffNoise);3 B3 ^! y0 l2 x: a
    diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
    1 f/ U- T# H! {" R* Y$ @( f, SmcSignals.diffNoise = mcSignals.diffNoise*...* N7 w* J8 m' ?0 j4 y5 s
        diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));/ |5 |4 v+ v$ L

    0 d8 ?1 i1 t, Q  q# b) G+ l& bmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    , u. s7 }$ z0 R1 E4 w. O0 osensNoisePowerMeas = var(mcSignals.sensNoise);3 k: P8 t  a9 h# q" U
    sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);
    , G# j, N, Q* K+ @: P( _mcSignals.sensNoise = mcSignals.sensNoise*...
    / J% u2 i4 Q  _( M2 }; y) K    diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));0 C; P2 b9 e6 o  [
    ; j3 f3 p+ a8 O# d( C- ]; j/ B9 w
    mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
    ; g  a% s# \1 C2 JmcSignals.observed = mcSignals.clean + mcSignals.noise;2 n4 S6 V" j3 k0 a9 ?: n
    9 l, j& |$ }4 A
    %------------------------------processing end-----------------------------------------------------------
    + I* m( J$ g/ U0 O3 |8 t) ~7 B# B7 z# p9 b
    0 ~0 @* E; y# ]; D1 h

    ' O$ }5 r! ^- c& G6 Y7 x( f. H$ H: z+ y( I4 @
    %----------------produce the noisy speech of MIc in the specific ervironment sets------------------------9 P9 A$ d2 T% w

    % X/ a. M0 j. K6 Z. @8 i! b7 G+ Bnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold; a6 l! U4 u" j2 p; [$ Y
    noisy_mix2=10*mcSignals.observed(:,2);
    $ Y5 T( ~3 u& ], ]* b3 u. y4 Jnoisy_mix3=10*mcSignals.observed(:,3);
    ( P# r: `$ n; C: E1 m4 V, N, s( inoisy_mix4=10*mcSignals.observed(:,4);
    5 s3 y5 k8 k5 f5 i; T( Dl1=size(noisy_mix1);; N7 o1 x* w  _: S3 R, [
    l2=size(noisy_mix2);4 ]' V( G2 e! |6 g& [) u
    l3=size(noisy_mix3);
    8 m0 p  ]0 R7 l1 R9 Al4=size(noisy_mix4);0 ]8 `. D9 _+ g! ?% o
    audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
    " ^' h+ ^- k, P$ f4 Aaudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);" J3 C0 F, |" ~6 k( W: x
    audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
    . [+ O) n9 v. F7 Daudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);: v" T7 x* k/ G. G: w( ^  t
    - V; u* s2 r2 e* B
    ' z3 Z7 x3 v. X
    %-----------------------------end-------------------------------------------------------------------------
    ; D5 i9 v5 }3 L: |4 \5 d; p9 _$ b这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。6 P- r. j8 K* z# k) t! j9 M
    直接把它们替换成你想要处理的音频文件即可。* E4 _" g' {1 B+ P# f

    6 _6 m9 R: ~* [& a* D( I7 `9 ~  除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
    - i6 ^2 L) F" x
    % C& @  p3 }* }" F' c9 X( j  [9 {0 A
    . _. P; h" C9 T0 X# z  ^
    图1 麦克风类型图: U" F3 s3 @, W
    ) u+ C+ r' ~5 w5 {4 I6 r1 E
    图二 房间的坐标系
    # c, r5 ]: |! Q4 w, A& w8 a1 B( g7 {  t0 F" [2 G  B$ `
      以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
    2 c  e- {! m/ H————————————————
    : Y. d: K( [+ v) `  C5 Q, Y版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    0 V) v5 m. |. s. M原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998, Q( d) T2 r5 y& G, v( Y0 f

    ! L% \% I! g4 w. @5 k  p' `! B9 N8 u0 i+ m4 |" V, k3 K$ T
    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-4-21 19:59 , Processed in 0.466167 second(s), 51 queries .

    回顶部