检测iPhone麦克风上的吹气?
我试图检测用户何时对着iPhone的麦克风吹气。现在我正在使用SCListener类从调用 在一段时间内。然而,有时候当我不吹的时候,这种情况就会出现。有没有人有任何示例代码来检查用户是否正在向麦克风吹气?我建议首先使用电源信号。总有一些瞬态噪声会干扰瞬时读数;低通滤波有助于缓解这种情况。一个简单的低通滤波器应该是这样的:检测iPhone麦克风上的吹气?,iphone,Iphone,我试图检测用户何时对着iPhone的麦克风吹气。现在我正在使用SCListener类从调用 在一段时间内。然而,有时候当我不吹的时候,这种情况就会出现。有没有人有任何示例代码来检查用户是否正在向麦克风吹气?我建议首先使用电源信号。总有一些瞬态噪声会干扰瞬时读数;低通滤波有助于缓解这种情况。一个简单的低通滤波器应该是这样的: // Make this a global variable, or a member of your class: double micPower = 0.0; // Tw
// Make this a global variable, or a member of your class:
double micPower = 0.0;
// Tweak this value to your liking (must be between 0 and 1)
const double ALPHA = 0.05;
// Do this every 'tick' of your application (e.g. every 1/30 of a second)
double instantaneousPower = [[SCListener sharedListener] peakPower];
// This is the key line in computing the low-pass filtered value
micPower = ALPHA * instantaneousPower + (1.0 - ALPHA) * micPower;
if(micPower > THRESHOLD) // 0.99, in your example
// User is blowing on the microphone
本教程适用于模拟器,但不适用于iphone。iphone麦克风没有响应。使用return,因为
低通结果
大于0.55。这很好:
-(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]));
double lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * 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;**
}
}
在iPhone上运行时,应在[recorder prepareToRecorder]之后添加以下代码
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
试试这个,对我来说很好。谢谢@廖金华
- (void)viewDidLoad {
[super viewDidLoad];
lowPassResults = 0.0;
[self 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];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
recorder.meteringEnabled = YES;
[recorder record];
levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
} else
NSLog([error description]);
}
- (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;
NSLog(@"lowpassResult is %f",lowPassResults);
if (lowPassResults > 0.95){
NSLog(@"Mic blow detected");
[levelTimer invalidate];
}
}
也许风在刮。:)对不起,这个问题让我笑了。哈,不。即使我在里面,只要轻敲屏幕就会触发该功能。如果音量超过阈值,你能停止录音吗?意思是如果有一个voip应用程序,并且不希望消防车警报器在对话中咆哮,我可以在超过阈值后暂停麦克风吗?现在你可以看到lowPassResults。只是没有对准。抱歉:)我收到lowPassResults的编译器错误,因为它正用于初始化它的方程。lowPassResults是否应该在其他地方初始化?是的,您必须在viewDidLoad中初始化lowPassResults,或者ViewWill将根据需要显示。只需初始化为lowPassResults=0.0;有人能解释一下这段代码中的“低通滤波器”吗。据我所知,低通滤波器会从测量值中排除高频声音。然而,这里没有提到声音频率。PeakPower ForChannel以分贝为单位返回音量。而代码只是操纵那个值。我遗漏了什么?我已经找了3个小时了。现在可以用了!。
- (void)viewDidLoad {
[super viewDidLoad];
lowPassResults = 0.0;
[self 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];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
recorder.meteringEnabled = YES;
[recorder record];
levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
} else
NSLog([error description]);
}
- (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;
NSLog(@"lowpassResult is %f",lowPassResults);
if (lowPassResults > 0.95){
NSLog(@"Mic blow detected");
[levelTimer invalidate];
}
}