我正在尝试检测非常小的(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;
}
任何帮助都非常适合。 -Que
答案 0 :(得分:2)
如果问题是要确定录制了哪一组预定义的声音,那么我可以想到两个选项:“比较”录音与数据库中的所有声音,或执行“查找”关于声音的一般特征(通常在音频分析文献中称为“描述符”)。对于描述符,我正在考虑像spectral centroid这样的事情。
对于“比较”情况,您可以使用correlation在时域中执行此操作,也可以通过计算频谱幅度差异在频域中执行此操作。对于时域比较,您需要在多个偏移处执行相关,因为您不知道声音的起始位置。对于频域情况,您需要将原始FFT数据转换为某种频谱包络 - 例如取一组(窗口)重叠帧的幅度谱的平均值。
对于“查找”案例,您将计算一组描述符,在您的语料库和候选输入上计算它们,然后查找最接近您为输入计算的描述符的语料库元素。您也可以在一系列帧中执行此操作:执行与时域“比较”情况相同的相关性分析,但不是计算每个样本的差异,而是计算每个描述符的差异 - 这比使用单个描述符更适合比较不断发展的声音。
如果您打算使用FFT,您不仅需要解决如何应用FFT,还需要解决如何计算幅度谱并对您正在处理的数据结构有所了解。获得结果需要执行FFT之外的许多步骤。可以通过多种方式优化匹配,特别是如果您的声音设置是固定的(例如,我正在考虑组测试方法)。
对于更简单的方法,您可以查看DTMF touch tone解码的方式。通过对源声音进行预分析,您可以确定一组非重叠频率,可用于指纹每个声音。
在所有情况下,我都会通过对左右声道进行求和来实现单声道。除非你确定输入与输出具有相同的平移,否则立体声不会给你太多。