0

我正在尝试检测非常小的(1-3 秒长)音效,目前我正在使用 FMod 使用环回技术来捕捉声音(在另一个程序上播放)。

这几天我一直在研究,如何将捕获的声音效果与我存储的大约 50 个数据库进行比较,我知道比较每个二进制字节不会起作用,因为轻微的干扰会改变它。声音是每次捕获的确切音频文件。所以每次都应该几乎没有特征。

我不能使用任何已经存在的指纹库,因为它们需要记录至少 10-90 秒的音频。

由于声音很小,而且数量很少,我想你们当中的一位大师知道一个简单的解决方案,我想尝试使用 FFT 并比较一些频率等,但无法让 Kiss FFT 库在那里工作绝对没有 DOCS。

我也刚刚创建了一个分割频道的功能。这里

int SeperateChannels(FMOD::Sound *sound)
{
    byte *ptr1, *ptr2;
    unsigned int lenbytes, len1, len2;

    sound->getLength(&lenbytes, FMOD_TIMEUNIT_PCMBYTES);
    sound->lock(0, lenbytes, (void**)&ptr1, (void**)&ptr2, &len1, &len2);

    byte *bufferLeft  = new byte[(lenbytes/2)];
    byte *bufferRight = new byte[(lenbytes/2)];

    for(int i = 0; i < lenbytes; i += 4)
    {
        bufferLeft[i]   = ptr1[i];
        bufferLeft[i+1] = ptr1[i+1];

        bufferRight[i]   = ptr1[i+2];
        bufferRight[i+1] = ptr1[i+3];
    }

    // Kiss FFT????

    return 1;
}

非常感谢任何帮助。-阙

4

1 回答 1

2

如果问题是要确定已录制了一组预定义的声音,那么我可以考虑两个选项:将录音与数据库中的所有声音“比较”,或者根据一般特征执行“查找”声音(在音频分析文献中通常称为“描述符”)。对于描述符,我正在考虑诸如频谱质心之类的东西。

对于“比较”情况,您可以使用相关性在时域中执行此操作,也可以通过计算频谱幅度差异在频域中执行此操作。对于时域比较,您需要在多个偏移处执行相关,因为您不知道声音从哪里开始。对于频域情况,您需要将原始 FFT 数据转换为某种频谱包络——例如,取一组(加窗)重叠帧的幅度谱的平均值。

对于“查找”情况,您将计算一组描述符,在您的语料库和候选输入上计算它们,然后查找最接近您为输入计算的描述符的语料库元素。您也可以在一系列帧上执行此操作:执行与时域“比较”情况相同的相关分析,但不是计算每个样本的差异,而是计算每个描述符的差异——这将比仅使用单个描述符更好地比较不断变化的声音。

如果您打算使用 FFT,您不仅需要了解如何应用 FFT,还需要了解如何计算幅度谱并对您正在处理的数据结构有一些了解。除了执行 FFT 之外,获得结果还需要许多步骤。有很多方法可以优化匹配,特别是如果您的声音设置是固定的(例如,我正在考虑组测试方法)。

对于更简单的方法,您可以查看DTMF 按键音解码的完成方式。通过对源声音进行预分析,您可能能够确定一组非重叠频率,这些频率可用于对每个声音进行指纹识别。

在所有情况下,我都会通过对左右声道求和来实现单声道。除非您确定输入与输出具有相同的平移,否则立体声不会给您太多。

于 2013-08-10T04:40:00.130 回答