【问题标题】:AVAudioRecorder averagePowerForChannel always returns -120.0AVAudioRecorder averagePowerForChannel 总是返回 -120.0
【发布时间】:2011-02-16 21:45:52
【问题描述】:

我正在尝试使用 AVAudioRecorder 的 averagePowerForChannel 方法来监控 iPad/iPhone 应用程序麦克风上的输入电平。我有一个回调,它在循环中轮询平均水平——在 iPhone 上它工作正常并返回合理的水平,但由于某种原因在 iPad 上它总是返回 -120.0。

这是我的一些设置代码:

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

以及我的开始录制方法:

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

还有一些 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]);

 ...

}

在 iPhone 上,NSLog 语句将返回合理的值,而 iPad 将始终返回 -120.0。

注意:我在 cocos2d 应用程序中使用它。出于某种原因,如果我在 iPad 上重新启动当前场景,麦克风电平将返回正确的值。

有人有什么建议吗?我在这里严重不知所措。 谢谢!

【问题讨论】:

标签: ios avfoundation avaudiorecorder avaudiosession


【解决方案1】:

我有同样的问题。我发现将类别设置为 AVAudioSessionCategoryPlayAndRecord 可以修复它:

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

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

【讨论】:

  • 你是传奇,伙计
【解决方案2】:

是的,我也是。只有一个共享的 AVAudioSession。设置其类别会影响所有录音机和播放器,因此在应用程序的一个区域将类别设置为 AVAudioSessionCategoryPlay 会禁用其他区域的录音机。

【讨论】:

    【解决方案3】:

    另一个可能的原因很简单,请确保您调用的是 [recorder record];

    那条线被意外删除了,我们花了一段时间才意识到这是仪表上返回 -120 值的原因。

    HTH

    【讨论】:

      【解决方案4】:

      1) 确保您有权限:

      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) 确保你的路径是合法的(/dev/null ok??):

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

      3) 激活音频会话

       [audioSession setActive:YES error:&error];
      

      4) 检查所有错误和返回值,包括

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

      【讨论】:

        【解决方案5】:

        您需要初始化 AVAudioSession(应该从 didMoveToview 方法完成,这可能是问题的原因)

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

        并启动记录器

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

        并通过调用获得分贝

        let decibels = recorder.averagePower(forChannel: 0)
        

        从 -120(最小值)到 0。例如,某些咖啡馆的噪音水平是 -20

        这里是更详细的例子http://www.mikitamanko.com/blog/2017/04/15/swift-how-to-get-decibels/ 注意:也使用更新方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多