我想了解AVAudioPlayer和音频电平表。 我有下面是一个对象“AudioPlayer”正在播放一个简短的音频声音。 现在,我要输出这个声音(分贝)的功率。 不知怎的,我不认为我这样做的权利。
audioPlayer.meteringEnabled = YES;
[audioPlayer play];
int channels = audioPlayer.numberOfChannels;
[audioPlayer updateMeters];
for (int i=0; i<channels; i++) {
//Log the peak and average power
NSLog(@"%d %0.2f %0.2f", i, [audioPlayer peakPowerForChannel:0],[audioPlayer averagePowerForChannel:0]);
这样做的NSLog的输出为0 -160.00 -160.00 -160.00 1 -160.00
根据苹果现在“0分贝的返回值表示满刻度,或最大功率; -160 dB的返回值表示最小功率”那么,这是否意味着这声音是最小功率? 我不认为,因为音频片段是一个相当响亮的声音,这是真实的。 我想我在这里失去了一些东西,任何澄清,将不胜感激。
您要更新,然后问了米的声音开始后的值几乎立即-这updateMeters
可能运行几十毫秒的您发送后play
。 所以,如果有在剪辑的开始任何的沉默,你很可能会得到正确的阅读。 你应该试图拖延你检查,你可能还需要发送updateMeters
在循环中 ,你检查值权之前。
你也从来没有真正得到计值频道> 0,因为你通过0不管的价值是什么i
是在循环。 我想你的意思是这样:
for (int currChan = 0; currChan < channels; currChan++) {
//Log the peak and average power
NSLog(@"%d %0.2f %0.2f", currChan, [audioPlayer peakPowerForChannel:currChan], [audioPlayer averagePowerForChannel:currChan]);
}
有几个问题与您的代码 - 雅克已经指出了其中的大多数。
你必须调用[audioPlayer updateMeters];
读值之前各一次。 你可能会最好关闭实例化NSTimer
。
声明伊娃NSTimer *playerTimer;
在你的类@interface
。
此外,它不会伤害到采用<AVAudioPlayerDelegate>
在您的类,所以你就可以播放播放完毕后无效计时器。
然后改变你的代码:
audioPlayer.meteringEnabled = YES;
audioPlayer.delegate = self;
if (!playerTimer)
{
playerTimer = [NSTimer scheduledTimerWithTimeInterval:0.001
target:self selector:@selector(monitorAudioPlayer)
userInfo:nil
repeats:YES];
}
[audioPlayer play];
收藏此两种方法类:
-(void) monitorAudioPlayer
{
[audioPlayer updateMeters];
for (int i=0; i<audioPlayer.numberOfChannels; i++)
{
//Log the peak and average power
NSLog(@"%d %0.2f %0.2f", i, [audioPlayer peakPowerForChannel:i],[audioPlayer averagePowerForChannel:i]);
}
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
NSLog (@"audioPlayerDidFinishPlaying:");
[playerTimer invalidate];
playerTimer = nil;
}
你应该是好去。