试图了解AVAudioPlayer和音频电平表(Trying to understand AVAud

2019-07-29 08:08发布

我想了解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的返回值表示最小功率”那么,这是否意味着这声音是最小功率? 我不认为,因为音频片段是一个相当响亮的声音,这是真实的。 我想我在这里失去了一些东西,任何澄清,将不胜感激。

Answer 1:

您要更新,然后问了米的声音开始后的值几乎立即-这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]);
}


Answer 2:

有几个问题与您的代码 - 雅克已经指出了其中的大多数。

你必须调用[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;
}

你应该是好去。



文章来源: Trying to understand AVAudioPlayer and audio level metering