主要内容

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

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

介绍

语音活动检测是许多音频系统的重要组成部分,例如自动语音识别和扬声器识别。语音活动检测可以在低信噪比(SNR)情况下尤其具有挑战性,其中语音被噪声阻挡。

该示例使用长期内存(LSTM)网络,这些网络是一种经常性的神经网络(RNN)非常适合研究序列和时间序列数据。LSTM网络可以在序列的时间步长之间学习长期依赖性。LSTM层(lstmLayer(深度学习工具箱))可以在向前方向上看时间序列,而双向LSTM层(bilstmLayer(深度学习工具箱))可以从正反两个方向看时间序列。这个例子使用了一个双向LSTM层。

这个例子训练了一个语音活动检测双向LSTM网络与频谱特征序列和谐波比率度量。

在高信噪比的情况下,传统的语音检测算法表现良好。读一个由单词组成的音频文件,中间有停顿。重新采样音频到16千赫。听录音。

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

使用检测找到语音区域的功能。的检测功能正确识别所有的言语区域。

win =汉明(50e-3 * fs,“周期”);detectSpeech(演讲、fs、'窗户',赢了)

在-20分贝的信噪比下损坏洗衣机的音频信号。听损坏的音频。

(噪音、fileFs) = audioread ('WashingMachine-16-8-Mono-200secs.mp3');噪音=重新取样(噪音、fs、fileFs);信噪比= -20;noise egain = 10^(-SNR/20) * norm(speech) / norm(noise);noisySpeech = speech + noiseGain*noise(1:numel(speech));noisySpeech = noisySpeech. / max (abs (noisySpeech));声音(noisySpeech fs)

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

detectSpeech (noisySpeech fs,'窗户',赢了)

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

url =“http://ssd.mathworks.com/万博1manbetxsupportfiles/audio/VoiceActivityDetection.zip”;downloadNetFolder = tempdir;netFolder = fullfile (downloadNetFolder,“VoiceActivityDetection”);如果~存在(netFolder“dir”)disp('下载掠夺网络(1文件 -  8 MB)......')解压缩(URL,DownloadNetFolder)结尾load(fullfile(netfolder,“voiceActivityDetectionExample.mat”));
SpeemDetectNet.
seathicDetectNet =具有属性的系列网络:图层:[6×1 nnet.cnn.layer.layer]输入名称:{'sequentInput'} OutputNames:{'classOutput'}
af
afe = audioFeatureExtractor with properties: properties Window: [256×1 double] OverlapLength: 128 SampleRate: 16000 FFTLength: [] SpectralDescriptorInput:'linearSpectrum' Enabled Features spectralCentroid, spectralCrest, spectralEntropy, spectralFlux, spectral峰度,spectralRolloffPoint, spectralSkewness, spectralSlope, harmonicRatio Disabled Features linearSpectrum, melSpectrum, barkSpectrum, erbSpectrum, mfcc, mfccDelta mfccDelta adelta, gtcc, gtccDelta, gtccDelta, spectralDecreasespectralFlatness spectralSpread, pitch要提取一个特征,设置对应的属性为true。例如,obj。MFCC = true,将MFCC添加到已启用特性列表中。

从语音数据中提取特征,并进行归一化处理。对特性进行定位,使时间跨列。

特点=提取物(AFE,Noisyspeech);特点=(功能 - 平均(特点,1))./ STD(特点,[],1);功能=特征';

将特征通过语音检测网络,对每个特征向量进行分类,判断是否属于一帧语音。

decisionsCategorical =分类(speechDetectNet、特点);

每个决定对应于分析的分析窗口audioFeatureExtractor.复制决策,使它们与音频样本一一对应。绘制演讲,嘈杂的演讲和VAD决策。

decisionsWindow = 1.2 *(双(decisionsCategorical) 1);decisionsSample = [repelem (decisionsWindow(1)元素个数(afe.Window)),...repelem (decisionsWindow(2:结束),元素个数(afe.Window) -afe.OverlapLength)];t =(0:元素个数(decisionsSample) 1) / afe.SampleRate;情节(t, noisySpeech(1:元素个数(t)),...t,演讲(1:元素个数(t)),...t, decisionsSample);包含(“时间(s)”) ylabel (“振幅”) 传奇(的嘈杂的演讲“演讲”'VAD'“位置”“西南”

您还可以在流环境中使用训练过的VAD网络。为了模拟流环境,首先将语音和噪声信号保存为WAV文件。为了模拟流输入,您将从文件中读取帧并按所需的信噪比混合它们。

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

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

testDuration =20.;sequenceLength =400;sequenchop =20.;信噪比=-20;noise egain = 10^(-SNR/20) * norm(speech) / norm(noise);signalToListenTo =“吵”

调用流演示助手功能来观察VAD网络在流音频上的性能。使用活动控件设置的参数不会中断流示例。当流演示完成后,您可以修改演示的参数,然后再次运行流演示。中可以找到流演示的代码万博1manbetx支持功能

求助者特特命运迪莫(SpeemDetectNet,AFE,...“Speech.wav”“Noise.wav”...testduration,sequencelength,sequenchop,signaltolistento,coxicgain);

本例的其余部分将对VAD网络进行培训和评估。

培训和评估VAD网络

培训:

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

  2. 创建一个训练信号,由不同持续时间的沉默片段分开的语音片段组成。

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

  4. 提取由噪声信号的光谱特性和谐波比组成的特征序列。

  5. 使用要素序列列出LSTM网络以识别语音活动区域。

预测:

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

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

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

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

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

以下是培训过程的草图。

以下是预测过程的草图。你用训练过的网络进行预测。

加载语音命令数据集

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

url ='https://ssd.mathwands.com/万博1manbetxsupportfiles/audio/google_speech.zip';downloadFolder = tempdir;datasetFolder = fullfile (downloadFolder,“google_speech”);如果~存在(datasetFolder“dir”)disp(“正在下载谷歌语音命令数据集(1.9 GB)……”)解压缩(URL,DownloadFolder)结尾
下载Google语音命令数据集(1.9 GB)......

创建一个audioDatastore指向训练数据集。

adsTrain = audioDatastore (fullfile (datasetFolder“火车”),“Includesubfolders”,真正的);

创建一个audioDatastore指向验证数据集。

adsvalidation = audiodataStore(fullfile(datasetfolder,“验证”),“Includesubfolders”,真正的);

创建语音加沉默训练信号

使用读取音频文件的内容.得到样本率Adsinfo.结构。

(数据、adsInfo) =阅读(adsTrain);Fs = adsInfo.SampleRate;

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

声音(数据、Fs)

绘制音频信号。

timeVector = (1/Fs) * (0:numel(data)-1); / /时间矢量情节(timeVector、数据)ylabel (“振幅”)包含(“时间”)标题(“音频样本”网格)

该信号具有不包含有用的语音信息的非语音部分(静音,背景噪声等)。此示例使用默默地默认检测功能。

提取数据的有用部分。定义50 ms的周期锤锤窗口以进行分析。称呼检测没有输出参数来绘制检测到的语音区域。称呼检测再次返回检测到的语音的索引。分离检测到的语音区域,然后使用声音命令,收听音频。

win =汉明(50e-3 * fs,“周期”);检测expeech(数据,FS,'窗户',赢了);

语音indices =检测echech(数据,fs,'窗户',赢了);声音(数据(言语(1,1):语音indices(1,2)),FS)

检测函数返回紧密包围检测到的语音区域的指数。实验地确定了,对于该示例,将检测到的语音指数扩展到任一侧的五个帧增加了最终模型的性能。通过五个帧扩展语音指数,然后侦听演讲。

言语indices(1,1)= max(语音indices(1,1) -  5 * numel(win),1);言语indices(1,2)= min(语音indices(1,2)+ 5 * numel(win),numel(数据));声音(数据(言语(1,1):语音indices(1,2)),FS)

重置训练数据存储,并将文件中的文件顺序置于数据存储中。

重置(adstrain)adstrain = shuffle(adstrain);ADSValidation = Shuffle(ADSValidation);

检测函数计算基于统计的阈值以确定语音区域。您可以跳过阈值计算,加速检测通过直接指定阈值来函数。确定数据集的阈值,调用检测在文件采样并获取它计算的阈值。采取阈值的平均值。

TM = [];为了index = 1:20 0 data = read(adsTrain); / /读取数据[~ T] = detectSpeech(数据、Fs、'窗户',赢了);tm = [tm; t];结尾T =意味着(TM);重置(adsTrain)

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

预先分配训练信号。

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

预先利用语音活动训练面具。掩模中的1的值对应于位于具有语音活动区域的样本。0值对应于没有语音活动的区域。

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

最大静默段持续时间为2秒。

maxsilencesmment = 2;

通过呼叫构造训练信号在循环中的数据存储上。

numSamples = 1;NUMSAMPLES <持续时间数据=读取(adstrain);数据=数据./ max(abs(数据));%标准化幅度确定语音区域IDX =检测expeech(数据,FS,'窗户',赢了,“阈值”,t);%如果检测到语音区域如果〜isempty(idx)%扩展索引5帧Idx (1,1) = max(1, Idx (1,1) - 5*numel(win));idx(1、2)= min(长度(数据),idx(1、2)+ 5 *元素个数(赢得));%隔离演讲data =数据(idx (1,1): idx(1、2);将语音片段写入训练信号audioTraining (numSamples: numSamples +元素个数(数据)1)=数据;%设置VAD基线maskTraining (numSamples: numSamples +元素个数(数据)1)= true;%随机沉默时间numSilenceSamples =兰迪(maxSilenceSegment * Fs, 1,1);numSamples = numSamples + nummel (data) + numsilencessamples;结尾结尾

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

图范围= 1:10*Fs;情节((1 / Fs) *(范围1)audioTraining(范围);抓住情节((1 / Fs) *(范围1)maskTraining(范围);网格行= findall (gcf,“类型”“行”);行(1)。线宽= 2;包含(“时间”) 传奇(“信号”“演讲地区”)标题(“训练信号(前10秒)”);

听训练信号的前10秒。

声音(audioTraining(范围),Fs);

向训练信号添加噪声

通过在语音信号中加入洗衣机噪声,使训练信号染上洗衣机噪声,使其信噪比为-10 dB。

读8千赫噪声,并将其转换为16千赫。

噪音= audioread (“洗衣机- 16 - 8 mono - 1000 - secs.mp3”);噪音=重新取样(噪音、2、1);

损坏训练信号,噪音。

喉头=觉醒(1:NUMER(噪音));SNR = -10;噪声= 10 ^( -  snr / 20)*噪声*常规(喉头)/常规(噪音);antioiotRainingNoisy =觉醒+噪音;AudioitRainingNoisy = AudiotRainingNoisy / Max(ABS(录音机));

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

图绘图((1 / fs)*(范围-1),呼吸率诺(范围));抓住情节((1 / Fs) *(范围1)maskTraining(范围);网格行= findall (gcf,“类型”“行”);行(1)。线宽= 2;包含(“时间”) 传奇(“噪声信号”“言语区”)标题(“训练信号(前10秒)”);

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

声音(audioTrainingNoisy(范围)、Fs)

请注意,您使用无声语音加静音信号获得了基线语音活动掩码。确认使用检测在噪声损坏的信号上不产生良好的结果。

speechIndices = detectSpeech (audioTrainingNoisy Fs,'窗户',赢了);语音indices(:,1)= max(1,语音indices(:,1) -  5 * numel(win));言语indices(:,2)= min(Numel(antioiotRainingnoisy),语言indices(:,2)+ 5 * numel(win));noisymask = zeros(大小(呼吸点钟表));为了II = 1:尺寸(语音indices)noisymask(语音indices(ii,1):言语indices(ii,2))= 1;结尾

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

图绘图((1 / fs)*(范围-1),呼吸率诺(范围));抓住绘图((1 / fs)*(范围-1),noisymask(范围));网格行= findall (gcf,“类型”“行”);行(1)。线宽= 2;包含(“时间”) 传奇(“噪声信号”“来自嘈杂信号的掩模”)标题(“训练信号(前10秒)”);

创建语音加静音验证信号

创建200秒的嘈杂语音信号以验证培训的网络。使用验证数据存储。请注意,验证和培训数据存储具有不同的扬声器。

预分配验证信号和验证掩码。你将使用这个面具来评估训练网络的准确性。

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

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

numSamples = 1;NumSamples <持续时间数据=读取(ADSValidation);数据=数据./ max(abs(数据));%标准化幅度确定语音区域IDX =检测expeech(数据,FS,'窗户',赢了,“阈值”,t);%如果检测到语音区域如果〜isempty(idx)%扩展索引5帧Idx (1,1) = max(1, Idx (1,1) - 5*numel(win));idx(1、2)= min(长度(数据),idx(1、2)+ 5 *元素个数(赢得));%隔离演讲data =数据(idx (1,1): idx(1、2);将语音片段写入训练信号audioValidation (numSamples: numSamples +元素个数(数据)1)=数据;%设置VAD基线MaskValidation(NumSamples:NumSamples + Numel(Data)-1)= true;%随机沉默时间numSilenceSamples =兰迪(maxSilenceSegment * Fs, 1,1);numSamples = numSamples + nummel (data) + numsilencessamples;结尾结尾

通过向语音信号添加洗衣机噪声来损坏带洗衣机噪声的验证信号,使得信噪比为-10 dB。对验证信号使用不同的噪声文件而不是您为训练信号做的。

噪音= audioread (“洗衣机- 16 - 8 mono - 200 - secs.mp3”);噪音=重新取样(噪音、2、1);噪音=噪音(1:持续时间);audioValidation = audioValidation(1:元素个数(噪声));noise = 10^(-SNR/20) * noise * norm(audioValidation) / norm(noise);audioValidationNoisy = audioValidation + noise;audioValidationNoisy = audioValidationNoisy / max(abs(audioValidationNoisy));

提取训练功能

本例使用以下特征训练LSTM网络:

这个例子用途audioFeatureExtractor为特征集创建一个最佳的特征提取管道。创建一个audioFeatureExtractor对象提取特征集。使用256点Hann窗口,50%重叠。

afe = audioFeatureExtractor ('采样率',fs,...'窗户'损害(256,“周期”),...“OverlapLength”, 128,......“spectralCentroid”,真的,...“spectralCrest”,真的,...“spectralEntropy”,真的,...“spectralFlux”,真的,...“spectralKurtosis”,真的,...“spectralRolloffPoint”,真的,...“spectralSkewness”,真的,...“spectralSlope”,真的,...“harmonicRatio”,真正的);FeatureStraining = Extract(AFE,AudiotRainingNoisy);

显示特征矩阵的尺寸。第一个维度对应于信号被分割成的窗口数(它取决于窗口长度和重叠长度)。第二个维度是本例中使用的特性数量。

[numWindows, numFeatures] =大小(featuresTraining)
numWindows = 125009
numFeatures = 9

在分类应用程序中,良好的做法是标准化所有特征,以具有零均值和单位标准偏差。

计算每个系数的平均值和标准差,并使用它们来规范化数据。

M =意味着(featuresTraining, 1);S =性病(featuresTraining [], 1);featurestrain = (featurestrain - M) ./ S;

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

audioValidationNoisy featuresValidation =提取(afe);featuresValidation = (featuresValidation - mean(featuresValidation,1)) ./ std(featuresValidation,[],1);

每个功能对应于128个数据样本(跳跃长度)。对于每跳,将预期的语音/否语音值设置为与那些128个样本相对应的基线掩模值的模式。将语音/无语音掩码转换为分类。

windowLength =元素个数(afe.Window);hopLength = windowLength - afe.OverlapLength;range = (hopLength) * (1:size(featurestrain,1)) + hopLength;maskMode = 0(大小(范围);为了index = 1:numel(range) maskMode(index) = mode(maskTraining((index-1)*hopLength+1:(index-1)*hopLength+windowLength));结尾maskTraining = maskMode。”;maskTrainingCat =分类(maskTraining);

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

range = (hopLength) * (1:size(featuresValidation,1)) + hopLength;maskMode = 0(大小(范围);为了maskMode(index) = mode(maskValidation((index-1)*hopLength+1:(index-1)*hopLength+windowLength));结尾maskValidation = maskMode。”;maskValidationCat =分类(maskValidation);

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

Sequencelength = 800;sequencoverlap = round(0.75 *序列);TrainFeaturecell = HelperFeatureVector2sequence(FeatureStraining',Sequencelength,sequencoverlap);trainlabelcell = helperfeaturevector2sequence(masktrainingcat',sequencelength,sequengoverlap);

定义LSTM网络架构

LSTM网络可以学习序列数据时间步长之间的长期依赖关系。本例使用双向LSTM层bilstmLayer(深度学习工具箱)查看向前和向后方向的序列。

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

层= [...sequenceInputLayer(size(特征过验证,2))bilstmlayer(200,“OutputMode”“序列”)Bilstmlayer(200,“OutputMode”“序列”) fulllyconnectedlayer (2) softmaxLayer classificationLayer];

接下来,为分类器指定训练选项。集MaxEpochs20.这样网络就能通过20个训练数据。集MiniBatchSize64.因此,网络一次看64个训练信号。集绘图“训练进步”当迭代次数增加时,生成显示培训进度的地块。集详细的错误的禁用打印与图中显示的数据相对应的表输出。集洗牌“every-epoch”在每个时代开始时播放训练序列。集LearnRateSchedule“分段”每次经过一定数量的纪元(10),学习率就降低一个指定的因子(0.1)。集ValidationData到验证预测因子和目标。

本例使用自适应矩估计(ADAM)求解器。ADAM在lstm这样的递归神经网络(RNNs)中比默认的SGDM (SGDM)求解器表现更好。

maxEpochs = 20;miniBatchSize = 64;选择= trainingOptions (“亚当”...“MaxEpochs”maxEpochs,...“MiniBatchSize”miniBatchSize,...“洗牌”“every-epoch”...“详细”,0,...“SequenceLength”sequenceLength,...“ValidationFrequency”、地板(元素个数(trainFeatureCell) / miniBatchSize),...“ValidationData”, {featuresValidation。“maskValidationCat。”},...“阴谋”“训练进步”...“LearnRateSchedule”“分段”...“LearnRateDropFactor”, 0.1,...“LearnRateDropPeriod”5);

训练LSTM网络

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

doTraining = true;如果doTraining [speechDetectNet,netInfo] = trainNetwork(trainFeatureCell,trainLabelCell,layers,options);流("验证精度:%f % .\n",netinfo.finalValidationAccuracy);别的加载SpeemDetectNet.结尾
验证准确度:91.320312%。

使用训练有素的网络检测语音活动

使用培训的网络估算验证信号中的语音活动。将估计的VAD掩码从“分类”转换为“双倍”。

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

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

figure cm = confusionchart(maskValidation,EstimatedVADMask,“标题”“验证准确性”);cm.columnsummary =“column-normalized”;cm.rowsummary =“row-normalized”

如果您更改了网络或特征提取管道的参数,请考虑使用新的网络和保存MAT文件audioFeatureExtractor对象。

resaveNetwork =错误的如果resaveNetwork保存('audio_voiceacctivitydetectionexample.mat'“speechDetectNet”“安全的”);结尾

万博1manbetx支持功能

将特征向量转换为序列

函数[序列,序列perfile] = HelperFeatureVector2序列(功能,FeatureVectorsPersequence,FeatureVectoroverlap)如果featureVectorsPerSequence <= featureVectorOverlap error(重叠特征向量的数量必须小于每个序列的特征向量的数量。结尾如果~iscell(feature) feature = {feature};结尾hopLength = featureVectorsPerSequence - featureVectorOverlap;idx1 = 1;序列= {};sequencePerFile =细胞(元素个数(特性),1);为了ii = 1:numel(features) sequencePerFile{ii} = floor(((size(features{ii},2) - featureVectorsPerSequence)/hopLength) + 1;idx2 = 1;为了j = 1:sequenceperfile {ii}序列{idx1,1} =特征{ii}(:, idx2:idx2 + featurevectorspersequence  -  1);%#OK Idx1 = Idx1 + 1;idx2 = idx2 + hopLength;结尾结尾结尾

流媒体演示

函数helperStreamingDemo (speechDetectNet afe cleanSpeech,噪音,testDuration, sequenceLength, sequenceHop, signalToListenTo, noiseGain)

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

SpeemReader = DSP.Audiofilereader(CleanSpeech,“PlayCount”、正);noiseReader = dsp。AudioFileReader(noise,“PlayCount”、正);fs = speechReader.SampleRate;

创建一个dsp。MovingStandardDeviation对象和一个dsp。MovingAverage对象。您将使用这些来确定标准化的标准偏差和均值。统计数据应随着时间的推移而改善。

movSTD = dsp。MovingStandardDeviation (“方法”指数权重的“ForgettingFactor”1);movmean = dsp.movi​​ngaverage(“方法”指数权重的“ForgettingFactor”1);

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

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

对于音频缓冲区,您将缓冲原始的干净的语音信号,和噪声信号。您将只播放指定的内容signalToListenTo.转换signalToListenTo变量到您要收听的频道。

channelToListenTo = 1;如果比较字符串(signalToListenTo“清洁”)ChannelTolistento = 2;结尾

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

范围= timescope ('采样率'fs,...'timespansource'“属性”...'时间跨度'3,...“BufferLength”,fs * 3 * 3,...'ylimits'[1],...“TimeSpanOverrunAction”“滚动”...“ShowGrid”,真的,...'numinputports'3,...'layoutdimensions'(3,1),...“标题”的嘈杂的演讲);scope.activedisplay = 2;scope.title =.'干净的演讲(原创)';范围。YLimits = [-1 1];范围。ActiveDisplay = 3;scope.title =.'检测到演讲';范围。YLimits = [-1 1];

创建一个audiodevicewriter.反对播放来自扬声器的原始或嘈杂的音频。

deviceWriter = audioDeviceWriter ('采样率'fs);

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

windowLength =元素个数(afe.Window);hopLength = windowLength - afe.OverlapLength;mymax = 0;audiobufferinitialized = false;featurebufferinitialized = false;

运行流媒体演示。

抽搐toc < testDuration读取一帧语音信号和一帧噪声信号speechIn = speechReader ();noiseIn = noiseReader ();%混合指定SNR的语音和噪声noisyAudio = speech + noiseGain*noise ein;为标准化更新一个运行最大值myMax = max (myMax max (abs (noisyAudio)));%将嘈杂的音频和语音写入缓冲区写(audioInBuffer [noisyAudio speechIn]);如果缓冲有足够的样本,则%%标记为初始化和按读取指针的音频缓冲区%为音频缓冲区向上一个窗口长度。如果探测器juffer.numunReadsamples> = windowlength &&〜audiobufferinitialized audiobufferinitialized = true;读(vightinbuffer,windowlength);结尾%如果音频缓冲区中有足够的样本来计算一个特征%向量,读取样本,归一化,提取特征向量,写入%最新的特征向量到特征缓冲区。(探测器juffer.numunReadsamples> = hoplength)&& audiobufferinitialized x = read(vightinbuffer,windowlength + hoplength,windowlength);写(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> = sequenchop && featurebufferinitialized功能=读取(featurebuffer,sequencelength,sequencelength  -  sequenchop);功能(ISNAN(特征))= 0;%只使用新功能来更新%标准差和平均值。规范化的特点。localSTD = movSTD(特性(end-sequenceHop + 1:,:));localMean = movMean(特性(end-sequenceHop + 1:,:));feature = (features - localMean(end,:))) ./ localSTD(end,:);决定= (speechDetectNet,功能分类');决策=决策(end-sequenceHop + 1:结束);= double(Decision)' - 1;决定= repelem(决定,hopLength);audioHop =阅读(audioOutBuffer, sequenceHop * hopLength);听演讲或演讲+噪音DeviceWriter(耳壁(AudioHop(:,ChannelTolistento));视觉化演讲+噪音,原始演讲,和%语音活动检测。范围(Audiohop(:,1),张视听(:,2),张视听(:,1)。*决定)结尾结尾release(deviceWriter) release(audioInBuffer) release(audioOutBuffer) release(featureBuffer) release(movSTD) release(movMean) release(scope)结尾

参考文献

[1]监狱长P。“语音指令:单字语音识别的公共数据集”,2017。可以从https://storage.googleapis.com/download.tensorflow.org/data/speech_commands_v0.01.tar.gz..版权2017年谷歌。语音命令数据集是在知识共享署名4.0许可下使用的