检测IOS中的拍手

Nat*_*ark 10 iphone algorithm core-audio ios

我正在尝试构建一个计算拍手的IOS应用程序.我一直在观看CoreAudio上的WWDC视频,主题看起来很大,我不太确定在哪里看.

我在stackoverflow中发现了类似的问题.这是C#中用于检测门猛击的一个:给定一个音频流,找到一个门猛击 (声压级计算?)

看来我需要这样做:

  1. 将样品分成几个部分
  2. 计算每个部分的能量
  3. 取上一个窗口和当前窗口之间的能量比
  4. 如果比率超过某个阈值,请确定突然发出巨响.

我不知道如何在Objective-C中实现这一目标.我已经能够弄清楚如何使用SCListener对音频进行采样 这是我的尝试:

- (void)levelTimerCallback:(NSTimer *)timer {
    [recorder updateMeters];

    const double ALPHA = 0.05;
    double peakPowerForChannel = pow(10, (0.05 * [recorder peakPowerForChannel:0]));
    lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;


    if ([recorder peakPowerForChannel:0] == 0)
        totalClapsLabel.text = [NSString stringWithFormat:@"%d", total++];

    SCListener *listener = [SCListener sharedListener];
    if (![listener isListening])
        return;

    AudioQueueLevelMeterState *levels = [listener levels];
    Float32 peak = levels[0].mPeakPower;
    Float32 average = levels[0].mAveragePower;


    lowPassResultsLabel.text = [NSString stringWithFormat:@"%f", lowPassResults];
    peakInputLabel.text      = [NSString stringWithFormat:@"%f", peak];
    averageInputLabel.text   = [NSString stringWithFormat:@"%f", average];

}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

虽然我看到了建议的算法,但我不清楚如何在Objective-C中实现它.

JDi*_*ler 4

您没有提到您正在寻找什么样的检测保真度?老实说,仅检查某种声音“压力”变化可能完全足以满足您的需求。

但请记住,对手机的碰撞最终可能会产生非常低的频率和相当高的功率脉冲,这样即使不是真正的拍手,它也会触发您的探测器。对于不太可能是拍手声的高频声源也是如此。

这可以满足您的需求吗?

如果没有,并且您希望获得更高的保真度,我认为您最好对输入信号进行频谱分析(FFT),然后在更窄的频带中查找尖锐的信号尖峰,类似于您的部分已经有。

我没有仔细研究过这个源代码,但这里有一些可能的开源 FFT 代码,您可以将其按原样用于您的 iphone 应用程序:

编辑: https: //github.com/alexbw/iPhoneFFT

绘制频谱结果的好处在于,它可以让您轻松调整您真正关心的频率范围。在我自己使用一些笔记本电脑软件进行的测试中,我的拍手声在 1kHz - 2kHz 左右有一个非常强的尖峰。

可能超出了您的需求,但如果您需要更高的保真度,那么我怀疑您不会满足于简单地跟踪信号尖峰而不首先知道什么频率范围导致信号尖峰。

干杯