QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3394|回复: 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. 引言- b/ d1 ]" o3 U. v3 J! |. i
      之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。/ \9 j, k+ n% W/ s4 W- C
    8 @  a+ q8 h. u9 {: |% @
      然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。
    ! d; l. h/ O% L7 z9 q8 y  S. Y2 K  S4 B& P6 u6 P9 }# b  D4 v
    2. 代码介绍" x% ?' L; r6 `' G1 ]" o2 B* J; d
      原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:
    + P. q7 p2 P* Ofunction [mcSignals,setup] = multichannelSignalGenerator(setup)
    : r' C* c0 _$ C# s: t
    0 U% G, C( x* j5 b" N6 I3 y* Z
    %-----------------------------------------------------------------------( O8 J, k8 O7 l$ U+ }3 i
    %  Producing the multi_noisy_signals for Mic array Beamforming.% R$ T9 q: ?. s/ D+ c0 _2 T# |
    % ' ]' c; Q8 U4 b" {  P4 j, o/ i
    %  Usage:  multichannelSignalGenerator(setup)
    # j  F0 r- i% ~4 ]8 Q, `& S%         
    7 k5 E. W+ |, E9 ]3 d' `" z8 O%        setup.nRirLength : The length of Room Impulse Response Filter1 r- a1 B5 \  B% C4 K
    %        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default" M1 y" O1 d' ~9 e+ d2 g
    %        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order., r& Q. J; I3 V! S! [
    %        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional.2 z$ e  W. a  G! b% ~
    %           . \/ O& j6 I, N
    %        setup.nSensors : The numbers of the Mic
    7 Y/ c' ^$ [+ Z! Y( b/ x6 `%        setup.sensorDistance : The distance between the adjacent Mics (m)4 S! {6 c8 x* W; ^( l
    %        setup.reverbTime : The reverberation time of room, z; ~/ K+ W) ]+ n" f) t
    %        setup.speedOfSound : sound velocity (m/s)2 w9 C/ m6 S% B$ |7 }( U2 q
    %
    3 j, m# }3 ~& j2 x& e* d%        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    ! L$ ~8 [. k$ ^, O8 @%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.) x* w# H/ r9 C
    %        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.; E' V! w/ [5 Q, o( G7 _' ]
    %
    ' o( p; r5 e, M* W3 R8 Q" f%        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           5 A/ Q4 ?) ^/ q7 a
    %        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). / `) y% D" r& r
    %        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m).
    7 a& ^6 \. w3 t' o%
    : @8 k8 e* Q8 l5 V: }( \$ L; O%        srcHeight : The height of target audio source8 l* K6 E+ b6 V5 s0 w
    %        arrayHeight : The height of mic array
    ) |. ]8 c7 Y% a8 O%4 x1 P8 [' G9 ^- z
    %        arrayCenter : The Center Postion of mic array
    * c1 y4 L% v+ G2 ~2 J; k: N%
    : ^2 h. x0 x/ D5 ^$ [3 ?, s%        arrayToSrcDistInt :The distance between the array and audio source on the xy axis
    * p: z( ?+ b3 p! }" I  y%
    / A0 o9 O+ }: F; w4 u9 E+ u# ~%                        7 J) R7 g# f! s9 T+ }, ?) `
    %! @  E' R5 _5 B4 S( H7 y8 w( [
    %
    - S) ^5 n" S! [8 p& X%         2 {4 O) ^  @- n: `# f
    %! {% t0 S9 u# e) B1 F
    %  How To Use : JUST RUN! Y) j' e- f! N! L6 ^9 D
    %
    6 {% z1 h( f, ^' X, b1 n%  * N- r9 c% H7 u, M4 J8 |: W
    %   0 F- c3 v: k' P+ P; l7 b
    % Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),- n* A/ ~& v+ m8 ^: X' P3 H
    %            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
      E" D$ m! z; C; W; q6 ~4 y%; b- W4 p' E( m9 Z
    % Copyright (C) 1989, 1991 Free Software Foundation, Inc.
    - I' j( d. U* l  M%-------------------------------------------------------------------------/ {; ?+ o( O& A8 x# C
    # o$ s+ p- Q; o" J! j9 y( [
    $ h; ]/ L* L4 p" g0 \- Q

    % L% w7 ]; o" caddpath([cd,'\..\rirGen\']);
    1 K: t0 k7 E: P$ A; x% |  S' f% R3 v# v- H( F0 R" u) L- a/ R- {3 w
    %-----------------------------------------------initial parameters-----------------------------------1 U, S6 M  j( H/ G/ K6 z8 v3 T
    0 |+ m0 \8 A4 x; H0 t0 b% A1 O9 D
    setup.nRirLength = 2048;3 o) s2 F. \/ d7 F, q
    setup.hpFilterFlag = 1;
    % Y* u& I- A& Q! ~$ V7 q2 P; R( t. w$ isetup.reflectionOrder = -1;
    - v. d8 ~# D4 y' |# K7 Ssetup.micType = 'omnidirectional';) S$ L9 E7 m4 o3 B
    setup.nSensors = 4;
    * h, \0 m2 _: X- N! Asetup.sensorDistance = 0.05;
    ! G2 K" e: [7 M! B& Isetup.reverbTime = 0.1;
    + x4 z+ z. K% Dsetup.speedOfSound = 340;5 J3 h% F9 [* o! E1 \9 h; E  x1 d" C

    5 \- ^6 w5 _3 U7 t- W5 K7 Jsetup.noiseField = 'spherical';9 R5 m3 ~! e5 m' r
    setup.sdnr = 20;
    & D: i* h9 g: |3 hsetup.ssnr = 25;* |$ s1 \% v* K+ I) q2 F) V( P: |
    * l  t5 v8 O' E
    setup.roomDim = [3;4;3];- ?# y, L+ H- A0 Y
    ! S, b0 O1 i* j8 _! p+ }8 _0 U+ N9 q
    srcHeight = 1;6 Q% L1 \& ^9 G6 ^1 ~( C/ |
    arrayHeight = 1;7 \" L! S, r+ I- P+ S0 i

    . p6 j" `0 _# V5 u/ i! [3 oarrayCenter = [setup.roomDim(1:2)/2;1];
    # w9 n6 ?. o2 ~( J3 S6 ]
      O4 a6 k9 J6 v6 L' harrayToSrcDistInt = [1,1];0 e. n; v& V* Z' g4 @% r3 v- m
    ) p1 `) i( n% z! n
    setup.srcPoint = [1.5;1;1];
    ' o! Y# ^: T) G' W9 }9 C% E
    $ i  C, E( E4 T) D# l2 F6 H9 S. ssetup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);+ }! J8 D1 |  x4 A: t$ T

    ' h4 e9 H; g5 d
    + }  |, q2 H6 n" J[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');! O/ \6 B& s7 h
    1 G0 w$ Q. ^) I6 x) d0 F$ a
    %---------------------------------------------------initial end----------------------------------------
    ; o4 @. G" h3 z7 }4 x5 p& M. a( T% c: P+ N4 ^
    1 L5 |6 [* x: o; r5 u/ D9 B+ Z& {

    , M3 ^1 v  _3 s5 R( d%-------------------------------algorithm processing--------------------------------------------------8 G7 A- Q7 B: J( y! I* v
    1 y7 D- C+ J' |. Q: ]% S
    if setup.reverbTime == 0,: ^6 |1 b# t0 r, X% U0 r( e$ r# v
        setup.reverbTime = 0.2;
    - ^. p1 M  Y& r) z    reflectionOrder = 0;& r! I9 z7 {5 }
    else' g7 e: D; I. r, F  r
        reflectionOrder = -1;/ H- [* ^9 J: Q
    end
    8 Y9 |# q( L" a" \5 q: P, j% r/ `, _* u2 A$ }4 A! V2 f' X
    rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...1 {: @' q" S, Y1 n  p; W' ]
        setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
    7 N, Q  R; \, I" ~: `; ~& f0 p
    ; L" v1 I9 ~6 S/ R' t1 |3 q0 bfor iSens = 1:setup.nSensors,( R7 K& d/ ]3 ]$ J% ~+ k
        tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);2 _* j# k8 g( ]1 g
    end& ]: n- d& N. h- k7 I* W
    mcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;
    $ ~* l1 k6 p/ N' p6 `  D; Jsetup.nSamples = length(mcSignals.clean);
      q3 q$ c1 T. Y( `  v9 ?' ~. U& L$ W) A
    mcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);
    % R3 {; E7 F# p1 f" M2 Z. Y6 {/ `; G/ D. E% y3 H; H& ^
    %-------produce the microphone recieved clean signals---------------------------------------------- z: h" `( r3 t% D0 z
    $ P& r* x8 P1 A$ K( b# b& c8 k$ W
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold, k% S1 N7 z; f! O
    mic_clean2=10*mcSignals.clean(:,2);( P# S8 d* C8 }. E
    mic_clean3=10*mcSignals.clean(:,3);
    2 u& O' Y  I: O$ s1 R: f# Dmic_clean4=10*mcSignals.clean(:,4);
    7 r4 B7 ~, B+ d5 d- ]; ^audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);
    ! l, H3 d! j# f- A0 F% I5 Gaudiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);1 ?5 V& v4 Q6 N* T& i! `- L3 _! B
    audiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);* ?  g; e9 N. Y
    audiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);7 c) Q- r5 d* l2 X! Y+ i' L
    4 ]6 S$ [$ \3 b: w$ K
    %----------------------------------end--------------------------------------------------
      q  G/ P; [3 o! Z' @& U0 D$ e* g& e% C* E
    addpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);
    ; q; q. F! {& |2 R- h
    - g5 o( x% h  P0 G7 }4 f  H2 gcleanSignalPowerMeas = var(mcSignals.clean);2 J% x% D  x' ~) P
    2 ?* o4 u2 ]2 F: G" ?3 q, S
    ' A& Z, @, t$ w. s% [7 S! O8 N
    mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...
    - E9 Z8 q+ X$ i7 i& D    setup.speedOfSound,setup.noiseField);* H; u- ^$ ~  K& ?9 G4 b  ~
    diffNoisePowerMeas = var(mcSignals.diffNoise);
    0 Y9 b- Q/ V5 H2 \9 X2 LdiffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);. b% [7 w* z; `$ D$ h7 H
    mcSignals.diffNoise = mcSignals.diffNoise*...
    : t1 G' z/ M: k8 B- B' ^    diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));/ I; W6 Q, {: u' [
    $ B8 D" g8 `4 F' t! s/ N( P; J
    mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    8 L* r" ~0 z* j; K) qsensNoisePowerMeas = var(mcSignals.sensNoise);
    # b, c+ U& ?8 n- S, BsensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);) h+ q1 {/ M4 s) U3 g& B
    mcSignals.sensNoise = mcSignals.sensNoise*...0 G3 ~) {3 ^! E( F% h% _/ W
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
    - ?5 ]5 }8 |- f% M; R& W
    ) A2 L* D2 @3 |! ~( SmcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;
    5 D6 _9 r; ^3 x% u# x- t0 l, K) {mcSignals.observed = mcSignals.clean + mcSignals.noise;
    8 ]* H0 q  V. A- g( }* w, A& `$ V* |: J( }9 H+ P% G+ K, T) V( P9 V
    %------------------------------processing end-----------------------------------------------------------7 I) g9 U1 V' x! L) L: [3 i

      Q, ~; w. |& q# t8 O% F5 J4 _( p
    5 e; S0 T* i2 C# K- O5 k! M4 u. L' @1 |
    0 q$ n( |+ T  b* y
    %----------------produce the noisy speech of MIc in the specific ervironment sets------------------------
    * Q' t* L2 [+ I! U: a4 j! K+ l" B9 T' b6 s
    noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold$ p8 c6 d8 }! n! p( u& \5 R: j
    noisy_mix2=10*mcSignals.observed(:,2);3 I' k/ Y+ n% f6 c
    noisy_mix3=10*mcSignals.observed(:,3);. }4 b& i0 P2 P7 y
    noisy_mix4=10*mcSignals.observed(:,4);
    8 h: W4 e/ v# _# C2 x% _, F1 S$ ul1=size(noisy_mix1);( f' p, R$ ]6 H% [
    l2=size(noisy_mix2);
    * x) H8 A' t) @  L7 w9 O$ c# i; D7 jl3=size(noisy_mix3);; P' Q8 @& w2 I# @7 i/ \- V4 [
    l4=size(noisy_mix4);
    8 h6 @9 `; D/ h- M3 B% paudiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);4 H% _0 d2 U% a
    audiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);
    # o: J3 P' R! T; u, o" taudiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);; V8 }5 m# p5 w, Z
    audiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);4 N& l. ^' C5 q: a) F

    / U& u, U  _$ Z4 J6 T/ X6 k8 N% u; u- a' N! P; X1 i. j
    %-----------------------------end-------------------------------------------------------------------------
    / f" ]  U5 @9 {$ {7 @5 _这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。
      x2 c) I) s# p* ?, ^- O直接把它们替换成你想要处理的音频文件即可。
    9 ~' p$ V2 k7 \8 i- t4 H& ]4 B
      e! r( T# |; f" h3 ~5 P  除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。9 q4 c- [! ^3 B  H# q

    * ]6 O/ R5 o. k$ m; z8 l
    2 O7 g5 @8 W4 J' ]
    " ^9 k3 k1 r# v7 a/ V, j* \图1 麦克风类型图* i0 O$ u; G- x" Q

    6 ?4 U( S3 ^2 A! S图二 房间的坐标系
    + K, ]. l' B$ y1 l
    ! A; U" w9 [; o$ q  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。
    5 N- p7 ~8 U# o+ Y: e- M8 C- x————————————————
    ) ~0 L7 |% t9 N* a+ C( H版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。7 _. z9 @( p" q  x" P( M" i) o% }
    原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998# X# T+ T% {8 ^2 F

    9 v/ a% F/ ?" t% l; z9 R4 j5 M
    . F' v+ ~1 {4 w. ]: t0 F9 I2 k
    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-9 12:26 , Processed in 0.634250 second(s), 51 queries .

    回顶部