AVAudioRecorder AveragePowerForChannel 始终返回 -120.0
我正在尝试使用 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 上重新启动当前场景,麦克风电平将返回正确的值。
有人有什么建议吗?我在这里严重不知所措。 谢谢!
I'm trying to use AVAudioRecorder's averagePowerForChannel method to monitor input levels on the microphone for an iPad/iPhone app. 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.
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:
- (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.
Note: I'm using this inside of a cocos2d application. For some reason, if I restart the current scene on the iPad, the mic levels will return correct values.
Anyone have any suggestions? I'm seriously at a loss here.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我有同样的问题。我发现将类别设置为 AVAudioSessionCategoryPlayAndRecord 可以解决此问题:
I had the same issue. I found setting the category to AVAudioSessionCategoryPlayAndRecord fixes it:
您需要初始化 AVAudioSession (应该从 didMoveToview 方法完成,这可能是问题的原因)
并启动录音机
调用来获取分贝。
并通过从 -120(最小值)到 0 某些咖啡馆的噪音水平示例是 -20
这是更详细的示例 http://www.mikitamanko.com/blog/2017/04/15/swift-how-to-get-decibels/ 注意:也使用更新方法。
You need to init the AVAudioSession (it should be done from didMoveToview method, it might be a reason of the problem)
and start recorder
And get the decibels by calling
from -120 (min value) up to 0. Noice level of some cafe for example is -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.
是的,我也这么做了。只有一个共享的 AVAudioSession。设置其类别会影响所有录音机和播放器,因此,例如,在应用程序的一个区域中将类别设置为 AVAudioSessionCategoryPlay 会禁用其他区域中的录音机。
Yes, I did too. There is only one shared 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.
另一个可能的原因很简单,请确保您正在调用[录音机记录];
该行被意外删除,我们花了一段时间才意识到这是仪表上返回 -120 值的原因。
华泰
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.
HTH
1) 确保您有权限:
2) 确保您的路径是合法的(/dev/null ok??):
3) 激活audioSession
4) 检查所有错误和返回值,包括
1) Make sure you have the permission:
2) Make sure your path is legitimate (/dev/null ok??):
3) activate audioSession
4) Check all errors and return values, including