我编写该代码的事实有助于我回答这个问题,但答案可能只适用于该代码。
您可以轻松地限制您收听的频率,只需将该输出阵列修剪为仅包含您需要的范围的片段。
详细说明: 简单来说 - array[0..255] 包含您在频域中的音频。例如,当您进行 FFT 时,您的采样率为 44100。
那么您可以编码的最大频率是 22050。(奈奎斯特定理)。
即 array[0] 包含 22050/256=86.13 Hz 的值。 Array[1] 包含 86.13*2 = 172.26 Hz 的值,array[2] 包含 86.13*3 = 258.39 Hz 的值。等等。您的全部范围分布在这 256 个值中。 (是的,精度会受到影响)
因此,如果您只需要收听某个范围,比方说高于 17000Hz,您只需获取该阵列的一部分而忽略其余部分。在这种情况下,您将 17000/86.13=197 到 255 子阵列,并且您拥有它。只有 17000-22050 范围。
在我的仓库中,你修改 strongestFrequencyHZ 函数如下:
static Float32 strongestFrequencyHZ(Float32 *buffer, FFTHelperRef *fftHelper, UInt32 frameSize, Float32 *freqValue) {
Float32 *fftData = computeFFT(fftHelper, buffer, frameSize);
fftData[0] = 0.0;
unsigned long length = frameSize/2.0;
Float32 max = 0;
unsigned long maxIndex = 0;
Float32 freqLimit = 17000; //HZ
Float32 freqsPerIndex = NyquistMaxFreq/length;
unsigned long lowestLimitIndex = (unsigned long) freqLimit/freqsPerIndex;
unsigned long newLen = length-lowestLimitIndex;
Float32 *newData = fftData+lowestLimitIndex; //address arithmetic
max = vectorMaxValueACC32_index(newData, newLen, 1, &maxIndex);
if (freqValue!=NULL) { *freqValue = max; }
Float32 HZ = frequencyHerzValue(lowestLimitIndex+maxIndex, length, NyquistMaxFreq);
return HZ;
}
我在那里做了一些地址运算,所以看起来有点复杂。您可以使用该 fftData 数组并执行常规操作。
其他注意事项:
寻找最强的频率。简单。您只需在该数组中找到最大值。就是这样。但是在您的情况下,您需要监视范围并找出它何时从常规的弱噪声变为某些强信号。换句话说,当东西达到顶峰时,这不是那么微不足道,而是可能的。您可能只需设置一些限制,超过该限制即可检测到信号,尽管这不是最佳选择。
我宁愿对此感到乐观,因为在现实生活中你在 18000Hz 的频率下看不到你周围的太多噪音。唯一能记住的是一些旧电视在打开时会发出那种高音。