matlab处理音频文件——语音识别实例

任务

教科书式的信号处理偏理论,不妨尝试现实中的音频文件,与实践接轨。

在工具包Signal Processing Toolbox的文档示例中有Find a Signal in a Measurement,通过相关xcorr()的计算找到一段数据中是否存在指定信号:与匹配滤波器的原理相一致。

导入音频文件

根据matlab提供丰富的文档说明

wholeFilePath='C:\Users\cascara\Documents\录音\paragraph.m4a'
keyFilePath='C:\Users\cascara\Documents\录音\sentence4.m4a'
wholeInfo = audioinfo(wholeFilePath)
[whole,Fs1] = audioread(wholeFilePath);
sound(whole,Fs1);
keyInfo = audioinfo(keyFilePath)
[key,Fs2] = audioread(keyFilePath);
sound(key,Fs2);

audioinfo(FilePath)

显示路径为FilePath文件的相应信息,例如第一个输出为如下所示,已知的信息如:压缩方式为’AAC’、2个声道、采样频率为48000Hz(1s采样48000次)、时长为44.0319、样本总数量2113532(采样频率*时长)

wholeInfo = 包含以下字段的 struct:
Filename: 'C:\Users\cascara\Documents\录音\paragraph.m4a' CompressionMethod: 'AAC'
NumChannels: 2
SampleRate: 48000
TotalSamples: 2113532
Duration: 44.0319
Title: 'paragraph'
Comment: []
Artist: []
BitRate: 199.3600

[y,Fs] = audioread(FilePath);

将文件路径FilePath对应的音频文件的样本y及频率Fs读取

sound(y,Fs)

电脑的扬声器播放音频的形式将读取的数据展示出来。

分离声道

time=0:1/Fs:(length(y)-1)/Fs;
ax(1)=subplot(3,1,1);
plot(time,y)
title('all channels')
ax(2)=subplot(3,1,2);
channel1=y(:,1);
plot(time,channel1)
title('Channel 1')
channel2=y(:,2);
ax(3)=subplot(3,1,3);
plot(time,channel2,'r')
title('Channel 2')

首先用采样数量length(y)除以采样频率获得时间尺度,以1/Fs为分度值。

channel1=y(:,1);

已知音频数据包含两个声道,直接绘制图像可看到两种颜色的叠加。由matlab的语法,将矩阵进行切片,以提取两个声道的数据。

假设一个矩阵A

A(1,:) %输出A矩阵的第一行

A(:,1) %输出A矩阵的第一列

A(1:2, 2:3) %输出A矩阵的1到2行和2到3列之间的数据

通过例子可以快速明白规则,来自回答:喵喵喵呱呱呱2

求取段落与句子的互相关

本着实际主义,尝试语音识别的形式:不同的音频文件,但暗号key是在整体whole中出现的语句。但朗读和歌唱都匹配正确率极低,语言识别并非如此简单。最后还是回归在原始音频文件中截取一段,进行相应测试。

[xCorr,lags]=xcorr(who1,key1);
plot(lags/Fs2,xCorr)
title('xcorr')

[xCorr,lags]=xcorr(who1,key1);

计算整体音频1声道who1与部分音频1声道key1的互相关,并将时延lags和对应的相关correlation传出至lags与xCorr,并作图

[~,I]=max(abs(xCorr));
maxt=lags(I);

[M,I]=max(X)

对于X为矩阵的情况,返回最大值M与相应位置I;此时~表示忽略读取输出M,只保留了最大值I

这里找到了互相关xCorr为最大值时对应的时延maxt=lags(I),而由相关的性质可知,此时正是key在who中出现的开始

验证

trial=NaN(size(who1));
snip=maxt+1:maxt+length(key1);
trial(snip)=key1;
figure
ax(1)=subplot(2,1,1);
plot(wholeTime,who1,wholeTime,trial)
title('together')
ax(2)=subplot(2,2,3);
plot(keyTime,key1)
title('key')
ax(3)=subplot(2,2,4);
plot(snip/Fs1,who1(snip))
title('possible')

trial=NaN(size(who1));

新声明一个与整体信号一致大小的未定义NaN数组,并将它对应上一节找到的开始部分赋值为key1的值,将who1与trial绘制在一张图表together中,可以显示看出二者完全重叠。

添加噪声

NoiseAmp = 2*max(abs(key1));
Fragment = key1+NoiseAmp*randn(size(key1));
Full_sig = who1+NoiseAmp*randn(size(who1));
% To hear
soundsc(Fragment,Fs)
figure
plot(wholeTime,Full_sig)
xlabel('Time (s)')
ylabel('Noisy')
axis tight

NoiseAmp = 2*max(abs(key1));

定义添加噪声的峰值大小,经过测试,这个音频文件在2*情况下依然能够识别正确相应信号,但再加大就会发生失败情况

randn(size(key1))

生成size与key1相同的矩阵,且产生的随机数值服从正态分布

鹤立鸡群一值,与上节一致的方法可以找到相应音频开始时段

Leave a comment

Your email address will not be published. Required fields are marked *