【问题标题】:Trying to understand AVAudioPlayer and audio level metering试图了解 AVAudioPlayer 和音频电平表
【发布时间】:2012-05-08 18:37:35
【问题描述】:

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

【问题讨论】:

    标签: iphone objective-c xcode ipad avaudioplayer


    【解决方案1】:

    您的代码有几个问题 - Jacques 已经指出了其中的大部分。

    在读取值之前,您必须每次调用[audioPlayer updateMeters];。 你最好实例化一个NSTimer

    在您的班级 @interface 中声明一个 iVar NSTimer *playerTimer;

    此外,在您的班级中采用&lt;AVAudioPlayerDelegate&gt; 也没有什么坏处,因此您可以在玩家完成游戏后使计时器无效。

    然后将代码更改为:

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

    你应该很高兴。

    【讨论】:

      【解决方案2】:

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

      您也永远不会真正获得通道 > 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]);
      }
      

      【讨论】:

        猜你喜欢
        • 2013-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 2016-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多