AVAudioRecorder averagePowerForChannel siempre devuelve -120.0

Estoy intentando utilizar el método averagePowerForChannel de AVAudioRecorder para monitorear los niveles de input en el micrófono para una aplicación iPad / iPhone. Tengo una callback que encuesta el nivel medio en un ciclo: en el iPhone funciona bien y devuelve niveles sensibles, pero por algún motivo en el iPad siempre regresa -120.0.

Aquí hay algunos de mis códigos de configuration:

- (void) setupMic { if (micInput) { [micInput release]; micInput = nil; } NSURL *newURL = [[NSURL alloc] initFileURLWithPath:@"/dev/null"]; NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init]; [recordSettings setObject:[NSNumber numberWithInt:kAudioFormatAppleLossless] forKey: AVFormatIDKey]; [recordSettings setObject:[NSNumber numberWithFloat:22050.0] forKey: AVSampleRateKey]; // [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey]; [recordSettings setObject:[NSNumber numberWithInt:12800] forKey:AVEncoderBitRateKey]; [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; [recordSettings setObject:[NSNumber numberWithInt: AVAudioQualityLow] forKey: AVEncoderAudioQualityKey]; micInput = [[AVAudioRecorder alloc] initWithURL:newURL settings:recordSettings error:nil]; // [micInput setMeteringEnabled:YES]; [newURL release]; [recordSettings removeAllObjects]; [recordSettings release]; } 

Además de mi método de grabación de inicio:

 - (void) startRecording { NSLog(@"startRecording!"); [micInput pause]; [micInput prepareToRecord]; micInput.meteringEnabled = YES; [micInput record]; [micInput updateMeters]; levelTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.0] interval:0.03 target:self selector:@selector(levelTimerCallback:) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:levelTimer forMode:NSDefaultRunLoopMode]; } 

y un poco de la callback levelTimer:

 - (void)levelTimerCallback:(NSTimer *)timer { [micInput updateMeters]; double avgPowerForChannel = pow(10, (0.05 * [micInput averagePowerForChannel:0])); [micSprite receiveInput:avgPowerForChannel]; NSLog(@"Avg. Power: %f", [micInput averagePowerForChannel:0]); ... } 

Donde en el iPhone, la instrucción NSLog devolverá valores sensibles, y el iPad siempre devolverá -120.0.

Nota: estoy usando esto dentro de una aplicación cocos2d. Por alguna razón, si reinicio la escena actual en el iPad, los niveles de micrófono devolverán los valores correctos.

¿Alguien tiene alguna sugerencia? Estoy seriamente perdido aquí. ¡Gracias!

Tuve el mismo problema. Encontré que establecer la categoría en AVAudioSessionCategoryPlayAndRecord lo corrige:

 NSError *error; [[AVAudioSession shanetworkingInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]; if (error) { NSLog(@"Error setting category: %@", [error description]); } 

Sí, yo también. Solo hay una AVAudioSession compartida. El establecimiento de su categoría afecta a todas las grabadoras y reproductores, por lo que establecer la categoría en AVAudioSessionCategoryPlay en un área de la aplicación, por ejemplo, desactiva las grabadoras en otras áreas.

Otra posible causa de esto es muy simple, asegúrese de que está llamando [logging de grabadora];

Esa línea se eliminó accidentalmente y nos tomó un time reconocer que como la causa de los -120 valores que se devolvían en el medidor.

HTH

1) Asegúrese de tener la autorización:

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { if([[AVAudioSession shanetworkingInstance] respondsToSelector:@selector(requestRecordPermission:)]) { [[AVAudioSession shanetworkingInstance] requestRecordPermission:^(BOOL granted) { NSLog(@"permission : %d", granted); if(granted)[self setupMic];// record ... }]; } } 

2) Asegúrate de que tu ruta sea legítima (/ dev / null ok ??):

 NSString* dir=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSArray *pathComponents = [NSArray arrayWithObjects:dir,fileName,nil]; recordedAudioURL = [NSURL fileURLWithPathComponents:pathComponents]; 

3) activar audioessionession

  [audioSession setActive:YES error:&error]; 

4) Verifique todos los errores y valores devueltos, incluidos

 BOOL ok=[micInput prepareToRecord]; ok=ok &&[micInput record]; 

Debe iniciar AVAudioSession (debe realizarse desde el método didMoveToview, podría ser una razón del problema)

 let session = AVAudioSession.shanetworkingInstance() try session.setCategory(AVAudioSessionCategoryPlayAndRecord) try session.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker) try session.setActive(true) try recorder = AVAudioRecorder(url: getDocumentsDirectory(), settings: settings) 

y arranque la grabadora

 func start() { recorder?.record() recorder?.updateMeters() } 

Y obtenga los decibeles llamando al

 let decibels = recorder.averagePower(forChannel: 0) 

desde -120 (valor mínimo) hasta 0. El nivel de ruido de alguna cafetería, por ejemplo, es -20

aquí está el ejemplo más detallado http://www.mikitamanko.com/blog/2017/04/15/swift-how-to-get-decibels/ Nota: utilice también el método de actualización.