检测到麦克风的一击

时间:2011-05-17 21:46:33

标签: iphone cocoa-touch signal-processing avfoundation avaudiorecorder

对于我的项目,我需要检测用户何时吹入麦克风。我已按照本教程:http://www.mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/和此问题:Detect blow in Mic and do something 但我仍然没有得到我想要的结果。这种打击方式检测得太晚,有时甚至根本检测不到。当我调整一些结果时,可以正确检测到打击,但随后触发打击太快,即。当你说话或发出咔哒声时,它也被视为一击。

有没有人找到一种检测打击的好方法?感谢。

3 个答案:

答案 0 :(得分:4)

AVAudioRecorder声级API并非旨在为您提供可靠的结果,将吹奏的声音与麦克风接收的其他类型的声音分开。

我建议使用音频队列或音频单元RemoteIO API,测量RMS信号能量,包络持续时间,然后使用加速FFT库检查频谱的宽带噪声与建议有声说话而不是吹气的峰值。

e.g。更可靠的结果将需要比1 OS调用更多的工作。

答案 1 :(得分:2)

Use return as you get first lowpass results >0.55

I have solve the issue have a look.

-(void)readyToBlow1 { NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithFloat: 44100.0],                 AVSampleRateKey,
                          [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
                          [NSNumber numberWithInt: 1],                         AVNumberOfChannelsKey,
                          [NSNumber numberWithInt: AVAudioQualityMax],         AVEncoderAudioQualityKey,
                          nil];

NSError *error;

recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];

if (recorder) {
    [recorder prepareToRecord];
    recorder.meteringEnabled = YES;
    [recorder record];
    levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.01 target: self selector: @selector(levelTimerCallback1:) userInfo: nil repeats: YES];
} else
    NSLog(@"%@",[error description]);
}

(void)levelTimerCallback1:(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; //NSLog(@"lowPassResults= %f",lowPassResults);

if (lowPassResults > 0.55) { lowPassResults = 0.0;

[self invalidateTimers];


NextPhase *objNextView =[[NextPhase alloc]init];

[UIView transitionFromView:self.view
                    toView:objNextView.view
                  duration:2.0
                   options:UIViewAnimationOptionTransitionCurlUp
                completion:^(BOOL finished) {
                }
 ];

[self.navigationController pushViewController:objNextView animated:NO];

**return;**
}

}

答案 2 :(得分:0)

我使用AudioQueueGetProperty()为kAudioQueueProperty_CurrentLevelMeter取得了很好的成功。