2012-05-08 3 views
5

Я пытаюсь понять уровень AVAudioPlayer и уровень звука. То, что у меня есть, - это объект «AudioPlayer», который воспроизводит короткий звуковой звук. Теперь я хочу вывести мощность этого звука (децибел). Почему-то я не думаю, что я делаю это правильно.Попытка понять уровень шума AVAudioPlayer и уровня звука

Выход NSLog этого является 0 -160,00 -160,00 1 -160,00 -160,00

Теперь в соответствии с Apple, «Возвращаемое значение 0 дБ показывает полную шкалу, или максимальную мощность, возврат значение -160 дБ указывает минимальную мощность «Значит ли это, что этот звук минимален? Я не думаю, что это правда, потому что аудио фрагмент довольно громкий звук. Я думаю, что здесь что-то не хватает, любые разъяснения будут оценены.

ответ

3

Вы обновляете, а затем запрашиваете значение счетчиков почти сразу после запуска звука, - 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]); 
} 
9

Есть несколько проблем с вашим кодом - Жак уже отметил, большинство из них.

Вы должны позвонить [audioPlayer updateMeters]; каждый раз перед чтением значений. Возможно, вам будет лучше создать экземпляр NSTimer.

Объявление iVar 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; 
} 

И вы должны быть хорошо идти.

Смежные вопросы