您如何交叉关联音频文件以查看样本是否与原始文件匹配?

How do you cross-correlate audio files to see if a sample matches the original?

我正在尝试在 MATLAB 中编写一个函数,该函数可以在 39 个音频文件中将 10 秒的音频样本与其来自的音频文件相匹配。我需要搜索音频文件目录以找到我的样本来自的文件。我知道我需要以某种方式使用 xcorr 函数,但我不知道如何通读目录来进行比较。基本上我需要:

读取音频文件

看看我的样本是不是来自当前的音频文件

如果是,我需要文件编号(共 39 个),以及我的样本在文件中出现的位置

如果没有,我需要转到下一个文件

如有任何帮助,我们将不胜感激

此过程的广泛概述涉及在每个信号和十秒样本之间进行互相关。在进行互相关后,我们发现取最大值 max() ,这将为我们提供每个比较的“最佳拟合”(最相关)因子。然后,我们采用峰值相关性的最大结果来找出最适合的信号。下面的脚本使用结构 struct 来保存音频信号、互相关和峰值相关等重要数据。我只针对 3 个音频文件测试了我的示例,因此尝试 39 个时结果可能会有所不同,但据我所知它应该有效。要停止播放声音,只需在命令 window.

中键入 clear sound

步骤:

• 使用 dir() 从 folder/directory 中读取音频文件名。

• 使用 audioread() 函数读取十秒音频样本和文件夹中的文件。

• 使用 xcorr() 函数比较信号并使用 max() 函数计算峰值相关性以进行比较。

• 通过在峰值相关数组上使用 max() 函数,找出哪个比较具有最高的峰值相关性。

• 请记住,我只使用了左声道,因此如果您的音频对于两个声道或单声道不同,您可能必须针对两个声道进行测试。


完整脚本:

%Loading ten second audio sample%
Ten_Second_Sample = audioread("Sample.mp3");
Audio_Properties = audioinfo("Sample.mp3");
Sampling_Frequency = Audio_Properties.SampleRate;

%Grabbing all the mp3 and mp4 file names in a folder named "Audio Folder"%
Folder_Name = 'Audio Folder';
Audio_Files = [dir(fullfile(Folder_Name,'*mp3')); dir(fullfile(Folder_Name,'*m4a'))];

%Creating a structure to hold all the audio data and cross-correlation
%results%
Audio_Signals = struct("Signal",[],"Cross_Correlation",[],"Peak_Correlation",[]);

%Evaluting the cross-correlation and peak-correlation between the audio and ten second sample%
for Audio_Index = 1: length(Audio_Files)
Audio_Signals(Audio_Index).Signal = audioread(fullfile('Audio Folder/',Audio_Files(Audio_Index).name));
Left_Channel = Audio_Signals(Audio_Index).Signal(:,1);
Audio_Signals(Audio_Index).Cross_Correlation = xcorr(Left_Channel,Ten_Second_Sample(:,1));
Audio_Signals(Audio_Index).Peak_Correlation = max(Audio_Signals(Audio_Index).Cross_Correlation);
end

%Evaluating the highest peak correlation among the compared signals%
Peak_Correlations = [Audio_Signals.Peak_Correlation].';
[~,Index] = max(Peak_Correlations);
disp(Audio_Files(Index).name);
sound(Audio_Signals(Index).Signal,Sampling_Frequency);