主要内容

基于深度学习的噪声中语音活动检测

这个例子说明了如何检测使用深度学习低信号噪声环境下的语音区域。该示例使用语音命令数据集来训练双向长短期记忆(BiLSTM)网络检测到语音活动。

介绍

语音活动检测是许多音频系统的重要组成部分,如自动语音识别和说话人识别。语音活动检测在低信噪比(SNR)的情况下尤其具有挑战性,在这种情况下,语音受到噪声的阻碍。

这个例子使用了长短期记忆(LSTM)网络,它是一种非常适合研究序列和时间序列数据的递归神经网络(RNN)。LSTM网络可以学习序列时间步长之间的长期依赖关系。LSTM层(第一层(深学习工具箱))可以看一下在正向方向的时间顺序,而一个双向LSTM层(Bilstmlayer.(深学习工具箱))可以看看在向前和向后方向的时间序列。这个例子使用一个双向LSTM层。

此示例训练话音活动检测双向LSTM网络的分光特性特征序列和一个谐波比度量。

在高信噪比的情况下,传统的语音检测算法可以充分发挥作用。读入一个音频文件,该文件包含在两个暂停之间的单词。将音频重新采样到16 kHz。聆听音频。

fs = 16 e3;[演讲,fileFs] = audioread (“Counting-16-44p1-mono-15secs.wav”);演讲=重新取样(演讲、fs、fileFs);演讲=演讲/ max (abs(演讲));声音(演讲中,fs)

使用detectSpeech功能找到讲话的区域。的detectSpeech函数正确识别所有语音区域。

赢=海明(50E-3 * FS,“周期”);检测语音(语音、fs、,'窗户',赢)

在-20 dB的信噪比下,用洗衣机噪声破坏音频信号。请收听被破坏的音频。

[噪音,文件]=音频读取('洗衣机-16-8-单200secs.mp3');噪声=重采样(噪音,FS,fileFs);SNR = -20;noiseGain = 10 ^( -  SNR / 20)*范数(语音)/常态(噪声);noisySpeech =语音+ noiseGain *噪声(1:numel(语音));noisySpeech = noisySpeech./max(abs(noisySpeech));声音(noisySpeech,FS)

调用detectSpeech在嘈杂的音频信号。由于信噪比很低,该函数无法检测到语音区域。

检测语音(NoiseSpeech,fs,'窗户',赢)

下载并加载预训练网络和配置音频特征提取器对象。该网络被训练用于在给定特征输出的低信噪比环境下检测语音音频特征提取器对象。

网址=“http://ssd.mathworks.com/金宝appsupportfiles/audio/VoiceActivityDetection.zip”;downloadNetFolder = TEMPDIR;netFolder =完整文件(downloadNetFolder,“语音活性检测”);如果~exist(netFolder,“dir”) disp ('下载预训练网络(1文件- 8mb)…')解压缩(URL,downloadNetFolder)结束负载(完整文件(netFolder,'voiceActivityDetectionExample.mat'));
speechDetectNet
speechDetectNet = SeriesNetwork与属性:层:[6×1 nnet.cnn.layer.Layer] InputNames:{ 'sequenceinput'} OutputNames:{ 'classoutput'}
afe
afe=audioFeatureExtractor带属性:属性窗口:[256×1双]重叠长度:128采样器:16000 FFT长度:[]光谱说明输入:“线性光谱”启用的功能包括光谱色、光谱色、光谱色、光谱色、光谱亮度、光谱色、光谱色、光谱衰减点光谱亮度、光谱坡度、和声禁用的功能包括线性光谱、melSpectrum、barkSpectrum、erbSpectrum、mfcc、mfccDelta mfccDelta、gtcc、gtccDelta、gtccDelta、,SpectralDecrese、spectralFlatness spectralSpread、pitch要提取特征,请将相应的属性设置为true。例如,obj.mfcc=true,将mfcc添加到已启用特征的列表中。

从语音数据中提取特征,然后对其进行规范化。确定特征的方向,使时间跨列。

特点=提取(afe noisySpeech);feature = (Features - mean(Features,1)) ./ std(Features,[],1);特点=功能”;

将这些特征通过语音检测网络,将每个特征向量分类为是否属于一个语音帧。

decisionsCategorical=分类(speechDetectNet,特征);

每个决策对应于由音频特征提取器.复制决策,使其与音频样本一一对应。绘制语音、嘈杂语音和VAD决策。

decisionsWindow = 1.2 *(双(decisionsCategorical)-1);decisionsSample = [repelem(decisionsWindow(1),numel(afe.Window)),......repelem (decisionsWindow(2:结束),元素个数(afe.Window) -afe.OverlapLength)];t =(0:元素个数(decisionsSample) 1) / afe.SampleRate;情节(t, noisySpeech(1:元素个数(t)),......t、 致辞全文(一:努梅尔(t)),,......吨,decisionsSample);Xlabel(‘时间’)伊拉贝尔(“振幅”) 传奇(“噪音演说”“演讲”'VAD''地点''西南'

您还可以在流媒体环境中使用经过培训的VAD网络。要模拟流媒体环境,首先将语音和噪声信号保存为WAV文件。要模拟流式输入,您将从文件中读取帧,并以所需的SNR将其混合。

audiowrite (“Speech.wav”,演讲,fs)音频写作(“Noise.wav”、噪音、fs)

要将VAD网络应用于流式音频,您必须在延迟和准确性之间进行权衡。定义噪声演示中流式语音活动检测的参数。您可以设置测试的持续时间、输入网络的序列长度、序列跳数长度和要测试的信噪比。通常,增加序列长度会增加精度,但也会增加滞后。您也可以选择输出到设备的信号作为原始信号或噪声信号。

testDuration =20.;sequenceLength =400;sequenceHop =20.;信噪比=-20噪声噪声=10^(-SNR/20)*标准(语音)/标准(噪声);信号监听=“嘈杂”

调用流媒体演示辅助函数来对音频流观察VAD网络的性能。参数您使用实时控件不打断流例子设置。流播演示完成后,您可以修改论证的参数,然后运行流演示一次。你可以找到的代码在流播演示金宝app支持功能

helperStreamingDemo (afe speechDetectNet,......“Speech.wav”“Noise.wav”......testDuration,sequenceLength,sequenceHop,signalToListenTo,noiseGain);

本示例的其余部分将介绍VAD网络的培训和评估。

培训和评估VAD网络

培训:

  1. 创建audioDatastore指向用于训练LSTM网络的音频语音文件。

  2. 创建由通过的不同的持续时间的无声段分离话音段的训练信号。

  3. 用洗衣机噪声(信噪比= -10 dB)破坏语音加静音信号。

  4. 组成的光谱特性和从所述噪声信号中的谐波比例提取特征的序列。

  5. 使用该功能序列识别语音活动的地区训练LSTM网络。

预测:

  1. 创建audioDatastore一组语音文件,用于测试训练后的网络,并创建一个测试信号,该测试信号由由静音段分隔的语音组成。

  2. 用洗衣机噪声(SNR=-10 dB)破坏测试信号。

  3. 从有噪声的测试信号提取特征的序列。

  4. 通过训练网络通过测试功能识别语音活动的区域。

  5. 将网络的准确性与来自信号加沉默测试信号的语音活动基线进行比较。

下面是培训过程的草图。

下面是预测过程的草图。您可以使用经过训练的网络进行预测。

加载语音命令数据集

下载并提取谷歌语音命令数据集[1]

网址=“https://ssd.mathworks.com/金宝appsupportfiles/audio/google_speech.zip”;downloadFolder = tempdir;datasetFolder = fullfile (downloadFolder,“谷歌演讲”);如果~exist(datasetFolder,“dir”) disp (“谷歌下载语音命令数据集(1.9 GB)......”)解压缩(URL,downloadFolder)结束
下载谷歌语音命令数据集(1.9 GB)...

创建audioDatastore这指向训练数据集。

adsTrain=音频数据存储(完整文件(数据集文件夹,“火车”),“Includesubfolders”,真的);

创建audioDatastore指向验证数据集。

adsValidation = audioDatastore(完整文件(datasetFolder,“验证”),“Includesubfolders”,真的);

创建语音加沉默训练信号

使用读取音频文件的内容阅读.从数据库中获取采样率adsInfo结构体。

[data,adsInfo]=read(adsTrain);Fs=adsInfo.SampleRate;

听用声音命令的音频信号。

声音(数据,FS)

绘制音频信号。

时间向量=(1/Fs)*(0:numel(数据)-1);绘图(时间向量,数据)标签(“振幅”)xlabel(“时间(s)”)头衔(“音频样本”)网格在…上

该信号具有非语音部分(无声、背景噪声等),不包含有用的语音信息。这个例子使用detectSpeech函数。

提取数据中有用的部分。定义一个50毫秒周期的汉明窗口用于分析。调用detectSpeech没有输出参数来绘制检测到的语音区域。调用detectSpeech再次返回检测到的语音的索引。分离检测到的语音区域,然后使用声音命令,收听音频。

赢=汉明(50E-3 * Fs的“周期”);detectSpeech(数据,FS,'窗户',赢了);

speechIndices = detectSpeech(数据、Fs、'窗户',赢了);声音(数据(speechIndices (1,1): speechIndices(1、2),Fs)

detectSpeech函数返回指数是紧紧围绕检测语音区间。据经验确定的是,对于本实施例中,由在任一侧上五帧延伸的检测到语音的索引增加最终模型的性能。由五帧扩展语音指标,然后听演讲。

= max(speech hindices (1,1) - 5*numel(win),1);= min(speech hindices (1,2) + 5*numel(win),numel(data));声音(数据(speechIndices (1,1): speechIndices(1、2),Fs)

重置训练数据存储并打乱数据存储中文件的顺序。

reset(adsTrain) adsTrain = shuffle(adsTrain);adsValidation = shuffle (adsValidation);

detectSpeech函数计算基于统计信息的阈值以确定语音区域。您可以跳过阈值计算并加快计算速度detectSpeech通过直接指定的阈值的功能。为了确定阈值数据集,呼叫detectSpeech并得到它计算的阈值。取阈值的平均值。

TM=[];索引1 = 1:500点的数据=读(adsTrain);[〜,T] = detectSpeech(数据,FS,'窗户',赢了);TM = [TM; T];结束T=平均值(TM);重置(adsTrain)

通过结合来自训练数据集的多个语音文件来创建1000秒的训练信号。使用detectSpeech删除每个文件中不需要的部分。在语音片段之间插入一个随机的沉默时期。

预先分配训练信号。

时间= 2000 * Fs;audioTraining = 0(持续时间,1);

预先分配语音活动训练面罩。掩码中1的值对应于位于有声音活动区域的样本。0值对应的是没有声音活动的区域。

maskTraining=零(持续时间,1);

指定最大静音段持续时间为2秒。

maxSilenceSegment = 2;

通过调用来构造训练信号阅读在循环中的数据存储上。

numSamples=1;虽然numSamples < duration data = read(adsTrain);Data = Data ./ max(abs(Data));%幅度正常化%确定演讲的地区IDX = detectSpeech(数据,FS,'窗户'“阈值”T);%如果检测到语音区域如果~ isempty (idx)%将索引扩展五帧Idx (1,1) = max(1, Idx (1,1) - 5*numel(win));idx(1、2)= min(长度(数据),idx(1、2)+ 5 *元素个数(赢得));%隔离演讲数据=数据(idx(1,1):idx(1,2));将语音片段写入训练信号audioTraining(NUMSAMPLES:NUMSAMPLES + numel(数据)-1)=数据;%设定VAD基线maskTraining (numSamples: numSamples +元素个数(数据)1)= true;%随机静默期numSilenceSamples =兰迪(maxSilenceSegment * Fs, 1,1);numSamples = numSamples + nummel (data) + numsilencessamples;结束结束

想象训练信号的10秒部分。绘制基线语音活动掩码。

图形范围=1:10*Fs;绘图((1/Fs)*(范围-1),音频培训(范围));保持在…上绘图((1/Fs)*(范围-1),maskTraining(范围));网格在…上行= findall (gcf,“类型”“行”);行(1)。线宽=2;xlabel(“时间(s)”) 传奇(“信号”“语音区间”)头衔(“训练信号(前10秒)”);

听训练信号的前10秒。

声音(音频训练(范围),Fs);

在训练信号中添加噪声

将洗衣机噪声添加到语音信号中,使信噪比为-10 dB,从而用洗衣机噪声破坏训练信号。

读取8 kHz噪声并将其转换为16 kHz。

噪音= audioread (“洗衣机-16-8-单1000secs.mp3”);噪声=重采样(噪音,2,1);

噪声腐败训练信号。

audioTraining = audioTraining(1:numel(噪声));SNR = -10;噪声= 10 ^( -  SNR / 20)* *噪声规范(audioTraining)/常态(噪声);audioTrainingNoisy = audioTraining +噪声;audioTrainingNoisy = audioTrainingNoisy / MAX(ABS(audioTrainingNoisy));

想象10秒的嘈杂训练信号。绘制基线语音活动掩模。

图绘制((1 / Fs) *(范围1)audioTrainingNoisy(范围);持有在…上绘图((1/Fs)*(范围-1),maskTraining(范围));网格在…上行= findall (gcf,“类型”“行”);行(1)。线宽=2;xlabel(“时间(s)”) 传奇(“噪声信号”“语音区”)头衔(“训练信号(前10秒)”);

听前10秒的噪声训练信号。

声音(audioTrainingNoisy(范围)、Fs)

请注意,您使用无噪语音加静音信号获得了基线语音活动掩码。请验证使用detectSpeech对噪声污染的信号并不能产生良好的结果。

speechIndices = detectSpeech (audioTrainingNoisy Fs,'窗户',赢了);speechIndices(:,1)= MAX(1,speechIndices(:,1) -  5 * numel(WIN));speechIndices(:,2)=分钟(numel(audioTrainingNoisy),speechIndices(:,2)+ 5 * numel(WIN));noisyMask =零(大小(audioTrainingNoisy));ii = 1:size(speech hindices) noisyMask(speech hindices (ii,1):speech hindices (ii,2)) = 1;结束

想象10秒的嘈杂训练信号。通过分析噪声信号,绘制出语音活动掩模。

图绘制((1 / Fs) *(范围1)audioTrainingNoisy(范围);持有在…上情节((1 / Fs) *(范围1)noisyMask(范围);网格在…上行= findall (gcf,“类型”“行”);行(1)。线宽=2;xlabel(“时间(s)”) 传奇(“噪声信号”“从噪声信号屏蔽”)头衔(“训练信号(前10秒)”);

创建语音加静音验证信号

创建一个200秒的噪声语音信号来验证训练过的网络。使用验证数据存储。请注意,验证和培训数据存储具有不同的发言人。

预先分配验证信号和验证掩码。您将使用此掩码评估已训练网络的准确性。

时间= 200 * Fs;audioValidation = 0(持续时间,1);maskValidation = 0(持续时间,1);

通过调用来构造验证信号阅读在循环中的数据存储上。

numSamples=1;虽然numSamples < duration data = read(adsValidation);Data = Data ./ max(abs(Data));%幅度正常化%确定演讲的地区IDX = detectSpeech(数据,FS,'窗户'“阈值”T);%如果检测到语音区域如果~ isempty (idx)%将索引扩展五帧Idx (1,1) = max(1, Idx (1,1) - 5*numel(win));idx(1、2)= min(长度(数据),idx(1、2)+ 5 *元素个数(赢得));%隔离演讲数据=数据(idx(1,1):idx(1,2));将语音片段写入训练信号audioValidation(NUMSAMPLES:NUMSAMPLES + numel(数据)-1)=数据;%设置VAD基线maskValidation (numSamples: numSamples +元素个数(数据)1)= true;%随机静默期numSilenceSamples =兰迪(maxSilenceSegment * Fs, 1,1);numSamples = numSamples + nummel (data) + numsilencessamples;结束结束

将洗衣机噪声加到语音信号中,使其信噪比为-10 dB,从而使验证信号受到洗衣机噪声的破坏。对验证信号使用与训练信号不同的噪声文件。

噪音= audioread (“洗衣机-16-8-单200secs.mp3”);噪声=重采样(噪音,2,1);噪声=噪声(1:持续时间);audioValidation = audioValidation(1:numel(噪声));噪声= 10 ^( -  SNR / 20)* *噪声规范(audioValidation)/常态(噪声);audioValidationNoisy = audioValidation +噪声;audioValidationNoisy = audioValidationNoisy / MAX(ABS(audioValidationNoisy));

提取训练功能

这个例子使用了以下功能训练的LSTM网络:

本例使用音频特征提取器为特征集创建最佳特征提取管道。创建音频特征提取器对象提取功能集。使用重叠50%的256点Hann窗口。

afe = audioFeatureExtractor ('采样率'Fs,......'窗户',hann(256,“周期”),......'OverlapLength',128,............'spectralCentroid',真的,......“幽灵休息”,真的,......“spectralEntropy”,真的,......“Spectraflux”,真的,......'spectralKurtosis',真的,......“光谱衰减点”,真的,......“光谱可见度”,真的,......“spectralSlope”,真的,......'harmonicRatio',真的);featuresTraining =提取物(AFE,audioTrainingNoisy);

显示特征矩阵的维数。第一维对应于窗口的信号被分解成(这取决于窗口长度和重叠长度)的数量。第二个维度是在本实施例中使用的特征数目。

[numWindows,numFeatures] =尺寸(featuresTraining)
numWindows=125009
numFeatures = 9

在分类的应用,这是一个很好的做法规范化,所有功能都具有零均值和统一的标准偏差。

计算每个系数的平均值和标准偏差,并用它们来归一化的数据。

M =平均(featuresTraining,1);S = STD(featuresTraining,[],1);featuresTraining =(featuresTraining  -  M)./ S;

从验证信号中提取特征使用相同的过程。

featuresValidation =提取物(AFE,audioValidationNoisy);featuresValidation =(featuresValidation  - 平均(featuresValidation,1))./ STD(featuresValidation,[],1);

每个特征对应于数据的128个样本(跳长度)。对于每一跳,设置预期语音/无语音值到对应于这些128个采样的基线掩模值的模式。语音/没有发言权面具转换为分类。

windowLength=numel(afe.Window);hopLength=windowLength-afe.OverlapLength;range=(hopLength)*(1:size(featuresTraining,1))+hopLength;maskMode=零(size(range));index=1:numel(range)maskMode(index)=模式(maskTraining((index-1)*hopLength+1:(index-1)*hopLength+windowLength));结束maskTraining = maskMode'。maskTrainingCat =分类(maskTraining);

对验证掩码执行相同的操作。

范围=(hopLength)*(1:尺寸(特征验证,1))+hopLength;maskMode=零(大小(范围));maskMode(index) = mode(maskValidation((index-1)*hopLength+1:(index-1)*hopLength+windowLength));结束maskValidation=maskMode.';maskValidationCat=categorical(maskValidation);

将训练特征和掩模分割成长度为800的序列,连续序列之间有75%的重叠。

sequenceLength = 800;sequenceOverlap = ROUND(0.75 * sequenceLength);trainFeatureCell = helperFeatureVector2Sequence(featuresTraining”,sequenceLength,sequenceOverlap);trainLabelCell = helperFeatureVector2Sequence(maskTrainingCat”,sequenceLength,sequenceOverlap);

定义LSTM网络体系结构

LSTM网络可以学习序列数据的时间步长之间的长期依赖关系。此示例使用双向LSTM层Bilstmlayer.(深学习工具箱)从正反两个方向看这个序列。

将输入大小指定为长度序列9(功能的数量)。指定输出大小为200的隐藏双向LSTM层并输出序列。此命令指示双向LSTM层将输入时间序列映射到200个要素中,这些要素将传递到下一层。然后,指定输出大小为200的双向LSTM层并输出序列的最后一个元素。此command指示双向LSTM层将其输入映射到200个要素,然后为完全连接的层准备输出。最后,通过包含大小完全连接的层来指定两个类2,接着是softmax层和分类层。

层=[......sequenceInputLayer(大小(featuresValidation,2))bilstmLayer(200,“输出outputmode”“顺序”) bilstmLayer (200,“输出outputmode”“顺序”)完整连接层(2)softmaxLayer分类层];

接下来,为分类器指定训练选项。集最大时代20.这样网络就可以对训练数据进行20次传递小批量64.这样这个网络一次就能观察64个训练信号。集地块“训练进度”生成图表,显示随着迭代次数的增加训练进度。集冗长的禁用打印与plot.Set中显示的数据相对应的表格输出的步骤洗牌“每个时代”在每一个时代的开始洗牌的训练序列。集学习进度表“分段”通过每隔一定数目的历元(10)经过的时间指定的因子(0.1)以降低学习率。集ValidationData到验证预测因子和目标。

此示例使用自适应矩估计(ADAM)解算器。ADAM使用类似LSTM的递归神经网络(RNN)比默认的带动量的随机梯度下降(SGDM)解算器性能更好。

maxEpochs = 20;miniBatchSize = 64;选择= trainingOptions (“亚当”......“最大时代”,maxEpochs,......“最小批量大小”,小批量,......“洗牌”“每个时代”......“详细”,0,......“SequenceLength”,序列长度,......“ValidationFrequency”,地板(numel(trainFeatureCell)/小批量尺寸),......“ValidationData”{featuresValidation。 'maskValidationCat。'},......“阴谋”“训练进度”......“LearnRateSchedule”“分段”......“LearnRateDropFactor”, 0.1,......“LearnRateDropPeriod”5);

训练LSTM网络

使用指定的训练选项和层架构来训练LSTM网络trainNetwork。由于培训集很大,培训过程可能需要几分钟。

doTraining = TRUE;如果doTraining[speechDetectNet,netInfo]=列车网络(列车功能单元、列车标签单元、层、选项);fprintf(“验证准确度:%F%的\ n”,netInfo.FinalValidationAccuracy);其他的负载speechDetectNet结束
验证精度:91.320312%。

利用训练的网络来检测到语音活动

用训练网络中的验证信号估计语音活动。从转换类别估计VAD面具双。

EstimatedVADMask =分类(speechDetectNet featuresValidation。');EstimatedVADMask =双(EstimatedVADMask);EstimatedVADMask = EstimatedVADMask。”——1;

根据实际标签和估计标签的向量计算并绘制验证混淆矩阵。

图cm=混淆图(maskValidation、EstimatedVadTask、,“标题”“验证准确度”);厘米。ColumnSummary =“列规格化”;厘米。RowSummary =“行标准化”

如果你改变了你的网络或特征提取管道的参数,可以考虑重新保存新的网络的MAT文件音频特征提取器对象。

resaveNetwork =如果resaveNetwork保存(“Audio_VoiceActivityDetectionExample.mat”'speechDetectNet'“afe”);结束

金宝app支持功能

转换特征向量与序列

作用[序列,sequencePerFile] = helperFeatureVector2Sequence(特性、featureVectorsPerSequence featureVectorOverlap)如果FeatureVector序列<=FeatureVector重叠错误(重叠特征向量的数量必须小于每个序列的特征向量的数量。结束如果~iscell(feature) feature = {feature};结束hopLength=featureVectorsPerSequence-featureVectorOverlap;idx1=1;sequences={};sequencePerFile=cell(numel(features),1);ii=1:numel(features)sequencePerFile{ii}=floor((size(features{ii},2)-featureVectorsPerSequence)/hopLength)+1;idx2=1;J = 1:sequencePerFile {II} {序列} i​​dx1,1 =功能{II}(:,IDX2:IDX2 + featureVectorsPerSequence  -  1);% #好< AGROW >idx1=idx1+1;idx2=idx2+hopLength;结束结束结束

流式演示

作用helperStreamingDemo(speechDetectNet、afe、cleanSpeech、noise、测试持续时间、sequenceLength、sequenceHop、signalToListenTo、noiseGain)

创造dsp。AudioFileReader对象一帧一帧地从语音和噪声文件中读取。

speechReader = dsp.AudioFileReader(cleanSpeech,“PlayCount”,inf);noiseReader=dsp.AudioFileReader(噪音,“PlayCount”、正);fs = speechReader.SampleRate;

创建一个运动标准偏差对象和dsp.MovingAverage对象。您将使用这些数据来确定标准偏差和正常化音频功能的意思。统计应该改进随着时间的推移。

movSTD = dsp。MovingStandardDeviation ('方法'指数权重的“遗忘因子”,1);movMean = dsp.MovingAverage('方法'指数权重的“遗忘因子”,1);

创造三个dsp.AsyncBuffer对象。一个用于缓冲输入音频,一个用于缓冲提取的特征,一个用于缓冲输出缓冲区。输出缓冲区仅用于实时可视化决策。

audioInBuffer = dsp.AsyncBuffer;featureBuffer = dsp.AsyncBuffer;audioOutBuffer = dsp.AsyncBuffer;

对于音频缓冲区,您将同时缓冲原始干净语音信号和噪声信号。您将仅播放指定的音频信号监听。转换信号监听变量要听的通道。

channelToListenTo = 1;如果strcmp(信号监听),“清洁”) channelToListenTo = 2;结束

创建一个时间范围,以可视化原始语音信号、应用网络的噪声信号以及网络的决策输出。

范围=时间波谱('采样率',财政司司长,......“TimeSpanSource”“属性”......'时间跨度'3.......“缓冲长度”,FS * 3 * 3,......“YLimits”,[-1 1],......'TimeSpanOverrunAction'“滚动”......“ShowGrid”,真的,......“NumInputPorts”3.......'LayoutDimensions',[3,1],......“头衔”“噪音演说”);scope.ActiveDisplay = 2;scope.Title =“干净的演讲(原始)”;scope.YLimits=[-1];scope.ActiveDisplay=3;scope.Title=“发现演讲”; scope.YLimits=[-1];

创建audioDeviceWriter对象播放扬声器中的原始音频或嘈杂音频。

deviceWriter=音频设备编写器('采样率',FS);

初始化循环中使用的变量。

windowLength =元素个数(afe.Window);hopLength = windowLength - afe.OverlapLength;myMax = 0;audioBufferInitialized = false;featureBufferInitialized = false;

运行流媒体演示。

抽搐虽然toc%读取一帧语音信号和一帧噪声信号speechIn = speechReader();noiseIn = noiseReader();%在指定的信噪比下混合语音和噪声noisyAudio = speech + noiseGain*noise ein;为标准化更新一个运行最大值myMax=max(myMax,max(abs(noiseyaudio));%将嘈杂的音频和语音写入缓冲区写作(音频缓冲,[noiseyaudio,speechIn]);%如果缓冲足够的样本,%标记音频缓冲器作为初始化,并推读指针%为音频缓冲区增加一个窗口长度。如果audioInBuffer。NumUnreadSamples >= windowLength && ~audioBufferInitialized audioBufferInitialized = true;读(audioInBuffer windowLength);结束%如果音频缓冲区中有足够的样本来计算特征%向量,读取样本,归一化,提取特征向量,写入%最新的特征向量的特征缓冲。虽然(audioInBuffer.NumUnreadSamples> = hopLength)&& audioBufferInitialized X =读(audioInBuffer,窗口长度+ hopLength,窗口长度);写(audioOutBuffer中,x(端hopLength + 1:端,:));noisyAudio = X(:,1);noisyAudio = noisyAudio / myMax;设有=提取物(AFE,noisyAudio);写(featureBuffer,特征(2,:));结束%如果缓冲了足够的特征向量,标记特征缓冲区%初始化,并将读取指针推入特性缓冲区%和音频输出缓冲区(以便它们同步)。如果featureBuffer。NumUnreadSamples >= (sequenceLength + sequenceHop) && ~featureBufferInitialized featureBufferInitialized = true;读(featureBuffer sequenceLength - sequenceHop);读(audioOutBuffer (sequenceLength - sequenceHop) * windowLength);结束虽然featureBuffer。NumUnreadSamples >= sequenceHop && featureBufferInitialized features = read(featureBuffer,sequenceLength,sequenceLength - sequenceHop);特性(isnan(特性))= 0;%仅使用新功能更新%标准差和平均值。将特征标准化。localSTD=movSTD(features(end sequenceHop+1:end,:);localMean=movMean(features(end sequenceHop+1:end,:);features=(features-localMean(end,:)。/localSTD(end,:);decision=classify(speechDetectNet,features');decision(end sequenceHop+1:end);decision=double(decision)-1;decision=Replem(decision,HopLen;audioHop=读取(AudioBuffer,sequenceHop*hopLength);%听演讲或演讲+噪音deviceWriter(audioHop(:,channelToListenTo));%将语音+噪波、原始语音和%语音活动检测。范围(audioHop(:,1),audioHop(:,2),audioHop(:,1)*决定)结束结束发布(deviceWriter)发布(audioInBuffer)发布(audioOutBuffer)发布(featureBuffer)发布(movSTD)发布(movMean)发布(scope)结束

工具书类

[1]看守P.“语音命令:用于单词语音识别一个公共数据集”,2017年可从https://storage.googleapis.com/download.tensorflow.org/data/speech_commands_v0.01.tar.gz.Google 2017版权所有。语音命令数据集根据Creative Commons Attribute 4.0许可证获得许可