10

我正在尝试构建一个计数拍手的 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];

}

在此处输入图像描述

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

4

2 回答 2

4

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

但是请记住,手机的碰撞最终可能是一个非常低的频率和相当高的脉冲,即使它不是真正的拍手,它也会触发你的检测器。同样适用于不太可能是拍手的高频声源。

这可以满足您的需求吗?

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

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

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

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

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

干杯

于 2012-10-19T16:49:11.883 回答
0

我为我的应用程序使用了 FFT https://itunes.apple.com/us/app/clapmera/id519363613?mt=8。频域中的 Clap 看起来像一个(不完美的)常数。

问候

于 2013-04-26T00:48:37.767 回答