简体   繁体   English

AVAudioRecorder averagePowerForChannel始终返回-120.0

[英]AVAudioRecorder averagePowerForChannel always returns -120.0

I'm trying to use AVAudioRecorder's averagePowerForChannel method to monitor input levels on the microphone for an iPad/iPhone app. 我正在尝试使用AVAudioRecorder的averagePowerForChannel方法来监控iPad / iPhone应用程序的麦克风输入电平。 I have a callback which polls the average level in a loop — on the iPhone it works fine and returns sensible levels, but for some reason on the iPad it always returns -120.0. 我有一个回调轮询循环中的平均水平 - 在iPhone上它工作正常并返回合理的水平,但由于某种原因在iPad上它总是返回-120.0。

Here's some of my setup code: 这是我的一些设置代码:

- (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 well as my start recording method: 以及我的开始录制方法:

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

and a bit of the levelTimer 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]);

 ...

}

Where on the iPhone, the NSLog statement will return sensible values, and the iPad will always return -120.0. 在iPhone上,NSLog语句将返回合理的值,iPad将始终返回-120.0。

Note: I'm using this inside of a cocos2d application. 注意:我在cocos2d应用程序中使用它。 For some reason, if I restart the current scene on the iPad, the mic levels will return correct values. 出于某种原因,如果我重新启动iPad上的当前场景,麦克风级别将返回正确的值。

Anyone have any suggestions? 有人有什么建议吗? I'm seriously at a loss here. 我在这里真的很茫然。 Thanks! 谢谢!

I had the same issue. 我遇到过同样的问题。 I found setting the category to AVAudioSessionCategoryPlayAndRecord fixes it: 我发现将类别设置为AVAudioSessionCategoryPlayAndRecord修复它:

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

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

Yes, I did too. 是的,我也是。 There is only one shared AVAudioSession. 只有一个共享的AVAudioSession。 Setting its category affects all recorders and players, so setting the category to AVAudioSessionCategoryPlay in one area of the app for example disables recorders in other areas. 设置其类别会影响所有录像机和播放器,因此在应用程序的一个区域中将类别设置为AVAudioSessionCategoryPlay会禁用其他区域中的录像机。

Another possible cause of this is really simple, be sure you're calling [recorder record]; 另一个可能的原因很简单,确保你正在调用[录音机记录];

That line was accidentally deleted and it took us a while to recognize that as the cause of the -120 values being returned on the meter. 那条线被意外删除了,我们花了一段时间才意识到这是因为仪表上返回-120值的原因。

HTH HTH

1) Make sure you have the permission: 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) Make sure your path is legitimate (/dev/null ok??): 2)确保你的路径是合法的(/ dev / null ok ??):

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

3) activate audioSession 3)激活audioSession

 [audioSession setActive:YES error:&error];

4) Check all errors and return values, including 4)检查所有错误和返回值,包括

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

You need to init the AVAudioSession (it should be done from didMoveToview method, it might be a reason of the problem) 你需要初始化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)

and start recorder 并启动录音机

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

And get the decibels by calling 并通过电话获得分贝

let decibels = recorder.averagePower(forChannel: 0)

from -120 (min value) up to 0. Noice level of some cafe for example is -20 从-120(最小值)到0.一些咖啡馆的噪音水平例如是-20

here's the more detailed example http://www.mikitamanko.com/blog/2017/04/15/swift-how-to-get-decibels/ Note: use the update method as well. 这里是更详细的示例http://www.mikitamanko.com/blog/2017/04/15/swift-how-to-get-decibels/注意:也可以使用更新方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM