Обнаружение удара по микрофону iPhone? - PullRequest
19 голосов
/ 28 апреля 2009

Я пытаюсь определить, когда пользователь дует в микрофон iPhone. Прямо сейчас я использую класс SCListener от Стивена Селиса для вызова

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

в NSTimer. Однако иногда это возвращает истину, когда я не дую. У кого-нибудь есть пример кода, чтобы проверить, дует ли пользователь в микрофон?

Ответы [ 5 ]

25 голосов
/ 28 апреля 2009

Я бы порекомендовал фильтрация нижних частот сначала сигнал мощности. Всегда будет некоторое количество переходного шума, который будет мешать мгновенным показаниям; фильтрация нижних частот помогает смягчить это. Хороший и простой фильтр нижних частот будет выглядеть примерно так:

// 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
13 голосов
/ 11 декабря 2013

при запуске на iPhone, вы должны добавить следующий код после [рекордер prepareToRecorder]

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
11 голосов
/ 23 января 2013

Используйте return, поскольку lowPassResults больше 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;**
    }
}
4 голосов
/ 06 декабря 2012

http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/

Этот урок отлично работает с симулятором, но в iphone он не работает, от iphone mic нет ответа

2 голосов
/ 20 мая 2014

Попробуй это у меня нормально работает. Спасибо @jinhua Ляо

- (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];
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...