QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3308|回复: 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. 引言& y- X6 \$ p  C8 r  S5 e  T+ `
      之前,我在语音增强一文中,提到了有关麦克风阵列语音增强的介绍,当然,麦克风阵列能做的东西远远不只是在语音降噪上的应用,它还可以用来做声源定位、声源估计、波束形成、回声抑制等。个人认为,麦克风阵列在声源定位和波束形成(多指抑制干扰语音方面)的优势是单通道麦克风算法无法比拟的。因为,利用多麦克风以后,就会将空间信息考虑到算法中,这样就特别适合解决一些与空间相关性很强的语音处理问题。
    / Z5 O1 J' L( k+ A/ U2 }
    ' g' a4 I' M2 B0 i5 v2 ~  然而,在做一些麦克风阵列相关的算法研究的时候,最先遇到的问题就是:实验环境的搭建。很多做麦克风阵列的爱好者并没有实际的硬件实验环境,这也就成了很多人进行麦克风阵列入门的难题。这里,我要分享的是爱丁堡大学语音实验室开源的基于MATLAB的麦克风阵列实验仿真环境。利用该仿真环境,我们就可以随意的设置房间的大小,混响程度,声源方向以及噪声等基本参数,然后得到我们想要的音频文件去测试你自己相应的麦克风阵列算法。3 U& N, z4 B. }% O# Y. ^9 N

    ; t( Z: Q; h. H4 e# i, {. m2. 代码介绍$ M/ O8 v# A7 X
      原始的代码被我加以修改,也是为了更好的运行,如果有兴趣的话,大家还可以参考爱丁堡大学最初的源码,并且我也上传到我的CSDN码云上了,链接是:https://gitee.com/wind_hit/Microphone-Array-Simulation-Environment。 这套MATLAB代码的主函数是multichannelSignalGenerator(),具体如下:( W3 Q& o6 W/ q' ]. D
    function [mcSignals,setup] = multichannelSignalGenerator(setup)4 W# h! m9 f6 U' w) x

    9 f3 W' c2 h* c8 y" p8 h7 n( L1 S$ y/ c6 _
    %-----------------------------------------------------------------------
    1 Y9 p4 @8 L% }$ z%  Producing the multi_noisy_signals for Mic array Beamforming.5 n" z; q! A1 ~- F( `; @7 o. u
    % + [& m; \  K! z$ t. S
    %  Usage:  multichannelSignalGenerator(setup)% G/ M' Q# K3 N8 Y; @) A+ [
    %         " G3 L- B+ v3 w' y) N4 m, D( {. w
    %        setup.nRirLength : The length of Room Impulse Response Filter
    9 @: u9 L+ v( W%        setup.hpFilterFlag  : use 'false' to disable high-pass filter, the high-%pass filter is enabled by default
    6 [! I; a8 P) G$ {) t0 E%        setup.reflectionOrder : reflection order, default is -1, i.e. maximum order.
    1 Z/ {. _9 t$ N0 C0 g: [%        setup.micType : [omnidirectional, subcardioid, cardioid, hypercardioid, bidirectional], default is omnidirectional." K0 N5 Q' _4 Q. T" o  O
    %           
    4 f/ m$ v5 U* ?6 C%        setup.nSensors : The numbers of the Mic6 \- B! |9 b9 _$ k
    %        setup.sensorDistance : The distance between the adjacent Mics (m)
    % V7 T0 D' ^" N* q5 \$ g* a%        setup.reverbTime : The reverberation time of room
    * L1 e6 ~( u$ J( u1 E7 p7 H%        setup.speedOfSound : sound velocity (m/s)
    $ x: E! h# M- V# D%
    3 C* L, R/ P" E2 G4 ^0 k%        setup.noiseField : Two kinds of Typical noise field, 'spherical' and 'cylindrical'
    9 M5 L" i6 D, g, P0 B, A6 h' @+ w%        setup.sdnr : The target mixing snr for diffuse noise and clean siganl.
    2 h4 p/ w% S" O%        setup.ssnr : The approxiated mixing snr for sensor noise and clean siganl.
    4 }3 J$ `3 M5 J2 w  z" [%  E- ^# W2 k7 J' S! u" o4 P1 ]
    %        setup.roomDim : 1 x 3 array specifying the (x,y,z) coordinates of the room (m).           
    6 m/ _0 g( D' d. u%        setup.micPoints : 3 x M array, the rows specifying the (x,y,z) coordinates of the mic postions (m). ' F* i, C" V: H$ J- ]! g
    %        setup.srcPoint  : 3 x M array, the rows specifying the (x,y,z) coordinates of the  audio source postion (m). ' X% \$ d) h5 v* ~0 T' ~4 d
    %
    ) D; n+ L  Z: k4 N4 `; @; W, |%        srcHeight : The height of target audio source
    " F6 O8 v, g. T: c! J%        arrayHeight : The height of mic array
    & u4 D% y! ?7 u# u%
    8 a2 a4 t6 o5 T% i( s, X%        arrayCenter : The Center Postion of mic array
    2 @3 u2 M" T! ^& l  d3 G& e%6 A* l6 k; z% i' }) Y, t5 U8 ~9 _
    %        arrayToSrcDistInt :The distance between the array and audio source on the xy axis' `. z" }- H8 i! B* ^5 ^
    %3 M0 Z' t  W; I) G/ |. U
    %                        # @* S: O: O/ ~$ N9 r6 r
    %2 z5 G7 W8 M8 ?2 R4 K7 D  c6 c
    %' P/ _$ A2 r& `5 b
    %         % a2 t+ j& r8 @" B3 \/ {; A% H& Z4 Y
    %3 m  X( j& o" c4 k- K9 m- q. }9 Z
    %  How To Use : JUST RUN/ x- H0 R# s' f4 ?" D
    %/ p3 r0 y0 Q, _# S9 m" Z! {) T( j
    %  
    * k: r: g' ^' B9 V1 g& l( Y%   
    1 q& T0 i/ R9 e1 z% Code From: Audio analysis Lab of Aalborg University (Website: https://audio.create.aau.dk/),
    ; ^# S& W* j7 s/ j4 ]%            slightly modified by Wind at Harbin Institute  of Technology, Shenzhen, in 2018.3.24
    8 d0 ?6 c; _$ j; q%
    9 }$ A% g% R) q0 }+ C3 ?% Copyright (C) 1989, 1991 Free Software Foundation, Inc.
    7 q" f  @3 J/ i" b1 @%-------------------------------------------------------------------------7 {: R' i# e4 B$ ^8 }

      S2 j' R0 |0 M0 F4 u
    2 L2 t( P# c9 \9 A/ ^
    5 M4 l" k% L0 E: u; x" G& caddpath([cd,'\..\rirGen\']);
    " \% i, K. @: a, f, j( C% W
    1 i$ U. e  L6 d: k! p; q/ ]%-----------------------------------------------initial parameters-----------------------------------( ]3 o$ i6 a# G- p4 L
    # N) @9 g% O! j& ?
    setup.nRirLength = 2048;# {/ }& ^4 y4 }2 J; h1 d
    setup.hpFilterFlag = 1;. Q* v! K) E# {; t
    setup.reflectionOrder = -1;' q" J6 i' d8 ]" j
    setup.micType = 'omnidirectional';
    0 E7 N5 b6 E( V9 W. Q$ |setup.nSensors = 4;
    7 f( _6 o" r' ]3 a/ }8 Wsetup.sensorDistance = 0.05;' |' {1 P6 Q' b( s& ~
    setup.reverbTime = 0.1;- T3 X: E, z" _7 z$ X
    setup.speedOfSound = 340;4 r2 Q( O4 I% A( [

    8 n" l6 x( W3 J& _; [: D8 |setup.noiseField = 'spherical';- e; A; I6 v2 T( m  Z; t3 Z/ O
    setup.sdnr = 20;8 ]+ {  i$ n) B  O' p
    setup.ssnr = 25;
    , D: L3 Y; T) Y) V9 Z. k
    ) j& g5 {: a; A2 f7 osetup.roomDim = [3;4;3];+ ?0 |( n0 m( `3 ^% }

    , \! A  N, ~; K( @' q+ V# M; t# ~srcHeight = 1;; S4 A! p# w4 I/ Q! K
    arrayHeight = 1;- f% ~. r- O0 X1 X1 [1 v

    ) M2 h" K- N8 A4 i3 s  A$ iarrayCenter = [setup.roomDim(1:2)/2;1];
    " r( T/ p% |* M* N3 n* ^% ]& c
    $ c# E! V0 [4 O+ \) D4 Y6 |arrayToSrcDistInt = [1,1];( \  p8 R3 m, E4 |& K. b; o
    . \# k4 D! M! x9 v% \- ^+ H
    setup.srcPoint = [1.5;1;1];/ \$ `8 X2 f% U0 {* S: R# L8 V/ Q, A+ K3 t) C
    $ d2 P' R/ f' G/ f2 o# X0 a1 h% R1 R; O
    setup.micPoints = generateUlaCoords(arrayCenter,setup.nSensors,setup.sensorDistance,0,arrayHeight);
    ' c' ^* d" d2 I4 R) p- ^5 B0 ?( r
    " x$ N3 d  s( k3 o) N% H  n
    [cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav');
    9 f5 b# ^; ~* D4 k4 K0 y" a  a
    # A! e, b7 D; O1 e- V%---------------------------------------------------initial end----------------------------------------/ b* C- L( c9 Z/ a" k/ B/ P) d" F

    ' Q. M* k" W; |+ ?0 M6 i
    0 E# C$ |3 Y# @' M6 W: F# \# s! [3 Q( y
    %-------------------------------algorithm processing--------------------------------------------------
    2 N  l+ |* s) l2 h( b. {5 \8 G3 w: L5 e/ m
    if setup.reverbTime == 0," X* I, V5 B2 n& }8 T! f6 Y
        setup.reverbTime = 0.2;1 h' f' k) ^4 o5 c$ L) D# c; y
        reflectionOrder = 0;
    / A% F$ ^0 Q5 X' p' C# v2 `, q: R1 telse
    / \) F% G8 B7 J) c: I9 w, J& j    reflectionOrder = -1;
    8 D6 H: \& j* ^4 P3 bend/ c- ~; \! r8 o3 K: H
    6 _9 e7 u0 p# U& [' L1 \
    rirMatrix = rir_generator(setup.speedOfSound,setup.sampFreq,setup.micPoints',setup.srcPoint',setup.roomDim',...
      ^1 e6 r; D& Z0 q    setup.reverbTime,setup.nRirLength,setup.micType,setup.reflectionOrder,[],[],setup.hpFilterFlag);
    - `: x9 e3 a) _. f8 g% _0 j) D! o$ t0 _4 l
    for iSens = 1:setup.nSensors,
    ; U$ @. F4 ]- Y9 X    tmpCleanSignal(:,iSens) = fftfilt(rirMatrix(iSens,',cleanSignal);
    ( Q) X. M  H( M4 j1 h  D/ O9 ~$ t- send
    1 g3 g& b0 n# e- |, z% OmcSignals.clean = tmpCleanSignal(setup.nRirLength:end,;) Y+ n0 `. X0 S$ a! d, F
    setup.nSamples = length(mcSignals.clean);
    2 [( x: u4 |0 t+ L1 C: ~* t8 A
    * b, L/ b0 m) m3 jmcSignals.clean = mcSignals.clean - ones(setup.nSamples,1)*mean(mcSignals.clean);. ?" q. G' u. p
    9 G4 Z9 M4 E+ y- G1 m* R
    %-------produce the microphone recieved clean signals---------------------------------------------. b6 A" b) V# |" J
    & i3 k: J! j; e& O
    mic_clean1=10*mcSignals.clean(:,1); %Because of the attenuation of the recievd signals,Amplify the signals recieved by Mics with tenfold! F. [8 c5 w5 }+ J: Z
    mic_clean2=10*mcSignals.clean(:,2);* m  ?; J1 q( f/ R' H
    mic_clean3=10*mcSignals.clean(:,3);! q7 C. |( |! _* H6 h
    mic_clean4=10*mcSignals.clean(:,4);: n) Y  t5 q, T8 J
    audiowrite('mic_clean1.wav' ,mic_clean1,setup.sampFreq);8 h1 b' o6 x' V( @1 I  z5 \
    audiowrite('mic_clean2.wav' ,mic_clean2,setup.sampFreq);
    . j" C9 M  c% `  i. Faudiowrite('mic_clean3.wav' ,mic_clean3,setup.sampFreq);
    3 e( _2 y) Y8 d% C: S0 jaudiowrite('mic_clean4.wav' ,mic_clean4,setup.sampFreq);0 ^& G5 A6 [4 f$ `2 ^$ }) M
    & }* Q- T2 a  F6 Y" _
    %----------------------------------end--------------------------------------------------
    * ^9 t2 ~. i+ ?3 {
    . B- n  T! l% y) o2 uaddpath([cd,'\..\nonstationaryMultichanNoiseGenerator\']);" c& x! y7 p8 l8 d+ v8 J0 X: w; j* _
    $ Q0 x: i" Q8 l2 t, H/ `
    cleanSignalPowerMeas = var(mcSignals.clean);
    , j% a' G6 `- c+ B8 F# L, d7 R8 f+ D0 D
    " c4 s, a6 e; ]* ]/ q
    mcSignals.diffNoise = generateMultichanBabbleNoise(setup.nSamples,setup.nSensors,setup.sensorDistance,...* w9 E4 ^! ]6 [4 b; u3 {
        setup.speedOfSound,setup.noiseField);
    + ^1 B8 }4 a( QdiffNoisePowerMeas = var(mcSignals.diffNoise);; l' D, W' d# @; b0 h. U
    diffNoisePowerTrue = cleanSignalPowerMeas/10^(setup.sdnr/10);
    ' V3 U1 a% R2 VmcSignals.diffNoise = mcSignals.diffNoise*...! {* m6 E2 j$ T
        diag(sqrt(diffNoisePowerTrue)./sqrt(diffNoisePowerMeas));
    1 T' [  Q- I! W, Z+ S5 b: R6 d- _. H, G8 t" e3 m
    mcSignals.sensNoise = randn(setup.nSamples,setup.nSensors);
    ! Z1 J) j+ i/ g4 usensNoisePowerMeas = var(mcSignals.sensNoise);
    5 h- {0 y8 X8 O6 o" A2 ~sensNoisePowerTrue = cleanSignalPowerMeas/10^(setup.ssnr/10);4 c$ D4 \# z# B. |8 `7 S
    mcSignals.sensNoise = mcSignals.sensNoise*...) X% f2 w( ]4 f# j5 V% a, A  ?
        diag(sqrt(sensNoisePowerTrue)./sqrt(sensNoisePowerMeas));
    " Z  J( ^' {, v- m1 U% K
    4 [% v9 g; h" W4 w7 U9 @mcSignals.noise = mcSignals.diffNoise + mcSignals.sensNoise;2 Z4 W& `2 _7 _) e
    mcSignals.observed = mcSignals.clean + mcSignals.noise;
    ' Y$ h: f, D9 \2 G; b- U. k% X' I/ T( y1 K* h
    %------------------------------processing end-----------------------------------------------------------
    ) B% H7 M3 E2 b* l7 p# j, k. ^
    / ^( \# S- Y' u! f' p
    ! H$ D7 U6 U/ c5 V
    : H& e5 @2 b7 _+ A& N
    ! Y/ ]: X4 F% B" H5 _%----------------produce the noisy speech of MIc in the specific ervironment sets------------------------; T  t' L4 a& T# [# J& b0 k

    # z. R1 P# A" R+ W% @noisy_mix1=10*mcSignals.observed(:,1); %Amplify the signals recieved by Mics with tenfold# Q5 L& p0 N. x- U
    noisy_mix2=10*mcSignals.observed(:,2);
    6 t% {2 ]' R; f; `- |9 b" a6 qnoisy_mix3=10*mcSignals.observed(:,3);
    8 g" A2 W6 T9 c0 mnoisy_mix4=10*mcSignals.observed(:,4);
    8 ^# k: K3 O" P; il1=size(noisy_mix1);( [8 b" m# F  V% G% t: q
    l2=size(noisy_mix2);
    8 I  ^( e& v  G4 Xl3=size(noisy_mix3);
    , f, j* w# ^; Y4 xl4=size(noisy_mix4);, {7 M# ?, l5 K7 {: Q4 ?; X
    audiowrite('diffused_babble_noise1_20dB.wav' ,noisy_mix1,setup.sampFreq);
    , o; c, c* _# M9 K" Aaudiowrite('diffused_babble_noise2_20dB.wav' ,noisy_mix2,setup.sampFreq);; O7 p7 K) i" ~) R; j4 _4 O9 \
    audiowrite('diffused_babble_noise3_20dB.wav' ,noisy_mix3,setup.sampFreq);
    2 ?3 @7 W* r# N9 S" uaudiowrite('diffused_babble_noise4_20dB.wav' ,noisy_mix4,setup.sampFreq);/ Q! o) ^5 V. n% l

    " F" U& @2 c6 ]) l$ G9 H+ t6 }6 y3 v, G( B9 U  r
    %-----------------------------end-------------------------------------------------------------------------
    5 F/ Q1 N# ]5 ~- W/ F( f, r* U  d9 C这个是主函数,直接运行尽可以得到想要的音频文件,但是你需要先给出你的纯净音频文件和噪声音频,分别对应着:multichannelSignalGenerator()函数中的语句:[cleanSignal,setup.sampFreq] = audioread('..\data\twoMaleTwoFemale20Seconds.wav'),和generateMultichanBabbleNoise()函数中的语句:[singleChannelData,samplingFreq] = audioread('babble_8kHz.wav') 。  y7 w7 N9 R& L4 P! z3 D+ w! k( b4 z
    直接把它们替换成你想要处理的音频文件即可。
    8 Q6 J: C1 H% C9 S- H
    ' Z6 B5 X$ d* h& b! `  除此之外,还有一些基本实验环境参数设置,包括:麦克风的形状为线性麦克风阵列(该代码只能对线性阵列进行仿真建模,并且还是均匀线性阵列,这个不需要设置);麦克风的类型(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)。
    8 R. V+ @* x' t* Y' ^" [' S' r6 ]2 x1 L1 R

    $ F/ K/ W0 |. e3 c0 C7 t, d5 _8 s8 d) @3 R1 e7 m
    图1 麦克风类型图7 z! i2 h. Y  n' E
    0 f! d6 U( S+ p; S
    图二 房间的坐标系
    $ j9 y. B, r7 [/ c' c$ G; ~# v
    7 C& Z, K; q8 H7 k1 k( p  以上便是整个仿真实验环境的参数配置,虽然只能对均匀线性的麦克风阵列进行实验测试,但是这对满足我们进行线阵阵列算法的测试是有很大的帮助。说到底,这种麦克风阵列环境的音频数据产生方法还是基于数学模型的仿真,并不可能取代实际的硬件实验环境测试,所以要想在工程上实现麦克风阵列的一些算法,仍然避免不了在实际的环境中进行测试。最后,希望分享的这套代码对大家进行麦克风阵列算法的入门提供帮助。3 v8 K# J0 j+ \5 \
    ————————————————3 }! O5 I+ p& e* {
    版权声明:本文为CSDN博主「Mr_Researcher」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ q) c9 T# {9 z: a
    原文链接:https://blog.csdn.net/zhanglu_wind/article/details/79674998
    " S: A/ x- d3 A* v, D2 i: I% O1 }* b% p+ L& Z) f& u. A9 G
    3 ]* u' Q1 {9 S8 T6 G' S% e
    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 08:55 , Processed in 0.446001 second(s), 51 queries .

    回顶部