2011-02-16 14 views
8

Estoy tratando de utilizar el método AveragePowerForChannel de AVAudioRecorder para monitorear los niveles de entrada en el micrófono para una aplicación de iPad/iPhone. Tengo una devolución de llamada que sondea el nivel promedio en un bucle: en el iPhone funciona bien y devuelve niveles razonables, pero por alguna razón en el iPad siempre devuelve -120.0.AVAudioRecorder averagePowerForChannel siempre devuelve -120.0

Aquí es parte de mi código de configuración:

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

Así como mi método de inicio de grabación:

- (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 devolución de llamada 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]); 

... 

} 

Cuando el el iPhone, la declaración NSLog arrojará valores razonables, 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 realmente perdido aquí. Gracias!

+0

Tal vez le ayudará a http://stackoverflow.com/questions/24991908/why-does-averagepowerforchannel-always-return-160 –

Respuesta

17

Tuve el mismo problema. Encontré el establecimiento de la categoría a la AVAudioSessionCategoryPlayAndRecord lo fija:

NSError *error; 
[[AVAudioSession sharedInstance] 
    setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]; 

if (error) { 
    NSLog(@"Error setting category: %@", [error description]); 
} 
+0

Oh, hombre, que ha remediado el dolor de cabeza. : D –

+0

Una leyenda que eres, amigo – mylogon

1

Sí, yo también. Solo hay una sesión compartida de AVAudio. Establecer su categoría afecta a todos los grabadores 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.

0

Otra posible causa de esto es realmente simple, asegúrese de estar llamando [grabación de grabadora];

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

HTH

0

1) Asegúrate de que tienes el permiso:

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

2) Asegúrese de que su trayectoria es 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 audioSession

[audioSession setActive:YES error:&error]; 

4) Comprobar todos los errores y valores de retorno, incluyendo

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

Es necesario inicializar el AVAudioSession (debe hacerse desde didMoveToview método, podría ser una razón del problema)

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

y empezar grabador

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

y obtener los decibelios llamando

let decibels = recorder.averagePower(forChannel: 0) 

desde -120 (valor mínimo) hasta 0. noice_nus nivel de algún café, por ejemplo, es de -20

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

Cuestiones relacionadas