Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAudioPlayer fade volume out

People also ask

What is fade in and out in audio?

Fade In (1) begins with silence and gradually becomes louder until full volume. Fade Out (2) makes audio progressively softer until it can no longer be heard.

What is fade out in audio editing?

A recorded song may be gradually reduced to silence at its end (fade-out), or may gradually increase from silence at the beginning (fade-in). Fading-out can serve as a recording solution for pieces of music that contain no obvious ending.


Here's how I'm doing it:

-(void)doVolumeFade
{  
    if (self.player.volume > 0.1) {
        self.player.volume = self.player.volume - 0.1;
        [self performSelector:@selector(doVolumeFade) withObject:nil afterDelay:0.1];       
     } else {
        // Stop and get the sound ready for playing again
        [self.player stop];
        self.player.currentTime = 0;
        [self.player prepareToPlay];
        self.player.volume = 1.0;
    }
}

.

11 years later: do note that setVolume#fadeDuration now exists!


Swift has an AVAudioPlayer method you can use for fading out which was included as of iOS 10.0:

var audioPlayer = AVAudioPlayer()
...
audioPlayer.setVolume(0, fadeDuration: 3)

I tackled this problem using an NSOperation subclass so fading the volume doesn't block the main thread. It also allows fades to be queued and and forgotten about. This is especially useful for playing one shot sounds with fade-in and fade-out effects as they are dealloced after the last fade is completed.

// Example of MXAudioPlayerFadeOperation in NSOperationQueue 
 NSOperationQueue *audioFaderQueue = [[NSOperationQueue alloc] init];
  [audioFaderQueue setMaxConcurrentOperationCount:1]; // Execute fades serially.

  NSString *filePath = [[NSBundle mainBundle] pathForResource:@"bg" ofType:@"mp3"]; // path to bg.mp3
  AVAudioPlayer *player = [[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:NULL] autorelease];
  [player setNumberOfLoops:-1];
  [player setVolume:0.0];

  // Note that delay is delay after last fade due to the Operation Queue working serially.
  MXAudioPlayerFadeOperation *fadeIn = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:player toVolume:1.0 overDuration:3.0];
  [fadeIn setDelay:2.0];
  MXAudioPlayerFadeOperation *fadeDown = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:player toVolume:0.1 overDuration:3.0];
  [fadeDown setDelay:0.0];
  MXAudioPlayerFadeOperation *fadeUp = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:player toVolume:1.0 overDuration:4.0];
  [fadeUp setDelay:0.0];
  MXAudioPlayerFadeOperation *fadeOut = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:player toVolume:0.0 overDuration:3.0];
  [fadeOut setDelay:2.0];

  [audioFaderQueue addOperation:fadeIn]; // 2.0s - 5.0s
  [audioFaderQueue addOperation:fadeDown]; // 5.0s - 8.0s
  [audioFaderQueue addOperation:fadeUp]; // 8.0s - 12.0s
  [audioFaderQueue addOperation:fadeOut]; // 14.0s - 17.0s

  [fadeIn release];
  [fadeDown release];
  [fadeUp release];
  [fadeOut release];

For MXAudioPlayerFadeOperation class code see this post.


I ended up combining some of the answer together and converted it to Swift ending up in this method:

func fadeVolumeAndPause(){
    if self.player?.volume > 0.1 {
        self.player?.volume = self.player!.volume - 0.1

        var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
        dispatch_after(dispatchTime, dispatch_get_main_queue(), {
            self.fadeVolumeAndPause()
        })

    } else {
        self.player?.pause()
        self.player?.volume = 1.0
    }
}