Программное уменьшение громкости AVAudioPlayerNode

У меня есть установка AVAudioEngine с AVAudioPlayerNode, которая воспроизводит фоновую музыку.

Я пытаюсь найти лучший подход для создания затухания громкости на узле за 2-секундный таймфрейм. Я рассматриваю возможность использования CADisplayLink для этого. Мне было интересно, есть ли у кого-нибудь опыт работы с этим сценарием и может ли он посоветовать мне свой подход?


person Danny Bravo    schedule 07.10.2015    source источник


Ответы (3)


Мой подход ниже. Обратите внимание, что я назначаю таймер переменной-члену, чтобы я мог сделать его недействительным в других точках (viewWillDisappear, delloc и т. Д.). Я волновался, что это не будет звучать гладко, но я попробовал, и он работает нормально, не нужно было использовать CADisplayLink.

- (void)fadeOutAudioWithDuration:(double)duration {
    double timerInterval = 0.1;
    NSNumber *volumeInterval = [NSNumber numberWithDouble:(timerInterval / duration)];
    self.fadeOutTimer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(fadeOutTimerDidFire:) userInfo:volumeInterval repeats:YES];
}

- (void)fadeOutTimerDidFire:(NSTimer *)timer {
    float volumeInterval = ((NSNumber *)timer.userInfo).floatValue;
    float currentVolume = self.audioEngine.mainMixerNode.outputVolume;
    float newValue = MAX(currentVolume - volumeInterval, 0.0f);
    self.audioEngine.mainMixerNode.outputVolume = newValue;
    if (newValue == 0.0f) {
        [timer invalidate];
    }
}
person Nigam Shah    schedule 01.07.2016

Вы можете использовать глобальное усиление в эквалайзере.

Например

AVAudioUnitEQ *Volume;
Volume = [[AVAudioUnitEQ alloc] init];
[engine attachNode:Volume];
[engine connect:Volume to:engine.outputNode format:nil];

А потом

Volume.globalGain = /*here your floatValue*/
person Ray    schedule 13.01.2016

Если кто-то вроде меня все еще ищет ответ:

  1. Как видно из документации, AVAudioPlayerNode не поддерживает свойство громкости, а только узел AVAudioMixerNode. Поэтому убедитесь, что вы конвертируете свой AVAudioPlayerNode в AVAudioMixerNode.

  2. Вот код, используемый для постепенного появления, исчезновения и общего исчезновения (Swift 5)

     typealias Completion = (() -> Void)
    
     let mixer = AVAudioMixerNode()
    
     func fade(from: Float, to: Float, duration: TimeInterval, completion: Completion?) {
         let stepTime = 0.01
         let times = duration / stepTime
         let step = (to - from) / Float(times)
         for i in 0...Int(times) {
             DispatchQueue.main.asyncAfter(deadline: .now() + Double(i) * stepTime) {
                 mixer.volume = from + Float(i) * step
    
                 if i == Int(times) {
                     completion?()
                 }
             }
         }
     }
    
     func fadeIn(duration: TimeInterval = 1.3, completion: Completion? = nil) {
         fade(from: 0, to: 1, duration: duration, completion: completion)
     }
    
     func fadeOut(duration: TimeInterval = 1.3, completion: Completion? = nil) {
         fade(from: 1, to: 0, duration: duration, completion: completion)
     }
    
person iago849    schedule 17.03.2021