任务
教科书式的信号处理偏理论,不妨尝试现实中的音频文件,与实践接轨。
在工具包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相同的矩阵,且产生的随机数值服从正态分布