Matlab ULA 仿真

    一直以来太忙,终于到了年前,有了时间把这段时间的收获记录和分享一下。在正式开始之前,我想说一下我这段时间做语音增强最大的感悟:矩阵论随机过程两门必须要狠抓,不然看的不是算法,看的是看不懂的公式,matlab实现的时候更是维度都分不清,这也算是给后来者的忠告把,放弃国产论文吧,看看英文的原文,那才是精华。

    那么我么进入主题,在学习麦克风阵列增强的过程中,最糟心的无过于找不到对应的板子(如果你自己会画或者焊接当我没说),我们不可能想测什么就去网上买一个,可能买的距离也跟我们设想的不一致。所以在学习麦克风阵列的过程中,关于如何获取多麦克的阵列变得尤为重要。好在matlab的Phased Array System Toolbox为我们提供了仿真的操作,那么接下来我介绍一下如何使用它来模拟我们自己的多麦克风指定声源的录音。

    具体链接如下:官方模拟

    这个例子阐述的是使用麦克风阵列波束增强干扰噪声的环境中提取出我们期望的信号。这种操作对于语音感知和进一步处理的语音质量有很大的提升。例如,嘈杂的环境可以是交易室,麦克风阵列可以安装到交易计算机的监视器上。如果计算机必须介绍来自于交易者的命令,则波束形成器操作对于增强语音接收到的质量并实现设计的语音识别准确性是十分重要的。

定义ULA

    首先我们要定义ULA去接受信号,阵列包含10个全向麦克风,麦克风之间的距离为5厘米。

microphone = ...
    phased.OmnidirectionalMicrophoneElement('FrequencyRange',[20 20e3]); % 后面是麦克风的相应频率范围

Nele = 10; % 10个麦克风 可以自己改动
ula = phased.ULA(Nele,0.05,'Element',microphone); % 5厘米对应0.05米
c = 340;                         % 声速

模拟接收到的数据

    下面我们模拟从麦克风阵列接收到的多麦克数据。我们首先读入两个录制好的语音和一个录制的笑声(单声道,可以使用audition来编辑)。我们把笑声作为干扰,采样率设置为8kHZ。

    由于语音信号一般很长,通常把所有数据读入内存进行处理是不切实际的。因此,在这个例子中,我们会用流的方式来模拟和处理信号,比如把信号打散成块的方式逐个进入,处理每一块,然后在结果中把他们组合起来。

    第一个语音信号的如何角度为-30°海拔为0°,同理第二个信号为-10°和10°,干扰来自于20°和0°。【如果你的麦克风阵列仅仅处理二维数据的话,建议海拔都设置为0】

ang_dft = [-30; 0];
ang_cleanspeech = [-10; 10];
ang_laughter = [20; 0];

    接下来我们使用宽带collector(我实在不知道该如何翻译它)去模拟阵列接收到的三秒钟的信号。注意,这种方式每个通道都是一个麦克风接收到的信号。

fs = 8000; % 频率
collector = phased.WidebandCollector('Sensor',ula,'PropagationSpeed',c,...
    'SampleRate',fs,'NumSubbands',1000,'ModulatedInput', false);

t_duration = 3;  % 3秒钟
t = 0:1/fs:t_duration-1/fs; % 每个点对应的时间

    我们生成10e-4瓦的白噪声来表示每个麦克风的热噪声。本地随机数字流可保证重现结果。

prevS = rng(2008);
noisePwr = 1e-4; % noise power

    我们现在开始模拟,在输出中,我们的信号被保存为10列的矩阵中。每列表示对应麦克风接收到的数据,请注意,我们也在模拟的过程中使用流的方式去播放音乐。

% preallocate
NSampPerFrame = 1000;  % 每块的长度 1000个点
NTSample = t_duration*fs; % 总共要取多少个点
sigArray = zeros(NTSample,Nele); % 最终输出结果 
voice_dft = zeros(NTSample,1); % 3秒钟的dft原声
voice_cleanspeech = zeros(NTSample,1); % 3秒钟的clean_speech的原声

voice_laugh = zeros(NTSample,1); % 3秒钟的laugh的原声

% set up audio device writer
audioWriter = audioDeviceWriter('SampleRate',fs, ...
        'SupportVariableSizeInput', true);
isAudioSupported = (length(getAudioDevices(audioWriter))>1); % 播放音乐使用,不必理会

dftFileReader = dsp.AudioFileReader('dft_voice_8kHz.wav',...
    'SamplesPerFrame',NSampPerFrame); % 按流的方式读取数据,以下类似 同时这三个文件Phased工具包自带
speechFileReader = dsp.AudioFileReader('cleanspeech_voice_8kHz.wav',...
    'SamplesPerFrame',NSampPerFrame);
laughterFileReader = dsp.AudioFileReader('laughter_8kHz.wav',...
    'SamplesPerFrame',NSampPerFrame);

% simulate
for m = 1:NSampPerFrame:NTSample
    sig_idx = m:m+NSampPerFrame-1;
    x1 = dftFileReader();
    x2 = speechFileReader();
    x3 = 2*laughterFileReader();
    temp = collector([x1 x2 x3],...
        [ang_dft ang_cleanspeech ang_laughter]) + ...
        sqrt(noisePwr)*randn(NSampPerFrame,Nele); % 核心步骤 模拟点源数据
    if isAudioSupported
        play(audioWriter,0.5*temp(:,3));
    end
    sigArray(sig_idx,:) = temp;
    voice_dft(sig_idx) = x1;
    voice_cleanspeech(sig_idx) = x2;
    voice_laugh(sig_idx) = x3;
end
    原文中下面还有一些有用的知识,不过对于模拟ULA以上知识足够,后面会使用模拟数据来看我们算法的效果。建议使用matlab2017以上。

猜你喜欢

转载自blog.csdn.net/qq_23660243/article/details/79303176
今日推荐