我有兴趣让我的iOS应用打开麦克风,只收听17000赫兹以上的频率。如果它听到该范围内的某些内容,我希望应用程序调用方法。
我找到了一个检测频率的存储库:https://github.com/krafter/DetectingAudioFrequency
这是一个分解FFT的帖子:
Get Hz frequency from audio stream on iPhone
使用这些例子,我已经能够让手机对它听到的最强频率作出反应,但我更感兴趣的是对上述17000赫兹的频率作出反应。
答案 0 :(得分:0)
我编写该代码的事实有助于我回答这个问题,但答案可能只适用于此代码。
只需将输出数组修剪为仅包含所需范围的部分,即可轻松限制您收听的频率。
详细信息:简单来说 - 数组[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左右看到很多噪音。唯一可以记住的是一些旧电视,当它们重新开启时产生高音调。