C#小型WAV文件的音频指纹技术

3

我需要在一个小型数据库中查找长度为5到7秒之间的40个wav文件中与另一个相似的wav文件。

这些wav文件是您拨打电话时电话服务提供商提供的记录。

例如:

https://clyp.it/lnz1aybd

我的参考时间为1或2秒。

所有的wav都是PCM编码,16位,8000Hz单声道

我尝试使用Aurio.AudioFingerPrint但没有成功。

https://github.com/protyposis/Aurio

// Setup the sources
var audioTrack1 = new AudioTrack(new FileInfo("Full5secs.wav"));
var audioTrack2 = new AudioTrack(new FileInfo("Part2Secs.wav"));

// Setup the fingerprint generator
var defaultProfile = FingerprintGenerator.GetProfiles()[0];
var generator = new FingerprintGenerator(defaultProfile);

// Create a fingerprint store
var store = new FingerprintStore(defaultProfile);

// Setup the generator event listener (a subfingerprint is a hash with its temporal index)
generator.SubFingerprintsGenerated += (sender, e) => {
    var progress = (double)e.Index / e.Indices;
    var hashes = e.SubFingerprints.Select(sfp => sfp.Hash);
    store.Add(e);
};

// Generate fingerprints for both tracks
generator.Generate(audioTrack1);
generator.Generate(audioTrack2);

// Check if tracks match
if (store.FindAllMatches().Count > 0) {
   Console.WriteLine("overlap detected!");
}

我的方法有什么问题?
有人知道我缺少哪些配置来处理小的wav文件吗?


顺便说一下,询问“另一个库”通常被视为不相关的,并导致问题被搁置或关闭。我考虑过这个问题,但在这篇文章中,主要问题是为什么你呈现的代码片段找不到匹配项,所以这完全属于相关内容。只需小心询问库。随着时间的推移,库会发生变化、演变和死亡。这就是为什么此类问题被认为不“好”的原因--没有办法回答寻求库的问题。“完全回答”这样的问题是不可能的。总有新东西或者有人相信另一个库更好。 - quetzalcoatl
你是否检查过指纹识别器是否能够找到理想情况下的匹配项?获取其中一个40个音频文件,并将该文件作为针来运行程序。对于完美的输入,任何(有效的)指纹识别服务都应该返回至少一个匹配项。如果它在完美的针上运行正常,但在实际输入上却不行,那么可能是配置问题,而不是代码本身(例如某些阈值或时间窗口过低/过高等)。 - quetzalcoatl
谢谢,你是对的,我已经删除了“其他库”的问题。 - Fraga
可能是c# tiny wavs audiofingerprint的重复问题。 - Paul R
1个回答

7
可能已经有点晚了,但我是Aurio的作者,可以帮你解决问题。我假设你正在使用来自Aurio.Matching.HaitsmaKalker2002命名空间的FingerprintGenerator,但其他命名空间中的指纹方法也类似。
你的问题是默认配置下的指纹需要大约3秒的音频,这意味着2秒长的音频文件将无法产生指纹,因此你无法得到匹配结果。
默认情况下,HaitsmaKalker2002方法的一个指纹由256个子指纹组成。这个长度在FingerprintStore中进行指纹匹配时被配置。子指纹是从采样率为5512的降采样音频流中取样窗口计算出来的。窗口长度为2048个样本,并且每64个样本取一次样。这些值设置在一个用于配置提取指纹的FingerprintGenerator的profile中,你可以在DefaultProfile中找到这些值。使用这个配置,你至少需要1/5512 * (255 * 64 + 2048) =~ 3.4秒的音频才能产生指纹。每个后续的指纹只需要多64个音频样本,所以在4秒音频中你就可以获得313个指纹,匹配的机会更高。
在你的情况下,你需要缩短指纹所需的音频长度,你可以通过创建自定义的FingerprintGenerator profile(扩展DefaultProfile或调整配置值)或者调整FingerprintStore中匹配阶段的设置来实现。为了将最小音频时间缩短一半,你可以加倍SampleRate或将FrameStep减半,默认情况下您还可以将指纹长度减半或进行所有这些可能性的组合。
// Setup the fingerprint generator
var defaultProfile = FingerprintGenerator.GetProfiles()[0];
defaultProfile.SampleRate = 11025; // Adjust the profile
var generator = new FingerprintGenerator(defaultProfile);

// Create a fingerprint store
var store = new FingerprintStore(defaultProfile);
// Set the fingerprint length to 128 instead of the default 256
store.FingerprintSize = 128;

另一种方法可能是通过静音填充来延长输入的音频,但这样您可能需要提高store.Threshold以允许更高的误差率(因为实际的音频负载太短,永远无法完全匹配任何地方)。不过,您必须在外部进行填充,因为通过Aurio的API目前无法实现这种用例。

请记住,选择默认值是因为它们会产生良好的结果。如果不知道自己在做什么就更改它们,可能会导致很多错误的阳性或漏检,但由于您的输入文件非常短,您必须尝试。我建议尝试AudioAlign,它基本上是围绕Aurio的一个GUI,您可以添加两个测试文件并轻松尝试FingerprintSizeThreshold值,并且它甚至会图形化显示音频文件中的匹配项,您可以直接听取它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接