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

此示例显示如何使用深度学习检测低信噪比环境中的语音区域。该示例使用语音命令数据集培训双向短期内存(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)

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

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

在-20 dB SNR处用洗衣机噪声损坏音频信号。听取损坏的音频。

[噪声,filefs] = audioread('WashingMachine-16-8-Mono-200secs.mp3');噪声=重组(噪声,FS,FILEFS);SNR = -20;noise egain = 10^(-SNR/20) * norm(speech) / norm(noise);noisyspeech =演讲+ jecuegain *噪音(1:numel(语音));noisyspeech = noisyspeech./max(abs(noisyspeech));声音(Noisyspeech,FS)

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

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

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

加载(“Audio_VoiceActivityDetectionExample.mat”'SpeemDetectNet''afe'
speechDetectNet
seathicDetectNet =具有属性的系列网络:图层:[6×1 nnet.cnn.layer.layer]输入名称:{'sequentInput'} OutputNames:{'classOutput'}
afe
AFE = AudioFeatureextractor具有属性:属性窗口:[256×1双]俯视长度:128 Samplege:16000 FFTLINPUT:[] SpectralDescriptorInput:'Linearspectrum'启用功能Spectralcentroid,SpectralcRest,Spectraloptopy,Spectralflux,Spectarkurtis,Spectralrock Offpectswnesswness,Spectralslope,Handonicratio DiscatectPoint SpectrancesswnessLinearspectrum,Melspectrum,Barkspectrum,Erbspectrum,MFCC,MFCCDelta MFCCDeltadelta,GTCC,GTCCDelta,GTCCDeltadelta,SpectralDeCrease,Spectralflate Spectralsprapread,Stick才能提取一个功能,将相应的属性设置为True。例如,obj.mfcc = true,将mfcc添加到启用功能列表中。

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

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

通过语音检测网络通过功能来将每个特征向量分类为属于语音帧。

decisionsCategorical=分类(speechDetectNet,特征);

每个决策对应于由音频特征提取器.复制决策,以便它们与音频样本相一对一对应。绘制语音,嘈杂的演讲和VAD决定。

DecisionsWindow = 1.2 *(Double(DeceningScational)-1);DecisionSample = [Repelem(DecisionsWindow(1),Numel(AFE.Window)),......repelem (decisionsWindow(2:结束),元素个数(afe.Window) -afe.OverlapLength)];t =(0:元素个数(decisionsSample) 1) / afe.SampleRate;情节(t, noisySpeech(1:元素个数(t)),......t,演讲(1:元素个数(t)),......T,Decisionsample);Xlabel('时间'')ylabel(“振幅”) 传奇('吵闹的演讲'“演讲”'VAD''地点''西南'

您还可以在流上下文中使用培训的VAD网络。要模拟流环境,请先将语音和噪声信号保存为WAV文件。要模拟Streaming Input,您将从文件中读取帧并将其与所需的SNR混合。

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

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

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

呼叫流式演示帮助程序功能以观察VAD网络在流式音频上的性能。使用Live控件设置的参数不会中断流媒体示例。在流式演示完成后,您可以修改演示的参数,然后再次运行流媒体演示。您可以找到流媒体演示的代码金宝app支持功能

helperStreamingDemo (afe speechDetectNet,......“Speech.wav”“Noise.wav”......testduration,sequencelength,sequenchop,signaltolistento,coxicgain);

该示例的其余部分通过培训和评估VAD网络。

培训和评估VAD网络

培训:

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

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

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

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

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

预测:

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

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

  3. 从嘈杂的测试信号中提取特征序列。

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

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

这是培训过程的草图。

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

加载语音命令数据集

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

url =“https://ssd.mathworks.com/金宝appsupportfiles/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'火车'),“upplyubfolders”,真的);

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

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

创建语音加沉默训练信号

使用读取音频文件的内容.从中获取样品率adsInfo结构体。

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

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

声音(数据,FS)

绘制音频信号。

TimeVector =(1 / FS)*(0:numel(数据)-1);绘图(TimeVector,Data)Ylabel(“振幅”)Xlabel(“时间(s)”)标题(“音频样本”) 网格

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

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

win =汉明(50e-3 * fs,“周期”);检测expeech(数据,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 = [];index1 = 1:500数据=读取(adstrain);[〜,t] =检测echech(数据,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 =检测expeech(数据,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));将语音片段写入训练信号朝南(NumSamples:NumSamples + Numel(Data)-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),筛选(范围));网格行= findall (gcf,“类型”“线”);线(1).linewidth = 2;Xlabel(“时间(s)”) 传奇(“信号”“讲话区域”)标题(“训练信号(前10秒)”);

听训练信号的前10秒。

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

在训练信号中添加噪声

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

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

噪音= audioread (“WashingMachine-16-8-Mono-1000secs.mp3”);噪声=重组(噪声,2,1);

损坏训练信号,噪音。

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

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

图绘制((1 / Fs) *(范围1)audioTrainingNoisy(范围);持有绘图((1 / FS)*(范围-1),筛选(范围));网格行= findall (gcf,“类型”“线”);线(1).linewidth = 2;Xlabel(“时间(s)”) 传奇(“嘈杂的信号”“讲话区”)标题(“训练信号(前10秒)”);

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

声音(audioTrainingNoisy(范围)、Fs)

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

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: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).linewidth = 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 =检测expeech(数据,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));将语音片段写入训练信号audioplation(NumSamples:NumSamples + Numel(Data)-1)=数据;%设置VAD基线maskValidation (numSamples: numSamples +元素个数(数据)1)= true;%随机静默期numSilenceSamples =兰迪(maxSilenceSegment * Fs, 1,1);numSamples = numSamples + nummel (data) + numsilencessamples;结束结束

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

噪音= audioread (“WashingMachine-16-8-Mono-200secs.mp3”);噪声=重组(噪声,2,1);噪声=噪声(1:持续时间);audioporidation = audioplation(1:numel(噪声));噪声= 10 ^( -  snr / 20)*噪声*常规(视听)/常规(噪音);audioporidationnoisy =视听+噪音;audioporidationnoisy = audioporidationnoisy / max(abs(absioporationnoisy));

提取训练功能

此示例使用以下功能列出LSTM网络:

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

afe = audioFeatureExtractor ('采样率'Fs,......'窗户',汉恩(256,“周期”),......'overlaplencth',128,............'spectralcentroid',真的,......'spectralcrest',真的,......“spectralEntropy”,真的,......'spectralflux',真的,......'spectarkurtosis',真的,......'spectralrolloffpoint',真的,......'spectrancewswness',真的,......“spectralSlope”,真的,......'halmonicratio',真的);FeatureStraining = Extract(AFE,AudiotRainingNoisy);

显示特征矩阵的尺寸。第一维度对应于信号被破坏的窗口数(取决于窗口长度和重叠长度)。第二维度是此示例中使用的特征数。

[NumWindows,NumFeatures] =大小(特色)
numwindows = 125009
numfeatures = 9.

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

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

m =均值(特色,1);s = std(featurestraining,[],1);FeatureStraining =(FeatureStraining  -  M)./ S;

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

特点验证=提取物(AFE,audioporationNoisy);特征idation =(特点过验证 - 意思是(特征过验证,1))./ std(特点过验,[],1);

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

windowLength =元素个数(afe.Window);hopLength = windowLength - afe.OverlapLength;Range =(HopLength)*(1:尺寸(特色(特色,1))+ HopLength;maskmode = zeros(尺寸(范围));index = 1:numel(range) maskMode(index) = mode(maskTraining((index-1)*hopLength+1:(index-1)*hopLength+windowLength));结束masktraining = maskMode。';masktrainingcat =分类(掩蔽);

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

range = (hopLength) * (1:size(featuresValidation,1)) + hopLength;maskmode = zeros(尺寸(范围));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通过训练数据进行。集小匹匹匹匹配64.这样这个网络一次就能观察64个训练信号。集绘图“培训 - 进展”当迭代次数增加时,生成显示培训进度的地块。集verb禁用打印与图中显示的数据相对应的表输出。集洗牌“每个时代”在每个时代开始时播放训练序列。集学习宿舍“分段”每次通过一定数量的时期(10)都通过了指定因子(0.1)的学习率。集ValidationData到验证预测因子和目标。

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

maxEpochs = 20;miniBatchSize = 64;选择= trainingOptions (“亚当”......“MaxEpochs”,maxepochs,......“迷你atchsize”,小匹马,......“洗牌”“每个时代”......“详细”,0,......“序列”sequenceLength,......“验证职业”,地板(numel(trainFeatureCell)/小批量尺寸),......“ValidationData”,{featuresvalidation。',maskvalidationcat。'},......“阴谋”“培训 - 进展”......“Learnrateschedule”“分段”......“LearnRateDropFactor”, 0.1,......“学习ropperiod”5);

训练LSTM网络

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

dotraining = true;如果dotRaining [SpealDetectNet,NetInfo] = Trainnetwork(训练鼠Featurecell,TrainLabelcell,图层,选项);fprintf(“验证准确性:%f%。\ n”,netinfo.finalValidationAccuracy);其他的负载speechDetectNet结束
验证精度:90.089844%。

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

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

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

从实际和估计标签的载体计算和绘制验证混淆矩阵。

figure cm = confusionchart(maskValidation,EstimatedVADMask,“标题”“验证准确性”);厘米。ColumnSummary =“column-normalized”;厘米。RowSummary =“行标准化”

如果您更改了网络或特征提取管道的参数,请考虑使用新网络重新定位垫文件音频特征提取器对象。

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

金宝app支持功能

将特征向量转换为序列

功能[序列,sequencePerFile] = helperFeatureVector2Sequence(特性、featureVectorsPerSequence featureVectorOverlap)如果featureVectorsPerSequence <= featureVectorOverlap error(重叠特征向量的数量必须小于每个序列的特征向量的数量。结束如果~iscell(feature) feature = {feature};结束hopLength = featureVectorsPerSequence - featureVectorOverlap;idx1 = 1;序列= {};sequencePerFile =细胞(元素个数(特性),1);II = 1:NUMER(特征)sequencerfile {II} =楼层((尺寸(特征{ii},2) -  featurevectorspersequence)/ hoplength)+ 1;IDX2 = 1;j = 1:sequenceperfile {ii}序列{idx1,1} =特征{ii}(:, idx2:idx2 + featurevectorspersequence  -  1);% #好< AGROW >Idx1 = Idx1 + 1;idx2 = idx2 + hopLength;结束结束结束

流媒体演示

功能everlerstreamingdemo(SpeemDetectNet,AFE,Cleanspeech,噪声,测试,序列精细,Sequenchop,SignalTolistento,Covergain)

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

SpeemReader = DSP.Audiofilereader(CleanSpeech,“PlayCount”、正);noisereader = dsp.audiofilereader(噪音,“PlayCount”、正);fs = speechReader.SampleRate;

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

movSTD = dsp。MovingStandardDeviation ('方法'指数权重的'忘记就活跃',1);movmean = dsp.movi​​ngaverage('方法'指数权重的'忘记就活跃',1);

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

audioinbuffer = dsp.asyncuffer;featurebuffer = dsp.asyncuffer;AudioOutBuffer = DSP.AsyncBuffer;

对于音频缓冲区,您将缓冲原始的清洁语音信号和嘈杂信号。您将仅播放指定的signalToListenTo.转换signalToListenTo变量到您要收听的频道。

channelToListenTo = 1;如果Strcmp(SignalTolistento,“清洁”) channelToListenTo = 2;结束

创建一个dsp.timescope.将原始语音信号、网络应用到的噪声信号以及网络的决策输出可视化。

范围= dsp.timescope('采样率',fs,......'时间跨度'3,......“缓冲长度”,fs * 3 * 3,......“YLimits”,[ -  1.2 1.2],......'timespanoverrunaction''滚动'......“ShowGrid”,真的,......“NumInputPorts”3,......'layoutdimensions'(3,1),......“标题”'吵闹的演讲');scope.activedisplay = 2;scope.title =“干净的演讲(原始)”;范围。ActiveDisplay = 3;scope.title =“发现演讲”

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

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

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

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

运行流媒体演示。

抽搐尽管toc %读取一帧语音信号和一帧噪声信号STANCENIN = SECONDECREADER();otcomein = noiseReader();%在指定的信噪比下混合语音和噪声noisyAudio = speech + noiseGain*noise ein;为标准化更新一个运行最大值myMax=max(myMax,max(abs(noiseyaudio));%将嘈杂的音频和语音写入缓冲区写(audioInBuffer [noisyAudio speechIn]);%如果缓冲足够的样本,%标记为初始化和按读取指针的音频缓冲区%为音频缓冲区向上一个窗口长度。如果audioInBuffer。NumUnreadSamples >= windowLength && ~audioBufferInitialized audioBufferInitialized = true;读(audioInBuffer 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 >= sequenceHop && featureBufferInitialized features = read(featureBuffer,sequenceLength,sequenceLength - sequenceHop);特性(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)。*决定)结束结束释放(DeviceWriter)释放(AudioInBuffer)释放(AudioOutBuffer)释放(FeatureBuffer)释放(MOVSTD)释放(MOVESEAN)释放(范围)结束

工具书类

[1] Warden P.“语音命令:用于单词语音识别的公共数据集”,2017.可从中获取https://storage.googleapis.com/download.tensorflow.org/data/speech_commands_v0.01.tar.gz..版权所有Google 2017.语音命令数据集在Creative Commons atticution 4.0许可下获得许可