author | sheepluva |
Tue, 22 Jun 2021 22:13:55 +0200 | |
changeset 15802 | d5c37e78ab83 |
parent 12872 | 00215a7ec5f5 |
permissions | -rw-r--r-- |
// MXAudioPlayerFadeOperation.m // // Created by Andrew Mackenzie-Ross on 30/11/10. // mackross.net. // #import "MXAudioPlayerFadeOperation.h" #import <AVFoundation/AVFoundation.h> #define SKVolumeChangesPerSecond 15 @interface MXAudioPlayerFadeOperation () @property (nonatomic, strong, readwrite) AVAudioPlayer *audioPlayer; - (void)beginFadeOperation; - (void)finishFadeOperation; @end @implementation MXAudioPlayerFadeOperation #pragma mark - #pragma mark Properties @synthesize audioPlayer = _audioPlayer; @synthesize fadeDuration = _fadeDuration; @synthesize finishVolume = _finishVolume; @synthesize playBeforeFade = _playBeforeFade; @synthesize pauseAfterFade = _pauseAfterFade; @synthesize stopAfterFade = _stopAfterFade; @synthesize delay = _delay; #pragma mark - #pragma mark Accessors - (AVAudioPlayer *)audioPlayer { AVAudioPlayer *result; @synchronized(self) { result = _audioPlayer; } return result; } - (void)setAudioPlayer:(AVAudioPlayer *)anAudioPlayer { @synchronized(self) { if (_audioPlayer != anAudioPlayer) { _audioPlayer = anAudioPlayer; } } } #pragma mark - #pragma mark NSOperation - (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration withDelay:(NSTimeInterval)timeDelay { if ((self = [super init])) { self.audioPlayer = player; [player prepareToPlay]; _fadeDuration = duration; _finishVolume = volume; _playBeforeFade = YES; _stopAfterFade = NO; _pauseAfterFade = (volume == 0.0) ? YES : NO; _delay = timeDelay; } return self; } - (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration { return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:duration withDelay:0.0]; } - (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume { return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:1.0]; } - (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player { return [self initFadeWithAudioPlayer:player toVolume:0.0]; } - (id) init { ALog(@"Failed to init class (%@) with AVAudioPlayer instance, use initFadeWithAudioPlayer:",[self class]); return nil; } - (void)main { @autoreleasepool { [NSThread sleepForTimeInterval:_delay]; if ([self.audioPlayer isKindOfClass:[AVAudioPlayer class]]) { [self beginFadeOperation]; } else { ALog(@"AudioPlayerFadeOperation began with invalid AVAudioPlayer"); } } } - (void)beginFadeOperation { if (![self.audioPlayer isPlaying] && _playBeforeFade) [self.audioPlayer play]; if (_fadeDuration != 0.0) { NSTimeInterval sleepInterval = (1.0 / SKVolumeChangesPerSecond); NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate]; NSTimeInterval now = startTime; float startVolume = [self.audioPlayer volume]; while (now < (startTime + _fadeDuration)) { float ratioOfFadeCompleted = (now - startTime)/_fadeDuration; float volume = (_finishVolume * ratioOfFadeCompleted) + (startVolume * (1-ratioOfFadeCompleted)); [self.audioPlayer setVolume:volume]; [NSThread sleepForTimeInterval:sleepInterval]; now = [[NSDate date] timeIntervalSinceReferenceDate]; } [self.audioPlayer setVolume:_finishVolume]; [self finishFadeOperation]; } else { [self.audioPlayer setVolume:_finishVolume]; [self finishFadeOperation]; } } - (void)finishFadeOperation { if ([self.audioPlayer isPlaying] && _pauseAfterFade) [self.audioPlayer pause]; if ([self.audioPlayer isPlaying] && _stopAfterFade) [self.audioPlayer stop]; } @end