QQ登录

只需要一步,快速开始

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

    ! [' w1 b  |6 J# N* O! p! n2. 代码介绍) Z( [0 w, Y* |7 X
      原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:* P; F' U% _2 v6 [3 Y* U
    function [mcSignals,setup] = multichannelSignalGenerator(setup)* B( C" j. S* X# W; X

    . |) c; h8 w2 g) c* `* G7 z# O: F( D, W
    %-----------------------------------------------------------------------
    ' ~% g1 g, |6 s2 J# w8 K%  Producing the multi_noisy_signals for Mic array Beamforming.
    8 W9 S8 Y3 N' E$ K%
      `0 e. U/ m5 @* n- Y# }( z%  Usage:  multichannelSignalGenerator(setup); J% {' w3 [3 o$ X4 i+ }' \
    %         . m" d/ W% C0 M  Q. `- U
    %        setup.nRirLength : The length of Room Impulse Response Filter
    5 K) m2 c6 x; q* s%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default+ H: a! x, o' ?. ^
    %        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.8 L: M8 I. C4 n% X& p$ z
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.5 Y) I9 h/ C+ V+ J% j% U
    %           2 c8 O( d% s( M7 f( q/ [
    %        setup.nSensors : The numbers of the Mic
    ; Y+ N0 y0 Q' S* e$ x& W# |; X: t%        setup.sensorDistance : The distance between the adjacent Mics (m)" K  M; k2 N0 V1 D( L7 M: b7 r
    %        setup.reverbTime : The reverberation time of room& w1 E0 N& _- l9 W, a  F1 m
    %        setup.speedOfSound : sound velocity (m/s)* I/ h0 k3 V! X( `0 a  o3 i5 }
    %1 N1 i7 q- t0 \3 z+ U9 H; s5 g
    %        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    ) f6 x+ F1 v/ e. d5 p& Q%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.( Q# U3 U# e: J; P6 I6 v
    %        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.9 P% M/ ]/ H9 w* C7 u7 J
    %
    ( e7 l' F( a/ c9 q  B7 k%        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
    1 G6 I6 |. o, W# ]( Y0 |%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m).
    # N- U, D/ d: O- q$ m%        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m).
    ' H/ V+ r% g9 j- _3 W%
    5 i0 `% K' m4 g2 P" c%        srcHeight : The height of target audio source. Z" I2 C7 O/ u+ p
    %        arrayHeight : The height of mic array
    0 A1 Z, V2 u1 a7 E%' Z# e% V8 f( F  `6 D
    %        arrayCenter : The Center Postion of mic array
    * k) D0 ~% b( p3 E. [& @  e%
    . h2 i, I- @7 N  b! g%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis
    ' x( ?: c+ t& f+ F- ~%/ G; l+ d- o* J. U2 t
    %                        , Z% w" X0 |9 F9 d
    %' Q7 w1 I1 I: F0 k3 F
    %
    $ k; [9 L+ L6 h' j6 p* M% C%         
      n# _- o1 J/ U: K5 e5 T%0 u* t) u% Z! v) `5 V$ P' `
    %  How To Use : JUST RUN
      M( M5 H. p, c4 f0 E%# d3 F+ |0 k. @# f
    %  - c) R* {4 y0 ?: v, m/ g0 A& w8 T" n
    %   6 E. u' b" S, }! ?( t% k' x4 `2 G, g
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),' @) V9 z  D" B6 x
    %            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    ) C) c; A! L2 t/ w  {1 S( L% F* ~%
    3 W. v+ m, z  T% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
    & v* o3 U" l# h0 l: @) e%-------------------------------------------------------------------------
    2 g6 i- N  }5 d1 p
    6 |3 z3 S) z! m' @' n
      `' O0 n/ @. ?% h$ p) p. J" o( ]  `/ i
    addpath([cd,'\..\rirGen\']);9 h' y4 [0 A4 G" e! u) |
    & u2 q( V6 E: h# k6 N& p
    %-----------------------------------------------initial parameters-----------------------------------
    8 K( F8 C$ B7 F3 _' Q; D! i7 W" n3 ?. Y$ o3 E* Y2 J  W
    setup.nRirLength = 2048;+ g9 Y. y( }% S% |
    setup.hpFilterFlag = 1;6 x3 m- @! @  O9 d, s  q( f' O% X
    setup.reflectionOrder = -1;
    ' _4 |; d5 P4 t9 d) a6 Qsetup.micType = 'omnidirectional';; N- Y2 ~' e5 Q& U( M
    setup.nSensors = 4;
    * ^& y6 Y" s+ T1 |* S" i: ?setup.sensorDistance = 0.05;7 E% v6 S9 n8 H+ J' B* H
    setup.reverbTime = 0.1;7 U, K# z  z* w  s/ m5 B& Y
    setup.speedOfSound = 340;, h& p  F9 x( f8 u2 r

    2 z- ]' @2 W4 ^# b& g, ysetup.noiseField = 'spherical';) w4 v' ^2 D+ X8 M
    setup.sdnr = 20;8 Q+ m- I1 Z# v/ M/ @
    setup.ssnr = 25;( u9 a) w7 I+ r7 H
    9 j/ Q- \" o) M) a
    setup.roomDim = [3;4;3];4 B" r0 p( F) ^8 J8 D8 N

    : b0 o" N! U7 ~4 e1 @# o1 @5 zsrcHeight = 1;
    * o$ U3 B- h  y3 varrayHeight = 1;, a0 ~6 U  _( ?0 R, J7 a

    3 u% _& R8 V) g" h, [2 tarrayCenter = [setup.roomDim(1:2)/2;1];7 W2 u; i# t" Y. S

    & Z! p# l3 ?  ]; RarrayToSrcDistInt = [1,1];
    - V; i( m' {0 P4 @- z
    # X6 V1 c0 u1 d- Gsetup.srcPoint = [1.5;1;1];4 h. N3 [5 I* w7 q' l) Z! `
    ! g" u) K9 V' D- w3 X
    setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
    0 F# R+ w2 \7 |! P3 z1 ]2 A, ^& Z. x
    - ]8 F3 N& ]- V
    [cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');3 S. ^3 i* A* \7 {0 Q; L

    + j: y. a: q4 Z%---------------------------------------------------initial end----------------------------------------/ [, Q3 P* t' S7 R: m, Z
    9 r( ~4 z2 r% b0 |1 }: E

    9 L* U# P' D: i4 {1 ^  r4 x1 N8 i( W
    %-------------------------------algorithm processing--------------------------------------------------
    6 q! I3 L5 X: e7 q% W+ Q
    $ ^' y0 ~  M! G" y( Bif setup.reverbTime == 0,
    % X0 L" N& U0 p" A    setup.reverbTime = 0.2;! Q8 R* W' d9 z4 x8 Y2 }4 ]$ R+ d' t
        reflectionOrder = 0;
    ' N5 r9 M! w3 |, Ielse
    # Q5 J1 ^, ?; a6 p. }6 q* ?    reflectionOrder = -1;
    & Y8 ]6 |6 T- E0 n7 J0 Oend
    5 l/ ], B/ ?! w4 |
    ) J" k8 h! P2 L0 e- lrirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
    % Q: h' h/ n1 `) n( }4 L    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);( `, W# F  a, W, c# k' _2 R

    , S" _5 x, Y1 Z, m9 y6 ifor iSens = 1:setup.nSensors,2 P, X  |/ ?' p& Z: |7 s5 D
        tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);1 X' f5 j; F7 r5 a! ]. e: w& L
    end
    + z' C: R( |: t  f: e, n# EmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;! r. V  o- d1 l2 V
    setup.nSamples = length(mcSignals.clean);- X/ E, J! ^% U( G9 N3 ^
      P) S! K& |; u- L/ u
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);4 d  N2 L! E. n7 r) S2 B

    ( w5 }2 p& C+ ?3 U( C%-------produce the microphone recieved clean signals---------------------------------------------1 P$ w7 ]- _+ R( N, i/ x3 O

    4 @1 i% }8 u' U- |mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold
    ! `- B2 W6 T5 \* {$ k( u( U6 gmic_clean2=10*mcSignals.clean(:,2);
    ; y" H5 i' y; y% E1 A. }, fmic_clean3=10*mcSignals.clean(:,3);
    4 k2 y! h4 h& E& X8 xmic_clean4=10*mcSignals.clean(:,4);
      C4 k8 U* j. c; i( ?audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    0 S7 ]  l4 S$ Q/ {9 caudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
    6 n4 G* \; T# ^# @7 Xaudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
    9 p' H, g. B$ r' P# G3 ]* z. \) haudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);
    : D/ q- f. ?/ L; w. g5 ?2 G  Z! o7 k6 U2 J; w
    %----------------------------------end--------------------------------------------------) @) S- X% G! ?1 A# s" W1 e) n8 U
    ( T% P" @8 J* A/ m0 a" Y
    addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
    9 g* i2 m; c: S" I/ \8 X
    ! e9 X; a' Y1 S5 CcleanSignalPowerMeas = var(mcSignals.clean);
    1 t( c0 y! C5 y6 c8 c5 l' H
    3 V: a8 X( G- }( U* B( s% t* v1 V* H' H1 n. @5 e1 _
    mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...+ f0 d. V- h& [- P5 H2 a! O
        setup.speedOfSound,setup.noiseField);
    ! X5 B; R* O% ZdiffNoisePowerMeas = var(mcSignals.diffNoise);
    * U# ?8 R- s0 R  \' f6 m3 x+ idiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
    2 ~5 H7 w+ d5 U" L' n8 l; XmcSignals.diffNoise = mcSignals.diffNoise*...
    . v" l4 q/ W3 P    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));# P' V/ L5 W( F4 ~4 N, c. y

    4 r1 {0 h6 v& |# t# PmcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);1 D4 R. W9 R& E- a, |
    sensNoisePowerMeas = var(mcSignals.sensNoise);
    8 f- h+ f6 z2 Q/ w* BsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);7 v$ W3 L  k: a% p% M  Y5 H
    mcSignals.sensNoise = mcSignals.sensNoise*...
    0 t  A( S; o, k; }8 F& h    diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
    / |0 l" Z; p1 R+ V7 |& d5 p1 k! H0 p. q  @% o2 Q/ g' {
    mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;* R$ R( A: `& i0 c; u" |" I2 b
    mcSignals.observed = mcSignals.clean + mcSignals.noise;* M/ D4 v/ g7 r( j, c# Y

    , q( t& K/ a4 S2 o5 {5 s0 q( \$ {& \) J%------------------------------processing end-----------------------------------------------------------$ R5 P* t- K8 W
    7 O/ L6 S# |. l

    : s5 g* _. s! s; J' K# l% P, r- e9 g6 i' L2 P
    " u) A4 I" {# n9 \6 ]4 ?
    %----------------produce the noisy speech of MIc in the specific ervironment sets------------------------0 u. `. C5 |" X" c/ u# J& p

    - Q6 Y/ t1 [8 r; T4 B1 w6 bnoisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold! X- _! e6 q; i& \) L: F, P& M
    noisy_mix2=10*mcSignals.observed(:,2);
    $ J4 A0 b7 |/ ?2 E5 Onoisy_mix3=10*mcSignals.observed(:,3);
    ) S5 J2 O! ~, C% Inoisy_mix4=10*mcSignals.observed(:,4);( U8 Z' K% L& `6 Z4 r
    l1=size(noisy_mix1);9 F/ n+ \& |! m
    l2=size(noisy_mix2);+ v! ?8 n* W& P; X7 ^3 W
    l3=size(noisy_mix3);! R6 p7 Y% n8 i( x. Q
    l4=size(noisy_mix4);
    8 B9 j3 A8 V6 A" \audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);% Z3 P( {2 p4 ?. c* C# u3 G
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);" ]7 F  F; M5 d4 n$ q
    audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);! X$ h! T+ }1 _5 Q: ~0 M+ V  K* g
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);  M" T) y/ v& A) A) V
    * K2 i/ C, \2 n$ c2 W9 x1 o% T$ p
    4 `/ o3 E9 l# g0 b) t
    %-----------------------------end-------------------------------------------------------------------------
    9 x  m' b$ x2 O# B, Z! o! C这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
    3 G$ s% G9 b2 v+ E直接把它们替换成你想要处理的音频文件即可。
    8 Y. A) m5 K2 |1 j* |6 T5 w" e  W) _" |) E
      除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。" V9 M9 [, E# |  }1 N) O

    5 M- ?3 r. C+ ~/ V/ d
    . Q% }- H- o; T7 x3 g9 ^, p2 O  r% j. ~: {! _/ w6 {1 d
    图1 麦克风类型图
    " n& J/ n: Q( N  l( ?0 L3 x
    - g+ `( ?" z8 m" O* s7 @图二 房间的坐标系
    , E5 P' ~: R2 E/ ~, ~$ h& k- b
    & Z. ^# S+ C/ T/ ~+ {) w  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。8 F/ S, y8 O# f5 y+ M1 Z* c# m
    ————————————————+ A2 y7 i+ }, T5 _8 x" @1 O( }
    版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    - w' o8 E" i# W: T5 H. j原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
    8 l: k, j$ A- C2 N% [$ c( r1 S# Q- A0 y. w

    # U+ W" D& p. C6 n2 _+ r
    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-8 21:07 , Processed in 0.303462 second(s), 50 queries .

    回顶部