试图了解AVAudioPlayer和音频电平计量

时间:2012-05-08 18:37:35

标签: iphone objective-c xcode ipad avaudioplayer

我正在尝试了解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 1 -160.00 -160.00

现在根据Apple“0 dB的返回值表示满量程或最大功率; -160 dB的返回值表示最小功率”这是否意味着此声音处于最小功率?我不认为这是真的,因为音频片段是一个相当响亮的声音。我想我在这里遗漏了一些东西,任何澄清都会受到赞赏。

2 个答案:

答案 0 :(得分:9)

你的代码有几个问题 - 雅克已经指出了大部分问题。

每次阅读值之前,您都必须致电[audioPlayer updateMeters];。 你可能最好实例化一个NSTimer

在您的班级NSTimer *playerTimer;中声明iVar @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;
}

你应该好好去。

答案 1 :(得分:3)

您正在更新,然后在声音开始后几乎立即询问电表的值 - 发送updateMetersplay可能正在运行几十毫秒。因此,如果剪辑开头有任何沉默,你很可能会得到正确的读数。您应该尝试延迟检查,并且在检查值之前,您可能还需要在循环中发送updateMeters

你也从未真正获得频道的电表值&gt; 0,因为无论循环中i的值是什么,都传递0。我想你打算这样做:

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