如何让我的 iPhone 收听高于某个阈值的声音频率?

Posted

技术标签:

【中文标题】如何让我的 iPhone 收听高于某个阈值的声音频率?【英文标题】:How can I get my iPhone to listen for sound frequencies above a certain threshold? 【发布时间】:2015-06-15 17:38:55 【问题描述】:

我有兴趣让我的 ios 应用打开麦克风并仅收听 17000 赫兹以上的频率。如果它听到该范围内的声音,我希望应用程序调用一个方法。

我能够找到一个检测频率的存储库:https://github.com/krafter/DetectingAudioFrequency

这是一个分解 FFT 的帖子:Get Hz frequency from audio stream on iPhone

使用这些示例,我可以让手机对它听到的最强频率做出反应,但我更感兴趣的是仅对 17000 赫兹以上的频率做出反应。

【问题讨论】:

显示一些代码,也许你会得到一些帮助。如果您已将传入的声音分成频率桶,那么我看不出您的问题是什么。因此,显示代码并解释您遇到困难的地方 【参考方案1】:

我编写该代码的事实有助于我回答这个问题,但答案可能只适用于该代码。

您可以轻松地限制您收听的频率,只需将该输出阵列修剪为仅包含您需要的范围的片段。

详细说明: 简单来说 - 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 的频率下看不到你周围的太多噪音。唯一能记住的是一些旧电视在打开时会发出那种高音。

【讨论】:

我进行了更改,但现在我得到:max HZ = 17225.553 打印到我的控制台和模拟器上。我在一个安静的房间里运行这个,所以我不应该在这里没有价值吗? 因为您只收听 17000-22050 范围内的值,所以您只能获得该范围内的值。正如我之前所说,现实世界的声音总是包含全频谱,无论它有多安静。您收到的该值可能是因为您的计算机内部的风扇旋转使其值稳定。 新修改的代码只显示最强频率。在 17000-22050 范围内,仅此而已。还有一个最强的。 @krafter:上面的代码似乎找到了幅度最大的 FFT bin。在某些情况下,这实际上不是信号中存在的最大幅度频率。请记住,FFT 是一组重叠的带通滤波器。如果信号中的主频率正好位于两个 bin 之间,则信号将在相邻的两个 bin 中平均分配(例如,在 -3dB 处)。即使您已取消选择这些情况,这也最多只能提供峰值箱所覆盖的频率范围。使用高通滤波器可以更轻松地实现 OP 的要求。 那么,当前的实现不是高通滤波器吗?它只是在频域中完成。由于 OP 不需要时域数据,这对他有用。最后,他只需要传递一点信息,而不是声音本身。至于频率范围 - 是的,每个 bin 只是一个范围。在具有 256 个 bin 的给定示例中,一个具有 86.13Hz 范围,这不是那么好。但是如果你有 32768 个垃圾箱呢?那么范围只有1.5Hz。这只是精度问题。

以上是关于如何让我的 iPhone 收听高于某个阈值的声音频率?的主要内容,如果未能解决你的问题,请参考以下文章

y_pred 的自定义损失函数 Keras 仅高于某个阈值

如何构建音频文件流 iPhone 应用程序?

如何让我的应用在 iPhone 上后台运行?

如何在 iPhone 上时移音频

iPhone应用程序仅在特定频率以上录音

如何从互联网下载音频/视频文件并存储在 iPhone 应用程序中?