2009-04-28 6 views
18

Ich versuche zu erkennen, wenn der Benutzer in das Mikrofon eines iPhone bläst. Im Moment bin ich mit der SCListener Klasse von Stephen CelisErkennen von Blasen am iPhone-Mikrofon?

if ([[SCListener sharedListener] peakPower] > 0.99) 

in einem NSTimer zu nennen. Dies ist jedoch manchmal wahr, wenn ich nicht blase. Jeder hat einen Beispielcode, um zu überprüfen, ob der Benutzer ins Mikrofon bläst?

+4

Vielleicht weht der Wind. :) Sorry, diese Frage hat mich zum Lachen gebracht. –

+0

Hah, nah. Selbst wenn ich drinnen wäre, würde das Tippen auf den Bildschirm dazu führen, dass die Funktion auslöst. –

Antwort

25

Ich würde low-pass filtering zuerst das Stromsignal empfehlen. Es wird immer ein gewisses Maß an transientem Rauschen geben, das mit augenblicklichen Messungen verwechselt wird; Tiefpassfilterung hilft dabei, das zu verringern. Eine schöne und einfache Tiefpassfilter würde wie folgt sein:

// 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 
+0

Kannst du die Aufnahme stoppen, wenn die Lautstärke auch über dem Schwellenwert liegt? was bedeutet, wenn eine voip app, und nicht wollen, dass eine feuerlöschsirene über die konversation brüllen kann ich pause das mikrofon sobald die schwelle überschritten ist? –

11

Verwenden Rückgabe als lowPassResults ist größer als 0,55. Dies funktioniert gut:

-(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;** 
    } 
} 
+0

Wo konfigurieren Sie die LowPassResults im Code? – user513790

+0

jetzt können Sie LowPassResults sehen. Es war nur falsch ausgerichtet. sorry :) –

+0

+1 für eine gute Antwort shashank –

13

wenn auf dem iPhone ausführen, sollten Sie den folgenden Code nach [Recorder prepareToRecorder]

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 
[[AVAudioSession sharedInstance] setActive:YES error:nil]; 
+3

Das hat gut für mich funktioniert. – slaveCoder

+2

Ich war auf der Suche nach dieser Information für 3 Stunden. Es funktioniert jetzt!. – bpolat

+0

oh Gott vielen Dank –

2

dieses Add Versuchen Sie arbeitet für mich. Danke @jinhua liao

- (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]; 
} 
} 
Verwandte Themen